דוגמה שצוירו על-ידי הבעלים של פריטי תפריט

הדוגמה בנושא זה עושה שימוש בפריטים שצוירו על-ידי הבעלים של התפריט בתפריט. פריטי תפריט בחר תכונות גופן מסוים, ומציג היישום כל פריט תפריט באמצעות גופן בעל התכונה המתאימה. לדוגמה, פריט התפריט נטוי מוצג בגופן נטוי. שם תפריט תווים בשורת התפריטים פותח את התפריט.

שורת התפריטים ואת התפריט הנפתח מוגדרים תחילה על-ידי משאב של תפריט מורחב-תבנית. מכיוון תבנית תפריט אין לציין פריטים שצוירו על-ידי הבעלים, התפריט כולל בתחילה ארבעה פריטים בתפריט טקסט למחרוזות הבאות: "רגילים", "מודגש," "נטוי" ו "Underline". היישום חלון הליך משנה אלה לפריטים שצוירו על-ידי הבעלים במהלך עיבוד הודעה WM_CREATE . כאשר הוא מקבל את ההודעה WM_CREATE, ההליך חלון קורא לפונקציה OnCreate המוגדר על-ידי היישום, אשר מבצע את הפעולות הבאות עבור כל פריט תפריט

  1. מקצה מבנה MYITEM מוגדר על-ידי יישום.
  2. מקבל את הטקסט של פריט התפריט ושומר אותו במבנה MYITEM מוגדר על-ידי יישום.
  3. יוצר הגופן המשמש כדי להציג את פריט התפריט ושומר האחיזה שלה במבנה MYITEM מוגדר על-ידי יישום.
  4. משנה את סוג פריט תפריט כדי MFT_OWNERDRAW ושומר מצביע למבנה MYITEM מוגדר על-ידי יישום פריט נתונים.

מכיוון מצביע כל מבנה MYITEM מוגדר על-ידי יישום נשמרים כנתונים הפריט, הוא מועבר הנוהל חלון יחד עם הודעות WM_MEASUREITEM ו- WM_DRAWITEM של פריט התפריט המתאים. המצביע נמצא בתוך האיבר נתוני פריט של מבנים גם MEASUREITEMSTRUCT וגם DRAWITEMSTRUCT.

WM_MEASUREITEM נשלחת הודעה עבור כל פריט תפריט שצוירו על-ידי הבעלים בפעם הראשונה שהוא מוצג. תהליכי יישום הודעה זו על-ידי בחירת הגופן עבור פריט התפריט לתוך בהקשר התקן וקביעת השטח הדרוש להצגת טקסט פריט התפריט בגופן זה. גופן וטקסט פריט תפריט שניהם שצוינו על-ידי מבנה MYITEM של פריט התפריט (מבנה שהוגדרו על-ידי היישום). היישום קובע את גודל הטקסט על-ידי שימוש GetTextExtentPoint32 הפונקציה.

ההליך חלון מעבד את הודעת WM_DRAWITEM על-ידי הצגת טקסט פריט התפריט בגופן המתאים. גופן וטקסט פריט תפריט שניהם שצוינו על-ידי המבנה MYITEM של פריט התפריט. היישום בוחר טקסט וצבעי רקע המתאים למצב של פריט התפריט.

ההליך חלון מעבד את הודעת WM_DESTROY להרוס גופנים וזיכרון פנוי. היישום מוחקת את הגופן ומשחרר את המבנה MYITEM מוגדר על-ידי יישום עבור כל פריט תפריט.

להלן החלקים הרלוונטיים של קובץ הכותרת של היישום.

 / / מזהי פריט התפריט עבור התפריט תו # הגדרת 10 IDM_CHARACTER # הגדרת IDM_REGULAR 11 # הגדרת IDM_BOLD 12 # הגדרת IDM_ITALIC 13 # הגדרת IDM_UNDERLINE 14 / / מבנה המשויכים tagMYITEM struct typedef של פריטי תפריט {HFONT hfont; 
    int cchItemText; 
    תו szItemText [1]; 
} MYITEM; 
 
# הגדרת 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