Here's some procs I just whipped together to replace my former method of using a bunch of macro and macro strings.
It copies the menu contents to the heap so that menu items can be removed and restored to emulate the VB capability of setting the .visible property which doesn't seem to exist in regular windows.
Call the first proc once to set up the menu in the heap. Call the other whenever.
There's probably a much better way to do this, if so, please let me know :P
; --------------- Hide Show Menu Items by JimG ---------------
.data?
hsmMnus dd ? ; start of menu buffer in heap
hsmMenuStuff Struct
MENUITEMINFO <?>
next dword ? ; address of next item
visible dword ? ; 1=visible, 0=not
menuh dword ? ; the handle of the menu this item belongs to
cap dword ? ; start of the variable length caption
hsmMenuStuff ends
hmsmnu textequ <[edi].hsmMenuStuff>
.code
hsmGetMenuInfo proc hWindow
; call once with handle of window, usually from WM_INITDIALOG, to get the full info for the menu
local rcnt,curmenu,mcount,hsmMenu,tempm[256 + sizeof hsmMenuStuff]:byte
pushad
invoke GetMenu,hWindow
or eax,eax
jz hmsGetMenuInfoWrap
mov hsmMenu,eax
lea edi,tempm ; first time through, just use scratch on stack
mov rcnt,1
mov ebx,sizeof hsmMenuStuff ; cumulative size. Need one extra for end flag and last try
.repeat ; twice, once to get size of memory needed, once to copy to heap
push 0 ; the flag that we have finished all menus/sub menus
mov esi,hsmMenu ; the starting point. esi will contain current menu throughout
again: mov mcount,0 ; menu item count for GetMenuItemInfo api
.repeat
mov hmsmnu.cbSize,sizeof MENUITEMINFO
mov hmsmnu.cch,255
mov hmsmnu.fMask,3Fh ; get everything
mov hmsmnu.visible,1
mov hmsmnu.menuh,esi
lea eax,hmsmnu.cap ; address of caption
mov hmsmnu.dwTypeData,eax
invoke GetMenuItemInfo,esi,mcount,TRUE,edi
.if eax==0
pop esi ; we ran out of this menu, move to next if any
or esi,esi ; is there any submenus stored up?
jnz again ; yes, go do next sub menu
.break .if rcnt != 0 ; all done with first pass, go set up for second pass
mov hmsmnu.next,0 ; we are totally done, flag end of data
jmp hmsGetMenuInfoWrap ; go wrap up
.endif
.if hmsmnu.hSubMenu ; see if there is a submenu to do later
push hmsmnu.hSubMenu ; save for later
.endif
.if rcnt==1
add ebx,sizeof hsmMenuStuff ; amount needed for everything but string
add ebx,hmsmnu.cch ; add in size of string
.else
mov ebx,edi ; compute address of next block
add ebx,sizeof hsmMenuStuff
add ebx,hmsmnu.cch
and ebx,0FFFFFFFCh ; mask off last two bits to keep on even dword alignment
mov hmsmnu.next,ebx ; save next address
mov edi,ebx ; and continue
.endif
inc mcount ; setup for next one
.until 0
invoke GetProcessHeap ; done with first pass
invoke HeapAlloc,eax,HEAP_ZERO_MEMORY,ebx ; allocate memory needed
mov hsmMnus,eax
mov edi,eax ; go back and save all in heap
mov eax,hWindow ; save window handle for HideShowMenus
stosd
dec rcnt
.until 0
hmsGetMenuInfoWrap:
popad
ret
hsmGetMenuInfo endp
HideShowMenus proc HideShow:dword,MenuIds:dword
; HideShow is 0 to hide, anything else to show
; MenuIds is the address of a list of Menu Ids to do, terminated with a zero ID.
local previous
pushad
mov edi,hsmMnus
add edi,4 ; skip window handle
mov previous,0 ; check for change
.repeat ; step through menu items
mov edx,hmsmnu.menuh
.if edx != previous ; submenu change, reset
mov ebx,0 ; restart running count
mov previous,edx
.endif
mov esi,MenuIds ; items to hide or show
.repeat ; step thought item to change
mov eax,[esi] ; id of the menu item we want
.break .if eax==0 ; all done
.if eax==hmsmnu.wID
.if HideShow ; if so, show
.if hmsmnu.visible==0 ; only make a change if it's not visible
mov hmsmnu.visible,1
invoke InsertMenuItem,edx,ebx,TRUE,edi
.endif
.else ; hide
.if hmsmnu.visible
mov hmsmnu.visible,0
invoke RemoveMenu,edx,ebx,MF_BYPOSITION
.endif
.endif
.break ; all done with this loop
.endif
add esi,4 ; go do next one
.until 0
add ebx,hmsmnu.visible ; count visible items
mov edi,hmsmnu.next ; location of menu item block
.until hmsmnu.next==0
mov edi,hsmMnus
invoke DrawMenuBar,[edi]
popad
ret
HideShowMenus endp
Unable to upload file, upload folder is full.
File and test program available here - http://www.winasm.net/forum/index.php?act=Attach&type=post&id=14593
Edit: uploaded source here
[attachment deleted by admin]
Jim,
That's very useful stuff.
The upload folder is full!?! Haven't run into that one yet. Was that a temporary condition? I just uploaded Suduko...
Paul
Okay, I uploaded here for those that didn't want to hassle with winasm.net