O exemplo neste tópico atribui bitmaps marca de seleção Personalizar para itens de menu em dois menus. Os itens de menu no primeiro menu especificam atributos de caracteres: negrito, itálico e sublinhado. Cada item de menu pode ser marcada ou desmarcada. Para esses itens de menu, o exemplo usa bitmaps de marca de seleção que se assemelham os Estados de um Controlarar de caixa de seleção checked and desmarcados.
Os itens de menu no segundo menu especificar configurações de alinhamento de parágrafo: esquerdo, centralizado e direito. Somente um desses itens de menu é verificado em qualquer tempo determinado. Para esses itens de menu, o exemplo usa bitmaps de marca de seleção que se assemelham os Estados marcados e desmarcados de um Controlarar de botão de rádio.
O procedimento janela processa a mensagem WM_CREATE , chamando a função de OnCreate application-defined. OnCreate cria quatro bitmaps marca de seleção e, em seguida, atribui-los aos seus itens de menu apropriado usando a função SetMenuItemBitmaps.
Para criar cada bitmap, OnCreate chama a função application-defined CreateMenuBitmaps, especificando um ponteiro para uma função de desenho específico do bitmap. CreateMenuBitmaps cria um bitmap monocromático do tamanho necessário, seleciona-lo em um contexto de dispositivo de memória e apaga o segundo plano. Em seguida, ele chama a função de desenho especificada para preencher em primeiro plano.
As quatro funções de desenho definido pelo aplicativo são DrawCheck, DrawUncheck, DrawRadioCheck e DrawRadioUncheck. Desenhar um retângulo com um X, um vazio retângulo, uma elipse contendo uma elipse preenchida menor e uma elipse vazia, respectivamente.
O procedimento janela processa a mensagem WM_DESTROY , excluindo os bitmaps marca de seleção. Ele recupera cada alça de bitmap usando a GetMenuItemInfo função e, em seguida, passa o identificador para o ExcluirObjeto função.
Quando o usuário escolhe um item de menu, uma mensagem WM_COMMAND é enviada para o janela proprietária. Para itens de menu no menu de personagem, o procedimento janela chama a função de CheckCharacterItem application-defined. Para itens no menu n º, o procedimento janela chama a função de CheckParagraphItem definidas pelo aplicativo.
Cada item no menu de personagem pode ser marcada e desmarcada independente. Portanto, CheckCharacterItem simplesmente alterna o estado de Marcar do item de menu especificado. Em primeiro lugar, a função chama a GetMenuItemInfo função para obter o menu atual item estado. Em seguida, ele alterna o Sinalizar de Estado MFS_CHECKED e define o novo estado chamando a função SetMenuItemInfo.
Ao contrário de atributos de caractere, o alinhamento de parágrafo apenas um pode ser selecionado por vez. Portanto, CheckParagraphItem verifica o item de menu especificado e remove a marca de seleção de todos os outros itens no menu. Para fazer isso, ele chama a função CheckMenuRadioItem.
A seguir estão as partes relevantes do arquivo de cabeçalho do aplicativo.
/ / Identificadores de item de menu para o menu de caracteres # define IDM_CHARACTER 10 # define IDM_BOLD 11 # define IDM_ITALIC 12 # define IDM_UNDERLINE 13 / / identificadores de item de Menu para o menu do n. O # define IDM_PARAGRAPH 20 # define IDM_LEFT 21 # define IDM_CENTER 22 # define IDM_RIGHT 23 / / tipo de ponteiro de função para desenho functions typedef VOID (WINAPI * DRAWFUNC) (HDC hdc, tamanho)
A seguir estão as partes relevantes do procedimento de janela do aplicativo e funções relacionadas.
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_COMMAND:
switch (LOWORD(wParam))
{
case IDM_BOLD:
case IDM_ITALIC:
case IDM_UNDERLINE:
CheckCharacterItem(hwnd, LOWORD(wParam));
break;
case IDM_LEFT:
case IDM_CENTER:
case IDM_RIGHT:
CheckParagraphItem(hwnd, LOWORD(wParam));
break;
// Process other commands here.
}
break;
// Process other messages here.
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
VOID WINAPI CheckCharacterItem(HWND hwnd, UINT uID)
{
HMENU hmenuBar = GetMenu(hwnd);
HMENU hmenuPopup;
MENUITEMINFO mii;
// Get the handle to the Character menu.
mii.fMask = MIIM_SUBMENU; // information to get
GetMenuItemInfo(hmenuBar, IDM_CHARACTER, FALSE, &mii);
hmenuPopup = mii.hSubMenu;
// Get the state of the specified menu item.
mii.fMask = MIIM_STATE; // information to get
GetMenuItemInfo(hmenuPopup, uID, FALSE, &mii);
// Toggle the checked state.
mii.fState ^= MFS_CHECKED;
SetMenuItemInfo(hmenuPopup, uID, FALSE, &mii);
}
VOID WINAPI CheckParagraphItem(HWND hwnd, UINT uID)
{
HMENU hmenuBar = GetMenu(hwnd);
HMENU hmenuPopup;
MENUITEMINFO mii;
// Get the handle to the Paragraph menu.
mii.fMask = MIIM_SUBMENU; // information to get
GetMenuItemInfo(hmenuBar, IDM_PARAGRAPH, FALSE, &mii);
hmenuPopup = mii.hSubMenu;
// Check the specified item and uncheck all the others.
CheckMenuRadioItem(
hmenuPopup, // handle to menu
IDM_LEFT, // first item in range
IDM_RIGHT, // last item in range
uID, // item to check
MF_BYCOMMAND // IDs, not positions
);
}
BOOL WINAPI OnCreate(HWND hwnd)
{
HMENU hmenuBar = GetMenu(hwnd);
HMENU hmenuPopup;
MENUITEMINFO mii;
UINT uID;
HBITMAP hbmChecked;
HBITMAP hbmUnchecked;
// Get the handle to the Character menu.
mii.fMask = MIIM_SUBMENU; // information to get
GetMenuItemInfo(hmenuBar, IDM_CHARACTER, FALSE, &mii);
hmenuPopup = mii.hSubMenu;
// Create the checked and unchecked bitmaps.
hbmChecked = CreateMenuBitmap(DrawCheck);
hbmUnchecked = CreateMenuBitmap(DrawUncheck);
// Set the checkmark bitmaps for each menu item.
for (uID = IDM_BOLD; uID <= IDM_UNDERLINE; uID++)
{
SetMenuItemBitmaps(hmenuPopup, uID, MF_BYCOMMAND,
hbmUnchecked, hbmChecked);
}
// Get the handle to the Paragraph pop-up menu.
mii.fMask = MIIM_SUBMENU; // information to get
GetMenuItemInfo(hmenuBar, IDM_PARAGRAPH, FALSE, &mii);
hmenuPopup = mii.hSubMenu;
// Create the checked and unchecked bitmaps.
hbmChecked = CreateMenuBitmap(DrawRadioCheck);
hbmUnchecked = CreateMenuBitmap(DrawRadioUncheck);
// Set the checkmark bitmaps for each menu item.
for (uID = IDM_LEFT; uID <= IDM_RIGHT; uID++)
{
SetMenuItemBitmaps(hmenuPopup, uID, MF_BYCOMMAND,
hbmUnchecked, hbmChecked);
}
// Initially check the IDM_LEFT paragraph item.
CheckMenuRadioItem(hmenuPopup, IDM_LEFT, IDM_RIGHT,
IDM_LEFT, MF_BYCOMMAND);
return TRUE;
}
HBITMAP WINAPI CreateMenuBitmap(DRAWFUNC lpfnDraw)
{
// Create a DC compatible with the desktop window's DC.
HWND hwndDesktop = GetDesktopWindow();
HDC hdcDesktop = GetDC(hwndDesktop);
HDC hdcMem = CreateCompatibleDC(hdcDesktop);
// Determine the required bitmap size.
SIZE size = { GetSystemMetrics(SM_CXMENUCHECK),
GetSystemMetrics(SM_CYMENUCHECK) };
// Create a monochrome bitmap and select it.
HBITMAP hbm = CreateBitmap(size.cx, size.cy, 1, 1, NULL);
HBITMAP hbmOld = SelectObject(hdcMem, hbm);
// Erase the background and call the drawing function.
PatBlt(hdcMem, 0, 0, size.cx, size.cy, WHITENESS);
(*lpfnDraw)(hdcMem, size);
// Clean up.
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
ReleaseDC(hwndDesktop, hdcDesktop);
return hbm;
}
VOID WINAPI DrawCheck(HDC hdc, SIZE size)
{
HBRUSH hbrOld;
hbrOld = SelectObject(hdc, GetStockObject(NULL_BRUSH));
Rectangle(hdc, 0, 0, size.cx, size.cy);
MoveToEx(hdc, 0, 0, NULL);
LineTo(hdc, size.cx, size.cy);
MoveToEx(hdc, 0, size.cy - 1, NULL);
LineTo(hdc, size.cx - 1, 0);
SelectObject(hdc, hbrOld);
}
VOID WINAPI DrawUncheck(HDC hdc, SIZE size)
{
HBRUSH hbrOld;
hbrOld = SelectObject(hdc, GetStockObject(NULL_BRUSH));
Rectangle(hdc, 0, 0, size.cx, size.cy);
SelectObject(hdc, hbrOld);
}
VOID WINAPI DrawRadioCheck(HDC hdc, SIZE size)
{
HBRUSH hbrOld;
hbrOld = SelectObject(hdc, GetStockObject(NULL_BRUSH));
Ellipse(hdc, 0, 0, size.cx, size.cy);
SelectObject(hdc, GetStockObject(BLACK_BRUSH));
Ellipse(hdc, 2, 2, size.cx - 2, size.cy - 2);
SelectObject(hdc, hbrOld);
}
VOID WINAPI DrawRadioUncheck(HDC hdc, SIZE size)
{
HBRUSH hbrOld;
hbrOld = SelectObject(hdc, GetStockObject(NULL_BRUSH));
Ellipse(hdc, 0, 0, size.cx, size.cy);
SelectObject(hdc, hbrOld);
}
VOID WINAPI OnDestroy(HWND hwnd)
{
HMENU hmenuBar = GetMenu(hwnd);
HMENU hmenuPopup;
MENUITEMINFO mii;
// Get the handle to the Character menu.
mii.fMask = MIIM_SUBMENU; // information to get
GetMenuItemInfo(hmenuBar, IDM_CHARACTER, FALSE, &mii);
hmenuPopup = mii.hSubMenu;
// Get the check-mark bitmaps and delete them.
mii.fMask = MIIM_CHECKMARKS;
GetMenuItemInfo(hmenuPopup, IDM_BOLD, FALSE, &mii);
DeleteObject(mii.hbmpChecked);
DeleteObject(mii.hbmpUnchecked);
// Get the handle to the Paragraph menu.
mii.fMask = MIIM_SUBMENU; // information to get
GetMenuItemInfo(hmenuBar, IDM_PARAGRAPH, FALSE, &mii);
hmenuPopup = mii.hSubMenu;
// Get the check-mark bitmaps and delete them.
mii.fMask = MIIM_CHECKMARKS;
GetMenuItemInfo(hmenuPopup, IDM_LEFT, FALSE, &mii);
DeleteObject(mii.hbmpChecked);
DeleteObject(mii.hbmpUnchecked);
}