Visual c - programare avansată scrie un manager de fișiere


nbspnbspBună, dragi abonați.
nbspnbspRad vă informează că în secțiunea „MFC - simplu și complex,“ a lansat o nouă serie de articole „Crearea File Manager“, care va fi discutat în detaliu procesul de dezvoltare a programului analogic cunoscut pentru Windows Commander - o. Sper că veți fi interesat.

nbspnbspÎntotdeauna, puteți să vă trimiteți dorințele făcând clic pe acest link.

Cu sinceritate. Sincer, Vakhturov Victor.

MFC este simplu și complex [Crearea unui manager de fișiere (partea 1)].

nbspnbspA cum am scris în ultimul buletin informativ, astăzi vom începe să luăm în considerare un nou subiect.

nbspnbsp Vreau să vă ofer o lecție interesantă - vom scrie un manager de fișiere. Vom scrie, desigur, folosind mediul de dezvoltare Microsoft Visual C ++ și biblioteca MFC.

nbspnbspAstfel, vom crea o interfață - "fața" produsului software și apoi vom "umple" cu "creier".

nbspnbspNu vom gândi mult timp la ce fel de interfață vom avea. Imaginea clasică a interfeței de utilizator a managerului de fișiere a existat o perioadă lungă de timp (de la primele versiuni ale programului Norton Commander). Apoi a fost reprodus în multe programe de shell care rulează sub DOS și moștenite de administratorii de fișiere de programe care lucrează sub Windows. Astfel, "centrul" întregii interfețe va fi, ca de obicei, două panouri care au același aspect (conținând liste de fișiere și directoare, precum și unele comenzi) și care poartă aceeași sarcină funcțională.

nbspnbspAșa cum am spus mai sus, nu vom depăși exemplul. În plus, învățați mai bine prin reproducerea unor lucruri clasice. De aceea, am ales ca model este un exemplu clasic - de acest gen printre programele eșantion din această clasă - pentru Windows Commander (acum este, cu toate acestea, numit Total Commander, pentru că unchiul Billy este foarte preocupat de puritatea percepției lor logo-ul orificiile de ventilație).
Așa este. Vom încerca pur și simplu să reproducem interfața Total Commander într-o oarecare măsură. De fapt, acest lucru nu este deloc dificil. Asta mi-a luat doar câteva ore. Dar dacă înțelegeți în mod clar ce trebuie să faceți.
Vă promit că, după citirea acestei serii de articole, veți putea dezvolta cu interfețe de utilizator MFC mult mai complexe decât Total Commander.

nbspnbspPentru regula principală în activitatea noastră vom adopta principiul. "împărțiți și cuceresc". Vom împărți problema în părți și fiecare parte - chiar și în părți. Și să pună în aplicare în mod consecvent ceea ce este necesar în această etapă. Vom construi un program de module care pot fi utilizate cu succes ulterior în alte aplicații.

nbspnbspO timp, aruncați o privire la interfața cu utilizatorul Total Commander.
Două panouri separate. SCHENGEN. Asta va fi discutată astăzi.
Despre ferestrele partajate. Despre separatoare.

Splittere.

nbspnbspCând începeți să creați proiectul, permiteți-mi să explic un pic de teorie (pentru, în cazul în care fără ea, nativ).

nbspnbsp Urmărind dezvoltarea interfeței de utilizare a aplicațiilor care rulează pe Windows, puteți observa progresele evidente în acest domeniu în ultimii ani. Interfața devine din ce în ce mai convenabilă și mai plăcută, din ce în ce mai prietenoasă. Un rol din ce în ce mai mare în acest proces îl joacă controalele Windows "non-native" care au funcționalități neimplementate în elementele standard și create de dezvoltatori pentru a rezolva probleme specifice.

nbspnbsp Ciudat cum se pare, splitterii se referă la grupul de controale "non-standard". Aceasta înseamnă că nu există o clasă de ferestre splitter definită de sistemul de operare și, dacă este necesar, va trebui să se implementeze ea însăși (splitter-ul). Din fericire, vânzătorii au avut grijă de nevoile programatorilor, iar bibliotecile de clasă pentru construirea interfeței cu utilizatorul includ de obicei clase care încapsulează funcționalitatea ferestrelor partajate.

nbspnbspÎn cazul în care vă uitați chiar mai mult la interfața utilizator a programelor care utilizează splittere, puteți vedea că nu toate separatoarele sunt aceleași și, evident, au diferite principii de funcționare. Într-adevăr, există de obicei două tipuri de separatoare. prietenos și ierarhic.

Să trăim mai mult pe fiecare tip.

nbspnbspPuteți vedea acest tip de splitter destul de des. Un exemplu viu al unei aplicații care utilizează un splitter prietenos este aplicația Windows hh.exe.
Înainte de Visual Studio NET și sistemul său de referință, toate fișierele de ajutor MSDN au fost vizualizate cu această aplicație. Rulați ajutorul Windows și veți înțelege despre ce vorbesc.

nbspnbspDispozitivul normal prietenos este o fereastră poziționată între ferestrele pe care le distribuie și având una cu ferestrele paranteze. Când „surprinde“ mouse-ul pe care fereastra, se mișcă pe orizontală sau pe verticală (în funcție de ce - splitter orizontal sau vertical), urmând indicatorul mouse-ului, sau simultan cu mișcarea sa (ceea ce duce la retrasarea frecvente ferestre partajate), sau după "Release" modifică dimensiunea celor mai multe ferestre partajate. Dezavantajele utilizării acestui splitter este posibilitatea de probleme cu redesenarea ca ferestrele comune, și ferestrele splitter, precum și ceea ce este în mod obișnuit splitter astfel încât să puteți „părți“ doar două ferestre. Încercați din nou pentru a porni Ajutor Windows și mutați splitter suficient de mult spre stânga și apoi dreapta - dreptul de poziția sa inițială. Am observat de mai multe ori că nu se repetă "urme" pe banda ferestrei splitter.

nbspnbspEste un astfel de splitter implementat în MFC. Principiul acestui splitter este că splitterul este fereastra părinte pentru toate ferestrele "partajate". Aceasta este, de obicei, utilizarea unui astfel de splitter acesta este poziționat în interiorul ferestrei - cadru în așa fel încât să umple întreaga zonă de client, și ferestre, care trebuie să fie separate ca un splitter creează copil ferestre de splitter. Când „glisarea“ schimbul acestor splitter, de obicei, blocuri sunt afișate într-o zonă dreptunghiulară ocupată de ele și produce caracteristica LockWindowUpdate desen „glisare și zona de picătură.“ Dezavantajul acestei abordări este că, la momentul „drag and drop“ blocuri toate de ieșire grafică a tuturor „partajate“ ferestre.
Dar avantajele unui astfel de splitter includ capacitatea de a "împărți" mai mult de două ferestre simultan atât pe orizontală cât și pe verticală. Cu alte cuvinte, puteți crea o întreagă "matrice" de ferestre care vor fi poziționate în fereastra splitter.

nbspnbspAcest lucru se încheie cu digresiunea lirică în câmpul teoretic și începem munca practică.

nbspnbspPentru a începe, vom crea proiectul.

nbspnbspCreați-l utilizând un expert normal (MFC AppWizard (exe)) Visual C ++ pentru a crea aplicații MFC.
Am sunat la proiectul VCmd. Pe scurt și pur și simplu.
În prima etapă a expertului, selectați tipul de document unic al aplicației și dezactivați suportul arhitecturii Document / imagine deselectând caseta de validare corespunzătoare. Înainte - toate în mod prestabilit la numărul de pas 4 al expertului. Aici, debifați pur și simplu caseta "Bară inițială de stare". Așa că am scăpat de linia de stare în avans (în Total Commander nu este). Asta e tot. Puteți apăsa butonul "gata". Proiectul a fost creat. După compilare, vom vedea doar un cadru de ferestre cu o bară de instrumente și un meniu. Bara de instrumente pe care o vom rezolva mai târziu și acum aș vrea să văd mai mult de două ferestre separate de un splitter.

nbspnbspCând creați un proiect cu arhitectura Document / Image, puteți crea o fereastră separată de un splitter simultan. Puteți crea chiar ceva de genul "bilet" Windows Explorer, dar, în primul rând, nu vrem un dirijor. În al doilea rând, nu avem nevoie de clase de documente în proiectul nostru - nu avem nevoie de serializare și de alte capabilități. Avem nevoie de un cadru de aplicare ușor și elegant. Asta o să facem.

nbspnbsp Mai întâi de toate, rețineți că dezvoltatorii buni de la Microsoft și aici au lăsat o mică "urmă" a documentației / aspectului arhitecturii. Proiectul are o clasă CChildView, derivată din clasa CWnd. Aceasta este clasa ferestrei create în zona client a ferestrei - cadrul și ocupând aproape întreaga zonă client (cu excepția zonei ocupate de bara de instrumente).
Obiectul clasa CChildView m_wndView este o variabilă componentă a clasei CMainFrame a clasei ferestrei principale a cadrului.

nbspnbsp Acum scapa de această fereastră, înlocuindu-l cu un splitter.

nbsp2. Eliminați crearea ferestrei m_wndView din funcția CMainFrame :: OnCreate. Adică ștergeți liniile:

nbspif (! m_wndView.Create (NULL, NULL, AFX_WS_DEFAULT_VIEW,
nbspnbspCRect (0, 0, 0, 0), acest lucru, AFX_IDW_PANE_FIRST, NULL))
nbsp nbspnbspTRACE0 ("Nu sa reușit crearea ferestrei de vizualizare \ n");
nbspnbspreturn -1;
nbsp>

nbsp3. În funcțiile CMainFrame :: OnSetFocus și CMainFrame :: OnCmdMsg, înlocuiți m_wndView cu m_wndSplitter.

nbsp4. Adăugați două variabile mai protejate la clasa CMainFrame:

nbspnbsp acest lucru în timp ce există ferestre - stubs pentru a le introduce în splitter și pentru a obține comportamentul corect.

nbsp5. Adăugați funcția OnCreateClient la clasa CMainFrame cu ajutorul instrumentului ClassWizard, în care adăugăm următorul cod pentru a crea un fereastră divizor și copil:

nbspBOOL CMainFrame :: OnCreateClient (LPCREATESTRUCT lpcs, CCreateContext * pContext)
nbsp nbspnbspif (! m_wndSplitter.CreateStatic (aceasta, 1, 2))
nbspnbspnbspnbspreturn FALSE;

nbspnbsp // Cod pentru crearea de liste, adăugarea de coloane la acestea și instalarea celor avansate
nbspnbsp // stilurile vor fi, desigur, înlocuite cu codul de inițializare a componentelor
nbspnbsp // manager de fișiere pentru afișarea conținutului
nbspnbsp // directoare pe care le vom scrie ulterior.

nbspnbspif (! m_wndLeftPane.Create (WS_CHILD | WS_VISIBLE,
nbspnbspnbspnbspCRect (0, 0, 0, 0), m_wndSplitter,
nbspnbspnbspnbspm_wndSplitter.IdFromRowCol (0, 0)))
nbspnbspnbspnbspreturn FALSE;

nbspnbspif (! m_wndRightPane.Create (WS_CHILD | WS_VISIBLE,
nbspnbspnbspnbspCRect (0, 0, 0, 0), m_wndSplitter,
nbspnbspnbspnbspm_wndSplitter.IdFromRowCol (0, 1)))
nbspnbspnbspnbspreturn FALSE;

nbspnbspm_wndLeftPane.InsertColumn (0, "Nume", LVCFMT_LEFT, 60, 0);
nbspnbspm_wndLeftPane.InsertColumn (1, "Ext", LVCFMT_LEFT, 28, 1);
nbspnbspm_wndLeftPane.InsertColumn (2, "Dimensiune", LVCFMT_LEFT, 32, 2);

nbspnbspm_wndRightPane.InsertColumn (0, "Nume", LVCFMT_LEFT, 60, 0);
nbspnbspm_wndRightPane.InsertColumn (1, "Ext", LVCFMT_LEFT, 28, 1);
nbspnbspm_wndRightPane.InsertColumn (2, "Dimensiune", LVCFMT_LEFT, 32, 2);

nbspnbspreturn CFrameWnd :: OnCreateClient (lpcs, pContext);
nbsp>

nbspWell, vedem o imagine plină de bucurie. fereastra-cadru, bara de instrumente (în starea inițială), un separator al cărui splitter este "lipit" de o margine a ferestrei.

nbspnbspNu este foarte frumos. Nu-i așa?

nbspnbsp Puteți deplasa splitter-ul splitter după cum este necesar, dar dacă schimbați dimensiunea ferestrei principale a ramei, splitterul splitter nu se va mișca. Adică, acesta (separatorul) are o poziție fixă.
Este trist. La urma urmei, în Total Commander, splitterul menține o poziție relativă (procentul lățimii ferestrei din dreapta în splitter la lățimea ferestrei din stânga este invariabil). Dar splitterul standard MFC nu acceptă această funcționalitate. Dar aceasta este problema și trebuie rezolvate.

nbspnbsp În următorul articol, voi vorbi despre cum să finalizați splitterul MFC, adăugând funcționalități utile.

nbspnbspnbspnbspToate pentru moment.

Codul sursă al proiectului considerat în articol poate fi găsit pe site-ul SoftMaker.fatal.ru de pe pagina principală a proiectului.