Поделиться через


Использование панелей инструментов для настольных приложений

Панель инструментов рабочего стола приложения (также называется панелью приложений) — это окно, аналогичное панели задач Windows. Он привязан к краю экрана, и обычно он содержит кнопки, которые предоставляют пользователю быстрый доступ к другим приложениям и окнам. Система запрещает другим приложениям использовать область рабочего стола, используемую панелью приложений. Любое количество панели приложений может существовать на рабочем столе в любое время.

Эта тема описана в следующих разделах.

Сведения о панели инструментов для настольных приложений

Windows предоставляет API, который позволяет воспользоваться службами панели приложений, предоставляемыми системой. Службы помогают гарантировать, что определяемые приложением панели приложений работают гладко друг с другом и с помощью панели задач. Система сохраняет сведения о каждой панели приложений и отправляет сообщения панели приложений, чтобы уведомить их о событиях, которые могут повлиять на их размер, положение и внешний вид.

отправка сообщений

Приложение использует специальный набор сообщений, называемых сообщениями appbar, для добавления или удаления панели приложений, задания размера и положения панели приложений, а также получения сведений о размере, положении и состоянии панели задач. Чтобы отправить сообщение панели приложений, приложение должно использовать функцию SHAppBarMessage. Параметры функции включают идентификатор сообщения, например ABM_NEW, и адрес структуры APPBARDATA. Члены структуры содержат сведения, необходимые системе для обработки данного сообщения.

Для любого заданного сообщения панели приложений система использует некоторые члены структуры APPBARDATA и игнорирует другие. Однако система всегда использует элементы cbSize и hWnd , поэтому приложение должно заполнять эти элементы для каждого сообщения панели приложений. Член cbSize указывает размер структуры, а элемент hWnd — это дескриптор окна панели приложений.

Некоторые сообщения на панели приложений запрашивают информацию из системы. При обработке этих сообщений система копирует запрошенные сведения в структуру APPBARDATA .

Регистрация

Система сохраняет внутренний список панели приложений и сохраняет сведения о каждой строке в списке. Система использует сведения для управления панели приложений, выполнения служб и отправки уведомлений.

Приложение должно зарегистрировать панель приложений (то есть добавить ее в внутренний список), прежде чем она сможет получать службы панели приложений из системы. Чтобы зарегистрировать панель приложений, приложение отправляет сообщение ABM_NEW. Сопровождающая структура APPBARDATA включает дескриптор окна панели приложений и идентификатор сообщения, определяемый приложением. Система использует идентификатор сообщения для отправки уведомлений в процедуру окна окна панели приложений. Дополнительные сведения см. в разделе "Сообщения уведомления о панели приложений".

Приложение отменяет регистрацию панели приложений, отправляя сообщение ABM_REMOVE . Отмена регистрации панели приложений удаляет ее из внутреннего списка панели приложений системы. Система больше не отправляет сообщения уведомлений на панель приложений или запрещает другим приложениям использовать область экрана, используемую панелью приложения. Приложение всегда должно отправлять ABM_REMOVE перед уничтожением панели приложений.

Размер и положение панели приложений

Приложение должно задать размер и положение панели приложений, чтобы она не вмешивалась в другие панели приложений или панель задач. Каждая панель приложений должна быть привязана к определенному краю экрана, а несколько панели приложений можно привязать к краю. Однако если панель приложений привязана к тому же краю, что и панель задач, система гарантирует, что панель задач всегда находится на самом внешнем крае.

Чтобы задать размер и положение панели приложений, приложение сначала предлагает край экрана и ограничивающий прямоугольник для панели приложения, отправив сообщение ABM_QUERYPOS . Система определяет, используется ли любая часть области экрана в предлагаемом прямоугольнике панели задач или другой панели приложений, настраивает прямоугольник (при необходимости) и возвращает настроенный прямоугольник в приложение.

Затем приложение отправляет сообщение ABM_SETPOS , чтобы задать новый ограничивающий прямоугольник для панели приложений. Опять же, система может настроить прямоугольник перед возвращением его в приложение. По этой причине приложение должно использовать скорректированный прямоугольник, возвращаемый ABM_SETPOS , чтобы задать окончательный размер и положение. Приложение может использовать функцию MoveWindow для перемещения панели приложений в положение.

С помощью двухэтапного процесса для задания размера и положения система позволяет приложению предоставлять пользователю промежуточные отзывы во время операции перемещения. Например, если пользователь перетаскивает панель приложений, приложение может отобразить затененным прямоугольником, указывающим новую позицию перед перемещением панели приложений.

Приложение должно задать размер и позицию его панели приложений после регистрации и всякий раз, когда панель приложений получает сообщение ABN_POSCHANGED уведомления. Панель приложений получает это сообщение уведомления при изменении размера, положения или видимости панели задач, а также при изменении размера, добавления или удаления другой панели приложений на той же стороне экрана.

Когда панель приложений получает сообщение WM_ACTIVATE, оно должно отправлять ABM_ACTIVATE сообщение. Аналогичным образом, когда панель приложений получает сообщение WM_WINDOWPOSCHANGED, он должен вызывать ABM_WINDOWPOSCHANGED. Отправка этих сообщений гарантирует, что система правильно задает z-порядок любых автохидентных панели приложений на одном крае.

Панели инструментов "Автоматический рабочий стол приложения"

Панель приложений autohide — это панель приложений, которая обычно скрыта, но становится видимой при перемещении курсора мыши на край экрана, с которым связана панель приложений. Панель приложений скрывает себя снова, когда пользователь перемещает курсор мыши из ограничивающего прямоугольника панели.

Хотя система разрешает несколько различных панели приложений в любой момент времени, она позволяет одновременно использовать только одну панель приложений автохидента для каждого края экрана на первом этапе. Система автоматически поддерживает z-порядок панели приложений автохиды (только в ее группе z-order).

Приложение использует сообщение ABM_SETAUTOHIDEBAR для регистрации или отмены регистрации панели приложений автохиды. Сообщение указывает край панели приложений и флаг, указывающий, является ли панель приложения зарегистрированной или отменой регистрации. Сообщение завершается ошибкой, если панель приложений автохидента зарегистрирована, но она уже связана с указанным краем. Приложение может получить дескриптор в панель приложений автохиденти, связанную с краем, отправив сообщение ABM_GETAUTOHIDEBAR .

Панель приложений автохиды не требует регистрации в качестве обычной панели приложений; т. е . его не нужно зарегистрировать, отправив ABM_NEW сообщение. Панель приложений, которая не зарегистрирована ABM_NEW перекрывает все панели приложений, привязанные к тому же краю экрана.

Сообщения уведомлений на панели приложений

Система отправляет сообщения, чтобы уведомить панель приложений о событиях, которые могут повлиять на его положение и внешний вид. Сообщения отправляются в контексте определяемого приложением сообщения. Приложение указывает идентификатор сообщения при отправке сообщения ABM_NEW для регистрации панели приложений. Код уведомления находится в параметре wParam сообщения, определяемого приложением.

Панель приложений получает сообщение ABN_POSCHANGED уведомления, когда размер, положение или видимость панели задач изменяется, когда другая панель приложений добавляется в тот же край экрана или когда другая панель приложений на том же краю экрана изменяется или удаляется. Панель приложений должна отвечать на это уведомление, отправляя ABM_QUERYPOS и ABM_SETPOS сообщения. Если позиция панели приложений изменилась, она должна вызвать функцию MoveWindow , чтобы переместить себя в новую позицию.

Система отправляет сообщение уведомления ABN_STATECHANGE всякий раз при изменении автоматического или постоянного состояния панели задач, т. е. когда пользователь выбирает или очищает поле always on top или auto hide проверка на листе свойств панели задач. Панель приложений может использовать это сообщение уведомления, чтобы задать его состояние в соответствии с состоянием панели задач, если это необходимо.

При запуске полноэкранного приложения или при закрытии последнего полноэкранного приложения панель приложений получает сообщение ABN_FULLSCREENAPP уведомления. Параметр lParam указывает, открывается или закрывается приложение с полноэкранным экраном. Если она открывается, панель приложений должна удалиться в нижней части z-порядка. Панель приложений должна восстановить положение z-порядка при закрытии последнего полноэкранного приложения.

Панель приложений получает сообщение ABN_WINDOWARRANGE уведомления, когда пользователь выбирает команду Каскада, плитки по горизонтали или плитки по вертикали из контекстного меню панели задач. Система отправляет сообщение два раза: перед переупорядочением окон (lParam имеет значение TRUE) и после упорядочения окон (lParam имеет значение FALSE).

Панель приложений может использовать ABN_WINDOWARRANGE сообщения, чтобы исключить себя из операции каскада или плитки. Чтобы исключить себя, панель приложений должна скрыть себя, если lParam имеет значение TRUE, и показать себя, когда lParam имеет значение FALSE. Если панель приложений скрывает себя в ответ на это сообщение, не нужно отправлять 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); 
}