The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: jbullard on August 25, 2006, 05:37:50 AM

Title: Dynamic Menu
Post by: jbullard on August 25, 2006, 05:37:50 AM
Alright.  So I have a tray icon, a menu, and then another submenu.  However, the submenu is dynamic which means I don't have a ID for it.  So how would you go about getting the text of the menu item that was clicked.  Here is what I tried but for some reason it just gives me an error.  Maybe someone can show me what I am doing wrong.


                    invoke GetCursorPos, ADDR itemPT
                    invoke MenuItemFromPoint, NULL, hwndDeskMenu, itemPT.x, itemPT.y
                    invoke GetMenuString, hwndDeskMenu, eax, NULL, 512, MF_BYPOSITION
                    invoke MessageBox, hWnd, eax, ADDR appName, MB_OK


Thanks for any help.

Jason
Title: Re: Dynamic Menu
Post by: Tedd on August 25, 2006, 01:40:12 PM
GetCursorPos ==> the screen coordinates of the cursor
MenuItemFromPoint ==> If hMenu specifies a menu bar, this parameter is in window coordinates. Otherwise, it is in client coordinates.

Hint: ScreenToClient :wink
Title: Re: Dynamic Menu
Post by: jbullard on August 27, 2006, 09:09:13 AM
Will this work eventhough it is a tray menu?

Thanks,
Jason
Title: Re: Dynamic Menu
Post by: zooba on August 27, 2006, 10:40:49 AM
The ID is either returned or set (can't remember which) when you create the menu. Perhaps you could post the code from where you are creating the menu.

AFAICT, Tedd's solution will work, but let's be honest, it's a bit of a hack :wink

Cheers,

Zooba :U
Title: Re: Dynamic Menu
Post by: jbullard on August 27, 2006, 11:08:57 AM
After taking a look at the ScreenToClient and MenuFromPoint I realized that I do not need the handle to the window, and to leave that null cause then it automatically defaults to a popup menu.  However, I am still getting -1 when I call MenuFromPoint after calling ScreenToClient or not.  Here is what I have so far.


LOCAL pt1:POINT

.ELSEIF uMsg == WM_COMMAND
.IF lParam == 0
mov eax, wParam

.IF ax == IDM_EXIT
.ELSEIF ax == IDM_CNTRL1
.ELSEIF ax == IDM_CNTRL2
.ELSE
invoke GetCursorPos, ADDR pt1
.IF eax != 0
;invoke ScreenToClient, hWin, ADDR pt1
;.IF eax != 0
invoke MenuItemFromPoint, NULL, hwndDeskMenu, ADDR pt1.x, ADDR pt1.y
.IF eax != -1
invoke GetMenuString, hwndDeskMenu, eax, ADDR buffer, 512, MF_BYPOSITION
invoke MessageBox, hWin, ADDR buffer, ADDR appName, MB_OK
.ELSE
invoke MessageBox, hWin, ADDR appName, ADDR appName, MB_OK
.ENDIF
;.ENDIF
.ENDIF
.ENDIF
.ENDIF
.ELSEIF


I just don't know what I am missing here.  Cause if I replace eax in GetMenuString with 1 then it returns the menu string for that position.  The MenuItemFromPoint does not seem to be working for me.

Jason
Title: Re: Dynamic Menu
Post by: zooba on August 27, 2006, 12:20:08 PM
Having thought a little bit more, MenuItemFromPoint probably will not work, since by the time you receive the message it's already disappeared.

As part of the MENUITEMINFO structure passed with InsertMenuItem you can set the wID parameter to whatever value you like (remember to set MIIM_ID in fMask) and this will be in AX on the WM_COMMAND message (the uIDNewItem parameter for InsertMenu is the same thing).

Cheers,

Zooba :U

Edit: Just noticed that you're passing the address of pt1.x and pt1.y - try passing the values instead
Title: Re: Dynamic Menu
Post by: drizz on August 27, 2006, 02:48:16 PM
you wanted dyn menu and custom font? see this example.


[attachment deleted by admin]
Title: Re: Dynamic Menu
Post by: ToutEnMasm on August 27, 2006, 04:44:34 PM

Good sample on how to create a dynamic menu and how make a list of the active process.
       
                                             ToutEnMasm
Title: Re: Dynamic Menu
Post by: drizz on August 27, 2006, 05:02:57 PM
thanks, i wrote it long ago when i was on win98 (it used to show file icons too).
It needs a few adjustments (like: elevate priviledge for process list, better WM_MEASUREITEM handling)
to be of any (frequent) use.
Title: Re: Dynamic Menu
Post by: jbullard on August 28, 2006, 04:51:35 AM
Thanks for the example.  It sorta helped out.  Mostly just rampaged through it looking for the parts.  However, I noticed that you were using ebx where as I was trying to use ax.  So this is what I did.


        .IF ax == IDM_EXIT
        .ELSE
          invoke GetMenuString, hwndDeskMenu, ebx, ADDR buffer, 512, MF_BYPOSITION
          invoke MessageBox, hWin, ADDR buffer, ADDR appName, MB_OK


Now that works to a degree.  In my menu (dynamic) I currently have three values (Default, Register, Unregister).  No matter which spot I click on it always returns Default as the string.  I am sure someone will be able to spot where I have messed up.  Thanks for all the help guys/gals.

Jason
Title: Re: Dynamic Menu
Post by: Tedd on August 29, 2006, 02:09:27 PM
Quick thought..

I presume your aim for this is to react to which menu item is selected.
But your 'problem' is that the menu is dynamic, and so you don't know the position each item will be in.
However, when constructing the menu (using AppendMenu or InsertMenu?) you get to specify an ID for each inserted menu-item, along with the associated text, etc. So couldn't oyu simply give the same ID to the individual items each time (according to their action, rather than position)?? Then when the given item is clicked, the resulting identifier will be passed-on in the same way as any other menu-id. And identifying the menu-item is implicit.

invoke AppendMenu, hMenu,MF_STRING,IDM_DEFAULT,ADDR str_default
.IF (want_register_item)
    invoke AppendMenu, hMenu,MF_STRING,IDM_REGISTER,ADDR str_register
.ENDIF
.IF (want_unregister_item)
    invoke AppendMenu, hMenu,MF_STRING,IDM_UNREGISTER,ADDR str_unregister
.ENDIF

If you receive IDM_REGISTER, then you know the "Register" item has been selected.

Is there a reason you can't do it like this?