Trecând prin ferestrele ferestrelor

Treci prin ferestrele Windows.

Toate sau aproape toate (deși nu mă angajez să spun exact ce constituie o excepție) în Windows are Handle. O traducere interesantă a sistemului Socrates a termenului "Handle" - "Pen", în rusă tehnică normală, va fi un descriptor (determinant, identificator, descriptor). Astfel, mânerul este un identificator unic al oricărei resursă Windows. Fiecare fereastră are un descriptor propriu.







Ierarhia ferestrelor în sistem este reprezentată astfel:

  • fiecare fereastră are o listă de ferestre slave. Lista poate fi goală, în cazul în care stilul ferestrei nu prevede stocarea elementelor subordonate.
  • fiecare fereastră are o fereastră proprietar. Descriptorul ferestrei proprietarului va fi zero (gol) dacă fereastra are un nivel superior de cuibare, de exemplu, fereastra principală a programului.
  • pentru fiecare fereastră puteți obține următoarea și cea precedentă, la nivelul cuiburilor, fereastra.
Avem o structură arborescentă cu capacitatea de a naviga pe copac, atât în ​​sus, cât și în jos, nivelul cuiburilor și orizontal. Navigarea orizontală este posibilă numai pe ferestrele care au aceeași fereastră de proprietar. Luați în considerare o schemă simplă:

Pentru fereastra 3, proprietarul ferestrei 1, ferestrele nivelului său - Fereastra 3 ... Fereastra N și ferestrele copilului corespunzător - Fereastra N + 1 ... N + M. În acest caz, nu puteți obține în mod direct identificatorii altor ferestre utilizând inițializatorul ferestrei sursă.

Să ne întoarcem la instrumentul Windows API, care permite implementarea celor de mai sus.

Ferestrele funcționează WinAPI, utilizate în acest proiect.

funcția GetWindow (hWnd: HWND; uCmd: UINT): HWND;

Funcția returnează un descriptor de fereastră, cu o poziție dată în ierarhia ferestrelor față de fereastra specificată.
  • hWnd - descriptorul ferestrei sursă.
  • uCmd - direcția de comunicare, adică în sus, în jos sau orizontal.
Valorile variabilei uCmd:
  • GW_CHILD - Returnează descriptorul ferestrei copil (slave), care se află în poziția superioară a comenzii Z. Dacă fereastra nu are ferestre copil, 0 este returnată.
  • GW_HWNDFIRST - Returnează mânerul ferestrei în poziția de comandă Z de top, la același nivel cu fereastra originală.
  • GW_HWNDLAST - Returnează mânerul ferestrei în poziția de comandă Z mai mică, la același nivel cu fereastra originală.
  • GW_HWNDNEXT - Returnează mânerul ferestrei în următoarea poziție de comandă Z de același nivel cu fereastra originală.
  • GW_HWNDPREV - Returnează mânerul ferestrei în poziția anterioară de comandă Z de același nivel cu fereastra originală.
  • GW_OWNER - Returnează mânerul ferestrei proprietarului ferestrei sursă. Dacă fereastra are un nivel zero de cuibare, este returnat 0.

Despre comanda Z: fereastra "de sus" de pe ecran are o pozitie zero, urmatoarea, fereastra suprapusa - prima pozitie si asa mai departe pana la partea de jos a ecranului. Astfel, noțiunea de tridimensionalitate se realizează, deși într-o carte inteligentă am citit că un mediu cu mai multe ferestre are în mod condiționat 2.5-dimensionalitate (2.5D).

Cu ajutorul acestei funcții, putem obține o listă a tuturor ferestrelor sistemului cu o plimbare simplă în copac (sarcina din primul an al universității "Tree crossing").

Vom avea nevoie de câteva funcții WinAPI:







funcția GetWindowText (hWnd: HWND; lpString: PChar; nMaxCount: Integer): Integer;

Funcția preia textul ferestrei prin identificatorul său și returnează lungimea de citire a șirului de text al ferestrei.
  • hWnd este identificatorul ferestrei.
  • lpString - textul ferestrei în variabila PChar. Variabila trebuie creată în avans.
  • nMaxCount este lungimea stringului lpString.
funcția GetClassName (hWnd: HWND; lpClassName: PChar; nMaxCount: Integer): Integer;
  • hWnd este identificatorul ferestrei.
  • lpClassName este numele clasei de fereastră din variabila PChar. Variabila trebuie creată în avans.
  • nMaxCount este lungimea șirului lpClassName.
funcția GetMenu (hWnd: HWND): HMENU;
Funcția returnează identificatorul de meniu prin identificatorul ferestrei trecute.

Să mergem la construirea directă a programului.

Rulați Delphi și creați o nouă aplicație în meniul File-> New Application.

Nu vom fi distrași de interfața cu heaped, nu mă îndoiesc că cei mai mulți oameni fac acest lucru cu ușurință, ca "doi octeți pentru a transmite";). Să construim ceva la "Explorer". Apelați formularul principal fmMain și modulul principal - Main.pas. Plasați componentele pe formular, după cum se arată în imagine:

În partea stângă a formularului este componenta Arbore: TTreeView, iar componenta client este componenta List: TListView.

Adăugați în formularul fmMain procedura de umplere a arborelui FillTree cu următorul conținut:

Acum, să încercăm să o înțelegem (vezi textul procedurii). Statutul - clasa TStatus Bar. Vă vom informa în bara de stare că actualizăm informațiile. Dezactivați afișarea actualizării copacului, astfel încât nimic să nu se înțepene pe ecran în timpul procesului de actualizare. Goliți arborele și creați un Buffer variabil, care va înregistra rezultatele șir ale funcțiilor WinAPI.

Următorul pas este să ajungeți la fereastra de sus și prima fereastră a sistemului. Apelam funcția GetWindow cu parametrul GW_OWNER - obținerea ferestrei proprietarului pornind de la fereastra principală a programului. Având o fereastră care nu are proprietar, găsim pentru această fereastră o fereastră cu zero ordine Z, apelând funcția GetWindow cu parametrul GW_HWNDFIRST - obținerea primei ferestre la acest nivel de cuibare. Acum putem începe să ocolim copacul ferestrelor, începând cu prima ordine de creștere a cuiburilor și a ordinii Z, apelând la procedura recursivă RegisterWindow.

Următoarele acțiuni sunt simple de dezamăgire (procedura RegisterWindow):

  • creați o variabilă de descriere a ferestrei;
  • obțineți textul, numele clasei și identificatorul de meniu descris mai sus prin funcțiile WinPI descrise mai sus și scrieți aceste valori la variabila ferestrei;
  • a crea un nod de copaci și a atribui o fereastră utilizatorului, specificând proprietarul nodului și atribuindu-i o valoare text;
  • obțineți identificatorul ferestrei copil și dacă identificatorul nu este egal cu 0, procesați-l recursiv, parcurgând parametrii primiți la RegisterWindow. În acest caz, ID-ul ferestrei copil primite și nodul copac nou creat sunt transmise procedurii;
  • Obțineți identificatorul de lângă fereastra curentă a aceluiași nivel de cuibărire. Și dacă nu este 0, treceți identificatorul primit și parametrul extern ParentTreeItem la RegisterWindow. În acest caz, nodurile copacului vor fi adăugate la același nivel ca nodul curent.
Dacă apelăm rutina FillTree în evenimentul FormCreate, copacul se va umple automat la pornirea programului. Creați o acțiune acRefresh: Acțiune și asociați-o cu butonul de actualizare din formular. În procesul de lansare a acțiunii, scriem următorul cod: Acum putem actualiza cu forța lista. Să trecem la afișarea tuturor informațiilor despre fereastră în componenta List: TListView. Procesăm evenimentul TTreeView.OnChange după cum urmează: Pentru a selecta elementul corespunzător arborelui (Nod: TTreeNode), adăugați rânduri către componenta List: TListView cu valorile tuturor câmpurilor din înregistrarea PNode ^.

Avem informații despre toate ferestrele și utilizând identificatorul de fereastră putem accesa parametrii ferestrei FOARTE LARGE prin intermediul WinAPI

Și de ce toate acestea sunt necesare?

Să ilustrăm cu patru exemple:
  • Ascundeți fereastra inutilă (citită, enervantă). De exemplu, fereastra sistemului de afișări banner. Se face astfel:
    ShowWindow (TNode (Tree.Selected.Data ^). Manipulați, sw_Hide).
    Adevărul de a ascunde în mod eficient această fereastră este să lucrați cu mesajele din seria ABM_ *, dar aceasta este o altă poveste.
  • Afișați fereastra ascunsă. Acțiune inversă:
    ShowWindow (TNode (Tree.Selected.Data ^) Manipulați, sw_Show).
    De exemplu, panoul cu butonul "Start" a zburat. Toate pictogramele din tava de sistem au dispărut. Fereastra de spectacol nu este o problemă.
  • Permiteți controlul restricționat:
    EnableWindow (TNode (Tree.Selected.Data ^). Manipulați, True).
    Pentru ceea ce este necesar, nu vom spune nici măcar.
  • Ucideți fereastra:
    PostMessage (TNode (Tree.Selected.Data ^). Maneta, wm_Close, 0,0).
    Pentru o explicație, a se vedea paragraful 3.






Articole similare

Trimiteți-le prietenilor: