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.
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.
- 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.
- 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.
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.
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.