Geiger Tamás: Delphi és Win32 API – Nem csak Delphi felhasználóknak: IV. rész

Application Desktop Toolbars - 1.

Bizonyára már minden olvasó találkozott olyan programokkal, amelyek új eszköztárakat varázsolnak az Asztalra, különböző új funkciókkal próbálták megkönnyíteni a mindennapos munkát. Egy ilyen, talán mindenki számára ismert program a Microsoft Office Irányítópult, mellyel egy-egy program gyors indítását lehet segíteni. Cikksorozatunk következő részeiben azzal fogunk foglalkozni, miként készíthetünk mi is hasonló eszköztárakat.

Miért más?

Mint azt a sorozat első részében tettük, most is nézzük át a Delphi-s megvalósítás előtt a szükséges Windows API ismereteket.

A gyűjtőfogalom, ami alatt megtalálhatjuk az ide vonatkozó információkat: Application Desktop Toolbars (ADT). A magyarra fordítástól most eltekintenék, ez a fogalom egyike azon keveseknek, amelyeket nem fordítunk magyarra.

Egy ilyen eszköztárnak alapvetően három állapota lehet: lebegés (float), dokkolt (docked) és rejtett (autohidden). Ez utóbbi valójában nem külön állapot, inkább a dokkolt állapot egy speciális esete. Lebegés során az eszköztár az Asztalon „lebeg”, mint minden hagyományos ablak. Dokkolt állapotban valamelyik képernyő szélhez kapcsolódik, elrejti címsorát, szélessége és magassága igazodik a beállított felbontáshoz, végül rejtett állapotban ugyan dokkolva van, de látszódni csak egy vékony csík látszódik belőle, melyre az egeret ráhúzva jelenik meg az eszköztár és el is tűnik azonnal, amint az egeret elvittük felőle.

Nézzük meg, miért is van szükség egy ilyen eszköztár elkészítéséhez Windows API ismeretekre, miért nem elegendő, ha egy TForm-ot egyszerűen a képernyő megfelelő részébe mozgatunk, esetleg elrejtünk, ha nincs rá szükség?

Először is egy ilyen ADT használatakor a rendszer úgy helyezi el az ikonokat az Asztalon, hogy azok ne kerüljenek takarásba. Szintén a rendszer felügyeli, hogy ha a képernyő egyik oldalán egy elrejtett eszköztár szerepel (pl. a Tálcát az „Automatikus elrejtés” funkcióval használjuk), akkor oda ne lehessen még egy elrejthető ADT-t elhelyezni, hiszen ilyenkor nem lehetne eldönteni, hogy az egeret a megfelelő szélhez közelítve melyik eszköztárat kell megjeleníteni. Végül, de nem utolsó sorban a rendszer felügyeli, hogy két azonos oldalon dokkolt eszköztár ne fedje el egymást.

 

Mit nem?

Ezen kívül azonban sokmindent magunknak kell megoldani, saját kóddal, mert a Windows ehhez már nem nyújt közvetlen segítséget. Ilyen például, hogy egy képernyő oldalához közelítve automatikusan dokkoljon, sőt a dokkolás folyamán szintén magunknak kell megoldani, hogy az ablak megfelelő helyre kerüljön át, címsora elrejtődjön.

Akkor kezdjük

Az implementáció során a rendszer SHAppBarMessage függvénye lesz segítségünkre, mely a shell32.dll-ben található meg. A Delphi import a shellapi.pas unitban szerepel. A függvény deklarációja a következő:

function SHAppBarMessage(dwMessage: DWORD; var pData: TAppBarData): UINT;

Először nézzük meg a második paraméter felépítését, mely egy rekord a következő mezőkkel:

  TAppBarData = record
    cbSize: DWORD;
    hWnd: HWND;
    uCallbackMessage: UINT;
    uEdge: UINT;
    rc: TRect;
    lParam: LPARAM;
  end;

A mezők jelentése:

Most nézzük az első paraméter lehetséges értékeit:

  ABM_NEW              = $00000000;

Ezzel jelezzük a Windows-nak, hogy új ADT-t szeretnénk regisztrálni a rendszerben. A rekord paraméter cdSize, hWnd és uCallback mezőjét kell kitölteni. Ebből az is kitűnik, hogy ezzel még nem jelezzük, hogy hova szeretnénk helyezni a dokkolt eszköztárat, csupán annyit mondunk a rendszernek, hogy elkezdheti az ablak számára küldeni speciális üzeneteit (pl. a már említett teljes képernyős alkalmazás indítását jelző üzenetet). A sikeres regisztrálást 0-tól különböző visszatérési értékkel nyugtázza.

  ABM_REMOVE           = $00000001;

Az előző üzenet párja, egy már regisztrált eszköztárat szüntet meg. Nagyon fontos, hogy ha egyszer már regisztrálunk egy ADT-t, akkor ezzel az üzenettel mindenképpen jelezzük a Windows számára, hogy programunk futása befejeződött, különben a dokkolt eszköztár számára fenntartott hely nem szabadul fel, az Asztal nem rendeződik vissza eredeti állapotába és szélsőséges esetben csak a Windows újraindításával tudunk újra rendet teremteni.

  ABM_QUERYPOS         = $00000002;

A dokkolás folyamata során egy adott képernyő szélhez szükséges koordinátákat adjuk át az rc mezőben. Ezt a rendszer ellenőrzi és úgy korrigálja, hogy más eszköztárak ne kerüljenek takarásba. Ha például, a képernyő tetején már van egy eszköztár és mi is oda szeretnénk dokkolni egyet, akkor ezzel az üzenettel olyan koordinátákat kérhetünk, amelyek a másik eszköztár alá helyezik a mi eszköztárunkat. Az rc paraméteren kívül még az uEdge mezőnek kell értéket adnunk.

  ABM_SETPOS           = $00000003;

Ezzel az üzenettel jelezzük, hogy mely koordinátákra dokkoljuk az ablakunkat. Az előbbi üzenethez hasonlóan a rendszer itt is korrigálja a pozíciókat, itt azonban a korrigált téglalaphoz tartozó területet lefoglalja és úgy rendezi át az Asztalt, hogy az ikonok ne legyenek takarásban. Fontos, hogy ezzel az ablakunk még nem helyeződik át a megadott koordinátákra, azt magunknak kell elvégezni!

  ABM_GETSTATE         = $00000004;
  ABM_GETTASKBARPOS    = $00000005;

Lehetőségünk van arra, hogy lekérdezzük a Windows Tálca pozícióját, és állapotát. Az állapot lekérdezése során az SHAppBarMessage visszatérési értékének értelmezése:

  ABM_ACTIVATE         = $00000006;

Jelzi a rendszernek, hogy egy eszköztárat aktiváltak. Ez akkor történik, amikor dokkolt állapotban használják az eszköztárat. Ilyenkor a Windows úgy rendezi az ablakokat, hogy a mi ablakunk kerüljön minden másik ablak fölé ezzel biztosítva a megfelelő működést.

  ABM_GETAUTOHIDEBAR   = $00000007;

Mint azt már fentebb említettem, a képernyő egy oldalán csak egyetlen elrejthető eszköztár lehet. Megelőzendő az esetleges ütközéseket, ezzel az üzenettel tudjuk lekérdezni, hogy adott szélen van-e már rajtunk kívül elrejthető eszköztár.

  ABM_SETAUTOHIDEBAR   = $00000008;

Magától elrejtődő eszköztárat nem kell az ABM_NEW üzenettel regisztrálni, nem kell neki helyet foglalni és nem kell miatta az Asztal ikonjait újrarendezni. Elegendő ezzel az üzenettel jelezni a rendszernek, hogy adott képernyő szélhez igazítjuk a saját eszköztárunkat. A második paraméter lParam mezőjének 0 értéket adva jelezzük a rendszernek, hogy éppen eltávolítunk egy ilyen eszköztárat, 0-tól különböző értékkel regisztrálunk új rejtett eszköztárat.

  ABM_WINDOWPOSCHANGED = $0000009;

Ha egy dokkolt eszköztár pozíciója megváltozik (pl. átméretezik), ezzel az üzenettel kell jelezni a rendszernek, hogy átrendezze az Asztal ikonokat és minden más eszköztárat.

A következő számban megnézzük még pár módszert, trükköt a komponens megírása előtt. Ahogy mondani szokták: folyt. köv.