Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Сообщения о меню в строке состояния





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

В процессе перемещения по строкам меню функция окна, к которому подключено меню, получает сообщение WM_MENUSELECT. При этом младшее слово параметра wParam равно идентификатору команды или позиции (если при выборе этой строки отображается временное меню) строки. Параметр lParam содержит дескриптор меню, по которому пере- нмещается курсор.

Воспользуемся этим для выдачи сообщений в процессе перемещения по строкам меню. В качестве примера возьмем задачу из параграфа 4.2.3, решение которой представлено в листинге 4.3, добавим к этому листингу обработку сообщения WM_MENUSELECT и подключим к окну строку состояния из двух частей.

Задача. Главное меню изначально содержит раздел "Файлы". При выборе строки "Файлы" отображается временное меню со строками "Открыть", "Сохранить", разделительной линией и строкой "Выход". Причем строка "Сохранить" заблокирована.

При выборе строки "Открыть" заблокировать ее. Затем разблокировать строку "Сохранить" и вставить разделы "Правка" и "Вид" в главное меню.

При выборе строки "Правка" отображается временное меню со строками "Найти" и "Заменить". Причем эти строки при их выборе должны быть отмечены как независимые флажки.

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

При выборе строки "Сохранить" заблокировать ее. Затем разблокировать строку "Открыть" и из главного меню удалить разделы "Правка" и "Вид".

В процессе перемещения по строкам меню сообщать о разделе главного меню и о той строке, над которой находится курсор.

Листинг 5.5. Сообщения о меню в строке состояния.

#include <windows.h>

#include <commctrl.h>

#pragma comment (lib, "comctl32.lib")

 

#define ID_STATUS 200

#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

#define CM_VIEW_NORM 3001

#define CM_VIEW_STRC 3002

 

BOOL RegClass(WNDPROC, LPCTSTR, UINT);

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

 

HINSTANCE hInstance;

TCHAR szClass[]=TEXT("SetMenuInfo");

 

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

}

 

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

static HMENU hMainMenu, hFileMenu, hEditMenu, hViewMenu;

static HWND hStatus;

static int pParts[2];

static short cx;

switch (msg)

{

case WM_SIZE:

{

MoveWindow(hStatus, 0, 0, 0, 0, TRUE);

cx=LOWORD(lParam);

pParts[0]=cx/2;

pParts[1]=cx;

SendMessage(hStatus, SB_SETPARTS, 2, (LPARAM)pParts);

return 0;

}

case WM_CREATE:

{

hMainMenu=CreateMenu();

//Создаем временное меню для раздела "Файлы"

hFileMenu=CreatePopupMenu();

int i=0; //Инициализация позиции в меню hFileMenu

CreateMenuItem(hFileMenu, TEXT("&Oткрыть"), i++, CM_FILE_OPEN, NULL, FALSE, MFT_STRING);

CreateMenuItem(hFileMenu, TEXT("&Coxpaнить"), i++, CM_FILE_SAVE, NULL, FALSE, MFT_STRING);

CreateMenuItem(hFileMenu, NULL, i++, 0, NULL, FALSE, MFT_SEPARATOR);

CreateMenuItem(hFileMenu, TEXT("&Bыход"), 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("&Заменить"), i++, CM_EDIT_REPLC, NULL, FALSE, MFT_STRING);

//Создаем временное меню для раздела "Вид"

hViewMenu=CreatePopupMenu();

i=0; //Инициализация позиции в меню hViewMenu

CreateMenuItem(hViewMenu, TEXT("&Обычный"), i++, CM_VIEW_NORM, NULL, FALSE, MFT_RADIOCHECK);

CreateMenuItem(hViewMenu, TEXT("&Cтруктура"), i++, CM_VIEW_STRC, NULL, FALSE, MFT_RADIOCHECK);

//Подключаем временные меню к главному меню 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);

hStatus=CreateStatusWindow(WS_CHILD | WS_VISIBLE, TEXT("Готово"), hwnd, ID_STATUS);

return 0;

}

case WM_COMMAND:

{

switch (LOWORD(wParam))

{

case CM_FILE_OPEN:

{

CreateMenuItem(hMainMenu, TEXT("&Правка"), 1, 0, hEditMenu, FALSE, MFT_STRING);

CreateMenuItem(hMainMenu, TEXT("&Вид"), 2, 0, hViewMenu, FALSE, MFT_STRING);

SetMenuItem(hFileMenu, CM_FILE_OPEN, MFS_GRAYED, FALSE);

SetMenuItem(hFileMenu, CM_FILE_SAVE, MFS_ENABLED, FALSE);

DrawMenuBar(hwnd);

return 0;

}

case CM_FILE_SAVE:

{

RemoveMenu(hMainMenu, 1, MF_BYPOSITION);

RemoveMenu(hMainMenu, 1, MF_BYPOSITION);

SetMenuItem(hFileMenu, CM_FILE_SAVE, MFS_GRAYED, FALSE);

SetMenuItem(hFileMenu, CM_FILE_OPEN, MFS_ENABLED, FALSE);

DrawMenuBar(hwnd);

return 0;

}

case CM_EDIT_FIND:

{

if (GetMenuItem(hEditMenu, CM_EDIT_FIND, FALSE)==MFS_CHECKED)

SetMenuItem(hEditMenu, CM_EDIT_FIND, MFS_UNCHECKED, FALSE);

else

SetMenuItem(hEditMenu, CM_EDIT_FIND, MFS_CHECKED, FALSE);

return 0;

}

case CM_EDIT_REPLC:

{

if (GetMenuItem(hEditMenu, CM_EDIT_REPLC, FALSE)==MFS_CHECKED)

SetMenuItem(hEditMenu, CM_EDIT_REPLC, MFS_UNCHECKED, FALSE);

else

SetMenuItem(hEditMenu, CM_EDIT_REPLC, MFS_CHECKED, FALSE);

return 0;

}

case CM_VIEW_NORM:

{

SetMenuItem(hViewMenu, CM_VIEW_NORM, MFS_CHECKED, FALSE);

SetMenuItem(hViewMenu, CM_VIEW_STRC, MFS_UNCHECKED, FALSE);

return 0;

}

case CM_VIEW_STRC:

{

SetMenuItem(hViewMenu, CM_VIEW_NORM, MFS_UNCHECKED, FALSE);

SetMenuItem(hViewMenu, CM_VIEW_STRC, MFS_CHECKED, FALSE);

return 0;

}

case CM_FILE_QUIT: { DestroyWindow(hwnd); return 0; }

}

return 0;

case WM_MENUSELECT:

{

if ((HMENU)lParam==hMainMenu)

{

switch (LOWORD(wParam))

{

case 0:

SendMessage(hStatus, SB_SETTEXT, 0, (LONG)TEXT("Открыть/закрыть документ или выход"));

SendMessage(hStatus, SB_SETTEXT, 1, NULL);

return 0;

case 1:

SendMessage(hStatus, SB_SETTEXT, 0, (LONG)TEXT("Найти и/или заменить фрагмент"));

SendMessage(hStatus, SB_SETTEXT, 1, NULL);

return 0;

case 2:

SendMessage(hStatus, SB_SETTEXT, 0, (LONG)TEXT("Cмена способа отображения документа"));

SendMessage(hStatus, SB_SETTEXT, 1, NULL);

return 0;

}

}

switch (LOWORD(wParam))

{

case CM_FILE_OPEN:

{ SendMessage(hStatus, SB_SETTEXT, 1, (LONG)TEXT("Oткрыть новый документ")); return 0; }

case CM_FILE_SAVE:

{ SendMessage(hStatus, SB_SETTEXT, 1, (LONG)TEXT("3aкрыть текущий документ")); return 0; }

case CM_EDIT_FIND:

{ SendMessage(hStatus, SB_SETTEXT, 1, (LONG)TEXT("Haйти фрагмент no выделенному образцу")); return 0; }

case CM_EDIT_REPLC:

{ SendMessage(hStatus, SB_SETTEXT, 1, (LONG)TEXT("3aменить найденный фрагмент на указанный образец")); return 0; }

case CM_VIEW_NORM:

{ SendMessage(hStatus, SB_SETTEXT, 1, (LONG)TEXT("Показать текущий документ в обычном виде")); return 0; }

case CM_VIEW_STRC:

{ SendMessage(hStatus, SB_SETTEXT, 1, (LONG)TEXT("Показать структуру текущего документа")); return 0; }

case CM_FILE_QUIT:

{ SendMessage(hStatus, SB_SETTEXT, 1, (LONG)TEXT("3aвершить работу приложения")); return 0; }

}

return 0;

}

case WM_DESTROY:

{ DestroyMenu(hEditMenu); DestroyMenu(hViewMenu); PostQuitMessage(0); return 0; }

}

}

return DefWindowProc(hwnd, msg, wParam, lParam);

}

 

Рассмотрим основные дополнения к листингу 4.3.

1. Дополнения, обусловленные созданием строки состояния, были изучены в приложении в листинге 5.4. Только теперь строка состояния включает две части.

2. Обработка сообщения WM_MENUSELECT состоит из трех частей.

2.1. Отдельно обрабатывают перемещение по названиям разделов главного меню. Если параметр lParam равен дескриптору главного меню, то определяют значение позиции курсора. Это значение содержится в LOWORD(wParam), если строка связана с разделом меню. Мы знаем, какой раздел соответствует каждой позиции. Например, в первой позиции (ей соответствует LOWORD(wParam)=0) находится раздел " Файл ". В этом случае в первой части строки состояния отображают текст " Открыть/закрыть документ или выход ":

 

SendMessage(hStatus, SB_SETTEXT, 0,

(LONG)"Открыть/Закрыть документ или выход");

 

и стирают текст во второй части строки состояния:

 

SendMessage(hStatus, SB_SETTEXT, 1, NULL);

 

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

 

if ((HMENU)lParam==hMainMenu)

{ switch (LOWORD(wParam))

{ case 0;

}

}

 

завершает обработку сообщения оператором возврата, только если курсор установлен на строке раздела меню. То есть не все строки меню с дескриптором lParam должны указывать на разделы меню.

Здесь мы оказываемся в том случае, если младшее слово параметра wParam может быть равно идентификатору команды строки меню. Тогда достаточно определить этот идентификатор и послать соответствующий текст сообщения во вторую часть строки состояния. Например, если курсор находится над строкой " Открыть " раздела " Файл ", то во второй части строки состояния окажется текст " Открыть новый документ ":

 

SendMessage(hStatus, SB_SETTEXT, 1,

(LONG)"Открыть новый документ");

 

Точно так же поступают для других идентификаторов команд.

Обработку завершают возвратом значения 0.

После запуска приложения на экране появится точно такое же окно и с таким же меню, что и после запуска приложения листинга 4.3. Только в этом случае добавлена строка состояния из двух частей. В первой части отображен текст " Готово ".

Если нажать строку " Файл ", в первой части строки состояния появляется текст " Открыть/закрыть документ или выход ", а вторая часть остается пустой. Если курсор перемещается на строку " Открыть ", то текст в первой части не изменится, а во второй части появится текст " Открыть новый документ ". Текст во второй части строки состояния будет меняться при перемещении по строкам этого временного меню, а текст в первой части будет постоянным и указывать на текущий раздел меню.

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

Контрольные вопросы

1. Перечислите основные шаги создания панели инструментов.

2. Что отличает состояние кнопок панели инструментов от состояния строк меню?

3. Какой константой определяют стиль окна панели инструментов, если все кнопки панели должны посылать уведомительные сообщения?

4. Перечислите основные шаги создания строки состояния.

Date: 2015-05-23; view: 584; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.007 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию