На главную

On-line справка по Win32 API

Написать письмо
БЕСПЛАТНАЯ ежедневная online лотерея! Выигрывай каждый день БЕСПЛАТНО!
Список всех статей A-B-C-D-E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T-U-V-W-X-Y-Z | Скачать Вниз

Example of Owner-Drawn Menu Items



The example in this topic uses owner-drawn menu items in a menu. The menu items select specific font attributes, and the application displays each menu item using a font that has the corresponding attribute. For example, the Italic menu item is displayed in an italic font. The Character menu name on the menu bar opens the menu.

The menu bar and drop-down menu are defined initially by an extended menu-template resource. Because a menu template cannot specify owner-drawn items, the menu initially contains four text menu items with the following strings: "Regular," "Bold," "Italic," and "Underline." The application's window procedure changes these to owner-drawn items when it processes the WM_CREATE message. When it receives the WM_CREATE message, the window procedure calls the application-defined OnCreate function, which performs the following steps for each menu item:

1. Allocates an application-defined MYITEM structure.
2. Gets the text of the menu item and saves it in the application-defined MYITEM structure.
3. Creates the font used to display the menu item and saves its handle in the application-defined MYITEM structure.
4. Changes the menu item type to MFT_OWNERDRAW and saves a pointer to the application-defined MYITEM structure as item data.



Because a pointer to each application-defined MYITEM structure is saved as item data, it is passed to the window procedure in conjunction with the WM_MEASUREITEM and WM_DRAWITEM messages for the corresponding menu item. The pointer is contained in the itemData member of both the MEASUREITEMSTRUCT and DRAWITEMSTRUCT structures.
A WM_MEASUREITEM message is sent for each owner-drawn menu item the first time it is displayed. The application processes this message by selecting the font for the menu item into a device context and then determining the space required to display the menu item text in that font. The font and menu item text are both specified by the menu item's MYITEM structure (the structure defined by the application). The application determines the size of the text by using the GetTextExtentPoint32 function.

The window procedure processes the WM_DRAWITEM message by displaying the menu item text in the appropriate font. The font and menu item text are both specified by the menu item's MYITEM structure. The application selects text and background colors appropriate to the menu item's state.
The window procedure processes the WM_DESTROY message to destroy fonts and free memory. The application deletes the font and frees the application-defined MYITEM structure for each menu item.

Following are the relevant portions of the application's header file.

// Menu-item identifiers for the Character menu

#define IDM_CHARACTER 10
#define IDM_REGULAR 11
#define IDM_BOLD 12
#define IDM_ITALIC 13
#define IDM_UNDERLINE 14

// Structure associated with menu items

typedef struct tagMYITEM {
HFONT hfont;
int cchItemText;
char szItemText[1];
} MYITEM;

#define CCH_MAXITEMTEXT 256


Following are the relevant portions of the application's window procedure and its associated functions.

LRESULT CALLBACK MainWindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch (uMsg) {
case WM_CREATE:
if (!OnCreate(hwnd))
return -1;
break;

case WM_DESTROY:
OnDestroy(hwnd);
PostQuitMessage(0);
break;

case WM_MEASUREITEM:
OnMeasureItem(hwnd, (LPMEASUREITEMSTRUCT) lParam);

return TRUE;

case WM_DRAWITEM:
OnDrawItem(hwnd, (LPDRAWITEMSTRUCT) lParam);
return TRUE;

.
. // Additional message processing goes here.
.

default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}


BOOL WINAPI OnCreate(HWND hwnd)
{
HMENU hmenuBar = GetMenu(hwnd);
HMENU hmenuPopup;
MENUITEMINFO mii;
UINT uID;

MYITEM *pMyItem;

// Get the handle of the pop-up menu.

mii.fMask = MIIM_SUBMENU; // information to get
GetMenuItemInfo(hmenuBar, IDM_CHARACTER, FALSE, &mii);
hmenuPopup = mii.hSubMenu;

// Modify each menu item. Assume that the IDs IDM_REGULAR
// through IDM_UNDERLINE are consecutive numbers.

for (uID = IDM_REGULAR; uID <= IDM_UNDERLINE; uID++) {

// Allocate an item structure, leaving space for a

// string of up to CCH_MAXITEMTEXT characters.

pMyItem = (MYITEM *) LocalAlloc(LMEM_FIXED,
sizeof(MYITEM) + CCH_MAXITEMTEXT);

// Save the item text in the item structure.

mii.fMask = MIIM_TYPE;
mii.dwTypeData = pMyItem->szItemText;
mii.cch = CCH_MAXITEMTEXT;
GetMenuItemInfo(hmenuPopup, uID, FALSE, &mii);
pMyItem->cchItemText = mii.cch;

// Reallocate the structure to the minimum required size.


pMyItem = (MYITEM *) LocalReAlloc(pMyItem,
sizeof(MYITEM) + mii.cch, LMEM_MOVEABLE);

// Create the font used to draw the item.

pMyItem->hfont = CreateMenuItemFont(uID);

// Change the item to an owner-drawn item, and save
// the address of the item structure as item data.

mii.fMask = MIIM_TYPE | MIIM_DATA;
mii.fType = MFT_OWNERDRAW;
mii.dwItemData = (DWORD) pMyItem;

SetMenuItemInfo(hmenuPopup, uID, FALSE, &mii);
}
return TRUE;
}

HFONT CreateMenuItemFont(UINT uID)
{
LOGFONT lf;

ZeroMemory(&lf, sizeof(lf));
lf.lfHeight = 20;
lstrcpy(lf.lfFaceName, "Times New Roman");

switch (uID) {
case IDM_BOLD:
lf.lfWeight = FW_HEAVY;
break;

case IDM_ITALIC:
lf.lfItalic = TRUE;
break;

case IDM_UNDERLINE:

lf.lfUnderline = TRUE;
break;
}
return CreateFontIndirect(&lf);
}

VOID WINAPI OnDestroy(HWND hwnd)
{
HMENU hmenuBar = GetMenu(hwnd);
HMENU hmenuPopup;
MENUITEMINFO mii;
UINT uID;
MYITEM *pMyItem;

// Get the handle of the menu.

mii.fMask = MIIM_SUBMENU; // information to get
GetMenuItemInfo(hmenuBar, IDM_CHARACTER, FALSE, &mii);
hmenuPopup = mii.hSubMenu;

// Free resources associated with each menu item.


for (uID = IDM_REGULAR; uID <= IDM_UNDERLINE; uID++) {

// Get the item data.

mii.fMask = MIIM_DATA;
GetMenuItemInfo(hmenuPopup, uID, FALSE, &mii);
pMyItem = (MYITEM *) mii.dwItemData;

// Destroy the font and free the item structure.

DeleteObject(pMyItem->hfont);
LocalFree(pMyItem);
}
}

VOID WINAPI OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis)
{
MYITEM *pMyItem = (MYITEM *) lpmis->itemData;

HDC hdc = GetDC(hwnd);
HFONT hfntOld = SelectObject(hdc, pMyItem->hfont);
SIZE size;

GetTextExtentPoint32(hdc, pMyItem->szItemText,
pMyItem->cchItemText, &size);

lpmis->itemWidth = size.cx;
lpmis->itemHeight = size.cy;

SelectObject(hdc, hfntOld);
ReleaseDC(hwnd, hdc);
}

VOID WINAPI OnDrawItem(HWND hwnd, LPDRAWITEMSTRUCT lpdis)
{
MYITEM *pMyItem = (MYITEM *) lpdis->itemData;
COLORREF clrPrevText, clrPrevBkgnd;

HFONT hfntPrev;
int x, y;

// Set the appropriate foreground and background colors.

if (lpdis->itemState & ODS_SELECTED) {
clrPrevText = SetTextColor(lpdis->hDC,
GetSysColor(COLOR_HIGHLIGHTTEXT));
clrPrevBkgnd = SetBkColor(lpdis->hDC,
GetSysColor(COLOR_HIGHLIGHT));
}
else {
clrPrevText = SetTextColor(lpdis->hDC,
GetSysColor(COLOR_MENUTEXT));
clrPrevBkgnd = SetBkColor(lpdis->hDC,

GetSysColor(COLOR_MENU));
}

// Determine where to draw and leave space for a check-mark.

x = lpdis->rcItem.left;
y = lpdis->rcItem.top;
x += LOWORD(GetMenuCheckMarkDimensions());

// Select the font and draw the text.

hfntPrev = SelectObject(lpdis->hDC, pMyItem->hfont);
ExtTextOut(lpdis->hDC, x, y, ETO_OPAQUE,
&lpdis->rcItem, pMyItem->szItemText,
pMyItem->cchItemText, NULL);


// Restore the original font and colors.

SelectObject(lpdis->hDC, hfntPrev);
SetTextColor(lpdis->hDC, clrPrevText);
SetBkColor(lpdis->hDC, clrPrevBkgnd);
}



Пригласи друзей и счет твоего мобильника всегда будет положительным!
Предыдущая статья
 
Сайт Народ.Ру Интернет
Следующая статья
Пригласи друзей и счет твоего мобильника всегда будет положительным!

Пример Пунктов Меню Owner-Drawn



Пример в этой теме использует пункты меню сделанного владельца в меню. Пункты меню выбираются специфические шрифтовые атрибуты, и приложение отображает каждый пункт меню, использовавший шрифт, который имеет соответствующий атрибут. Например, пункт меню Курсива отображен в шрифте курсива. Имя меню Символа в зоне меню открытой меню.

Зона меню и капли-вниз меню определяются первоначально расширенным меню-шаблоном ресурса. Поскольку шаблон меню не может определить сделанные пункты владельца, меню первоначально содержит четыре текстовых пункта меню с следующими строками: "Регулярный," "Жирный шрифт," "Курсив," и "Подчеркивание." Прикладная процедура окна изменяет ей в сделанные пункты владельца когда она обрабатывает сообщение WM_CREATE. Когда это получает сообщение WM_CREATE, процедура окна вызывает определенную прикладную функцию OnCreate, которая выполняет следующее шагов для каждого пункта меню:

1. Распределяет определенную прикладную структуру MYITEM.
2. Получает текст пункта меню и сохраняет это в определенной прикладной структуре MYITEM.
3. Создает шрифт использованный, чтобы отображать пункт меню и сохранять свою ручку в определенной прикладной структуре MYITEM.
4. Изменяет тип пункта меню на MFT_OWNERDRAW и сохраняет указатель в определенную прикладную структуру MYITEM как данные пункта.



Поскольку указатель на каждый определившее прикладную структуру MYITEM сохранен как данные пункта, она пройдена в процедуру окна в связи (вместе)с WM_MEASUREITEM и сообщениями WM_DRAWITEM для соответствующего пункта меню. Указатель содержался в элементе itemData как MEASUREITEMSTRUCT так и структур DRAWITEMSTRUCT.
Сообщение WM_MEASUREITEM послано для каждого сделавшим пунктом меню владельца сначала отображено. Приложение обрабатывает это сообщение выбираясь шрифт для пункта меню в контекст устройства и затем определяя пространство требовавшееся, чтобы отображать текст пункта меню в этом шрифте. Шрифтовой и текст пункта меню оба определен пунктом меню MYITEM структуры ( структура определялась приложением). Приложение определяет размер текста используя функцию GetTextExtentPoint32.

Процедура окна обрабатывает сообщение WM_DRAWITEM отображая текст пункта меню в подходящем шрифте. Шрифтовой и текст пункта меню оба определен пунктом меню MYITEM структуры. Приложение выбирается текст и цвета фона присваиваются в состояние пункта меню.
Процедура окна обрабатывает сообщение WM_DESTROY, чтобы уничтожать шрифты и освобождать память. Приложение удаляет шрифт и освобождает определенную прикладную структуру MYITEM для каждого пункта меню.

Следующее является важными частями прикладного файла заголовка.

// Меню-пункт идентификаторов для меню Символа

#define IDM_CHARACTER 10 #define IDM_REGULAR 11 #define IDM_BOLD 12 #define IDM_ITALIC 13 #define IDM_UNDERLINE 14

// Структура связанная пунктами меню

typedef struct tagMYITEM { HFONT hfont;
int cchItemText;
символ szItemText[1];
} MYITEM;

#define CCH_MAXITEMTEXT 256


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

LRESULT CALLBACK MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
)
{
ключ (uMsg) { случай WM_CREATE: если (!OnCreate ВОЗВРАТА(hwnd)) -1;
прерывание;

случай WM_DESTROY: OnDestroy(hwnd);
PostQuitMessage(0);
прерывание;

случай WM_MEASUREITEM:
OnMeasureItem(hwnd, (LPMEASUREITEMSTRUCT) lParam);

возвращайтесь ВЕРНО;

случай WM_DRAWITEM:
OnDrawItem(hwnd, (LPDRAWITEMSTRUCT) lParam);
возвращайтесь ВЕРНО;

.
. // Дополнительная обработка сообщения идет сюда.
.

умолчание:
возвращайте DefWindowProc(hwnd, uMsg, wParam, lParam);
}
возврат 0;
}


BOOL WINAPI OnCreate(HWND hwnd)
{
HMENU hmenuBar = GetMenu(hwnd);
HMENU hmenuPopup;
mii MENUITEMINFO;
UINT uID;

MYITEM *pMyItem;

// Получите ручку управляющего меню.

mii.fMask = MIIM_SUBMENU; // информация, чтобы получать GetMenuItemInfo(hmenuBar, IDM_CHARACTER, ЛОЖЬ, &mii);
hmenuPopup = mii.hSubMenu;

// Модифицируйте каждый пункт меню. Допустите что IDs IDM_REGULAR // через IDM_UNDERLINE - последовательные числа.

для (uID = IDM_REGULAR; uID <= IDM_UNDERLINE; uID++) {

// Распределите структуру пункта, оставляя пространство для a

// строка вплоть до символов CCH_MAXITEMTEXT.

pMyItem = (MYITEM *) LocalAlloc(LMEM_FIXED, sizeof(MYITEM) + CCH_MAXITEMTEXT);

// Сохраните пункту текст в структуре пункта.

mii.fMask = MIIM_TYPE;
mii.dwTypeData = pMyItem->szItemText;
mii.cch = CCH_MAXITEMTEXT;
GetMenuItemInfo(hmenuPopup, uID, ЛОЖЬ, &mii);
pMyItem->cchItemText = mii.cch;

// Reallocate Структура на минимум требовала размер.


pMyItem = (MYITEM *) LocalReAlloc(pMyItem, sizeof(MYITEM) + mii.cch, LMEM_MOVEABLE);

// Создайте шрифт использованный, чтобы делать пунктом.

pMyItem->hfont = CreateMenuItemFont(uID);

// Изменение пункт в сделанный пункт владельца, и сохраняемый // адрес структуры пункта как данные пункта.

mii.fMask = MIIM_TYPE | MIIM_DATA;
mii.fType = MFT_OWNERDRAW;
mii.dwItemData = (DWORD) pMyItem;

SetMenuItemInfo(hmenuPopup, uID, ЛОЖЬ, &mii);
}
возвращайтесь ВЕРНО;
}

HFONT CreateMenuItemFont(UINT uID)
{
lf LOGFONT;

ZeroMemory(&lf, sizeof(lf));
lf.lfHeight = 20;
lstrcpy(lf.lfFaceName, "Время Новое Римское");

ключ (uID) { случай IDM_BOLD: lf.lfWeight = FW_HEAVY;
прерывание;

случай IDM_ITALIC: lf.lfItalic = ИСТИНА;
прерывание;

случай IDM_UNDERLINE:

lf.lfUnderline = ИСТИНА;
прерывание;
}
возвращайте CreateFontIndirect(&lf);
}

ПУСТОТА WINAPI OnDestroy(HWND hwnd)
{
HMENU hmenuBar = GetMenu(hwnd);
HMENU hmenuPopup;
mii MENUITEMINFO;
UINT uID;
MYITEM *pMyItem;

// Получите ручку меню.

mii.fMask = MIIM_SUBMENU; // информация, чтобы получать GetMenuItemInfo(hmenuBar, IDM_CHARACTER, ЛОЖЬ, &mii);
hmenuPopup = mii.hSubMenu;

// Свободные ресурсы связывались каждым пунктом меню.


для (uID = IDM_REGULAR; uID <= IDM_UNDERLINE; uID++) {

// Получите данные пункта.

mii.fMask = MIIM_DATA;
GetMenuItemInfo(hmenuPopup, uID, ЛОЖЬ, &mii);
pMyItem = (MYITEM *) mii.dwItemData;

// Уничтожьте шрифт и освобождайте структуру пункта.

DeleteObject(pMyItem->hfont);
LocalFree(pMyItem);
}
}

ПУСТОТА WINAPI OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis)
{
MYITEM *pMyItem = (MYITEM *) lpmis->itemData;

HDC hdc = GetDC(hwnd);
HFONT hfntOld = SelectObject(hdc, pMyItem->hfont);
РАЗМЕР размера;

GetTextExtentPoint32(hdc, pMyItem->szItemText, pMyItem->cchItemText, &размер);

lpmis->itemWidth = size.cx;
lpmis->itemHeight = size.cy;

SelectObject(hdc, hfntOld);
ReleaseDC(hwnd, hdc);
}

ПУСТОТА WINAPI OnDrawItem(HWND hwnd, LPDRAWITEMSTRUCT lpdis)
{
MYITEM *pMyItem = (MYITEM *) lpdis->itemData;
COLORREF clrPrevText, clrPrevBkgnd;

HFONT hfntPrev;
int x, y;

// Установившее подходящий передний план и цвета фона.

если (lpdis->itemState & ODS_SELECTED) { clrPrevText = SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
}
еще {
clrPrevText = SetTextColor(lpdis->hDC, GetSysColor(COLOR_MENUTEXT));
clrPrevBkgnd = SetBkColor(lpdis->hDC,

GetSysColor(COLOR_MENU));
}

// Определитесь где, чтобы делать и оставлять пространство для контрольной-отметки.

x = lpdis->rcItem.left;
y = lpdis->rcItem.top;
x += LOWORD(GetMenuCheckMarkDimensions());

// Выберитесь шрифт и делайте текстом.

hfntPrev = SelectObject(lpdis->hDC, pMyItem->hfont);
ExtTextOut(lpdis->hDC, x, y, ETO_OPAQUE, &lpdis->rcItem, pMyItem->szItemText, pMyItem->cchItemText, НЕДЕЙСТВИТЕЛЬНОЕ);


// Восстановление оригинальный шрифт и цвета.

SelectObject(lpdis->hDC, hfntPrev);
SetTextColor(lpdis->hDC, clrPrevText);
SetBkColor(lpdis->hDC, clrPrevBkgnd);
}



Вверх Version 1.3, Oct 26 2010 © 2007, 2010, mrhx Вверх
 mrhx software  Русский перевод OpenGL  Русский перевод Win32 API
 
Используются технологии uCoz