소유자가 그린 메뉴 항목의 예

이 항목의 예제에서는 메뉴에서 소유자가 그린 메뉴 항목을 사용합니다. 메뉴 항목 글꼴 특성을 선택 하 고 해당 특성을 가진 글꼴을 사용 하 여 각 메뉴 항목을 표시 하는 응용 프로그램. 예를 들어, 기울임꼴 글꼴에 기울임꼴 메뉴 항목이 표시 됩니다. 문자 메뉴 이름 메뉴 표시줄에서 메뉴를 엽니다.

메뉴 모음 및 드롭 다운 메뉴를 처음 확장된 메뉴 템플릿 리소스에 의해 정의 됩니다. 메뉴에서 다음 문자열 4 텍스트 메뉴 항목을 처음 포함 메뉴 서식 파일 소유자가 그린 항목을 지정할 수 없습니다, 때문에: "일반", "굵게," "기울임꼴" 및 "밑줄." 응용 프로그램의 창 프로시저 WM_CREATE 메시지를 처리할 때이 소유자가 그린 항목을 변경 합니다. 창 프로시저에 각 메뉴 항목에 대해 다음 단계를 수행 하는 응용 프로그램 정의 OnCreate 함수 호출 WM_CREATE 메시지를 받으면

  1. 응용 프로그램 정의 MYITEM 구조 할당.
  2. 응용 프로그램 정의 MYITEM 구조에 저장 하는 메뉴 항목의 텍스트를 가져옵니다.
  3. 메뉴 항목을 표시 하는 데 사용 하는 글꼴을 만들고 응용 프로그램 정의 MYITEM 구조에 핸들을 저장.
  4. MFT_OWNERDRAW 메뉴 항목 형식을 변경 하 고 항목 데이터와 응용 프로그램 정의 MYITEM 구조에 대 한 포인터를 저장.

각 응용 프로그램 정의 MYITEM 구조를 가리키는 포인터 항목 데이터를 저장 하기 때문에 해당 하는 메뉴 항목에 대 한 WM_MEASUREITEMWM_DRAWITEM 메시지와 함께에서 창 프로시저에 전달 됩니다. 포인터 MEASUREITEMSTRUCTDRAWITEMSTRUCT 구조의 itemData 구성원에 포함.

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; 
    char szItemText [1]; 
} MYITEM; 
 
# define CCH_MAXITEMTEXT 256 
 

다음은 응용 프로그램의 창 프로시저와 관련 된 함수의 관련 부분.

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 to 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 to 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 += GetSystemMetrics(SM_CXMENUCHECK); 
 
    // 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); 
} 
 

 

Index