Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Поcобие_БЕЛОВ_Графический_интерфейс_API

.pdf
Скачиваний:
141
Добавлен:
18.03.2016
Размер:
2.75 Mб
Скачать

161

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.flype = fType; mii.fState= MFS_ENABLED; mii.dwTypeData = str; mii.cch=sizeof(str); mii.wID=uCom; mii.hSubMenu=hSubMenu;

return InsertMenuItem(hMenu, ulns, flag, &mii);

}

LRESULT CALLBACK

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

{ static HMENU hMainMenu, hFileMenu, hEditMenu; static BOOL fFileOpened; switch (msg)

{case WM_CREATE:

{hMainMenu=CreateMenu();

//Создаем временное меню для раздела "Файлы" hFileMenu=CreatePopupMenu();

int i=0;

//Инициализация позиции в меню hFileMenu CreateMenuItem( hFileMenu, "&Открыть", i++, CM_FILE_OPEN, NULL, FALSE, MFT_STRING); CreateMenuItem( hFileMenu, "&Сохранить", i++, CM_FILE_SAVE, NULL, FALSE, MFT_STRING ); CreateMenuItem( hFileMenu, NULL, i++,

0, NULL, FALSE, MFT_SEPARATOR); CreateMenuItem( hFileMenu, "&Выход", i++, CM_FILE_QUIT, NULL, FALSE, MFT_STRING); //Создаем временное меню для раздела "Правка" hEditMenu=CreatePopupMenu();

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

hEditMenu CreateMenuItem( hEditMenu, "&Найти", i++, CM_EDIT_FIND, NULL, FALSE, MFT_STRING); CreateMenuItem( hEditMenu, "&3аменить", i++,

162

CM_EDIT_REPLC, NULL, FALSE, MFT_STRING); //Подключаем временные меню к главному меню i=0; //Инициализация позиции в меню

hMainMenu CreateMenuItem( hMainMenu, "&Файл", i++, 0, hFileMenu,FALSE, MFT_STRING); SetMenu(hwnd,hMainMenu);

DrawMenuBar(hwnd); fFileOpened=FALSE; return 0;

}

case WM_COMMAND:

{switch (LOWORD(wParam)) { case CM_FILE_OPEN:

{ if (!fFileOpened)

{ CreateMenuItem( hMainMenu, "&Правка", 1,0, hEditMenu, FALSE, MFT_STRING); DrawMenuBar( hwnd ); fFileOpened=TRUE;

}

return 0;

}

case CM_FILE_SAVE:

{if(fFileOpened)

{RemoveMenu(hMainMenu,1, MF_BYPOSITION); DrawMenuBar( hwnd); fFileOpened=FALSE;

}

return 0;

}

case CM_EDIT_FIND:

{ MessageBox(hwnd, "Команда CM_EDIT_FIND", "Меню",МВ_ОК); return 0;

}

case CM_EDIT_REPLC:

{ MessageBox(hwnd, "Команда CM_EDIT_REPLC", "Меню",МВ_ОК);

163

return 0;

}

caseCM_FILE_QUIT:

{ DestroyWindow(hwnd); return 0;

}

}

return 0;

}

case WM_DESTROY:

{ if (!fFileOpened) DestroyMenu( hEditMenu); PostQuitMessage(0);

return 0;

}

}

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

Это приложение от предыдущего отличается следующим:

1. Временное меню hEditMenu в главное меню вставляют лишь после выбора строки «Открыть». При этом проверяют флаг состояния fFileOpened – если файл открыт, то меню hEditMenu вставлено в главное меню и еще раз его вставлять не требуется:

if(!fFileOpened)

{CreateMenuItem( hMainMenu, "&Правка", 1,0, hEditMenu,

FALSE, MFT_STRING); DrawMenuBar( hwnd); fFileOpened=TRUE;

}

Как видно, операция вставки буквально скопирована из предыдущего приложения.

2. Временное меню hEditMenu удаляют из главного меню после выборастроки «Сохранить». Здесь закрытие файла подразумевается. При этом проверяют флаг состояния fFileOpened – если файл закрыт, то меню hEditMenu удалено и еще раз его удалять не требуется:

if (fFileOpened)

{RemoveMenu( hMainMenu, 1, MF_BYPOSITION');

DrawMenuBar( hwnd); fFileOpened=FALSE;

}

3. До разрушения окна проверяют, вставлено ли меню

164

hEditMenu вглавное меню. Если нет, то его необходимо разрушать отдельно:

if (!fFileOpened) DestroyMenu( hEditMenu);

4.2.3. Управление состоянием элементов меню

Следующая функция изменяет состояние элемента меню hMenu: BOOL SetMenuItemInfo( MENU hMenu, UINT uItem,

BOOL fByPosition, LPMENUITEMINFO lpmii);

При fByPosition=FALSE значение uItem равно идентификатору команды элемента, иначе – позиции элемента в меню. Значение lpmii указывает на структуру типа MENUITEMINFO, которая содержит новые данные для элемента. При успешном выполнении функция возвращает ненулевое значение.

Проанализируем вызов функции SetMenuItemInfo. Первые 3 аргумента указывают на элемент, параметры которого изменяют. Последний аргумент содержит параметры нового состояния элемента. При этом изменяют те параметры, на которые указывает поле fMask.

Задача. Описать функцию для изменения состояния элемента. Следующая функция является примером решения задачи: BOOL SetMenuItem(HMENU hMenu, UINT ulns, UINT fState, BOOL flag)

{ MENUITEMINFO mii; mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_STATE | MIIM_ID; mii.fState = fState;

mii.wID = ulns;

return SetMenuItemInfo( hMenu, ulns, flag, &mii);

}

Список формальных параметров этой функции:

hMenu – дескриптор меню, состояние элемента которого необходимо изменить;

ulns и flag совпадают соответственно с параметрами uItem

и fByPosition, функции SetMenuItemInfo; fState задает новое состояние элемента.

Поле fMask указывает, что у элемента изменяется только значение поля fState, а поле wID структуры mii операционная система использует для получения указания на изменяемый элемент.

165

Следующая функция выбирает данные элемента меню hMenu: BOOL GetMenuItemInfo (HMENU hMenu, UINT uItem,

BOOL fByPosition, LPMENUITEMINFO lpmii);

При fByPosition=FALSE значение uItem равно идентификатору команды элемента, иначе – позиции элемента в меню. Значение lpmii указывает на структуру типа MENUITEMINFO, поле fMask которой содержит указания на запрашиваемые параметры. В эту же структуру будут записаны значения запрошенных параметров элемента. При успешном выполнении функция возвращает ненулевое значение.

Задача. Описать функцию для запроса состояния элемента. Следующая функция является примером решения данной

задачи:

UINT GetMenuItem(HMENU hMenu, UINT ulns, BOOL flag)

{MENUITEMINFO mii; mii.cbSize=sizeof(MENUITEMINFO); mii.fMask = MIIM_STATE; GetMenuItemInfo(hMenu, ulns, flag, &mii);

return mii.fState;

}

Список формальных параметров этой функции:

hMenu – дескриптор меню, состояние элемента которого необходимо запросить;

ulns и flag совпадают соответственно с параметрами uItem

и fByPosition функции GetMenuItemInfo.

Функция возвращает значение состояния элемента. Поле fMask указывает, что запрашивается только значение поля fState элемента.

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

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

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

При выборе строки «Сохранить» заблокировать ее. Затем

166

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

Листинг 4.3. Управление состоянием строк меню.

#include <windows.h>

#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; char szClass[]="SetMenuInfo";

int WINAPI WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { MSG msg; HWND hwnd; ::hInstance=hInstance;

if (!RegClass(WndProc, szClass,COLOR_WINDOW)) return FALSE;

hwnd = CreateWindow(szClass,

"Управление состоянием элементов меню",

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;

167

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 ulns, UINT fState, BOOL flag)

{MENUITEMINFO mii; mii.cbSize=sizeof(MENUITEMINFO); mii.fMask = MIIM_STATE | MIIM_ID; mii.fState = fState;

mii.wID = ulns;

return SetMenuItemInfo( hMenu, ulns, flag, &mii);

}

UINT GetMenuItem(HMENU hMenu, UINT ulns, BOOL flag)

{MENUITEMINFO mii; mii.cbSize=sizeof(MENUITEMINFO); mii.fMask = MIIM_STATE; GetMenuItemInfo(hMenu, ulns, flag, &mii); return mii.fState;

}

BOOL CreateMenuItem(HMENU hMenu, char *str, UINT ulns, UINT uCom, HMENU hSubMenu, BOOL flag, UINT fType)

{MENUITEMINFO mii; mii.cbSize=sizeof(MENUITEMINFO);

miifMask = 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, ulns, flag, &mii);

}

LRESULT CALLBACK WndProc( HWND hwnd, UINT msg,

168 WPARAM wParam, LPARAM lParam)

{ static HMENU hMainMenu, hFileMenu, hEditMenu, hViewMenu;

switch (msg)

{caseWM_CREATE:

{ hMainMenu=CreateMenu();

//Создаем временное меню для раздела "Файлы" hFileMenu=CreatePopupMenu();

int i=0; //Инициализация позиции в меню hFileMenu CreateMenuItem( hFileMenu, "&Открыть", i++, CM_FILE_OPEN, NULL, FALSE, MFT_STRING); CreateMenuItem( hFileMenu, "&Сохранить", i++, CM_FILE_SAVE, NULL, FALSE, MFT_STRING); CreateMenuItem( hFileMenu, NULL, i++, 0,

NULL, FALSE, MFT_SEPARATOR); CreateMenuItem(hFileMenu,"&Выход",i++, CM_FILE_QUIT, NULL, FALSE, MFT_STRING);

//Создаем временное меню для раздела "Правка" hEditMenu=CreatePopupMenu();

i=0; //Инициализация позиции в меню hEditMenu CreateMenuItem( hEditMenu, "&Найти", i++, CM_EDIT_FIND, NULL, FALSE, MFT_STRING ); CreateMenuItem( hEditMenu, "&3аменить", i++, CM_EDIT_REPLC, NULL, FALSE, MFT_STRING); //Создаем временное меню для раздела "Вид" hViewMenu=CreatePopupMenu();

i=0; //Инициализация позиции в меню hViewMenu CreateMenuItem( hViewMenu, "&Обычный", i++, CM_VIEW_NORM, NULL, FALSE, MFT_RADIOCHECK);

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

//Подключаем временные меню к главному меню i=0; //Инициализация позиции в меню hMainMenu CreateMenuItem( hMainMenu, "&Файл", i++, 0, hFileMenu, FALSE, MFT_STRING); SetMenu(hwnd, hMainMenu);

169 SetMenuItem(hFileMenu,CM_FILE_SAVE, MFS.GRAYED, FALSE); DrawMenuBar(hwnd); return 0;

}

caseWM_COMMAND:

{switch (LOWORD(wParam)) { case CM_FILE_OPEN:

{ SetMenuItem( hFileMenu, CM_FILE_OPEN, MFS_GRAYED, FALSE); SetMenuItem( hFileMenu, CM_FILE_SAVE, MFS_ENABLED, FALSE); CreateMenuItem( hMainMenu, "&Правка", 1,0, hEditMenu, FALSE, MFT_STRING); CreateMenuItem(hMainMenu, "&Вид", 2,0, hViewMenu, FALSE, MFT_STRING);

DrawMenuBar(hwnd); return 0;

}

case CM_FILE_SAVE:

{ SetMenuItem( hFileMenu, CM_FILE_SAVE, MFS_GRAYED, FALSE); SetMenuItem( hFileMenu, CM_FILE OPEN, MFS_ENABLED, FALSE); RemoveMenu(hMainMenu,1, MF_BYPOSITION); RemoveMenu(hMainMenu,1, MF_BYPOSITION); DrawMenuBar(hwnd);

return 0;

}

case CM_EDIT_FIND:

{ if (GetMenuItem(hEditMenu, CM_EDIT_FIND,FALSE)

170 ==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;

}