Séta az ablakokon

Séta a Windows ablakokon.

Az összes vagy szinte mindegyik (bár nem vállalom, hogy azt mondja ki, ami pontosan kivétel) a Windows kezeli. A "Handle" - "Pen" kifejezés Socrates rendszerének érdekes fordítása, a normál műszaki orosz nyelvben leíró (meghatározó, azonosító, leíró). Így a fogantyú egyes Windows-erőforrások egyedi azonosítója. Minden ablaknak saját leírója van.

A rendszerben lévő ablakok hierarchiája tehát:

  • minden ablaknak van egy listája a slave ablakokról. A lista lehet üres, abban az esetben, ha az ablak stílus nem biztosítja az alárendelt elemek tárolását.
  • mindegyik ablak rendelkezik egy tulajdonosablakkal. A tulajdonos ablakának leírója nulla (üres), ha az ablak felső szintje van, például a fő programablak.
  • minden ablakhoz kapható a következő és az előző, fészkelő szintjén az ablak.
Van egy fa szerkezete, amely képes a fát navigálni a fészekszint felfelé és lefelé, valamint vízszintesen. A vízszintes navigáció csak olyan ablakokon lehetséges, amelyek ugyanazt a tulajdonos ablakot használják. Tekintsünk egy egyszerű rendszert:

A Window 3 esetében az ablak 1 ablakának tulajdonosai, az ablakok ablakai - Ablak 3 ... Ablak N, és a megfelelő gyermek ablakok - Ablak N + 1 ... N + M. Ebben az esetben nem lehet közvetlenül megkapni más ablakok azonosítóit a forrásablak inicializálójával.

Forduljunk a Windows API eszközhöz, amely lehetővé teszi a fentiek végrehajtását.

Ablakfunkciók A WinAPI, amelyet ebben a projektben használnak.

funkció GetWindow (hWnd: HWND; uCmd: UINT): HWND;

A függvény egy ablakleírást ad vissza, egy adott pozícióval az ablak hierarchiájában a megadott ablakhoz képest.
  • hWnd - a forrás ablak leírója.
  • uCmd - a kommunikáció iránya, azaz felfelé, lefelé vagy vízszintesen.
Az uCmd változó értékei:
  • GW_CHILD - Visszaadja a gyermek (slave) ablakának leíróját, amely a Z-sorrend legmagasabb pozíciójában van. Ha az ablakban nincs gyermeket, akkor 0-t kap.
  • GW_HWNDFIRST - Visszaadja az ablak fogantyúját a legmagasabb Z-rendelési pozícióban, mint az eredeti ablak.
  • GW_HWNDLAST - Visszaadja az ablak fogantyúját az alsó Z-sorrendben, amely ugyanolyan szintű, mint az eredeti ablak.
  • GW_HWNDNEXT - Visszaadja az ablak fogantyúját a következő Z-sorrendben, ugyanolyan szinten, mint az eredeti ablak.
  • GW_HWNDPREV - Visszaadja az ablaknak az eredeti Z-sorrendbe rendezett pozíciójában levő fogantyúját.
  • GW_OWNER - Visszaadja a forrás ablak tulajdonosának ablakfogantyúját. Ha az ablaknak nincs nullázási szintje, akkor 0 visszakerül.

A Z-rendelésről: a képernyő "felső" ablakának nulla pozíciója van, a következő, az átfedő ablak - az első pozíció, és így tovább a képernyő "alsó" részéig. Így megvalósul a háromdimenziós fogalom, bár egy okos könyvben azt olvastam, hogy egy több ablakos közeg feltételesen 2,5-dimenziós (2,5D).

Ezzel a funkcióval a rendszer összes ablakát egy egyszerű rekurzív séta segítségével (a "Tree Bypass" egyetem első évének feladata) kapjuk.

Több WinAPI funkcióra van szükségünk:

függvény GetWindowText (hWnd: HWND; lpString: PChar; nMaxCount: Integer): Integer;

A függvény átveszi az ablak szövegét az azonosítójával és visszaadja az ablak szövegszövegének olvasási hosszát.
  • hWnd az ablak azonosítója.
  • lpString - a PChar változó ablakának szövege. A változót előre kell létrehozni.
  • Az nMaxCount az lpString karakterlánc hossza.
function GetClassName (hWnd: HWND; lpClassName: PChar; nMaxCount: Integer): Integer;
  • hWnd az ablak azonosítója.
  • Az lpClassName az ablakosztály neve a PChar változóban. A változót előre kell létrehozni.
  • Az nMaxCount az lpClassName karakterlánc hossza.
funkció GetMenu (hWnd: HWND): HMENU;
A függvény a kijelölt ablakazonosítót adja vissza a menü azonosítójának.

Folytassuk a program közvetlen felépítését.

Futtassa a Delphi-t, és hozzon létre egy új alkalmazást a Fájl-> Új alkalmazás menüben.

Nem fogjuk figyelmen kívül hagyni a feltört felület, nem kétlem, hogy a legtöbb ember ezt egyszerűen végzi, mint például "két bájt előre";). Építsünk valamit a "Explorer" -nek. Hívja az fmMain fő formanyomtatványt, és a főmodulot - Main.pas. Helyezze az alkatrészeket az ábrán látható módon a képen látható módon:

Az űrlap bal oldalán a Fa komponens: a TTreeView, és az ügyfél összetevő a List: TListView összetevő.

Adja hozzá az fmMain-hoz a FillTree-fa kitöltésével kapcsolatos eljárást az alábbi tartalommal:

Most próbáljuk megérteni (lásd az eljárás szövegét). Állapot - osztály TStatus Bar. Az állapot sávon tájékoztatjuk, hogy frissítjük az információkat. Kikapcsoljuk a fafrissítés megjelenítését, hogy a frissítési folyamat során semmi ne fusson a képernyőn. Törölje a fát, és hozzon létre egy változó puffert, amely rögzíti a WinAPI funkciók string eredményeit.

A következő lépés a rendszer felső és első ablakának elérése. A GetWindow függvényt GW_OWNER paraméterrel hívjuk - a tulajdonos ablakának megnyitása a fő programablakból. Kapok egy ablakot, amely nincs tulajdonosa, meg ehhez az ablakhoz doboz nincs Z érdekében hívja GetWindow funkció GW_HWNDFIRST lehetőség - kezd az első ablakot ebben fészkelő szinten. Most elkezdhetjük megkerülve az ablakok fa, kezdve az első szerint növekvő sorrendben fészkelő és a Z-order meghívásával rekurzív eljárás RegisterWindow.

Az alábbi műveletek egyszerűen szégyenletesek (RegistryWindow eljárás):

  • hozzon létre egy ablakleíró változót;
  • a fentebb leírt szöveg, az osztály nevét és a menü azonosítóját a fentiekben ismertetett WinPI függvényekkel kapja meg, és ezeket az értékeket írja az ablakváltozóra;
  • hozzon létre egy fa csomópontot, és rendeljen hozzá egy ablakot a felhasználóhoz a csomópont tulajdonosának megadásával és egy szövegérték hozzárendelésével;
  • kapja meg a gyermek ablak azonosítóját, és ha az azonosító nem egyenlő 0-val, rekurzívan feldolgozza azt, a kapott paramétereket a RegisterWindow-hoz továbbítja. Ebben az esetben a kapott gyermek ablakának azonosítója és az újonnan létrehozott fa csomópont átkerül az eljárásba;
  • Szerezd meg az azonosítót az azonos szintű fészkelés aktuális ablakához. És ha nem 0, adja át a vett azonosítót és a külső ParentTreeItem paramétert a RegisterWindow-hoz. Ebben az esetben a fa csomópontjai ugyanolyan szinten kerülnek hozzá, mint az aktuális csomópont.
Ha a FillTree réteget az FormCreate eseményben hívjuk, a fa automatikusan kitöltődik a program indításakor. Hozzon létre egy acRefresh: TAction műveletet, és hozzárendelje a frissítés gombra az űrlapon. Az akcióeljárás feldolgozásakor a következő kódot írjuk le: Most már erőteljesen frissíthetjük a listát. Lépjünk tovább a listán szereplő összes információ megjelenítéséhez: TListView összetevő. A TTreeView.OnChange eseményt az alábbiak szerint dolgozzuk fel: A fa megfelelő elemének (Csomópont: TTreeNode) kiválasztásához sorokat adjon a List: TListView összetevőhöz a PNode ^ rekord összes mezőjének értékeivel.

Információk vannak az összes ablakról, és az ablakazonosító használatával hozzáférhetünk a NAGYON nagy ablakparaméterekhez a WinAPI segítségével

És miért van ez mindez?

Négy példával illusztráljuk:
  • Szükségtelen (elolvasni, zavaró) ablakot elrejteni. Például a banner-megjelenítések rendszerének ablaka. Ez így történik:
    ShowWindow (TNode (Tree.Selected.Data ^) Fogantyú, sw_Hide).
    Az az igazság, hogy hatékonyan rejtegetjük ezt az ablakot, az ABM_ * sorozat üzeneteivel dolgozik, de ez egy másik történet.
  • A rejtett ablak megjelenítése. Hátramenet:
    ShowWindow (TNode (Tree.Selected.Data ^) Handle, sw_Show).
    Például a "Start" gomb megnyomása után a panel elrepült. A rendszer tálcán lévő összes ikon eltűnt. A bemutató ablak nem jelent problémát.
  • Korlátozott ellenőrzés engedélyezése:
    EnableWindow (TNode (Tree.Selected.Data ^) Handle, True).
    Amire szükség van, még csak nem is mondhatjuk.
  • Öld meg az ablakot:
    PostMessage (TNode (Tree.Selected.Data ^) Fogantyú, wm_Close, 0,0).
    A magyarázatot lásd a 3. bekezdésben.

Kapcsolódó cikkek