ProMiNick
Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
|
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.
; 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.
|