Полезное:
Как сделать разговор полезным и приятным
Как сделать объемную звезду своими руками
Как сделать то, что делать не хочется?
Как сделать погремушку
Как сделать так чтобы женщины сами знакомились с вами
Как сделать идею коммерческой
Как сделать хорошую растяжку ног?
Как сделать наш разум здоровым?
Как сделать, чтобы люди обманывали меньше
Вопрос 4. Как сделать так, чтобы вас уважали и ценили?
Как сделать лучше себе и другим людям
Как сделать свидание интересным?
Категории:
АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника
|
Управление состоянием кнопок панелиПанель инструментов во многом ведет себя как обычное окно. Например, в нем, кроме кнопок, можно расположить другие органы управления и управлять ими обычным способом. Но управление кнопками панели имеет свои отличия. Задача. Главное меню окна изначально содержит раздел "Файлы". При выборе строки "Файлы" отображается временное меню со строками "Открыть", "Сохранить" и "Выход". Причем строка "Сохранить" заблокирована. При выборе строки "Открыть" заблокировать ее, разблокировать строку "Сохранить" и в главное меню добавить раздел "Правка". При выборе строки "Правка" отображается временное меню со строками "Найти" и "Заменить". Причем эти строки при их выборе должны быть отмечены как независимые флажки. При выборе строки "Сохранить" заблокировать ее, разблокировать строку "Открыть" и из главного меню удалить элемент "Правка". Команды для строк "Открыть", "Сохранить", "Найти" и "Заменить" продублировать кнопками панели инструментов. Кнопки должны изменять свои состояния подобно соответствующим строкам. Листинг 5.2. Управление кнопками панели инструментов. #include <windows.h> #include <commctrl.h>
#pragma comment (lib, "comctl32.lib") #define ID_TOOLBAR 100 #define CM_FILE_OPEN 1001 #define CM_FILE_SAVE 1002 #define CM_FILE_QUIT 1003 #define CM_EDIT_FIND 2001 #define CM_EDIT_REPLC 2002
BOOL RegClass(WNDPROC, LPCTSTR, UINT); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInstance; TCHAR szClass[] = TEXT("CtrlToolbar");
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow) { MSG msg; HWND hwnd; hInstance = hInst; if (!RegClass(WndProc, szClass, COLOR_WINDOW)) return FALSE; hwnd = CreateWindow(szClass, TEXT("Панель инструментов"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, NULL); if (!hwnd) return FALSE; while(GetMessage(&msg, 0, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }
BOOL RegClass(WNDPROC Proc, LPCTSTR szName, UINT brBackground) { WNDCLASS wc; wc.style = wc.cbClsExtra = wc.cbWndExtra = 0; wc.lpfnWndProc = Proc; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(brBackground + 1); wc.lpszMenuName = NULL; wc.lpszClassName = szName; return (RegisterClass(&wc)!= 0); }
BOOL SetMenuItem(HMENU hMenu, UINT uIns, UINT fState, BOOL flag) { MENUITEMINFO mii; mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_STATE | MIIM_ID; mii.fState = fState; mii.wID = uIns; return SetMenuItemInfo(hMenu, uIns, flag, &mii); }
UINT GetMenuItem(HMENU hMenu, UINT uIns, BOOL flag) { MENUITEMINFO mii; mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_STATE; GetMenuItemInfo(hMenu, uIns, flag, &mii); return mii.fState; }
BOOL CreateMenuItem(HMENU hMenu, TCHAR *str, UINT uIns, UINT uCom, HMENU hSubMenu, BOOL flag, UINT fType) { MENUITEMINFO mii; mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_STATE | MIIM_TYPE | MIIM_SUBMENU | MIIM_ID; mii.fType = fType; mii.fState = MFS_ENABLED; mii.dwTypeData = str; mii.cch = sizeof(str); mii.wID = uCom; mii.hSubMenu = hSubMenu; return InsertMenuItem(hMenu, uIns, flag, &mii); }
HWND CreateToolBar(HWND hwnd, DWORD dwStyle, UINT uCom) { static TBBUTTON but[6]; but[0].fsStyle = TBSTYLE_SEP; but[1].iBitmap = STD_FILEOPEN; but[1].idCommand = CM_FILE_OPEN; but[1].fsState = TBSTATE_ENABLED; but[1].fsStyle = TBSTYLE_GROUP; but[2].iBitmap = STD_FILESAVE; but[2].idCommand = CM_FILE_SAVE; but[2].fsState = TBSTATE_ENABLED; but[2].fsStyle = TBSTYLE_GROUP; but[3].fsStyle = TBSTYLE_SEP; but[4].iBitmap = STD_FIND; but[4].idCommand = CM_EDIT_FIND; but[4].fsState = TBSTATE_HIDDEN; but[4].fsStyle = TBSTYLE_GROUP; but[5].iBitmap = STD_REPLACE; but[5].idCommand = CM_EDIT_REPLC; but[5].fsState = TBSTATE_HIDDEN; but[5].fsStyle = TBSTYLE_GROUP; return CreateToolbarEx(hwnd, dwStyle, uCom, 0, HINST_COMMCTRL, IDB_STD_LARGE_COLOR, but, 6, 0, 0, 0, 0, sizeof(TBBUTTON)); }
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static HMENU hMainMenu, hFileMenu, hEditMenu; static HWND hToolbar; switch (msg) { case WM_SIZE: { MoveWindow(hToolbar, 0, 0, 0, 0, TRUE); return 0; } case WM_CREATE: { hMainMenu = CreateMenu(); //Создаем временное меню для раздела "Файлы" hFileMenu = CreatePopupMenu(); int i=0; //Инициализация позиции в меню hFileMenu CreateMenuItem(hFileMenu, TEXT("&Открыть"), i++, CM_FILE_OPEN, NULL, FALSE, MFT_STRING); CreateMenuItem(hFileMenu, TEXT("&Сохранить"), i++, CM_FILE_SAVE, NULL, FALSE, MFT_STRING); CreateMenuItem(hFileMenu, NULL, i++, 0, NULL, FALSE, MFT_SEPARATOR); CreateMenuItem(hFileMenu, TEXT("&Выход"), i++, CM_FILE_QUIT, NULL, FALSE, MFT_STRING); //Создаем временное меню для раздела "Правка" hEditMenu = CreatePopupMenu(); i=0; //Инициализация позиции в меню hEditMenu CreateMenuItem(hEditMenu, TEXT("&Найти"), i++, CM_EDIT_FIND, NULL, FALSE, MFT_STRING); CreateMenuItem(hEditMenu, TEXT("&3аменить"), i++, CM_EDIT_REPLC, NULL, FALSE, MFT_STRING); //Подключаем временные меню к главному меню i=0; //Инициализация позиции в меню hMainMenu CreateMenuItem(hMainMenu, TEXT("&Файл"), i++, 0, hFileMenu, FALSE, MFT_STRING); SetMenu(hwnd, hMainMenu); SetMenuItem(hFileMenu, CM_FILE_SAVE, MFS_GRAYED, FALSE); DrawMenuBar(hwnd); //Создаем панель инструментов DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_DLGFRAME; hToolbar = CreateToolBar(hwnd, dwStyle, ID_TOOLBAR); return 0; } case WM_COMMAND: { switch (LOWORD(wParam)) { case CM_FILE_OPEN: { if (GetMenuItem(hFileMenu, CM_FILE_OPEN, FALSE)==MFS_GRAYED) return 0; CreateMenuItem(hMainMenu, TEXT("&Правка"), 1, 0, hEditMenu, FALSE, MFT_STRING); SetMenuItem(hFileMenu, CM_FILE_OPEN, MFS_GRAYED, FALSE); SetMenuItem(hFileMenu, CM_FILE_SAVE, MFS_ENABLED, FALSE); DrawMenuBar(hwnd); SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_FILE_OPEN, (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0)); SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_FILE_SAVE, (LPARAM)MAKELONG(TBSTATE_ENABLED, 0)); if (GetMenuItem(hEditMenu, CM_EDIT_FIND, FALSE)==MFS_CHECKED) SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_FIND, (LPARAM)MAKELONG(TBSTATE_CHECKED | TBSTATE_ENABLED, 0)); else SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_FIND, (LPARAM)MAKELONG(TBSTATE_ENABLED, 0)); if (GetMenuItem(hEditMenu, CM_EDIT_REPLC, FALSE)==MFS_CHECKED) SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_REPLC, (LPARAM)MAKELONG(TBSTATE_CHECKED | TBSTATE_ENABLED, 0)); else SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_REPLC, (LPARAM)MAKELONG(TBSTATE_ENABLED, 0)); return 0; } case CM_FILE_SAVE: { if (GetMenuItem(hFileMenu, CM_FILE_SAVE, FALSE)==MFS_GRAYED) return 0; RemoveMenu(hMainMenu, 1, MF_BYPOSITION); SetMenuItem(hFileMenu, CM_FILE_SAVE, MFS_GRAYED, FALSE); SetMenuItem(hFileMenu, CM_FILE_OPEN, MFS_ENABLED, FALSE); DrawMenuBar(hwnd); SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_FILE_OPEN, (LPARAM)MAKELONG(TBSTATE_ENABLED, 0)); SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_FILE_SAVE, (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0)); SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_FIND, (LPARAM)MAKELONG(TBSTATE_HIDDEN, 0)); SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_REPLC, (LPARAM)MAKELONG(TBSTATE_HIDDEN, 0)); return 0; } case CM_EDIT_FIND: { if (GetMenuItem(hEditMenu, CM_EDIT_FIND, FALSE)==MFS_CHECKED) { SetMenuItem(hEditMenu, CM_EDIT_FIND, MFS_UNCHECKED, FALSE); SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_FIND, (LPARAM)MAKELONG(TBSTATE_ENABLED, 0)); } else { SetMenuItem(hEditMenu, CM_EDIT_FIND, MFS_CHECKED, FALSE); SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_FIND, (LPARAM)MAKELONG (TBSTATE_CHECKED | TBSTATE_ENABLED, 0)); } return 0; } case CM_EDIT_REPLC: { if (GetMenuItem(hEditMenu, CM_EDIT_REPLC, FALSE)==MFS_CHECKED) { SetMenuItem(hEditMenu, CM_EDIT_REPLC, MFS_UNCHECKED, FALSE); SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_REPLC, (LPARAM)MAKELONG(TBSTATE_ENABLED, 0)); } else { SetMenuItem(hEditMenu, CM_EDIT_REPLC, MFS_CHECKED, FALSE); SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_REPLC, (LPARAM)MAKELONG(TBSTATE_CHECKED | TBSTATE_ENABLED, 0)); } return 0; } case CM_FILE_QUIT: { DestroyWindow(hwnd); return 0; } } return 0; } case WM_DESTROY: { PostQuitMessage(0); return 0; } } return DefWindowProc(hwnd, msg, wParam, lParam); }
Работа этого приложения похожа на работу приложения из листинга 4.3. В целях сокращения объема текста в этом примере отсутствуют раздел меню " Вид " и соответствующие кнопки панели инструментов. При запуске приложения полоса меню отображает только раздел " Файл " главного меню. А на панели инструментов отображены две кнопки: " Открыть " и " Сохранить ". Причем последняя заблокирована. Рассмотрим, как это достигнуто. Функция CreateToolBar изиачальио создает панель из шести кнопок: " малый промежуток ", " Открыть ", " Сохранить ", " Малый промежуток ", " Найти " и " Заменить ". При этом изначально доступна только кнопка " Открыть ", о чем говорит ее состояние:
but[1].fsState = TBSTATE_ENABLED;
Кнопка " Сохранить " видима, но недоступна:
but[2].fsState = TBSTATE_INDETERMINATE;
Кнопки " Найти " и " Заменить " изначально создают невидимыми:
but[4].fsState = TBSTATE_HIDDEN; but[5].fsState = TBSTATE_HIDDEN;
Если выбрать строку или нажать на кнопку " Открыть ", в главном меню появляется раздел " Правка " со строками " Найти " и " Заменить ", строка " Открыть " блокируется, " Сохранить " – разблокируется. На панели инструментов эти действия дублируют: появляются кнопки " Найти " и " Заменить ", кнопка " Открыть " блокируется, " Сохранить " – разблокируется. Рассмотрим, как это достигается. Очевидно, что эти действия выполняют при обработке сообщения WM_COMMAND со значением LOWORD(wParam), равным CM_FILE_OPEN. Обсудим шаги обработки этого сообщения. 1. Первая часть хорошо знакома по примеру листинга 4.3. 1.1. Если строка " Открыть " заблокирована, то обработку завершить. 1.2. Иначе подключить раздел " Правка " к главному меню. 1.3. Заблокировать строку " Открыть " в разделе " Файл " и разблокировать строку " Сохранить ". 1.4. Перерисовать полосу меню. 2. Вторая часть посвящена управлению состоянием кнопок панели инструментов. Здесь вызывают функцию SendMessage со специфическими для кнопок панели инструментов параметрами. 2.1. Заблокировать кнопку " Открыть ":
SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_FILE_OPEN, (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
2.2. Разблокировать кнопку " Сохранить ":
SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_FILE_SAVE, (LPARAM)MAKELONG(TBSTATE_ENABLED, 0)));
2.3. Кнопка " Найти " дублирует одноименную строку меню и отображает состояние этого элемента меню. Поэтому перед отображением кнопки "Найти" нужно анализировать состояние элемента меню " Найти ". Если этот элемент меню отмечен, то и кнопку " Найти " нужно отметить и оставить в доступном состоянии:
SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_FIND, (LPARAM)MAKELONG (TBSTATE_CHECKED | TBSTATE_ENABLED,0));
иначе кнопку " Найти " отобразить в доступном состоянии:
SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_FIND, (LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
2.4. Так же управляют состоянием кнопки " Заменить ":
if(GetMenuItem(hEditMenu, CM_EDIT_REPLC,FALSE)==MFS_CHECKED) SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_REPLC, (LPARAM)MAKELONG (TBSTATE_CHECKED | TBSTATE_ENABLED,0)); else SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_REPLC, (LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
Этим завершают обработку команды, которая поступает после выбора строки меню "Открыть" или нажатия кнопки панели инструментов " Открыть ". Намного меньше усилий требует обработка команды, которая поступает после выбора строки меню " Сохранить " или нажатия кнопки панели инструментов " Сохранить ": 1. Если элемент меню " Сохранить " заблокирован, то завершить обработку:
if (GetMenuItem(hFileMenu, CM_FILE_SAVE, FALSE)==MFS_GRAYED) return 0;
2. Иначе удалить раздел меню " Правка ":
RemoveMenu(hMainMenu, 1, MF_BYPOSITION);
3. Заблокировать строку меню " Сохранить ":
SetMenuItem(hFileMenu, CM_FILE_SAVE, MFS_GRAYED, FALSE);
4. Разблокировать строку меню " Открыть ":
SetMenuItem(hFileMenu, CM_FILE_OPEN, MFS_ENABLED, FALSE);
5. Перерисовать полосу меню:
DrawMenuBar(hwnd);
6. Разблокировать кнопку " Открыть "
SendMessage(hToolbar,TB_SETSTATE,(WPARAM)CM_FILE_OPEN, (LPARAM)MAKELONG(TBSTATE_ENABLED,0));
7. Заблокировать кнопку " Сохранить ":
SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_FILE_SAVE, (LPARAM)MAKELONG(TBSTATE_INDETERMINATE,0));
8. Скрыть кнопку " Найти ":
SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_FIND, (LPARAM)MAKELONG(TBSTATE_HIDDEN, 0));
9. Скрыть кнопку " Заменить ":
SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_REPLC, (LPARAM)MAKELONG(TBSTATE_HIDDEN, 0));
Этим завершают обработку команды, которая поступает после выбора строки меню " Сохранить " или нажатия кнопки панели инструментов " Сохранить ". Обработку команд от строк и кнопок " Найти " и " Заменить " рассмотрим на примере команды, которая поступает после выбора строки меню " Заменить " или нажатия кнопки панели инструментов " Заменить ". Эта кнопка при первом нажатии должна сохранить нажатое состояние, а при втором нажатии – вернуться в исходное состояние. При этом кнопка " Заменить " дублирует и отображает состояние элемента меню " Заменить ". Рассмотрим, как это достигается. Если строка меню " Заменить " отмечена галочкой, то удалить признак отметки со строки меню " Заменить ":
SetMenuItem(hEditMenu, CM_EDIT_REPLC, MFS_UNCHECKED, FALSE);
и перевести кнопку " Заменить " в отжатое состояние:
SendMessage(hToolbar, TB_SETSTATE, (WPARAM)CM_EDIT_REPLC, (LPARAM)MAKELONG(TB_STATE_ENABLED,0));
иначе отметить галочкой строку меню " Заменить ":
SetMenuItem(hEditMenu, CM_EDIT_REPLC, MFS_CHECKED, FALSE);
и перевести кнопку " Заменить " в нажатое состояние:
SendMessage(hTooIbar, TB_SETSTATE, (WPARAM)CM_EDIT_REPLC, (LPARAM)MAKELONG(TBSTATE_CHECKED | TBSTATE_ENABLED, 0));
Здесь состояние TBSTATE_CHECKED | TBSTATE_ENABLED выбрано таким, что кнопка при отмеченном состоянии остается и доступной для нажатия. Других особенностей в работе этого приложения нет.
|