The MASM Forum

General => The Campus => Topic started by: xandaz on May 14, 2013, 09:10:57 AM

Title: Owner Drawn Menus
Post by: xandaz on May 14, 2013, 09:10:57 AM
   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
Title: Re: Owner Drawn Menus
Post by: dedndave on May 14, 2013, 09:25:54 AM
WndProc     PROC USES EDI hWnd:DWORD............
Title: Re: Owner Drawn Menus
Post by: xandaz on May 14, 2013, 09:52:22 AM
   yeah....i tend to forget that. How do  you get the menu strings? i always have problems with ownerdraw things...
Title: Re: Owner Drawn Menus
Post by: dedndave on May 14, 2013, 11:42:04 AM
GetMenuString

http://msdn.microsoft.com/en-us/library/windows/desktop/ms647983%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms647983%28v=vs.85%29.aspx)
Title: Re: Owner Drawn Menus
Post by: 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 (http://www.winasm.net/forum/index.php?showtopic=568)
Title: Re: Owner Drawn Menus
Post by: Gunther on May 14, 2013, 06:50:55 PM
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 (http://www.winasm.net/forum/index.php?showtopic=568)

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

Gunther
Title: Re: Owner Drawn Menus
Post by: dedndave on May 14, 2013, 10:22:31 PM
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
Title: Re: Owner Drawn Menus
Post by: dedndave on May 14, 2013, 10:36:08 PM
here is an sDraw demo program   :P

http://www.masmforum.com/archive2012/4755_sDrawTest2.zip (http://www.masmforum.com/archive2012/4755_sDrawTest2.zip)
Title: Re: Owner Drawn Menus
Post by: Gunther on May 14, 2013, 10:45:15 PM
Hi Dave,

Quote from: dedndave on May 14, 2013, 10:36:08 PM
here is an sDraw demo program   :P

http://www.masmforum.com/archive2012/4755_sDrawTest2.zip (http://www.masmforum.com/archive2012/4755_sDrawTest2.zip)

thank you, nice example. Is it your code?

Gunther
Title: Re: Owner Drawn Menus
Post by: dedndave on May 14, 2013, 11:09:43 PM
no
sDraw was written by a guy named Ultrano (aka "u")
the demo was by chlankboot
Title: Re: Owner Drawn Menus
Post by: xandaz on May 15, 2013, 07:55:58 AM
   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
Title: Re: Owner Drawn Menus
Post by: qWord on May 15, 2013, 10:36:20 AM
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
Title: Re: Owner Drawn Menus
Post by: Dubby on May 15, 2013, 08:29:54 PM
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
Title: Re: Owner Drawn Menus
Post by: ragdog on May 16, 2013, 02:50:22 AM
hi

For o good OwnerDraw menu look in Radasm 3 source code :t
Title: Re: Owner Drawn Menus
Post by: xandaz on May 18, 2013, 07:49:49 AM
thanks Q. ty all.
Title: Re: Owner Drawn Menus
Post by: xandaz on May 22, 2013, 07:40:53 AM
   I'm kinda rusty. this took a while to come together... but yeah. the dwItemData is used istead of the dwTypeData member. It works. ty all :)
Title: Re: Owner Drawn Menus
Post by: dedndave on May 22, 2013, 08:05:48 AM
 :t
Title: Re: Owner Drawn Menus
Post by: xandaz on June 05, 2013, 08:47:08 AM
   Has  anyone ever done ownerdrawn menu bars? any hints?  :t
Title: Re: Owner Drawn Menus
Post by: xandaz on June 05, 2013, 09:55:53 AM
  another odm but with icons.