アプリケーション デスクトップ ツール バーの使用

アプリケーション デスクトップ ツール バー (アプリ バーとも呼ばれます) は、Windows タスク バーに似たウィンドウです。 画面の端に固定され、通常は他のアプリケーションやウィンドウにすばやくアクセスできるボタンが含まれています。 システムは、アプリ バーによって使用されるデスクトップ領域を他のアプリケーションが使用できないようにします。 デスクトップには、いつでも任意の数のアプリ バーを存在させることができます。

このトピックは、次のセクションで構成されています。

アプリケーション デスクトップ ツール バーについて

Windows には、システムによって提供されるアプリ バー サービスを利用できる API が用意されています。 このサービスは、アプリケーション定義のアプリ バーが互いにタスク バーとスムーズに動作することを保証するのに役立ちます。 システムは、各アプリ バーに関する情報を維持し、サイズ、位置、および外観に影響を与える可能性があるイベントについて通知するアプリ バー メッセージを送信します。

sending messages

アプリケーションは、アプリ バー メッセージと呼ばれる特別なメッセージ セットを使用して、アプリ バーの追加または削除、アプリ バーのサイズと位置の設定、タスク バーのサイズ、位置、状態に関する情報の取得を行います。 アプリ バー メッセージを送信するには、アプリケーションで SHAppBarMessage 関数を使用する必要があります。 この関数のパラメーターには、ABM_NEW などのメッセージ識別子と、APPBARDATA 構造体のアドレスが含まれます。 構造体メンバーには、システムが与えられたメッセージを処理するために必要な情報が含まれています。

与えられた任意のアプリ バー メッセージに対して、システムは APPBARDATA 構造体の一部のメンバーを使用し、それ以外のメンバーは無視します。 ただし、システムでは常に cbSize メンバーと hWnd メンバーが使用されるため、アプリケーションではすべてのアプリ バー メッセージごとにこれらのメンバーを入力する必要があります。 cbSize メンバーは構造体のサイズを指定し、hWnd メンバーはアプリ バーのウィンドウへのハンドルです。

一部のアプリ バー メッセージは、システムからの情報を要求します。 これらのメッセージを処理する際に、システムは要求された情報を APPBARDATA 構造体にコピーします。

登録

システムは、アプリ バーの内部リストを保持し、リスト内の各バーに関する情報を維持します。 システムはこの情報を使用して、アプリバーの管理、サービスの実行、通知メッセージの送信を行います。

アプリケーションは、システムからアプリ バー サービスを受ける前に、アプリ バーを登録する (つまり、内部リストに追加する) 必要があります。 アプリ バーを登録するために、アプリケーションは ABM_NEW メッセージを送信します。 付随する APPBARDATA 構造体には、アプリ バーのウィンドウへのハンドルと、アプリケーション定義のメッセージ識別子が含まれます。 システムはメッセージ識別子を使用して、アプリ バー ウィンドウのウィンドウ プロシージャに通知メッセージを送信します。 詳細については、「アプリ バーの通知メッセージ」を参照してください。

アプリケーションは、ABM_REMOVE メッセージを送信してアプリ バーの登録を解除します。 アプリ バーの登録を解除すると、システム内部のアプリ バー リストから削除されます。 システムは、アプリ バーに通知メッセージを送信したり、他のアプリケーションがアプリ バーで使用される画面領域を使用できないように制限しなくなりました。 アプリケーションは、アプリ バーを破棄する前に常に ABM_REMOVE を送信する必要があります。

アプリ バーのサイズと位置

アプリケーションは、他のアプリ バーやタスク バーに干渉しないように、アプリ バーのサイズと位置を設定する必要があります。 すべてのアプリ バーは特定の画面端に固定する必要があり、複数のアプリ バーを同じ画面端に固定できます。 ただし、アプリ バーがタスク バーと同じ画面端に固定されている場合、システムはタスク バーが常に一番外側の画面端にあることを確認します。

アプリ バーのサイズと位置を設定するために、アプリケーションはまず、ABM_QUERYPOS メッセージを送信して、アプリ バーの画面端と外接する四角形を提案します。 システムは、提案された四角形内の画面領域の一部がタスク バーまたは別のアプリ バーで使用されているかどうかを判断し、(必要に応じて) 四角形を調整して、調整された四角形をアプリケーションに返します。

次に、アプリケーションは ABM_SETPOS メッセージを送信して、アプリ バーの新しい外接する四角形を設定します。 ここでも、システムはアプリケーションに返す前に四角形を調整できます。 このため、アプリケーションでは、ABM_SETPOS によって返される調整済みの四角形を使用して、最終的なサイズと位置を設定する必要があります。 アプリケーションは MoveWindow 関数を使用して、アプリ バーを所定の位置に移動できます。

2 段階のプロセスを使用してサイズと位置を設定することで、移動操作中にアプリケーションがユーザーに中間フィードバックを提供できるようになります。 たとえば、ユーザーがアプリ バーをドラッグした場合、アプリ バーが実際に移動する前に、アプリケーションに新しい位置を示す網掛けされた四角形が表示されることがあります。

アプリケーションは、アプリ バーの登録後、およびアプリ バーが ABN_POSCHANGED 通知メッセージを受信するたびに、そのアプリ バーのサイズと位置を設定する必要があります。 アプリ バーは、タスク バーのサイズ、位置、または表示状態に変更が発生するたびに、および画面の同じ側にある別のアプリ バーのサイズ変更、追加、または削除が行われるたびに、この通知メッセージを受け取ります。

アプリ バーは、WM_ACTIVATE メッセージを受信するたびに、ABM_ACTIVATE メッセージを送信する必要があります。 同様に、アプリ バーは、WM_WINDOWPOSCHANGED メッセージを受信する際に ABM_WINDOWPOSCHANGED を呼び出す必要があります。 これらのメッセージを送信すると、同じ画面端上の自動非表示のアプリ バーの z オーダーがシステムによって適切に設定されます。

アプリケーション デスクトップ ツール バーの自動非表示

自動非表示のアプリ バーは、通常は非表示になっていますが、ユーザーがマウス カーソルをアプリ バーが関連付けられている画面端に移動すると表示されます。 ユーザーがマウス カーソルをバーの外の四角形から移動すると、アプリ バーは再び非表示になります。

システムでは、いつでも複数の異なるアプリ バーを許可しますが、先着順で各画面端に対して一度に 1 つの自動非表示アプリ バーしか許可しません。 システムは、自動非表示アプリ バーの z オーダーを自動的に維持されます (その z オーダー グループ内のみ)。

アプリケーションは、ABM_SETAUTOHIDEBAR メッセージを使用して、自動非表示アプリ バーの登録または登録解除を行います。 メッセージは、アプリ バーの画面端と、アプリ バーを登録または登録解除するかどうかを指定するフラグを指定します。 自動非表示のアプリ バーが登録されようとしていますが、指定した画面端に既に関連付けられている場合、メッセージは失敗します。 アプリケーションは、ABM_GETAUTOHIDEBAR メッセージを送信することで、画面端に関連付けられている自動非表示アプリ バーへのハンドルを取得できます。

自動非表示のアプリ バーは、通常のアプリ バーとして登録する必要はありません。つまり、ABM_NEW メッセージを送信して登録する必要はありません。 ABM_NEW によって登録されていないアプリ バーは、同じ画面端に固定されているアプリ バーと重なります。

アプリ バーの通知メッセージ

システムは、メッセージを送信し、アプリ バーの位置や外観に影響を与える可能性のあるイベントを通知します。 メッセージは、アプリケーション定義メッセージのコンテキストで送信されます。 アプリケーションは、ABM_NEW メッセージを送信してアプリ バーを登録するときに、メッセージの識別子を指定します。 通知コードは、 アプリケーション定義メッセージの wParam パラメーターにあります。

タスク バーのサイズ、位置、または表示状態が変更されたとき、別のアプリ バーが同じ画面端に追加されたとき、または同じ画面端にある別のアプリ バーのサイズが変更または削除されたときに、アプリ バーは ABN_POSCHANGED 通知メッセージを受け取ります。 アプリ バーは、ABM_QUERYPOS メッセージおよび ABM_SETPOS メッセージを送信することで、この通知メッセージに応答する必要があります。 アプリ バーの位置が変更された場合は、MoveWindow 関数を呼び出して新しい位置に移動する必要があります。

システムは、タスク バーの自動非表示または常に上部に表示の状態が変更されるたびに、ABN_STATECHANGE 通知メッセージを送信します。つまり、ユーザーがタスク バーのプロパティ シートの [常に上部に表示] または [自動非表示] チェック ボックスをオンまたはオフにするたびに、システムはこの通知メッセージを送信します。 アプリ バーでは、この通知メッセージを使用して、必要に応じてタスク バーの状態に準拠するように状態を設定できます。

全画面表示アプリケーションが起動されたとき、または最後の全画面表示アプリケーションが閉じたとき、アプリ バーは ABN_FULLSCREENAPP 通知メッセージを受け取ります。 lParam パラメーターは、全画面表示アプリケーションが開いているか閉じているかを示します。 開いている場合、アプリ バーは z オーダーの一番下に落とす必要があります。 アプリ バーは、最後の全画面表示アプリケーションが閉じられたときに、その z オーダー位置を復元する必要があります。

ユーザーがタスク バーのショートカット メニューから [カスケード]、[水平方向に並べる]、または [垂直方向に並べる] コマンドを選択すると、アプリ バーは ABN_WINDOWARRANGE 通知メッセージを受け取ります。 システムは、メッセージをウィンドウを並べ替える前 (lParamTRUE)、ウィンドウを並べ替えた後 (lParamFALSE) の 2 回送信します。

アプリ バーでは、ABN_WINDOWARRANGE メッセージを使用して、カスケード操作または並べ替え操作から自身を除外できます。 アプリ バー自体を除外するには、lParamTRUE の場合はアプリ バー自体を非表示にし、lParamFALSE の場合はアプリ バー自体を表示する必要があります。 このメッセージに応答してアプリ バー自体が非表示になる場合、カスケード操作または並べ替え操作に応答して ABM_QUERYPOS メッセージと ABM_SETPOS メッセージを送信する必要はありません。

アプリケーション デスクトップ ツール バーの登録

アプリケーションは、ABM_NEW メッセージを送信してアプリ バーを登録する必要があります。 アプリ バーを登録すると、アプリ バーがシステムの内部リストに追加され、アプリ バーに通知メッセージを送信するために使用するメッセージ識別子がシステムに提供されます。 終了する前に、アプリケーションは ABM_REMOVE メッセージを送信してアプリ バーの登録を解除する必要があります。 登録を解除すると、システムの内部リストからアプリ バーが削除され、アプリ バーの通知メッセージを受信できなくなります。

次の例の関数は、ブール値のフラグ パラメーターの値に応じて、アプリ バーを登録または登録解除します。

// 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; 
}

アプリ バーのサイズと位置の設定

アプリケーションは、アプリ バーの登録後、ユーザーがアプリ バーを移動またはサイズ変更した後、およびアプリ バーが ABN_POSCHANGED 通知メッセージを受信するたびに、アプリ バーのサイズと位置を設定する必要があります。 アプリ バーのサイズと位置を設定する前に、アプリケーションは、ABM_QUERYPOS メッセージを送信して、承認された外接する四角形をシステムに照会します。 システムは、タスク バーやその他のアプリ バーに干渉しない外接する四角形を返します。 システムは純粋に四角形の減算によって四角形を調整するため、四角形の初期サイズを保持しません。 このため、アプリ バーは ABM_QUERYPOS を送信した後、必要に応じて四角形を再調整する必要があります。

次に、アプリケーションは ABM_SETPOS メッセージを使用して、外接する四角形をシステムに渡します。 そして、MoveWindow 関数を呼び出して、アプリ バーを所定の位置に移動します。

次の例は、アプリ バーのサイズと位置を設定する方法を示しています。

// 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); 

}

アプリ バーの通知メッセージの処理

タスク バーの状態が変化したとき、アプリ バーは、全画面表示アプリケーションが起動したとき (または最後のアプリケーションが終了したとき)、またはアプリ バーのサイズと位置に影響を与える可能性のあるイベントが発生したときに通知メッセージを受信します。 次の例は、さまざまな通知メッセージを処理する方法を示しています。

// 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; 
    } 
}

次の関数は、アプリ バーの外接する四角形を調整し、アプリケーション定義の AppBarQuerySetPos 関数 (前のセクションに含まれています) を呼び出して、それに応じてバーのサイズと位置を設定します。

// 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); 
}