Používání panelů nástrojů plochy aplikace
Panel nástrojů plochy aplikace (označovaný také jako appbar) je okno podobné hlavnímu panelu Windows. Je ukotvený na okraji obrazovky a obvykle obsahuje tlačítka, která uživateli umožňují rychlý přístup k jiným aplikacím a oknu. Systém brání ostatním aplikacím v používání plochy používané panelem aplikace. V daném okamžiku může na ploše existovat libovolný počet appbarů.
Toto téma obsahuje následující části.
- O panelech nástrojů desktopu aplikací
- Registrace Panelu Nástrojů na Ploše Aplikace
- Nastavení velikosti a umístění panelu aplikace
- Zpracování zpráv oznámení na panelu aplikace
Informace o panelech nástrojů plochy aplikací
Windows poskytuje rozhraní API, které umožňuje využívat služby appbar poskytované systémem. Služby pomáhají zajistit, aby aplikační panely definované aplikací fungovaly plynule navzájem a s hlavním panelem. Systém udržuje informace o jednotlivých appbarech a odesílá zprávy appbarů, aby je informoval o událostech, které můžou ovlivnit jejich velikost, pozici a vzhled.
Odesílání zpráv
Aplikace používá speciální sadu zpráv označovaných jako zprávy appbaru k přidání nebo odebrání appbaru, nastavení velikosti a umístění panelu aplikace a načtení informací o velikosti, umístění a stavu hlavního panelu. Pokud chcete odeslat zprávu appbaru, musí aplikace použít funkci SHAppBarMessage. Parametry funkce zahrnují identifikátor zprávy, například ABM_NEW, a adresu struktury APPBARDATA. Členové struktury obsahují informace, které systém potřebuje ke zpracování dané zprávy.
Pro každou zprávu appbaru systém používá některé členy struktury APPBARDATA a ignoruje ostatní. Systém však vždy používá členy cbSize a hWnd, takže aplikace musí tyto členy vyplnit pro každou zprávu panelu aplikací. cbSize člen určuje velikost struktury a hWnd člen je úchyt pro okno appbaru.
Některé zprávy panelu aplikace požadují informace ze systému. Při zpracování těchto zpráv systém zkopíruje požadované informace do struktury APPBARDATA.
Registrace
Systém uchovává interní seznam appbarů a udržuje informace o jednotlivých panelech v seznamu. Systém používá informace ke správě appbarů, provádění služeb a odesílání oznámení.
Aplikace musí zaregistrovat aplikační panel (tj. přidat ho do interního seznamu), aby mohl přijímat služby appbaru ze systému. Pokud chcete zaregistrovat panel aplikace, odešle aplikace zprávu ABM_NEW. Doprovodná APPBARDATA struktura obsahuje popisovač okna appbaru a identifikátor zprávy definovaný aplikací. Systém používá identifikátor zprávy k odesílání oznámení do procedury okna pro appbar okno. Další informace najdete v tématu Zprávy oznámení na panelu aplikací.
Aplikace se odregistrovává z panelu aplikace odesláním zprávy ABM_REMOVE. Zrušení registrace panelu aplikace ho odebere z interního seznamu panelů aplikace systému. Systém už na appbar neodesílá zprávy s oznámením nebo brání jiným aplikacím v používání oblasti obrazovky používané panelem aplikace. Aplikace by měla vždy odesílat ABM_REMOVE před zničením panelu aplikace.
Velikost a umístění panelu aplikace
Aplikace by měla nastavit velikost a umístění appbaru tak, aby nenarušovala žádné jiné appbary nebo hlavní panel. Každý appbar musí být ukotvený k určitému okraji obrazovky a k okraji je možné ukotvit několik appbarů. Pokud je ale appbar ukotvený ke stejnému okraji jako hlavní panel, systém zajistí, že hlavní panel bude vždy na vnějším okraji.
Pokud chcete nastavit velikost a umístění appbaru, aplikace nejprve navrhne okraj obrazovky a ohraničující obdélník pro appbar odesláním ABM_QUERYPOS zprávy. Systém určuje, jestli se část oblasti obrazovky v navrhovaném obdélníku používá na hlavním panelu nebo jiném appbaru, upraví obdélník (v případě potřeby) a vrátí upravený obdélník do aplikace.
Dále aplikace odešle ABM_SETPOS zprávu, která nastaví nový ohraničující obdélník pro appbar. Systém může znovu upravit obdélník před vrácením do aplikace. Z tohoto důvodu by aplikace měla použít upravený obdélník vrácený ABM_SETPOS k nastavení konečné velikosti a pozice. Aplikace může pomocí funkce MoveWindow přesunout appbar na pozici.
Pomocí dvoustupňového procesu pro nastavení velikosti a pozice systém umožňuje aplikaci poskytnout uživateli během operace přesunutí průběžnou zpětnou vazbu. Pokud například uživatel přetáhne panel aplikace, může aplikace zobrazit stínovaný obdélník označující nové umístění před tím, než se appbar skutečně přesune.
Aplikace by měla nastavit velikost a umístění jejího appbaru po registraci a pokaždé, když appbar obdrží ABN_POSCHANGED zprávu s oznámením. Appbar obdrží tuto zprávu s oznámením vždy, když dojde ke změně velikosti, umístění nebo viditelnosti hlavního panelu a kdykoli se změní velikost, přidání nebo odebrání jiného panelu aplikace na stejné straně obrazovky.
Pokaždé, když appbar obdrží WM_ACTIVATE zprávu, měla by odeslat zprávu ABM_ACTIVATE. Podobně, když appbar obdrží zprávu WM_WINDOWPOSCHANGED, musí volat ABM_WINDOWPOSCHANGED. Odesílání těchto zpráv zajišťuje, že systém správně nastaví z-index všech appbarů s funkcí automatického skrývání na stejném okraji.
Automaticky skrýt panely nástrojů aplikace na ploše
Automaticky skrytý panel aplikace je ten, který je normálně skrytý, ale je viditelný, když uživatel přesune kurzor myši na okraj obrazovky, ke kterému je přidružený panel aplikace. Appbar se znovu skryje, když uživatel přesune kurzor myši mimo ohraničující obdélník pruhu.
Ačkoli systém umožňuje mít v daném okamžiku několik různých panelů aplikace, povoluje pouze jeden automaticky skrytý panel aplikace pro každý okraj obrazovky na principu "kdo dřív přijde, je dřív na řadě". Systém automaticky udržuje z-řád panelu nástrojů s automatickým skrýváním (pouze ve své skupině z-řádu).
Aplikace používá zprávu ABM_SETAUTOHIDEBAR k registraci nebo odregistraci automaticky skrývaného panelu aplikace. Zpráva určuje okraj pro panel aplikace a příznak, který určuje, jestli se má panel aplikace zaregistrovat nebo zrušit jeho registraci. Pokud se zaregistruje automaticky skrývaný panel aplikace, ale jeden už je přiřazený k zadanému okraji, zpráva selže. Aplikace může načíst popisovač k automaticky skrytému panelu aplikací přidruženému k okraji odesláním zprávy ABM_GETAUTOHIDEBAR.
Automaticky skrytý panel aplikace se nemusí registrovat jako normální appbar; to znamená, že není nutné ji zaregistrovat odesláním ABM_NEW zprávy. Aplikační panel, který není zaregistrován pomocí ABM_NEW, překrývá jakékoli panely aplikací ukotvené na stejném okraji obrazovky.
Oznámení zpráv Appbaru
Systém odesílá zprávy, které upozorní appbar na události, které můžou ovlivnit jeho pozici a vzhled. Zprávy se odesílají v kontextu zprávy definované aplikací. Aplikace určuje identifikátor zprávy, když odešle zprávu ABM_NEW pro registraci panelu aplikace. Kód oznámení je v parametru wParam zprávy definované aplikací.
Když se změní velikost, umístění nebo stav viditelnosti hlavního panelu, panel aplikace obdrží zprávu s upozorněním ABN_POSCHANGED. Tato zpráva se také zobrazí při přidání jiného panelu aplikace na stejný okraj obrazovky nebo když se jiný panel aplikace na stejném okraji obrazovky změní nebo odebere. Appbar by měl na tuto oznámení reagovat odesláním zpráv ABM_QUERYPOS a ABM_SETPOS. Pokud se pozice appbaru změnila, měla by volat funkci MoveWindow, aby se přesunula na novou pozici.
Systém odešle zprávu s oznámením ABN_STATECHANGE vždy, když se automaticky skryje hlavní panel nebo se změní stav always-on - to znamená, že když uživatel vybere nebo zruší zaškrtnutí Always On nahoře nebo Automaticky skrýt zaškrtávací políčko na seznamu vlastností hlavního panelu. V případě potřeby může panel aplikace použít tuto zprávu s oznámením k nastavení svého stavu tak, aby odpovídal hlavnímu panelu.
Když se aplikace na celé obrazovce spustí nebo když se zavře poslední aplikace na celé obrazovce, zobrazí se na panelu aplikace zpráva s oznámením ABN_FULLSCREENAPP. Parametr lParam označuje, jestli je aplikace na celé obrazovce otvíraná nebo zavíraná. Pokud se otevírá, musí aplikační panel poklesnout na spodní úroveň pořadí vykreslování. Appbar by měl obnovit svou úroveň zobrazení po zavření poslední aplikace na celé obrazovce.
Aplikační panel obdrží zprávu oznámení ABN_WINDOWARRANGE, když uživatel vybere příkaz Kaskáda, dlaždice vodorovně nebo dlaždice svisle z kontextové nabídky hlavního panelu. Systém zprávu odešle dvakrát – před změnou uspořádání oken (lParam je TRUE) a po uspořádání oken (lParam je FALSE).
Panel aplikací může použít ABN_WINDOWARRANGE zpráv, aby se vyloučil z kaskádní nebo dlaždicové operace. Pokud chcete vyloučit sám sebe, měl by se appbar skrýt, když lParam je TRUE a zobrazí se, když lParam je FALSE. Pokud se appbar skryje jako reakce na tuto zprávu, nemusí posílat zprávy ABM_QUERYPOS a ABM_SETPOS v rámci kaskádové nebo dlaždicové operace.
Registrace desktopového panelu nástrojů aplikace
Aplikace musí zaregistrovat panel aplikace odesláním zprávy ABM_NEW. Registrace appbaru ho přidá do interního seznamu systému a poskytne systému identifikátor zprávy, který se použije k odesílání zpráv s oznámeními na panel aplikace. Před ukončením musí aplikace zrušit registraci panelu aplikace odesláním zprávy ABM_REMOVE. Zrušení registrace odebere appbar z interního seznamu systému a zabrání panelu přijímat zprávy s oznámením na panelu aplikací.
Funkce v následujícím příkladu buď zaregistruje nebo zruší registraci aplikačního panelu v závislosti na hodnotě parametru logického příznaku.
// RegisterAccessBar - registers or unregisters an appbar.
// Returns TRUE if successful, or FALSE otherwise.
// hwndAccessBar - handle to the appbar
// fRegister - register and unregister flag
// Global variables
// g_uSide - screen edge (defaults to ABE_TOP)
// g_fAppRegistered - flag indicating whether the bar is registered
BOOL RegisterAccessBar(HWND hwndAccessBar, BOOL fRegister)
{
APPBARDATA abd;
// An application-defined message identifier
APPBAR_CALLBACK = (WM_USER + 0x01);
// Specify the structure size and handle to the appbar.
abd.cbSize = sizeof(APPBARDATA);
abd.hWnd = hwndAccessBar;
if (fRegister)
{
// Provide an identifier for notification messages.
abd.uCallbackMessage = APPBAR_CALLBACK;
// Register the appbar.
if (!SHAppBarMessage(ABM_NEW, &abd))
return FALSE;
g_uSide = ABE_TOP; // default edge
g_fAppRegistered = TRUE;
}
else
{
// Unregister the appbar.
SHAppBarMessage(ABM_REMOVE, &abd);
g_fAppRegistered = FALSE;
}
return TRUE;
}
Nastavení velikosti a umístění panelu aplikace
Aplikace by měla nastavit velikost a pozici appbaru po jeho registraci, když uživatel přesune nebo změní velikost appbaru, a pokaždé, když appbar obdrží oznámení ABN_POSCHANGED. Před nastavením velikosti a umístění aplikačního panelu aplikace odešle systému dotaz na schválený ohraničující obdélník prostřednictvím zprávy ABM_QUERYPOS. Systém vrátí ohraničující obdélník, který nezasahuje do hlavního panelu nebo jiného aplikačního panelu. Systém upraví obdélník čistě odečítáním obdélníků; nesnaží se zachovat počáteční velikost obdélníku. Z tohoto důvodu by měl appbar po odeslání ABM_QUERYPOSupravit obdélník podle potřeby.
Následně aplikace předá ohraničující obdélník zpět systému pomocí ABM_SETPOS zprávy. Potom zavolá funkci MoveWindow, která přesune appbar na pozici.
Následující příklad ukazuje, jak nastavit velikost a pozici appbaru.
// AppBarQuerySetPos - sets the size and position of an appbar.
// uEdge - screen edge to which the appbar is to be anchored
// lprc - current bounding rectangle of the appbar
// pabd - address of the APPBARDATA structure with the hWnd and cbSize members filled
void PASCAL AppBarQuerySetPos(UINT uEdge, LPRECT lprc, PAPPBARDATA pabd)
{
int iHeight = 0;
int iWidth = 0;
pabd->rc = *lprc;
pabd->uEdge = uEdge;
// Copy the screen coordinates of the appbar's bounding
// rectangle into the APPBARDATA structure.
if ((uEdge == ABE_LEFT) || (uEdge == ABE_RIGHT))
{
iWidth = pabd->rc.right - pabd->rc.left;
pabd->rc.top = 0;
pabd->rc.bottom = GetSystemMetrics(SM_CYSCREEN);
}
else
{
iHeight = pabd->rc.bottom - pabd->rc.top;
pabd->rc.left = 0;
pabd->rc.right = GetSystemMetrics(SM_CXSCREEN);
}
// Query the system for an approved size and position.
SHAppBarMessage(ABM_QUERYPOS, pabd);
// Adjust the rectangle, depending on the edge to which the appbar is anchored.
switch (uEdge)
{
case ABE_LEFT:
pabd->rc.right = pabd->rc.left + iWidth;
break;
case ABE_RIGHT:
pabd->rc.left = pabd->rc.right - iWidth;
break;
case ABE_TOP:
pabd->rc.bottom = pabd->rc.top + iHeight;
break;
case ABE_BOTTOM:
pabd->rc.top = pabd->rc.bottom - iHeight;
break;
}
// Pass the final bounding rectangle to the system.
SHAppBarMessage(ABM_SETPOS, pabd);
// Move and size the appbar so that it conforms to the
// bounding rectangle passed to the system.
MoveWindow(pabd->hWnd,
pabd->rc.left,
pabd->rc.top,
pabd->rc.right - pabd->rc.left,
pabd->rc.bottom - pabd->rc.top,
TRUE);
}
Zpracování zpráv o oznámení Appbaru
Appbar obdrží zprávu s oznámením, když se změní stav hlavního panelu, když se spustí aplikace na celé obrazovce (nebo když se poslední zavře), nebo když dojde k události, která může ovlivnit jeho velikost a umístění. Následující příklad ukazuje, jak zpracovat různé zprávy oznámení.
// AppBarCallback - processes notification messages sent by the system.
// hwndAccessBar - handle to the appbar
// uNotifyMsg - identifier of the notification message
// lParam - message parameter
void AppBarCallback(HWND hwndAccessBar, UINT uNotifyMsg,
LPARAM lParam)
{
APPBARDATA abd;
UINT uState;
abd.cbSize = sizeof(abd);
abd.hWnd = hwndAccessBar;
switch (uNotifyMsg)
{
case ABN_STATECHANGE:
// Check to see if the taskbar's always-on-top state has changed
// and, if it has, change the appbar's state accordingly.
uState = SHAppBarMessage(ABM_GETSTATE, &abd);
SetWindowPos(hwndAccessBar,
(ABS_ALWAYSONTOP & uState) ? HWND_TOPMOST : HWND_BOTTOM,
0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
break;
case ABN_FULLSCREENAPP:
// A full-screen application has started, or the last full-screen
// application has closed. Set the appbar's z-order appropriately.
if (lParam)
{
SetWindowPos(hwndAccessBar,
(ABS_ALWAYSONTOP & uState) ? HWND_TOPMOST : HWND_BOTTOM,
0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
else
{
uState = SHAppBarMessage(ABM_GETSTATE, &abd);
if (uState & ABS_ALWAYSONTOP)
SetWindowPos(hwndAccessBar,
HWND_TOPMOST,
0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
case ABN_POSCHANGED:
// The taskbar or another appbar has changed its size or position.
AppBarPosChanged(&abd);
break;
}
}
Následující funkce upraví ohraničující obdélník appbaru a potom zavolá funkci AppBarQuerySetPos definovanou aplikací (zahrnutou v předchozí části), aby se odpovídajícím způsobem nastavil velikost a umístění pruhu.
// AppBarPosChanged - adjusts the appbar's size and position.
// pabd - address of an APPBARDATA structure that contains information
// used to adjust the size and position.
void PASCAL AppBarPosChanged(PAPPBARDATA pabd)
{
RECT rc;
RECT rcWindow;
int iHeight;
int iWidth;
rc.top = 0;
rc.left = 0;
rc.right = GetSystemMetrics(SM_CXSCREEN);
rc.bottom = GetSystemMetrics(SM_CYSCREEN);
GetWindowRect(pabd->hWnd, &rcWindow);
iHeight = rcWindow.bottom - rcWindow.top;
iWidth = rcWindow.right - rcWindow.left;
switch (g_uSide)
{
case ABE_TOP:
rc.bottom = rc.top + iHeight;
break;
case ABE_BOTTOM:
rc.top = rc.bottom - iHeight;
break;
case ABE_LEFT:
rc.right = rc.left + iWidth;
break;
case ABE_RIGHT:
rc.left = rc.right - iWidth;
break;
}
AppBarQuerySetPos(g_uSide, &rc, pabd);
}