Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Большинство приложений под управлением Windows используют элементы управления панелью инструментов для предоставления пользователям удобного доступа к функциям программы. Однако статические панели инструментов имеют некоторые недостатки, например слишком мало места для эффективного отображения всех доступных инструментов. Решение этой проблемы заключается в том, чтобы сделать панели инструментов приложения настраиваемыми для пользователя. Затем пользователи могут выбрать отображение только необходимых инструментов, и они могут упорядочить их таким образом, чтобы соответствовать их личному стилю работы.
Заметка
Панели инструментов в диалоговых окнах не могут быть настроены.
Чтобы включить настройку, добавьте флаг общего стиля элементов управления CCS_ADJUSTABLE при создании элемента управления панели инструментов. Существует два основных подхода к настройке:
- Диалоговое окно настройки. Это диалоговое окно, предоставленное системой, является самым простым подходом. Он предоставляет пользователям графический пользовательский интерфейс, позволяющий им добавлять, удалять или перемещать значки.
- Перетаскивание и вставка инструментов. Реализация функций перетаскивания позволяет пользователям перемещать средства в другое расположение на панели инструментов или удалять их, перетаскивая их с панели инструментов. Он предоставляет пользователям быстрый и простой способ упорядочить свою панель инструментов, но не позволяет им добавлять средства.
Вы можете реализовать любой подход или оба подхода в зависимости от потребностей приложения. Ни одно из этих двух подходов к настройке не предоставляет встроенный механизм, например кнопку "Отмена" или "Отменить", чтобы вернуть панель инструментов в прежнее состояние. Вы должны явно использовать API управления панелью инструментов для хранения её предварительного состояния настройки. При необходимости эту хранимую информацию можно использовать позже для восстановления панели инструментов в исходном состоянии.
Что нужно знать
Технологии
Необходимые условия
- C/C++
- Программирование пользовательского интерфейса Windows
Инструкции
Диалоговое окно настройки
Диалоговое окно настройки предоставляется элементом управления панели инструментов, чтобы предоставить пользователям простой способ добавления, перемещения или удаления инструментов. Пользователи могут запустить его, дважды щелкнув панель инструментов. Приложения могут программным способом запускать диалоговое окно настройки, отправив панели инструментов сообщение TB_CUSTOMIZE.
На следующем рисунке показан пример диалогового окна настройки панели инструментов.
Инструменты в списке справа находятся на панели инструментов. Изначально этот список будет содержать средства, указанные при создании панели инструментов. Поле списка слева содержит средства, которые доступны для добавления на панель инструментов. Ваше приложение отвечает за заполнение этого списка (кроме разделителя, которое отображается автоматически).
Элемент управления панели инструментов уведомляет приложение о запуске диалогового окна настройки, отправляя в его родительское окно код уведомления TBN_BEGINADJUST, а затем - код уведомления TBN_INITCUSTOMIZE. В большинстве случаев приложению не нужно реагировать на эти коды уведомлений. Однако, если вы не хотите, чтобы в диалоговом окне "Настройка панели инструментов" отображалась кнопка "Справка", обработайте TBN_INITCUSTOMIZE, возвращая TBNRF_HIDEHELP.
Затем элемент управления панели инструментов собирает сведения, необходимые для инициализации диалогового окна, отправляя три ряда кодов уведомлений в следующем порядке:
- Код уведомления TBN_QUERYINSERT для каждой кнопки на панели инструментов, чтобы определить, куда можно вставить кнопки. Верните FALSE, чтобы предотвратить вставку кнопки слева от кнопки, указанной в сообщении уведомления. Если вы возвращаете FALSE для всех кодов уведомлений TBN_QUERYINSERT, диалоговое окно не будет отображаться.
- Код уведомления TBN_QUERYDELETE для каждого средства, находящегося на панели инструментов. Верните TRUE, если средство можно удалить, или верните FALSE, если нельзя.
- Набор кодов оповещения TBN_GETBUTTONINFO для заполнения списка доступных кнопок. Чтобы добавить кнопку в список, заполните структуру NMTOOLBAR, передаваемую с кодом уведомления, и верните TRUE. Если у вас больше нет средств для добавления, вернитесь FALSE. Обратите внимание, что можно возвращать сведения о кнопках, которые уже находятся на панели инструментов; Эти кнопки не будут добавлены в список.
Откроется диалоговое окно, и пользователь может начать настраивать панель инструментов.
При открытии диалогового окна приложение может получать различные коды уведомлений в зависимости от действий пользователя:
- TBN_QUERYINSERT. Пользователь изменил расположение инструмента на панели инструментов или добавил инструмент. Верните FALSE, чтобы предотвратить вставку средства в этом расположении.
- TBN_DELETINGBUTTON. Пользователь собирался удалить инструмент на панели инструментов.
- TBN_CUSTHELP. Пользователь щелкнул кнопку справки.
- TBN_TOOLBARCHANGE. Пользователь добавил, переместил или удалил инструмент.
- TBN_RESET. Пользователь щелкнул кнопку "Сброс".
После уничтожения диалогового окна приложение получит код уведомления TBN_ENDADJUST.
В следующем примере кода показан один из способов реализации настройки панели инструментов.
// The buttons are stored in an array of TBBUTTON structures.
//
// Constants such as STD_FILENEW are identifiers for the
// built-in bitmaps that have already been assigned as the toolbar's
// image list.
//
// Constants such as IDM_NEW are application-defined command identifiers.
TBBUTTON allButtons[] =
{
{ MAKELONG(STD_FILENEW, ImageListID), IDM_NEW, TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"New" },
{ MAKELONG(STD_FILEOPEN, ImageListID), IDM_OPEN, TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Open"},
{ MAKELONG(STD_FILESAVE, ImageListID), IDM_SAVE, TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Save"},
{ MAKELONG(STD_CUT, ImageListID), IDM_CUT, TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Cut" },
{ MAKELONG(STD_COPY, ImageListID), IDM_COPY, TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Copy"},
{ MAKELONG(STD_PASTE, ImageListID), IDM_PASTE, TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Paste"}
};
// The following appears in the window's message handler.
case WM_NOTIFY:
{
switch (((LPNMHDR)lParam)->code)
{
case TBN_GETBUTTONINFO:
{
LPTBNOTIFY lpTbNotify = (LPTBNOTIFY)lParam;
// Pass the next button from the array. There is no need to filter out buttons
// that are already used—they will be ignored.
int buttonCount = sizeof(allButtons) / sizeof(TBBUTTON);
if (lpTbNotify->iItem < buttonCount)
{
lpTbNotify->tbButton = allButtons[lpTbNotify->iItem];
return TRUE;
}
else
{
return FALSE; // No more buttons.
}
}
break;
case TBN_QUERYINSERT:
case TBN_QUERYDELETE:
return TRUE;
}
}
Перетаскивание и отпускание инструментов
Пользователи также могут изменить порядок кнопок на панели инструментов, нажав клавишу SHIFT и перетащив кнопку в другое расположение. Процесс перетаскивания обрабатывается автоматически элементом управления панели инструментов. Он отображает фантомное изображение кнопки при перетаскивании и переупорядочивает панель инструментов после ее отпускания. Пользователи не могут добавлять кнопки таким образом, но они могут удалить кнопку, удалив ее с панели инструментов.
Хотя элемент управления панели инструментов обычно выполняет эту операцию автоматически, он также отправляет приложение два кода уведомлений: TBN_QUERYDELETE и TBN_QUERYINSERT. Чтобы управлять процессом перетаскивания, обработайте эти коды уведомлений следующим образом:
- Код уведомления TBN_QUERYDELETE отправляется сразу после того, как пользователь пытается переместить кнопку перед отображением кнопки призрака. Верните false, чтобы предотвратить перемещение кнопки. Если вы возвращаете TRUE, пользователь сможет переместить средство или удалить его, удалив его с панели инструментов. Если средство можно переместить, его можно удалить. Однако если пользователь удаляет средство, элемент управления панели инструментов отправит приложению код уведомления TBN_DELETINGBUTTON, в какой момент можно повторно ввести кнопку в исходном расположении, тем самым отменив удаление.
- Код уведомления TBN_QUERYINSERT отправляется, когда пользователь пытается удалить кнопку на панели инструментов. Чтобы предотвратить перемещение кнопки влево от кнопки, указанной в уведомлении, верните FALSE. Этот код уведомления не отправляется, если пользователь удаляет средство с панели инструментов.
Если пользователь пытается перетащить кнопку без нажатия клавиши SHIFT, элемент управления панели инструментов не будет обрабатывать операцию перетаскивания. Однако приложение отправляет код уведомления TBN_BEGINDRAG, чтобы указать начало операции перетаскивания, а также код уведомления TBN_ENDDRAG для указания конца. Если вы хотите включить эту форму перетаскивания, приложение должно обрабатывать эти коды уведомлений, предоставлять необходимый пользовательский интерфейс и изменять панель инструментов, чтобы отразить любые изменения.
Сохранение и восстановление панелей инструментов
В процессе настройки панели инструментов приложению может потребоваться сохранить сведения, чтобы можно было восстановить панель инструментов в исходном состоянии. Чтобы инициировать сохранение или восстановление состояния панели инструментов, отправьте элементу управления TB_SAVERESTORE сообщение, установив значение wParam в TRUE. Значение wParam этого сообщения указывает, запрашивается ли операция сохранения или восстановления. После отправки сообщения существует два способа обработки операции сохранения и восстановления:
- При использовании распространенных элементов управления версии 4.72 и более ранних версий необходимо реализовать обработчик TBN_GETBUTTONINFO. Элемент управления панели инструментов отправляет этот код уведомления для запроса сведений о каждой кнопке по мере восстановления.
- Версия 5.80 включает параметр сохранения и восстановления. В начале процесса и по мере сохранения или восстановления каждой кнопки приложение получит код уведомлений TBN_SAVE или TBN_RESTORE. Чтобы использовать этот параметр, необходимо реализовать обработчики уведомлений, чтобы предоставить растровое изображение и сведения о состоянии, необходимые для успешного сохранения или восстановления состояния панели инструментов.
Состояния панели инструментов сохраняются в потоке данных, состоящем из блоков определенных оболочкой данных, чередующихся с блоками данных, определенных приложением. Для каждой кнопки хранится один блок данных каждого типа, а также необязательный блок глобальных данных, которые приложения могут размещать в начале потока. Во время процесса сохранения обработчик TBN_SAVE добавляет в поток данных блоки, определенные приложением. В процессе восстановления обработчик TBN_RESTORE считывает каждый блок и предоставляет оболочке сведения, необходимые для восстановления панели инструментов.
Обработка уведомления TBN_SAVE
Первый TBN_SAVE код уведомления отправляется в начале процесса сохранения. Перед сохранением кнопок элементы структуры NMTBSAVE задаются, как показано в следующей таблице.
Член | Настройка |
---|---|
iItem | –1 |
cbData | Объем памяти, необходимой для данных, определенных оболочкой. |
cButtons | Количество кнопок. |
pData | Вычисляемый объем памяти, необходимый для данных, определенных приложением. Как правило, вы включаете некоторые глобальные данные, а также данные для каждой кнопки. Добавьте это значение к cbData и выделите достаточно памяти для pData, чтобы всё это уместилось. |
pCurrent | Первый неиспользуемый байт в потоке данных. Если вам не требуются сведения о глобальной панели инструментов, задайте pCurrent = pData, чтобы он указывает на начало потока данных. Если требуется глобальная информация о панели инструментов, сохраните ее в pData, а затем задайте pCurrent в начало неиспользуемой части потока данных перед возвратом. |
Если вы хотите добавить некоторые сведения о глобальной панели инструментов, поместите его в начало потока данных. Сдвиньте pCurrent к концу глобальных данных, чтобы он указывал на начало неиспользуемой части потока данных, и вернитесь.
После вашего возвращения система начнет сохранять сведения о кнопке. Он добавляет определяемые оболочкой данные для первой кнопки в pCurrent, а затем перемещает pCurrent в начало неиспользуемой части.
После сохранения каждой кнопки отправляется код уведомления TBN_SAVE и возвращается NMTBSAVE с этими элементами, установленными следующим образом.
Член | Настройка |
---|---|
iItem | Отсчитываемый от нуля индекс номера кнопки. |
pCurrent | Указатель на первый неиспользуемый байт в потоке данных. Если вы хотите сохранить дополнительные сведения о кнопке, сохраните их в расположении, на которое указывает pCurrent, и обновите pCurrent, чтобы указать на первую неиспользуемую часть потока данных после этого. |
ТБКНОПКА | Структура ТБBUTTON, описывающая сохраненную кнопку. |
При получении кода уведомления следует извлечь любую информацию, относящуюся к кнопке, из TBBUTTON. Помните, что при добавлении кнопки можно использовать член dwData структуры TBBUTTON для хранения данных, специфичных для приложения. Загрузите данные в поток данных pCurrent. Продвиньте pCurrent к концу ваших данных, снова укажите на начало неиспользуемой части потока, и вернитесь.
Затем оболочка переходит к следующей кнопке, добавляет сведения в pData, переходит к pCurrent, загружает TBBUTTON, и отправляет другой код уведомлений TBN_SAVE. Этот процесс продолжается, пока все кнопки не будут сохранены.
Восстановление сохраненных панелей инструментов
Процесс восстановления в основном изменяет процесс сохранения. В начале приложение получит код уведомления TBN_RESTORE с iItem членом структуры NMTBRESTORE значение –1. Элемент cbData имеет размер pData, а cButtons — количество кнопок.
Обработчик уведомлений должен извлечь глобальную информацию, размещенную в начале pData во время сохранения, и переместить pCurrent к началу первого блока данных, определяемых оболочкой. Задайте cBytesPerRecord размер блоков данных, используемых для сохранения данных кнопки. Установите cButtons равным числу кнопок, и вернитесь.
Следующая NMTBRESTORE предназначена для первой кнопки. Элемент pCurrent указывает на начало первого блока данных о кнопках, а iItem задан на индекс кнопки. Извлеките те данные и продвиньте pCurrent. Загрузите данные в TBBUTTONи вернитесь. Чтобы исключить кнопку из восстановленной панели инструментов, установите член idCommand структуры TBBUTTON в ноль. Оболочка повторит процесс для оставшихся кнопок. Помимо сообщений NMTBSAVE и NMTBRESTORE, можно также использовать такие сообщения, как TBN_RESET, для сохранения и восстановления панели инструментов.
Следующий пример кода сохраняет панель инструментов перед настройкой и восстанавливает ее, если приложение получает сообщение TBN_RESET.
int i;
LPNMHDR lpnmhdr;
static int nResetCount;
static LPTBBUTTON lpSaveButtons;
LPARAM lParam;
switch( lpnmhdr->code)
{
case TBN_BEGINADJUST: // Begin customizing the toolbar.
{
LPTBNOTIFY lpTB = (LPTBNOTIFY)lparam;
// Allocate memory for the button information.
nResetCount = SendMessage(lpTB->hdr.hwndFrom, TB_BUTTONCOUNT, 0, 0);
lpSaveButtons = (LPTBBUTTON)GlobalAlloc(GPTR, sizeof(TBBUTTON) * nResetCount);
// In case the user presses reset, save the current configuration
// so the original toolbar can be restored.
for(i = 0; i < nResetCount; i++)
{
SendMessage(lpTB->hdr.hwndFrom,
TB_GETBUTTON, i,
(LPARAM)(lpSaveButtons + i));
}
}
return TRUE;
case TBN_RESET:
{
LPTBNOTIFY lpTB = (LPTBNOTIFY)lparam;
int nCount, i;
// Remove all of the existing buttons, starting with the last one.
nCount = SendMessage(lpTB->hdr.hwndFrom, TB_BUTTONCOUNT, 0, 0);
for(i = nCount - 1; i >= 0; i--)
{
SendMessage(lpTB->hdr.hwndFrom, TB_DELETEBUTTON, i, 0);
}
SendMessage(lpTB->hdr.hwndFrom, // Restore the saved buttons.
TB_ADDBUTTONS,
(WPARAM)nResetCount,
(LPARAM)lpSaveButtons);
}
return TRUE;
case TBN_ENDADJUST: // Free up the memory you allocated.
GlobalFree((HGLOBAL)lpSaveButtons);
return TRUE;
}
Связанные разделы
-
значения индекса изображения стандартной кнопки панели инструментов
-
Демонстрация стандартных элементов управления Windows (CppWindowsCommonControls)