Esempio di voci di Menu creati dal proprietario

Nell'esempio in questo argomento vengono voci di menu creati dal proprietario in un menu. Le voci di menu selezionare gli attributi del tipo di carattere specifico e l'applicazione visualizza ogni voce di menu utilizzando un tipo di carattere che ha l'attributo corrispondente. Ad esempio, la voce di menu corsivo viene visualizzata in un tipo di carattere corsivo. Il nome del personaggio menu sulla barra dei menu si apre il menu.

Barra dei menu e menu a discesa sono inizialmente definiti da una risorsa modello di menu esteso. Poiché un modello di menu non č possibile specificare gli elementi creati dal proprietario, il menu contiene inizialmente quattro voci di menu testo con le seguenti stringhe: "Regolari", "Bold," "Italic" e "Sottolineato". Routine della finestra dell'applicazione cambia queste agli elementi creati dal proprietario quando elabora il messaggio WM_CREATE . Quando riceve il messaggio WM_CREATE, la routine della finestra chiama la funzione OnCreate definite dall'applicazione, che esegue le seguenti operazioni per ogni voce di menu

  1. Alloca una struttura MYITEM definiti dall'applicazione.
  2. Ottiene il testo della voce di menu e lo salva nella struttura MYITEM definiti dall'applicazione.
  3. Crea il tipo di carattere utilizzato per visualizzare la voce di menu e la salva suo manico nella struttura MYITEM definiti dall'applicazione.
  4. Cambia il tipo di elemento di menų a MFT_OWNERDRAW e salva un puntatore alla struttura MYITEM come elemento di dati definiti dall'applicazione.

Perché un puntatore a ogni struttura MYITEM definiti dall'applicazione viene salvato come dati dell'elemento, viene passato alla routine di finestra in congiunzione con i messaggi WM_MEASUREITEM e WM_DRAWITEM per la voce di menu corrispondente. Il puntatore č contenuto nel membro di strutture sia MEASUREITEMSTRUCT che DRAWITEMSTRUCT itemData.

La prima volta che viene visualizzato per ogni voce di menu creati dal proprietario viene inviato un messaggio WM_MEASUREITEM. I processi di applicazione questo messaggio selezionando il tipo di carattere per la voce di menu in un contesto di periferica e quindi determinare lo spazio richiesto per visualizzare il testo dell'elemento dal menu in quel tipo di carattere. Il testo dell'elemento font e menų vengono specificati entrambi dalla struttura MYITEM della voce di menu (la struttura definita dall'applicazione). L'applicazione determina la dimensione del testo utilizzando il GetTextExtentPoint32 funzione.

La routine della finestra elabora il messaggio WM_DRAWITEM visualizzando il testo dell'elemento dal menu nel tipo di carattere appropriato. Il testo dell'elemento font e menų vengono specificati entrambi dalla struttura MYITEM della voce di menu. L'applicazione consente di selezionare colori di testo e di sfondo appropriati allo stato della voce di menu.

La routine della finestra elabora il messaggio WM_DESTROY per distruggere i caratteri e la memoria libera. L'applicazione consente di eliminare il tipo di carattere e libera la struttura MYITEM definito dall'applicazione per ogni voce di menu.

Di seguito sono le parti pertinenti del file di intestazione dell'applicazione.

 / / Gli identificatori di voci di menu per il menu carattere # define IDM_CHARACTER 10 # define IDM_REGULAR 11 # define IDM_BOLD 12 # define IDM_ITALIC 13 # define IDM_UNDERLINE 14 / / struttura connesso con menų oggetti typedef struct tagMYITEM {HFONT hfont; 
    int cchItemText; 
    char szItemText [1]; 
} MYITEM; 
 
# define CCH_MAXITEMTEXT 256 
 

Di seguito sono le parti rilevanti di routine della finestra dell'applicazione e le sue funzioni associate.

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); 
} 
 

Rimedio: Inserire il CD-ROM CD di MSDN Library.

Index