News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Owner Drawn Menus

Started by xandaz, May 14, 2013, 09:10:57 AM

Previous topic - Next topic

xandaz

   whats up with the DRAWITEM msg. How should one proceed as to the effect of geting the items data into the screen. This is what i've done so far... i also used GetMenuItemInfo but it doesnt work either. __UNICODE__     equ         1
.586
.model flat,stdcall
option casemap:none

WinMain PROTO   :DWORD,:DWORD,:DWORD,:DWORD
CreateMenus PROTO   :DWORD

incl    MACRO       spec
include \masm32\include\spec.inc
includelib \masm32\lib\spec.lib
ENDM

include \masm32\include\windows.inc
incl    kernel32
incl    user32
incl    gdi32
include \masm32\macros\macros.asm

.const
MainWindowWidth     equ             600
MainWindowHeight    equ             450

LC_APPICON          equ             IDI_APPLICATION
LC_CURSOR           equ             IDC_ARROW
noMenuItems         equ             2
noMenuFileItems     equ             4
noMenuExitItems     equ             1
IDM_DIE             equ             100
IDM_LIVE            equ             101
IDM_SQUASH          equ             102
IDM_EXIT            equ             103
.data
hInstance           HINSTANCE       ?

hMainWindow         HWND            ?
UCSTR               MainWindowClass,"MainWindowClass,",0
UCSTR               MainWindowName,"",0
wcex                WNDCLASSEX      <sizeof wcex,CS_HREDRAW+CS_VREDRAW,offset WndProc,\
                                    0,0,?,?,?,COLOR_WINDOW,0,offset MainWindowClass,?>
; ++++ Menus +++

hMenu               HMENU       ?
miiMenu             MENUITEMINFO <sizeof MENUITEMINFO,MIIM_TYPE+MIIM_SUBMENU,\
                                    MFT_STRING,MFS_ENABLED,0,0,0,0,0,offset szFile,sizeof szFile/2>
                    MENUITEMINFO    <sizeof MENUITEMINFO,MIIM_TYPE+MIIM_SUBMENU,\
                                    MFT_STRING,MFS_ENABLED,0,0,0,0,0,offset szExit,sizeof szExit/2>
UCSTR               szFile,"File",0
UCSTR               szExit,"Exit",0
                                   
hMenuFile           HMENU           ?
miiMenuFile         MENUITEMINFO <sizeof MENUITEMINFO,MIIM_TYPE+MIIM_ID,\
                                    MFT_STRING+MFT_OWNERDRAW,0,IDM_DIE,0,0,0,0,offset szDie,sizeof szDie/2>
                    MENUITEMINFO    <sizeof MENUITEMINFO,MIIM_TYPE+MIIM_ID,\
                                MFT_STRING+MFT_OWNERDRAW,0,IDM_LIVE,0,0,0,0,offset szLive,sizeof szLive/2>
                    MENUITEMINFO <sizeof MENUITEMINFO,MIIM_TYPE,\
                                MFT_SEPARATOR+MFT_OWNERDRAW,0,0,0,0,0,0,0,0>
                    MENUITEMINFO    <sizeof MENUITEMINFO,MIIM_TYPE+MIIM_ID,\
                                    MFT_STRING+MFT_OWNERDRAW,0,IDM_SQUASH,0,0,0,0,offset szSquash,sizeof szSquash/2>
UCSTR               szDie,"Die",0
UCSTR               szLive,"Live",0
UCSTR               szSquash,"Squash",0

hMenuExit           HMENU       ?
miiMenuExit         MENUITEMINFO <sizeof MENUITEMINFO,MIIM_TYPE+MIIM_ID,MFT_STRING+MFT_OWNERDRAW,0,IDM_EXIT,\
                                    0,0,0,0,offset szExit,sizeof szExit/2>
mii                 MENUITEMINFO    <>   
TextBuffer          dw              MAX_PATH dup(0)                                                                                                                                                                       
.code
    start:
        invoke  GetModuleHandle,0
        mov     hInstance,eax
        invoke  WinMain,hInstance,0,0,SW_SHOWNORMAL
        invoke  ExitProcess,eax

WinMain PROC    hInst:DWORD,hPreInst:DWORD,CmdLine:DWORD,CmdShow:DWORD

    local   msg:MSG

    push    hInstance
    pop     wcex.hInstance
    invoke  LoadIcon,hInstance,LC_APPICON
    mov     wcex.hIcon,eax
    mov     wcex.hIconSm,eax
    invoke  LoadCursor,hInstance,LC_CURSOR
    mov     wcex.hCursor,eax
    invoke  RegisterClassEx,addr wcex
    invoke  GetSystemMetrics,SM_CYSCREEN
    shr     eax,1
    sub     eax,MainWindowHeight/2
    push    eax
    invoke  GetSystemMetrics,SM_CXSCREEN
    shr     eax,1
    sub     eax,MainWindowWidth/2
    pop     ebx
    invoke  CreateWindowEx,0,addr MainWindowClass,addr MainWindowName,WS_TILEDWINDOW,\
                eax,ebx,MainWindowWidth,MainWindowHeight,0,0,hInstance,0
    mov     hMainWindow,eax
    invoke  ShowWindow,eax,CmdShow
    invoke  UpdateWindow,hMainWindow

msg_loop:
    invoke  GetMessage,addr msg,NULL,0,0
    or      eax,eax
    jz      end_msg_loop
    invoke  TranslateMessage,addr msg
    invoke  DispatchMessage,addr msg
    jmp     msg_loop
end_msg_loop:
    mov     eax,msg.wParam
    ret

WinMain     endp

WndProc     PROC        hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD

    .if     uMsg==WM_CREATE
        mov     edi,lParam
        .if     [edi.CREATESTRUCT].hWndParent==0
            invoke  CreateMenus,hWnd
        .endif 
    .elseif uMsg==WM_MEASUREITEM
        mov     edi,lParam
        mov     [edi.MEASUREITEMSTRUCT].itemWidth,150
        mov     [edi.MEASUREITEMSTRUCT].itemHeight,20
       
    .elseif uMsg==WM_DRAWITEM
        mov     edi,lParam
        assume  edi:PTR DRAWITEMSTRUCT
        invoke  GetMenuString,[edi].hwndItem,[edi].itemID,addr TextBuffer,sizeof TextBuffer/2,MF_BYCOMMAND           
        invoke  CreateSolidBrush,0e000h
        invoke  FillRect,[edi].hdc,addr [edi].rcItem,eax
        invoke  DrawText,[edi].hdc,addr TextBuffer,-1,addr [edi].rcItem,DT_LEFT
         
    .elseif uMsg==WM_DESTROY
        invoke  PostQuitMessage,0
    .else
        invoke  DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .endif
    xor     eax,eax
    ret
                           
WndProc     endp                                               

CreateMenus PROC    hWnd:DWORD

    invoke  CreateMenu
    mov     hMenu,eax
    invoke  SetMenu,hWnd,eax
    invoke  CreatePopupMenu
    mov     hMenuFile,eax
    invoke  CreatePopupMenu
    mov     hMenuExit,eax

    lea     edi,miiMenu
    mov     ecx,noMenuItems
loop_1:
    push    ecx
    .if     ecx==2       
        push    hMenuFile
        pop     [edi.MENUITEMINFO].hSubMenu
    .else
        push    hMenuExit
        pop     [edi.MENUITEMINFO].hSubMenu
    .endif
    invoke  InsertMenuItem,hMenu,-1,TRUE,edi
    pop     ecx
    dec     ecx
    jcxz    end_loop_1
    add     edi,sizeof MENUITEMINFO
    jmp     loop_1
end_loop_1:
    lea     edi,miiMenuFile
    mov     ecx,noMenuFileItems
loop_2:
    push    ecx
    invoke  InsertMenuItem,hMenuFile,-1,TRUE,edi
    pop     ecx
    dec     ecx
    jcxz    end_loop_2
    add     edi,sizeof MENUITEMINFO
    jmp     loop_2
end_loop_2:
    invoke  InsertMenuItem,hMenuExit,-1,TRUE,addr miiMenuExit
    invoke DrawMenuBar,hWnd
    ret
                                       
CreateMenus endp
end start

thanks
x

dedndave

WndProc     PROC USES EDI hWnd:DWORD............

xandaz

   yeah....i tend to forget that. How do  you get the menu strings? i always have problems with ownerdraw things...


dedndave


Gunther

Hi Dave,

Quote from: dedndave on May 14, 2013, 11:43:34 AM
there are some good examples in xxcontrols by Chib
http://www.winasm.net/forum/index.php?showtopic=568

thank you for the link. It shows: you're everywhere in the web.  :lol:

Gunther
You have to know the facts before you can distort them.

dedndave

i used xxcontrols to learn from when i first started playing with GUI apps   :P
another one is called sDraw.lib - if you can find it

dedndave


Gunther

You have to know the facts before you can distort them.

dedndave

no
sDraw was written by a guy named Ultrano (aka "u")
the demo was by chlankboot

xandaz

   yeah nice example dave. Who wants to know about ownerdrawn menus?
   ME!!! can someone fix the code so i can see some menu items. Has anyone ever been there?
   Ty x

qWord

Quote from: xandaz on May 15, 2013, 07:55:58 AMcan someone fix the code so i can see some menu items. Has anyone ever been there?
IIRC there is the problem that owner drawn menu items can't use strings and instead must use dwItemData member ...
__UNICODE__     equ         1
.586
.model flat,stdcall
option casemap:none

WinMain PROTO   :DWORD,:DWORD,:DWORD,:DWORD
CreateMenus PROTO   :DWORD

incl    MACRO       spec
include \masm32\include\spec.inc
includelib \masm32\lib\spec.lib
ENDM

include \masm32\include\windows.inc
incl    kernel32
incl    user32
incl    gdi32
include \masm32\macros\macros.asm

.const
MainWindowWidth     equ             600
MainWindowHeight    equ             450

LC_APPICON          equ             IDI_APPLICATION
LC_CURSOR           equ             IDC_ARROW
noMenuItems         equ             2
noMenuFileItems     equ             4
noMenuExitItems     equ             1
IDM_DIE             equ             100
IDM_LIVE            equ             101
IDM_SQUASH          equ             102
IDM_EXIT            equ             103
.data
hInstance           HINSTANCE       ?

hMainWindow         HWND            ?
UCSTR               MainWindowClass,"MainWindowClass,",0
UCSTR               MainWindowName,"",0
wcex                WNDCLASSEX      <sizeof wcex,CS_HREDRAW+CS_VREDRAW,offset WndProc,\
                                    0,0,?,?,?,COLOR_WINDOW,0,offset MainWindowClass,?>
; ++++ Menus +++

hMenu               HMENU       ?
miiMenu             MENUITEMINFO <sizeof MENUITEMINFO,MIIM_TYPE+MIIM_SUBMENU,\
                                    MFT_STRING,MFS_ENABLED,0,0,0,0,0,offset szFile,sizeof szFile/2>
                    MENUITEMINFO    <sizeof MENUITEMINFO,MIIM_TYPE+MIIM_SUBMENU,\
                                    MFT_STRING,MFS_ENABLED,0,0,0,0,0,offset szExit,sizeof szExit/2>
UCSTR               szFile,"File",0
UCSTR               szExit,"Exit",0
                                   
hMenuFile           HMENU           ?
miiMenuFile         MENUITEMINFO <sizeof MENUITEMINFO,MIIM_TYPE+MIIM_ID+MIIM_DATA,\
                                    MFT_OWNERDRAW,0,IDM_DIE,0,0,0,offset szDie,0,0>
                    MENUITEMINFO    <sizeof MENUITEMINFO,MIIM_TYPE+MIIM_ID+MIIM_DATA,\
                                MFT_OWNERDRAW,0,IDM_LIVE,0,0,0,offset szLive,0,0>
                    MENUITEMINFO <sizeof MENUITEMINFO,MIIM_TYPE,\
                                MFT_SEPARATOR+MFT_OWNERDRAW,0,0,0,0,0,0,0,0>
                    MENUITEMINFO    <sizeof MENUITEMINFO,MIIM_TYPE+MIIM_ID+MIIM_DATA,\
                                    MFT_OWNERDRAW,0,IDM_SQUASH,0,0,0,offset szSquash,0,0>
UCSTR               szDie,"Die",0
UCSTR               szLive,"Live",0
UCSTR               szSquash,"Squash",0

hMenuExit           HMENU       ?
miiMenuExit         MENUITEMINFO <sizeof MENUITEMINFO,MIIM_TYPE+MIIM_ID+MIIM_DATA,MFT_OWNERDRAW,0,IDM_EXIT,\
                                    0,0,0,offset szExit,0,0>
mii                 MENUITEMINFO    <>   
TextBuffer          dw              MAX_PATH dup(0)                                                                                                                                                                       
.code
    start:
        invoke  GetModuleHandle,0
        mov     hInstance,eax
        invoke  WinMain,hInstance,0,0,SW_SHOWNORMAL
        invoke  ExitProcess,eax

WinMain PROC    hInst:DWORD,hPreInst:DWORD,CmdLine:DWORD,CmdShow:DWORD

    local   msg:MSG

    push    hInstance
    pop     wcex.hInstance
    invoke  LoadIcon,hInstance,LC_APPICON
    mov     wcex.hIcon,eax
    mov     wcex.hIconSm,eax
    invoke  LoadCursor,hInstance,LC_CURSOR
    mov     wcex.hCursor,eax
    invoke  RegisterClassEx,addr wcex
    invoke  GetSystemMetrics,SM_CYSCREEN
    shr     eax,1
    sub     eax,MainWindowHeight/2
    push    eax
    invoke  GetSystemMetrics,SM_CXSCREEN
    shr     eax,1
    sub     eax,MainWindowWidth/2
    pop     ebx
    invoke  CreateWindowEx,0,addr MainWindowClass,addr MainWindowName,WS_TILEDWINDOW,\
                eax,ebx,MainWindowWidth,MainWindowHeight,0,0,hInstance,0
    mov     hMainWindow,eax
    invoke  ShowWindow,eax,CmdShow
    invoke  UpdateWindow,hMainWindow

msg_loop:
    invoke  GetMessage,addr msg,NULL,0,0
    or      eax,eax
    jz      end_msg_loop
    invoke  TranslateMessage,addr msg
    invoke  DispatchMessage,addr msg
    jmp     msg_loop
end_msg_loop:
    mov     eax,msg.wParam
    ret

WinMain     endp

WndProc     PROC  uses edi      hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD

    .if     uMsg==WM_CREATE
        mov     edi,lParam
        .if     [edi.CREATESTRUCT].hWndParent==0
            invoke  CreateMenus,hWnd
        .endif 
    .elseif uMsg==WM_MEASUREITEM
        mov     edi,lParam
        mov     [edi.MEASUREITEMSTRUCT].itemWidth,150
        mov     [edi.MEASUREITEMSTRUCT].itemHeight,20
       
    .elseif uMsg==WM_DRAWITEM
        mov     edi,lParam
        assume  edi:PTR DRAWITEMSTRUCT
        .if [edi].CtlType == ODT_MENU
        mov mii.cbSize,SIZEOF mii
        mov mii.fMask,MIIM_STATE or MIIM_FTYPE
        invoke GetMenuItemInfo,[edi].hwndItem,[edi].itemID,FALSE,ADDR mii
       
        .if !(mii.fType & (MFT_MENUBARBREAK or MFT_MENUBREAK or MFT_SEPARATOR))
        .if mii.fState & MFS_HILITE
        mov eax,0e000h
        .else
        mov eax,0ffh
        .endif
        .else
        mov eax,0ff0000h
        .endif
        invoke  CreateSolidBrush,eax
        push eax
        invoke  FillRect,[edi].hdc,addr [edi].rcItem,eax
        pop eax
        invoke DeleteObject,eax
        .if [edi].itemData
        invoke SaveDC,[edi].hdc
        invoke SetBkMode,[edi].hdc,TRANSPARENT
        invoke  DrawText,[edi].hdc,[edi].itemData,-1,addr [edi].rcItem,DT_CENTER or DT_SINGLELINE
        invoke RestoreDC,[edi].hdc,-1
        .endif
        .else
        jmp @1
        .endif
         
    .elseif uMsg==WM_DESTROY
        invoke  PostQuitMessage,0
    .else
@1:
        invoke  DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .endif
    xor     eax,eax
    ret
                           
WndProc     endp                                               

CreateMenus PROC    hWnd:DWORD

    invoke  CreateMenu
    mov     hMenu,eax
    invoke  SetMenu,hWnd,eax
    invoke  CreatePopupMenu
    mov     hMenuFile,eax
    invoke  CreatePopupMenu
    mov     hMenuExit,eax

    lea     edi,miiMenu
    mov     ecx,noMenuItems
loop_1:
    push    ecx
    .if     ecx==2       
        push    hMenuFile
        pop     [edi.MENUITEMINFO].hSubMenu
    .else
        push    hMenuExit
        pop     [edi.MENUITEMINFO].hSubMenu
    .endif
    invoke  InsertMenuItem,hMenu,-1,TRUE,edi
    pop     ecx
    dec     ecx
    jcxz    end_loop_1
    add     edi,sizeof MENUITEMINFO
    jmp     loop_1
end_loop_1:
    lea     edi,miiMenuFile
    mov     ecx,noMenuFileItems
loop_2:
    push    ecx
    invoke  InsertMenuItem,hMenuFile,-1,TRUE,edi
    pop     ecx
    dec     ecx
    jcxz    end_loop_2
    add     edi,sizeof MENUITEMINFO
    jmp     loop_2
end_loop_2:
    invoke  InsertMenuItem,hMenuExit,-1,TRUE,addr miiMenuExit
    invoke DrawMenuBar,hWnd
    ret
                                       
CreateMenus endp
end start
MREAL macros - when you need floating point arithmetic while assembling!

Dubby

I think qWord is right....
here is another example
http://www.aye13.com/WinAPITutorial/Tutorials/ownerDrawMenu/ownerDrawMenu.html

but it's in C though..

and if you want only to add an icon into menu here is the reference:
http://www.nanoant.com/programming/themed-menus-icons-a-complete-vista-xp-solution

ragdog

hi

For o good OwnerDraw menu look in Radasm 3 source code :t

xandaz