Örneğin, menü öğelerinin sahibi çizilmiş

Bu konudaki örnek, bir menüde sahibi çizilmiş menü öğeleri kullanır. Menü öğelerini belirli yazı tipi özniteliklerini seçin ve uygulama ilgili özniteliğine sahip bir yazı tipi kullanarak her bir menü öğesi görüntülenir. Örneğin, italik menü öğesi bir italik yazı tipiyle görüntülenir. Karakter menü adını menü çubuğundaki menüyü açar.

Başlangıçta menü çubuğu ve açılır menüden bir genişletilmiş menü şablonu kaynak tarafından tanımlanır. Menü menü şablonu sahibi çizilmiş öğeleri belirtemezsiniz nedeniyle, başlangıçta dört metin menü öğeleri aşağıdaki dizeleri ile içermektedir: "Normal," "kalın," "İtalik" ve "Altı çizili". wm_create iletiyi işlerken uygulama penceresinin yordam bunlar sahibi çizilmiş öğeleri değiştirir. wm_create iletiyi aldığında, pencere yordamı her bir menü öğesi için aşağıdaki adımları gerçekleştirir uygulama tanımlı OnCreate işlevini çağırır.

  1. Bir uygulama tanımlı ÖĞE1 yapısı ayırır.
  2. Menü öğesinin metni alır ve onu uygulama tanımlı ÖĞE1 yapısında kaydeder.
  3. Menü öğesini görüntülemek için kullanılan yazı tipi oluşturur ve onun kolu uygulama tanımlı ÖĞE1 yapısında kaydeder.
  4. Mft_ownerdraw için menü öğesi türü değişir ve uygulama tanımlı ÖĞE1 yapısına öğe veri işaretçisi kaydeder.

Her uygulama-tanımlı ÖĞE1 yapısı için işaretçi öğe verisi olarak kaydedildiğinden, bu pencere yordamı WM_MEASUREITEM ve WM_DRAWITEM iletiler ile birlikte ilgili menü öğesi için geçirilir. İşaretçiyi hem MEASUREITEMSTRUCT hem de DRAWITEMSTRUCT yapıları ItemData üyesi bulunan.

WM_MEASUREITEM mesaj her sahibi çizilmiş menü öğesi için görüntülenen ilk kez gönderilir. Uygulama işlemlerini bir aygıt içeriğini menü öğesi için yazı tipi seçerek ve sonra alanı belirleme bu iletiyi menü öğesi metin bu yazı tipinde görüntülemek için gerekli. Yazı tipi ve menü öğesi metin hem belirtilen menü öğesinin ÖĞE1 yapısı (uygulama tarafından tanımlanan yapı). Uygulamayı kullanarak metin boyutunu belirler GetTextExtentPoint32 işlevi.

Pencere yordamı, uygun yazı tipi menü madde metni görüntüleyerek WM_DRAWITEM iletisini işler. Yazı tipi ve menü öğesi metin hem belirtilen menü öğesinin ÖĞE1 yapısına göre. Metin ve arka plan renklerini menü öğesinin durumuna uygun uygulamayı seçer.

Pencere yordamı, yazı tipleri ve boş bellek yok wm_destroy iletisini işler. Uygulama yazı tipi siler ve her bir menü öğesi uygulama tanımlı ÖĞE1 yapısını boşaltır.

Aşağıda ilgili bölümlerini uygulamanın üstbilgi dosyası.

 / / Karakter menüsünden menü öğesi tanımlayıcıları # define IDM_CHARACTER # define IDM_REGULAR # define IDM_BOLD # define IDM_ITALIC # define 13 12 11 10 IDM_UNDERLINE 14 / / yapısı ilişkili menü öğeleri typedef struct tagMYITEM ile {hfont hfont; 
    int cchItemText; 
    char szItemText [1]; 
} ÖĞE1; 
 
# define CCH_MAXITEMTEXT 256 

 

Uygulama penceresinin yordam ve ilişkili işlevleri ilgili kısımları şunlardır.

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