Полезное:
Как сделать разговор полезным и приятным
Как сделать объемную звезду своими руками
Как сделать то, что делать не хочется?
Как сделать погремушку
Как сделать так чтобы женщины сами знакомились с вами
Как сделать идею коммерческой
Как сделать хорошую растяжку ног?
Как сделать наш разум здоровым?
Как сделать, чтобы люди обманывали меньше
Вопрос 4. Как сделать так, чтобы вас уважали и ценили?
Как сделать лучше себе и другим людям
Как сделать свидание интересным?
Категории:
АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника
|
Вывод подсказок в панели инструментовПри остановке курсора мыши над любой кнопкой панели инструментов можно отображать текст подсказки, связанный с этой кнопкой. Для этого используют механизм уведомительных сообщений, при котором у функции окна можно запросить текст и отобразить его. Панель инструментов функции родительского окна посылает уведомительное сообщение WM_NOTIFY о том, что с ней что-то сделали или требуется дополнительная информация. Для идентификации отправителя и истолкования сообщения используют параметр lParam. Он указывает на структуру типа NMHDR, которая содержит код и дополнительную информацию сообщения. После обработки сообщения WM_NOTIFY можно возвращать любое значение. Структура NMHDR описана следующим образом: typedef struct { HWND hwndFrom; UINT idFrom; UINT code; } NMHDR; Здесь hwndFrom – дескриптор пославшего сообщение органа управления, idFrom – идентификатор этого органа управления, code – специфический для органа управления код сообщения. Структура NMHDR обычно является частью структуры более высокого уровня. В случае панели инструментов она является частью структуры TOOLTIPTEXT: typedef struct { NMHDR hdr; LPTSTR IpszText; char szText[80]; HINSTANCE hinst; UINT uFlags; } TOOLTIPTEXT; Назначение полей этой структуры: 1. hdr – структура типа NMHDR. 2. IpszText – указатель на строку, которая содержит или получает текст для панели инструментов. 3. szText – буфер для получения текста от панели инструментов. 4. hinst – дескриптор приложения, которое содержит строковый ресурс. Если lpszText указывает на строку, hinst=NULL. 5. uFlags – флажок, который указывает, как интерпретировать значение поля idFrom структуры hdr. Если uFlags=TTF_IDISHWND, то idFrom – дескриптор, иначе idFrom – идентификатор кнопки панели инструментов. Эти структуры обычно описывают и инициируют после получения сообщения WM_NOTIFY. Например, следующим образом: Описывают указатель на структуру типа TOOLTIPTEXT: LPTOOLTIPTEXT TTStr; Связывают указатель TTStr с параметром lParam: TTStr=(LPTOOLTIPTEXT)IParam; Далее анализируют код сообщения и принимают соответствующее решение. Например, в случае организации подсказок, анализ сводится к проверке: if (TTStr->hdr.code!=TTN_NEEDTEXT) return 0; То есть обработку завершают, если код не равен TTN_NEEDTEXT. Сообщение TTN_NEEDTEXT говорит, что для панели инструментов требуется текст. Представим, что принято уведомительное сообщение от кнопки панели о том, что требуется некий текст. Тогда определяют идентификатор этой кнопки и записывают соответствующий текст. Эту процедуру можно реализовать многими способами. Например: switch (TTStr->hdr.idFrom) { case CM_FILE_NEW: { TTStr-MpszText-'Создать новый документ"; return 0; } default: return 0; } В качестве подсказки можно посылать любые тексты (даже с управляющими символами типа \n). Задача. В рассмотренном ранее приложении (листинг 4.6) к командам меню подключить кнопки панели инструментов и обеспечить выдачу подсказок в момент остановки курсора мыши над кнопкой панели. Листинг 5.3. Выдача подсказок к кнопкам панели инструментов. #include <windows.h> #include <commctrl.h>
#pragma comment (lib, "comctl32.lib")
#define ID_TOOLBAR 100 #define CM_FILE_NEW 1000 #define CM_FILE_OPEN 1001 #define CM_FILE_SAVE 1002 #define CM_FILE_QUIT 1003 #define CM_EDIT_CUT 2000 #define CM_EDIT_PASTE 2001 #define CM_EDIT_COPY 2002 #define CM_EDIT_DEL 2003 #define CM_HELP_HELP 3000 #define CM_HELP_ABOUT 3001
BOOL RegClass(WNDPROC, LPCTSTR, UINT); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); HACCEL CreateAccelTable(void);
HINSTANCE hInstance; TCHAR szClass[] = TEXT("NotifyClass"); 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; HACCEL hAccel = CreateAccelTable(); while(GetMessage(&msg, 0, 0, 0)) { if (!hAccel ||!TranslateAccelerator(hwnd, hAccel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } DestroyAcceleratorTable(hAccel); 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 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); }
HACCEL CreateAccelTable(void) { //Массив акселераторов ACCEL Accel[8]; //Создать Accel[0].fVirt = FVIRTKEY | FCONTROL; Accel[0].key = 0x4e; Accel[0].cmd = CM_FILE_NEW; //Открыть Accel[1].fVirt= FVIRTKEY | FCONTROL; Accel[1].key = 0x4f; Accel[1].cmd = CM_FILE_OPEN; //Сохранить Accel[2].fVirt= FVIRTKEY | FCONTROL; Accel[2].key = 0x53; Accel[2].cmd = CM_FILE_SAVE; //Выход Accel[3].fVirt= FVIRTKEY | FALT; Accel[3].key = 0x73; Accel[3].cmd = CM_FILE_QUIT; //Вырезать Accel[4].fVirt= FVIRTKEY | FCONTROL; Accel[4].key = 0x58; Accel[4].cmd = CM_EDIT_CUT; //Вклеить Accel[5].fVirt= FVIRTKEY | FCONTROL; Accel[5].key = 0x56; Accel[5].cmd = CM_EDIT_PASTE; //Копировать Accel[6].fVirt= FVIRTKEY | FCONTROL; Accel[6].key = 0x43; Accel[6].cmd = CM_EDIT_COPY; //Удалить Accel[7].fVirt= FVIRTKEY; Accel[7].key = 0x2e; Accel[7].cmd = CM_EDIT_DEL; return CreateAcceleratorTable((LPACCEL)Accel, 8); }
HWND CreateToolBar(HWND hwnd, DWORD dwStyle, UINT uCom) { static TBBUTTON but[10]; but[0].fsStyle=TBSTYLE_SEP; //Создать but[1].iBitmap = STD_FILENEW; but[1].idCommand=CM_FILE_NEW; but[1].fsState=TBSTATE_ENABLED; but[1].fsStyle=TBSTYLE_BUTTON; //Открыть but[2].iBitmap=STD_FILEOPEN; but[2].idCommand=CM_FILE_OPEN; but[2].fsState=TBSTATE_ENABLED; but[2].fsStyle=TBSTYLE_BUTTON; //Сохранить but[3].iBitmap=STD_FILESAVE; but[3].idCommand=CM_FILE_SAVE; but[3].fsState=TBSTATE_ENABLED; but[3].fsStyle=TBSTYLE_BUTTON; //Вырезать but[4].iBitmap=STD_CUT; but[4].idCommand=CM_EDIT_CUT; but[4].fsState=TBSTATE_ENABLED; but[4].fsStyle=TBSTYLE_BUTTON; //Копировать but[5].iBitmap=STD_COPY; but[5].idCommand=CM_EDIT_COPY; but[5].fsState=TBSTATE_ENABLED; but[5].fsStyle=TBSTYLE_BUTTON; //Вставить but[6].iBitmap=STD_PASTE; but[6].idCommand=CM_EDIT_PASTE; but[6].fsState=TBSTATE_ENABLED; but[6].fsStyle=TBSTYLE_BUTTON; //Удалить but[7].iBitmap=STD_DELETE; but[7].idCommand=CM_EDIT_DEL; but[7].fsState=TBSTATE_ENABLED; but[7].fsStyle=TBSTYLE_BUTTON; //Запрос помощи but[8].iBitmap=STD_HELP; but[8].idCommand=CM_HELP_HELP; but[8].fsState=TBSTATE_ENABLED; but[8].fsStyle=TBSTYLE_BUTTON; return CreateToolbarEx(hwnd, dwStyle, uCom, 0, HINST_COMMCTRL, IDB_STD_LARGE_COLOR, but, 9, 0, 0, 0, 0, sizeof(TBBUTTON)); }
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static HMENU hMainMenu, hPopUpFile, hPopUpEdit, hPopUpHelp; static HWND hToolbar; switch (msg) { case WM_SIZE: { MoveWindow(hToolbar, 0, 0, 0, 0, TRUE); return 0; } case WM_CREATE: { hMainMenu=CreateMenu(); hPopUpFile=CreatePopupMenu(); int i=0; //Инициализация позиции в меню CreateMenuItem(hPopUpFile, TEXT("&Новый\t Ctrl+N"), i++, CM_FILE_NEW, NULL, FALSE, MFT_STRING); CreateMenuItem(hPopUpFile, TEXT("&Oткрыть\t Ctrl+O"), i++, CM_FILE_OPEN, NULL, FALSE, MFT_STRING); CreateMenuItem(hPopUpFile, TEXT("&Coxpaнить\t Ctrl+S"), i++, CM_FILE_SAVE, NULL, FALSE, MFT_STRING); CreateMenuItem(hPopUpFile, NULL, i++, 0, NULL, FALSE, MFT_SEPARATOR); CreateMenuItem(hPopUpFile, TEXT("В&ыход\t Alt+F4"), i++, CM_FILE_QUIT, NULL, FALSE, MFT_STRING); hPopUpEdit=CreatePopupMenu(); i=0; //Инициализация позиции в меню CreateMenuItem(hPopUpEdit, TEXT("&Bырезать\t Ctrl+X"), i++, CM_EDIT_CUT, NULL, FALSE, MFT_STRING); CreateMenuItem(hPopUpEdit, TEXT("B&ставить\t Ctrl+V"), i++, CM_EDIT_PASTE, NULL, FALSE, MFT_STRING); CreateMenuItem(hPopUpEdit, TEXT("&Копировать\t Ctrl+C"), i++, CM_EDIT_COPY, NULL, FALSE, MFT_STRING); CreateMenuItem(hPopUpEdit, TEXT("&Удалить\t Delete"), i++, CM_EDIT_DEL, NULL, FALSE, MFT_STRING); hPopUpHelp=CreatePopupMenu(); i=0; //Инициализация позиции в меню CreateMenuItem(hPopUpHelp, TEXT("&Помощь\ F1"), i++, CM_HELP_HELP, NULL, FALSE, MFT_STRING); CreateMenuItem(hPopUpHelp, NULL, i++, 0, NULL, FALSE, MFT_SEPARATOR); CreateMenuItem(hPopUpHelp, TEXT("&О программе"), i++, CM_HELP_ABOUT, NULL, FALSE, MFT_STRING); //Подключаем временные меню к главному меню i=0; //Инициализация позиции в меню CreateMenuItem(hMainMenu, TEXT("&Файл"), i++, 0, hPopUpFile, FALSE, MFT_STRING); CreateMenuItem(hMainMenu, TEXT("&Правка"), i++, 0, hPopUpEdit, FALSE, MFT_STRING); CreateMenuItem(hMainMenu, TEXT("&Помощь"), i++, 0, hPopUpHelp, FALSE, MFT_STRING); SetMenu(hwnd, hMainMenu); DrawMenuBar(hwnd); DWORD dwStyle = WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS | WS_DLGFRAME; hToolbar=CreateToolBar(hwnd, dwStyle, ID_TOOLBAR); return 0; } case WM_COMMAND: { switch (LOWORD(wParam)) { case CM_FILE_NEW: case CM_FILE_OPEN: case CM_FILE_SAVE: case CM_EDIT_CUT: case CM_EDIT_PASTE: case CM_EDIT_COPY: case CM_EDIT_DEL: case CM_HELP_HELP: case CM_HELP_ABOUT: { return 0; } case CM_FILE_QUIT: { DestroyWindow(hwnd); return 0; } } } case WM_NOTIFY: { LPTOOLTIPTEXT TTStr; TTStr=(LPTOOLTIPTEXT)lParam; if (TTStr->hdr.code!= TTN_NEEDTEXT) return 0; switch (TTStr->hdr.idFrom) { case CM_FILE_NEW: { TTStr->lpszText = TEXT("Создать новый документ"); return 0; } case CM_FILE_OPEN: { TTStr->lpszText = TEXT("Открыть существующий документ"); return 0; } case CM_FILE_SAVE: { TTStr->lpszText = TEXT("Coxpaнить текущий документ"); return 0; } case CM_EDIT_CUT: { TTStr->lpszText = TEXT("Вырезать и запомнить выделенный объект"); return 0; } case CM_EDIT_PASTE: { TTStr->lpszText = TEXT("Bcтавить копированный объект"); return 0; } case CM_EDIT_COPY: { TTStr->lpszText = TEXT("Копировать выделенный объект"); return 0; } case CM_EDIT_DEL: { TTStr->lpszText = TEXT("Удаление выделенного объекта"); return 0; } case CM_HELP_HELP: { TTStr->lpszText = TEXT("Добро пожаловать в справочную систему:\n\n", "1. Найдите ответы на возникающие вопросы\n\n", "2. Просмотрите электронную версию справочника"); return 0; } case CM_HELP_ABOUT: { TTStr->lpszText = TEXT("Сообщение о программе"); return 0; } case CM_FILE_QUIT: { TTStr->lpszText = TEXT("3aвершить работу приложения"); return 0; } default: return 0; } return 0; } case WM_DESTROY: { PostQuitMessage(0); return 0; } } return DefWindowProc(hwnd, msg, wParam, lParam); }
Рассмотрим, какие изменения потребовались для решения данной задачи. 1. Описан идентификатор панели инструментов:
#define ID_TOOLBAR 100
2. Описана функция создания панели инструментов:
HWND CreateToolBar(HWND hwnd, DWORD dwStyle, UINT uCom);
Она от предыдущих версий отличается другим составом кнопок и тем, что отсутствует управление состоянием кнопок. 3. Для того чтобы кнопки панели инструментов посылали сообщение WMNOTIFY, изменен стиль dwStyle окна панели инструментов:
DWORD dwStyle = WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS | WS_DLGFRAME;
Здесь применен стиль TBSTYLE_TOOLTIPS. Затем стиль dwStyle используют при вызове функции CreateToolBar для создания панели инструментов:
hToolbar = CreateToolBar(hwnd, dwStyle, ID_TOOLBAR);
4. Обработка уведомительного сообщения WM_NOTIFY. 4.1. Запоминают значение параметра lParam. Для этого описывают переменную-указатель на структуру типа TOOLTIPTEXT:
LPTOOLTIPTEXT TTStr;
4.2. Затем в эту переменную записывают значение параметра lParam:
TTStr = (LPTOOLTIPTEXT)lParam;
4.3. Если уведомительное сообщение WM_NOTIFY не требует текста подсказки, завершают обработку:
if (TTStr->hdr.code!= TTN_NEEDTEXT) return 0;
4.4. Оператор варианта по идентификатору кнопки, которая послала сообщение WM_NOTIFY, записывает тот или иной текст в структуру TTStr:
switch (TTStr->hdr.idFrom) { case CM_FILE_NEW: { TTStr->lpszText = "Создать новый документ"; return 0; } case CM_FILE_QUIT: { TTStr->lpszText = "3aвершить работу приложения"; return 0; } default: return 0; }
Как видно из листинга, здесь перечислены все команды меню. Хотя не для всех команд созданы кнопки на панели инструментов. В любом случае подсказка соответствует той кнопке, над которой остановился курсор мыши. Подсказки будут появляться в том случае, если кнопка отображена на панели. При этом операционную систему не интересует состояние кнопки: достаточно того, что кнопка посылает уведомительное сообщение WM_NOTIFY. Другие изменения в тексте приложения не обязательны. Данный способ обработки сообщения WM_NOTIFY отличается простотой, наглядностью и информативностью сообщений. Например, можно выдать большее сообщение:
TTStr->lpszText="Добро пожаловать в справочную систему:\n\n" "1. Найдите ответы на возникающие вопросы.\n\n" "2. Просмотрите электронную версию справочника";
|