flat assembler
Message board for the users of flat assembler.

Index > Tutorials and Examples > Fasmed menudemo of Example 3 of masm32

Author
Thread Post new topic Reply to topic
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 07 Aug 2017, 10:02
in masm32 version there is a bug with checking states of menuitems:
there are used cmp instead of test as result incorrect displaying of owner draw items.
here it is fixed.
However in program are stayed some rudiments no needed for current realization.
Code:
; Programed by Ewayne Wagner for masm32
; E-MAIL: yooper@kalamazoo.net

; Fasmed by ProMiNick

format PE GUI 4.0
entry start

IDR_MENU       = 37
IDR_MENU2      = 700

IDB_CUTBMP     = 701
IDB_CPYBMP     = 702
IDB_PSTBMP     = 703
IDB_DELBMP     = 704
IDB_CU2BMP     = 705
IDB_CP2BMP     = 706
IDB_PS2BMP     = 707
IDB_DL2BMP     = 708

IDM_NEW        = 1001
IDM_OPEN       = 1002
IDM_SAVE       = 1003
IDM_EXIT       = 2001
IDM_CUT        = 1005
IDM_COPY       = 1006
IDM_PASTE      = 1007
IDM_DEL        = 1008
IDM_SET1       = 1101
IDM_SET2       = 1102
IDM_SET3       = 1103
IDM_SET4       = 1104
IDM_SET5       = 1105
IDM_SET6       = 1106
IDM_SET7       = 1107
IDM_SET8       = 1108
IDM_SET9       = 1109
IDM_SET10      = 1110
IDM_SET11      = 1111
sizeof.dword_pushed_before = 4

include 'win32ax.inc'

section '.text' code readable executable

  start:

        invoke  GetModuleHandle,0
        mov     [hInst], eax
        mov     [wc.hInstance], eax
        invoke  LoadIcon,0,IDI_APPLICATION
        mov     [wc.hIcon],eax
        invoke  LoadCursor,0,IDC_ARROW
        mov     [wc.hCursor],eax
        invoke  RegisterClassEx,wc

        invoke  GetSystemMetrics, SM_CXSCREEN
        sub     eax, 350
        shr     eax, 1
        push    eax
        invoke  GetSystemMetrics, SM_CYSCREEN
        sub     eax, 300
        shr     eax, 1
        pop     ebx

        invoke  CreateWindowEx,WS_EX_CLIENTEDGE,ClassName,AppName,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,ebx,eax,350,300,NULL,NULL,[wc.hInstance],NULL
        mov     [hWnd], eax
        invoke  ShowWindow, [hWnd], SW_SHOWNORMAL
        invoke  UpdateWindow, [hWnd]
        invoke  GetMenu, [hWnd]              ; Get handle to main menu
        mov     [hMenu], eax
        invoke  GetSubMenu, [hMenu], 0       ; Get handle to 1st sub menu
        mov     [hSMenu1], eax
        invoke  GetSubMenu, [hMenu], 1       ; Get handle to 2nd sub menu
        mov     [hSMenu2], eax

  msg_loop:
        invoke  GetMessage,msg,NULL,0,0
        cmp     eax,1
        jb      end_loop
        jne     msg_loop
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        jmp     msg_loop

  end_loop:
        invoke  ExitProcess,eax
        invoke  InitCommonControls

proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam
        locals
                ID          dd ?
                Cnt         dd ?
                Disable     dd ?
                dwRob       dd ?
                hMemDC      dd ?
                hBR         dd ?
                rect        RECT
                szBuff      db 25 dup (?)
        endl
        mov     eax,[wmsg]
        cmp     eax,WM_COMMAND
        je      .wmcommand
        cmp     eax,WM_DRAWITEM
        je      .wmdrawitem
        cmp     eax,WM_MEASUREITEM
        je      .wmmeasureitem
        cmp     eax,WM_SIZE
        je      .wmsize
        cmp     eax,WM_NOTIFY
        je      .wmnotify
        cmp     eax,WM_CREATE
        je      .wmcreate
        cmp     eax,WM_CLOSE
        je      .wmclose
        cmp     eax,WM_DESTROY
        je      .wmdestroy
  .defwndproc:
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
        jmp     .finish
  .wmcommand:
        mov     ebx, [lparam]
        test    ebx,ebx
        jnz     .defwndproc
        mov     eax, [wparam]
        and     eax,0FFFFh
        cmp     eax, IDM_EXIT
        jnz     @F
        invoke  SendMessage, [hwnd], WM_CLOSE, 0, 0
        jmp     .finish

  .settable:     dd .wmcmdset1,.wmcmdset2,.wmcmdset3,.wmcmdset4,\
                   .wmcmdset5,.wmcmdset6,.wmcmdset7,.wmcmdset8,\
                   .wmcmdset9,.wmcmdset10,.wmcmdset11
  @@:
        mov     ecx,1
        xchg    eax,ecx
        cmp     ecx, IDM_SET11
        ja      .defwndproc
        sub     ecx, IDM_SET1
        jb      .defwndproc

        shl     eax, cl
        test    [Set], eax
        jnz     .ret0
        or      [Set], eax
        jmp     dword [.settable+ecx*4]
  .wmcmdset1:
        mov     [mii.fType], MFT_STRING or MFT_RADIOCHECK
        mov     [mii.fState], MFS_CHECKED
        mov     [mii.wID], IDM_SAVE
        mov     eax, szSaveIt
        mov     [mii.dwTypeData], eax
        invoke  SetMenuItemInfo, [hSMenu1], IDM_SAVE, FALSE, mii
        jmp     .ret0
  .wmcmdset2:
        mov     [mii.fType], MFT_STRING
        mov     [mii.fState], 0
        mov     [mii.wID], 1019
        mov     eax, szSaveAs
        mov     [mii.dwTypeData], eax
        invoke  InsertMenuItem, [hSMenu1], 3, TRUE, mii
        jmp     .ret0
  .wmcmdset3:
        invoke  CreatePopupMenu
        mov     [hSMenu3], eax
        mov     [mii.hSubMenu], eax
        mov     [mii.fType], MFT_STRING
        mov     eax, szNewMenu1
        mov     [mii.dwTypeData], eax
        invoke  InsertMenuItem, [hMenu], 2, TRUE, mii
        invoke  DrawMenuBar,[hwnd]
        jmp     .ret0
  .wmcmdset4:
        mov     [mii.fType], MFT_STRING
        mov     [mii.hSubMenu], 0
        mov     [mii.wID], 1020
        mov     eax, szNewSubMenu1
        mov     [mii.dwTypeData], eax
        invoke  InsertMenuItem, [hSMenu3], 0, TRUE, mii
        invoke  DrawMenuBar,[hwnd]
        jmp     .ret0
  .wmcmdset5:
        invoke  GetMenuItemCount,[hSMenu3]
        mov     edx,eax
        mov     [mii.fType], MFT_SEPARATOR
        mov     [mii.dwTypeData], eax
        invoke  InsertMenuItem, [hSMenu3], edx, TRUE, mii
        mov     [mii.fType], MFT_STRING
        mov     [mii.wID], 1021
        mov     [mii.hSubMenu], 0
        mov     eax, szNewSubMenu2
        mov     [mii.dwTypeData], eax
        invoke  InsertMenuItem, [hSMenu3], 99, TRUE, mii
        invoke  DrawMenuBar,[hwnd]
        jmp     .ret0
  .wmcmdset6:
        invoke  SetMenuItemBitmaps,[hSMenu2], IDM_CUT, MF_BYCOMMAND, [hMBmp1], [hMBmp1]
        invoke  SetMenuItemBitmaps,[hSMenu2], IDM_COPY, MF_BYCOMMAND, [hMBmp2], [hMBmp2]
        invoke  SetMenuItemBitmaps,[hSMenu2], IDM_PASTE, MF_BYCOMMAND, [hMBmp3], [hMBmp3]
        invoke  SetMenuItemBitmaps,[hSMenu2], IDM_DEL, MF_BYCOMMAND, [hMBmp4], [hMBmp4]
        jmp     .ret0
  .wmcmdset7:
        invoke  CreatePopupMenu
        mov     [hSMenu4], eax
        mov     [mii.hSubMenu], eax
        invoke  GetMenuItemCount,[hMenu]
        dec     eax
        mov     edx,eax
        mov     [mii.fType], MFT_STRING
        mov     [mii.fState], MFS_ENABLED
        mov     [mii.hbmpChecked], 0
        mov     [mii.hbmpUnchecked], 0
        mov     eax, szNewMenu2
        mov     [mii.dwTypeData], eax
        invoke  InsertMenuItem, [hMenu], edx, TRUE, mii
        mov     [mii.fType], MFT_STRING
        mov     eax,[hSMenu5]
        mov     [mii.hSubMenu], eax
        mov     eax, szEdit
        mov     [mii.dwTypeData], eax
        invoke  InsertMenuItem, [hSMenu4], 0, TRUE, mii
        invoke  DrawMenuBar,[hwnd]
        jmp     .ret0
  .wmcmdset8:
        mov     [mii.fType], MFT_STRING
        mov     [mii.fState], MFS_ENABLED
        mov     eax, szOwner
        mov     [mii.dwTypeData], eax
        invoke  SetMenuItemInfo, [hSMenu4], 0, TRUE, mii
        mov     [mii.fType], MFT_OWNERDRAW
        mov     [mii.fState], MFS_ENABLED
        mov     [mii.hSubMenu], 0
        mov     [mii.wID], IDM_CUT
        mov     [mii.dwItemData], IDM_CUT
        mov     [mii.dwTypeData], 0
        invoke  SetMenuItemInfo, [hSMenu5], IDM_CUT, FALSE, mii
        mov     [mii.wID], IDM_COPY
        mov     [mii.dwItemData], IDM_COPY
        invoke  SetMenuItemInfo, [hSMenu5], IDM_COPY, FALSE, mii
        mov     [mii.wID], IDM_PASTE
        mov     [mii.dwItemData], IDM_PASTE
        invoke  SetMenuItemInfo, [hSMenu5], IDM_PASTE, FALSE, mii
        mov     [mii.wID], IDM_DEL
        mov     [mii.dwItemData], IDM_DEL
        invoke  SetMenuItemInfo, [hSMenu5], IDM_DEL, FALSE, mii
        invoke  DrawMenuBar,[hwnd]
        jmp     .ret0
  .wmcmdset9:
        invoke  GetMenuItemInfo, [hSMenu2], IDM_COPY, FALSE, mii
        xor     [mii.fState],MF_GRAYED
        invoke  EnableMenuItem, [hMenu], IDM_COPY, [mii.fState]
        jmp     .ret0
  .wmcmdset10:
        push    [mii.fMask]
        mov     [mii.fMask], MIIM_STATE
        invoke  GetMenuItemInfo, [hSMenu5], IDM_COPY, FALSE, mii
        xor     [mii.fState],MF_GRAYED
        test    [Set],1 shl 7
        jz      .no_owndraw
        mov     [mii.fType], MFT_OWNERDRAW
  .no_owndraw:
        invoke  SetMenuItemInfo, [hSMenu5], IDM_COPY, FALSE, mii
        pop     [mii.fMask]
        jmp     .ret0
  .wmcmdset11:
        invoke  DestroyMenu, [hMenu]
        invoke  LoadMenu, [wc.hInstance], IDR_MENU
        mov     [hMenu], eax
        invoke  SetMenu, [hwnd], [hMenu]
        invoke  GetSubMenu, [hMenu], 0       ; Get handle to 1st sub menu
        mov     [hSMenu1], eax
        invoke  GetSubMenu, [hMenu], 1       ; Get handle to 2nd sub menu
        mov     [hSMenu2], eax
        invoke  LoadMenu, [wc.hInstance], IDR_MENU2
        invoke  GetSubMenu, eax, 0
        mov     [hSMenu5], eax
        xor     eax,eax
        mov     [Set],eax
        jmp     .finish
  .wmdrawitem:
        mov     eax,[wparam]
        test    eax,eax
        jnz     .defwndproc
        mov     esi,[lparam]
        mov     edi,dis
        mov     ecx, sizeof.DRAWITEMSTRUCT
        rep     movsb
        cmp     [dis.itemID],-1
        jz      .skipdraw
        mov     [dis.rcItem.left], 17
        mov     [dis.rcItem.top], 0
        mov     [dis.rcItem.right], 100
        mov     [dis.rcItem.bottom], 16

        mov     eax, [dis.itemData]
        sub     eax, IDM_CUT
        mov     edx, [hMBmp5+eax*4]
        mov     [hMBmp], edx
        shl     eax,4 ; eax = eax*16
        add     [dis.rcItem.top], eax
        add     [dis.rcItem.bottom], eax
        shr     eax,2
        mov     eax,[szs+eax]
        invoke  lstrcpy, addr szBuff, eax
        and     [Disable],0
        mov     [dwRob], SRCCOPY
        mov     eax,[dis.itemState]
        cmp     [dis.itemState],7
        ja      .skip_enabling
        je      .do_enable
        test    [dis.itemState],1
        jnz     .skip_enabling
  .do_enable:
        inc     [Disable]
        mov     [dwRob], SRCAND
  .skip_enabling:
        invoke  CreateCompatibleDC, [dis.hDC]
        push    eax
        invoke  SelectObject, eax, [hMBmp]
        invoke  BitBlt, [dis.hDC], 0, [dis.rcItem.top], 16, 16, dword [esp+sizeof.dword_pushed_before*3], 0, 0, [dwRob]
        invoke  DeleteDC;, [hMemDC]; from stack

        test    [dis.itemState],ODS_GRAYED
        jz      .cont
        invoke  GetSysColor, COLOR_GRAYTEXT
        invoke  SetTextColor, [dis.hDC], eax
        invoke  SetBkMode, [dis.hDC], TRANSPARENT
        jmp     .end_cases

  .cont:
        test    [dis.itemState],ODS_SELECTED
        jz     .cont2
        invoke  CreateSolidBrush, 00000000h
        mov     [hBR], eax
        invoke  FillRect, [dis.hDC], dis.rcItem, eax
        invoke  SetTextColor, [dis.hDC], 00ffff00h
        invoke  SetBkColor, [dis.hDC], 00000000h
        mov     [rect.left], 0
        mov     eax,[dis.rcItem.top]
        mov     [rect.top],eax
        mov     [rect.right], 16
        mov     eax,[dis.rcItem.bottom]
        mov     [rect.bottom],eax
        invoke  DrawEdge, [dis.hDC], addr rect, BDR_RAISEDINNER, BF_TOPLEFT
        invoke  DrawEdge, [dis.hDC], addr rect, BDR_RAISEDOUTER, BF_BOTTOMRIGHT
        jmp     .end_cases
  .cont2:
        invoke  GetBkColor, [dis.hDC]
        invoke  CreateSolidBrush, eax
        mov     [hBR], eax
        invoke  FillRect, [dis.hDC], dis.rcItem, eax
        invoke  SetTextColor, [dis.hDC], 00ff0000h
        invoke  SetBkMode, [dis.hDC], TRANSPARENT
  .end_cases:
        add     [dis.rcItem.left], 4
        invoke  DrawText, [dis.hDC], addr szBuff, -1, dis.rcItem, DT_LEFT or DT_VCENTER or DT_SINGLELINE
        invoke  DeleteObject, [hBR]
  .skipdraw:
        mov     [dis.itemState], ODS_DEFAULT
        mov     [dis.hDC], 0
        jmp     .ret0
  .wmmeasureitem:
        cmp     [wparam],0
        jnz     .defwndproc
        mov     edx, [lparam]
        mov     [edx+MEASUREITEMSTRUCT.itemWidth], 80
        mov     [edx+MEASUREITEMSTRUCT.itemHeight], 16
        jmp     .finish
  .wmsize:
  .wmnotify:
        jmp     .finish

  .wmcreate:
        invoke  LoadMenu, [wc.hInstance], IDR_MENU2
        invoke  GetSubMenu, eax, 0
        mov     [hSMenu5], eax
        mov     [ID],IDB_CUTBMP
        mov     [Cnt],8
  @@:
        invoke  LoadBitmap, [wc.hInstance], [ID]
        mov     ecx,[ID]
        sub     ecx,IDB_CUTBMP
        mov     [ecx*4+hMBmp1],eax
        inc     [ID]
        sub     [Cnt],1
        jnz     @B
  @@:
        mov     [mii.cbSize], sizeof.MENUITEMINFO
        mov     [mii.fMask], MIIM_DATA or MIIM_ID or MIIM_STATE or MIIM_SUBMENU or MIIM_TYPE or MIIM_CHECKMARKS
        jmp     .finish
  .wmclose:
        jmp     .defwndproc
  .ret1:
        xor     eax,eax
        inc     eax
        jmp     .finish
  .wmdestroy:
        invoke  PostQuitMessage,0
  .ret0:
        xor     eax,eax
  .finish:
        ret
endp

section '.data' data readable writeable
    szs            dd  szCut,szCopy,szPaste,szDelete

    ClassName      db  'MenuDemo',0
    AppName        db  'MenuDemo (ProMiNick)',0
    MenuName       db  'MainMenu',0
    szNull         db  0

    szSaveIt       db  '&Save It',0
    szSaveAs       db  'Save &As',0
    szNewMenu1     db  'New Menu 1',0
    szNewMenu2     db  'New Menu 2',0
    szNewSubMenu1  db  'New SubMenu 1',0
    szNewSubMenu2  db  'New SubMenu 2',0

    szOwner        db  'OwnerDrawn',0
    szCut          db  'Cu&t',0
    szCopy         db  '&Copy',0
    szPaste        db  '&Paste',0
    szDelete       db  '&Delete',0
    szEdit         db  '&Edit',0
    align 4
    wc             WNDCLASSEX sizeof.WNDCLASSEX, 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,IDR_MENU,ClassName,0
    msg            MSG
    mii            MENUITEMINFO
    mis            MEASUREITEMSTRUCT
    dis            DRAWITEMSTRUCT
    hInst          dd  ?
    MainExit       dd  ?
    hWnd           dd  ?
    hMenu          dd  ?
    hSMenu1        dd  ?
    hSMenu2        dd  ?
    hSMenu3        dd  ?
    hSMenu4        dd  ?
    hSMenu5        dd  ?
    MenuCnt        dd  ?
    Set            dd  ?
    hMBmp          dd  ?
    hMBmp1         dd  ?
    hMBmp2         dd  ?
    hMBmp3         dd  ?
    hMBmp4         dd  ?
    hMBmp5         dd  ?
    hMBmp6         dd  ?
    hMBmp7         dd  ?
    hMBmp8         dd  ?

    ItemID         dd  ?

section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL',\
          comctl32,'COMCTL32.DLL',\
          gdi32,'GDI32.DLL'

  include 'api\kernel32.inc'
  include 'api\user32.inc'
  include 'api\comctl32.inc'
  include 'api\gdi32.inc'

section '.rsrc' resource data readable discardable

  directory RT_MENU,menus,\
            RT_BITMAP,bitmaps

  resource menus,\
           IDR_MENU,LANG_ENGLISH+SUBLANG_DEFAULT,main_menu,\
           IDR_MENU2,LANG_ENGLISH+SUBLANG_DEFAULT,scnd_menu

  resource bitmaps,\
           IDB_CUTBMP,LANG_NEUTRAL,cut_bitmap,\
           IDB_CPYBMP,LANG_NEUTRAL,cpy_bitmap,\
           IDB_PSTBMP,LANG_NEUTRAL,pst_bitmap,\
           IDB_DELBMP,LANG_NEUTRAL,del_bitmap,\
           IDB_CU2BMP,LANG_NEUTRAL,cu2_bitmap,\
           IDB_CP2BMP,LANG_NEUTRAL,cp2_bitmap,\
           IDB_PS2BMP,LANG_NEUTRAL,ps2_bitmap,\
           IDB_DL2BMP,LANG_NEUTRAL,dl2_bitmap

  menu main_menu
       menuitem '&File',0,MFR_POPUP
                menuitem '&New',IDM_NEW
                menuitem '&Open',IDM_OPEN
                menuitem '&Save',IDM_SAVE
                menuseparator
                menuitem 'E&xit',IDM_EXIT,MFR_END
       menuitem '&Edit',0,MFR_POPUP
                menuitem 'Cu&t',IDM_CUT
                menuitem '&Copy',IDM_COPY;,,MF_GRAYED
                menuitem '&Paste',IDM_PASTE
                menuitem '&Delete',IDM_DEL,MFR_END
       menuitem '&Menu Functions',0,MFR_POPUP + MFR_END
                menuitem 'Change the name of &Save in the &File Menu',IDM_SET1
                menuitem 'Insert a Save As Menu Item in the &File Menu',IDM_SET2
                menuseparator
                menuitem 'Insert a &New Menu in the Menu bar',IDM_SET3
                menuitem 'Insert a Menu Item in the &New Menu',IDM_SET4
                menuitem 'Insert a Sep and Menu Item in the &New Menu',IDM_SET5
                menuseparator
                menuitem 'Add Bitmaps to the &Edit Menu  (Ugly)',IDM_SET6
                menuseparator
                menuitem 'Insert a &New Menu and Submenu in the Menu bar',IDM_SET7
                menuitem 'Change the new Submenu to OwnerDrawn  (Nice)',IDM_SET8
                menuseparator
                menuitem 'Gray or Enable &Copy in the &Edit Menu',IDM_SET9
                menuitem 'Gray or Enable &Copy in the OwnerDrawn &Edit Menu',IDM_SET10
                menuseparator
                menuitem 'Restore the Menu bar',IDM_SET11,MFR_END

  menu scnd_menu
       menuitem '&Edit',0,MFR_POPUP + MFR_END
                menuitem 'Cu&t',IDM_CUT
                menuitem '&Copy',IDM_COPY
                menuitem '&Paste',IDM_PASTE
                menuitem '&Delete',IDM_DEL,MFR_END

  bitmap cut_bitmap,'resource\B05_Cut.bmp'
  bitmap cpy_bitmap,'resource\B06_Copy.bmp'
  bitmap pst_bitmap,'resource\B07_Paste.bmp'
  bitmap del_bitmap,'resource\B08_Delete.bmp'
  bitmap cu2_bitmap,'resource\B05_Cut4.bmp'
  bitmap cp2_bitmap,'resource\B06_Copy4.bmp'
  bitmap ps2_bitmap,'resource\B07_Paste4.bmp'
  bitmap dl2_bitmap,'resource\B08_Delete4.bmp'    


Out of topic: is anyone know how to code item additional data to menuitem in resource not in code.
MS says it is impossible.
For menu ver0 it is realy impossible: I checked every combination of (16 bit) flags.
In ver1 therefore 16-bit flags separated into 4 32-bit flags with exclusive low parts, but in higher parts... it is not good documented - what is there...

_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 07 Aug 2017, 10:02
View user's profile Send private message Send e-mail Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.