|
Динамическое создание пунктов меню и создание формы окна средствами Win32APIТе, кто программировал на Borland C++ Builder или Delphi знают, как легко там создавать меню (изменять его) и внешний вид главного окна, перетаскивая туда кнопки, списки и другие элементы. Однако, средствами Win32 API это делается немного по-другому. Создать меню статически просто – это можно сделать по аналогии с присоединением иконки к окну. Но как вы будете менять элементы окна, добавлять и удалять пункты меню? Для этого надо знать, как работать с меню динамически. Основные функции для создания меню перечислены ниже. Функция CreateMenu HMENU CreateMenu (VOID); Функция CreateMenu создает меню. Изначально меню пустое, но оно может быть заполнено пунктами меню, используя функции InsertMenuItem, AppendMenu и InsertMenu. В случае успеха возвращается дескриптор созданного меню. В случае неудачи возвращается NULL. Функция AppendMenu BOOL AppendMenu ( HMENU hMenu, // дескриптор меню, которое будет изменено UINT uFlags, // флажки пункта меню UINT uIDNewItem, // идентификатор пункта меню или дескриптор // «выскакивающего» меню // или подменю LPCTSTR lpNewItem // пункт контекстного меню ); Функция AppendMenu добавляет в конец определяемой строки меню, «выскакивающего» меню, подменю или контекстного меню новый пункт. Вы можете использовать эту функцию, чтобы определить содержание, внешний вид и характеристики пункта меню. Параметры: hMenu – идентифицирует строку меню, «выскакивающее» меню, подменю или контекстное меню, которое будет изменено. uFlags – определяет флажки, которые управляют внешним видом и характеристиками нового пункта меню. Этот параметр может быть комбинация значений. uIDNewItem – определяет или идентификатор нового пункта меню или, если параметр uFlags установлен в MF_POPUP, дескриптор «выскакивающего» меню или подменю. lpNewItem – определяет содержание нового пункта меню. Интерпретация lpNewItem зависит от того, включает ли параметр uFlags в себя флажок MF_BITMAP, MF_OWNERDRAW или MF_STRING, как указано ниже: MF_BITMAP – Содержит дескриптор растрового рисунка. MF_OWNERDRAW – Содержит 32-разрядное значение, предоставленное прикладной программой, которое может быть использовано, чтобы утвердить, что дополнительные данные касаются пункта меню. Значение является членом itemData структуры, указываемой параметром lParam при помощи передачи сообщения WM_MEASURE или WM_DRAWITEM, когда создается меню, или его внешний вид модифицируется. MF_STRING – Содержит указатель на строку с символом нуля в конце. Возвращаемые значения Если функция завершается успешно, величина возвращаемого значения – не ноль. Если функция не выполняет задачу, величина возвращаемого значения – ноль. Чтобы получать расширенные данные об ошибках, вызовите GetLastError. Функция CreatePopupMenu HMENU CreatePopupMenu (VOID); Функция CreatePopupMenu создает выпадающее меню (drop-down menu), подменю (submenu) или меню быстрого вызова (shortcut menu). Меню визначально пустое. Вы можете вставить или добавить пункты меню, используя функцію InsertMenuItem. Вы также можете использовать функцию InsertMenu для вставки пунктов меню и функцию AppendMenu для добавления пунктов меню. В случае успеха возвращается дескриптор созданного меню. В случае неудачи возвращается NULL. Функция SetMenuItemInfo BOOL WINAPI SetMenuItemInfo ( HMENU hMenu, UINT uItem, BOOL fByPosition, LPMENUITEMINFO lpmii ); Функция SetMenuItemInfo изменяет информацию о пункте меню. Параметры: hMenu – дескриптор меню, которое содержит пункт меню. uItem – идентификатор или позиция пункта меню, который измениться. Предназначение этого параметра зависит от значения fByPosition. fByPosition – значение, определяющее предназначение uItem. Если этот параметр – FALSE, то uItem – идентификатор пункта меню. Иначе, он - позиция пункта меню. lpmii – указатель на структуру MENUITEMINFO, которая содержит информацию о пункте меню и определяет, какие атрибуты пункта меню изменятся. Возвращаемые значения Если функция завершается успешно, величина возвращаемого значения – не ноль. Если функция не выполняет задачу, величина возвращаемого значения – ноль. Чтобы получать расширенные данные об ошибках, используйте функцию GetLastError. Функция SetMenu BOOL SetMenu ( HWND hWnd, // дескриптор окна HMENU hMenu // дескриптор меню ); Функция SetMenu связывает новое меню с заданным окном. Параметры: hWnd – идентифицирует окно, с которым должно быть связано меню. hMenu – идентифицирует новое меню. Если этот параметр имеет значение NULL, текущее меню окна удаляется. Возвращаемые значения Если функция завершается успешно, величина возвращаемого значения – не ноль. Если функция не выполняет задачу, величина возвращаемого значения – ноль. Чтобы получать расширенные данные об ошибках, вызовите GetLastError. В листинге 5 представлен участок программного кода динамического создания меню. //Создание меню int i; HMenu=CreateMenu(); if (HMenu==NULL) return 1; //Добавить "File" i=AppendMenu(HMenu,MF_POPUP,M_FILE,"File"); if (i==0) return 1; //Создать подменю "File" HMENU h; h=CreatePopupMenu(); i=AppendMenu(h,MFT_STRING,M_FILE1,"Новый"); if (i==0) return 1; i=AppendMenu(h,MFT_STRING,M_FILE2,"Выход"); if (i==0) return 1; //Добавить к меню MENUITEMINFO mi; mi.cbSize=sizeof(mi); mi.fMask=MIIM_SUBMENU; mi.hSubMenu=h; i=SetMenuItemInfo(HMenu,M_FILE,false,&mi); if (i==0) return 1; //Добавление меню к окну i=SetMenu(hWnd,HMenu); if (i==0) return 1; Листинг 5 – Динамическое добавление меню к окну Создание меню должно происходить во время обработки сообщения WM_CREATE. В программе hWnd – это дескриптор окна (HWND). M_FILE, M_FILE1, M_FILE2 и HMenu должны быть объявлены ранее, например как показано в листинге 6. #define M_FILE 10001 #define M_FILE1 10002 #define M_FILE2 10003 HMENU HMenu=NULL; Листинг 6 – Объявление определений и переменных Меню добавлено, однако надо получать сигналы о выборах пунктов меню. Для этого в функции обработки сообщений вы должны отлавливать сообщение WM_COMMAND и просматривать параметр wParam (листинг 7). int wID = LOWORD(wParam); switch (wID) { case M_FILE2: DestroyWindow(hWnd); break; case M_FILE1: break; } Листинг 7 – Обработка выбора пункта меню Теперь перейд.м к созданию формы. Для этого надо перейти к редактору ресурсов и добавить диалоговое окно. Нажмите правой кнопкой на диалоговом окне и выберите «Properties» (Рисунок 7). Рисунок 7 – Изменение свойств диалогового окна В программе нужно, чтобы это диалоговое окно работало, как форма (Builder или Delphi). Поэтому переходим во вкладку «Styles» и меняем свойства: в пункте «Style» на «Child», в пункте «Border» на «None». Не забываем ставить флажок в More Stules>Visible. Автоматически созданное содержимое диалогового окна удаляем и переносим туда компонент «Edit Box». Открываем его свойства и помечаем галочкой следующие пункты: Visible, Tab stop, Multiline, Horizontal scroll, Auto HScroll, Vertical scroll, Auto VScroll, No hide selection, Border, Read-only, Static edge. А также растягиваем «Edit Box» до размеров окна. Заготовка готова, теперь надо е. натянуть на главное окно. Первоначально изменяем класс окна: WndClass.hbrBackground=(HBRUSH)NULL; А затем также при обработке сообщения WM_CREATE созда.м диалоговое окно (Листинг 8). hEdit=CreateDialog(hInst,MAKEINTRESOURCE(IDD_DIALOG1),hWnd,(DLGPROC) WIN32DIAL); if (hEdit==NULL) { return 1; } Листинг 8 – Создание немодального диалогового окна Перед вызовом hEdit должен быть у вас объявлен как HWND, а также должна существовать функция обработки сообщения диалогового окна (Листинг 9). LRESULT CALLBACK WIN32DIAL(HWND hWnd,UINT Message, UINT wParam,LONG lParam) { return DefWindowProc(hWnd,Message,wParam,lParam); } Листинг 9 – Функция обработки сообщений диалогового окна Компилируем – картинка не очень хорошая, т.к. диалоговое окно не растягивается самостоятельно. Для этого нужно написать свою функцию (Листинг10). int SizeEdit(HWND hWnd) { RECT Rect; //получаем размер клиентской области окна GetClientRect(hWnd,&Rect); //меняем размеры окон SetWindowPos(hEdit,hWnd,0,0,Rect.right-Rect.left,Rect.bottom-Rect.top,SWP_NOZORDER); HWND h=GetDlgItem(hEdit,IDC_EDIT1); GetClientRect(hEdit,&Rect); SetWindowPos(h,hEdit,0,0,Rect.right-Rect.left,Rect.bottom-Rect.top,SWP_NOZORDER); return 0; } Листинг 10 – Функция установки размеров Добавьте вызов этой функции в двух местах – непосредственно после создания диалогового окна и во время обработке сообщения WM_SIZE главного окна. Теперь другое дело. Ваша простейшая форма готова. Простейший пример добавления текста в Edit Box: char new_str[3]={ 0x0d, 0x0a,0 }; char buf[256]; lstrcpy(buf,"Привет!"); lstrcat(buf,new_str); lstrcat(buf,"Это моя первая программа!"); SetDlgItemText(hEdit,IDC_EDIT1,buf); Листинг 11 – Добавление текста Задание: 1. Ознакомиться с динамическим способом добавления меню. 2. Ознакомиться с элементами создания формы рабочего окна. 3. Разработать программу, в которой есть несколько пунктов меню и форма с «Edit Box». Названия пунктов меню должны загружаться из файла. По нажатию пунктов должен появляться и удаляться текст с формы. Контрольные вопросы: 1. Чем отличается статическое и динамическое присоединение меню к окну? 2. Какие операции производит функция AppendMenu? 3. Как обрабатывается выбор пункта меню? 4. Чем отличается модальное окно от немодального? 5. Объясните назначения свойств диалогового окна. 6. Каким образом осуществляется изменение размеров формы? Для самостоятельного изучения: 1. Функции работы с меню InsertMenuItem и InsertMenu. 2. Статистический способ добавления меню. 3. Удаление пунктов меню. 4. Использование различных элементов диалогового окна на форме. ЧТО ТАКОЕ УВЕРЕННОЕ ПОВЕДЕНИЕ В МЕЖЛИЧНОСТНЫХ ОТНОШЕНИЯХ? Исторически существует три основных модели различий, существующих между... Что способствует осуществлению желаний? Стопроцентная, непоколебимая уверенность в своем... Что вызывает тренды на фондовых и товарных рынках Объяснение теории грузового поезда Первые 17 лет моих рыночных исследований сводились к попыткам вычислить, когда этот... ЧТО ПРОИСХОДИТ, КОГДА МЫ ССОРИМСЯ Не понимая различий, существующих между мужчинами и женщинами, очень легко довести дело до ссоры... Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:
|