I suggest that EVENT_MENUACTION events return the menu gadget used as the event source value.
EVENT_MENUACTION should return the event source
BlitzMax Forums/BlitzMax GUI Programming/EVENT_MENUACTION should return the event source I think also
Agreed.
Would definititely solve some problems with dynamic menues.
Would definititely solve some problems with dynamic menues.
Spooky... I just stumbled across this today after porting an app from GTK to Mac and now to Win32...
...and it breaks on win32 because event.source is Null...
I would say that this is a Bug then... no?
...and it breaks on win32 because event.source is Null...
I would say that this is a Bug then... no?
If you change something in the win32maxgui module, you should be able to get your apps working.
However, before you do any changes you should syncmds, since my line numbers refer to the latest version.
Change in mod/brl.mod/win32maxgui.mod/win32gui/win32hwnd.cpp
lines 15 to 21
from
from
lines 321 to 329
from
from
from
from
from
If this really behaves different on Mac/Win32 I'd say it's a bug.
However, before you do any changes you should syncmds, since my line numbers refer to the latest version.
Change in mod/brl.mod/win32maxgui.mod/win32gui/win32hwnd.cpp
lines 15 to 21
from
extern "C"{ void brl_event_EmitEvent( BBObject *event ); BBObject *brl_maxgui_HotKeyEvent( int key,int mods,int owner ); void brl_win32maxgui_EmitWin32OSEvent( HWND hwnd,UINT msg,WPARAM wp,LPARAM lp,void *source ); }to
extern "C"{ void brl_event_EmitEvent( BBObject *event ); BBObject *brl_maxgui_HotKeyEvent( int key,int mods,int owner ); void brl_win32maxgui_EmitWin32OSEvent( HWND hwnd,UINT msg,WPARAM wp,LPARAM lp,void *source ); int brl_win32maxgui_bb_GetMenuTag(int id); BBObject* brl_win32maxgui_bb_GetMenuSource(int id); }lines 133 to 141
from
case WM_COMMAND: if( !lp ){ if( wp>100 ){ bbPostWin32GuiEvent( BBEVENT_MENUACTION,0,wp-100,0,0,0,&bbNullObject ); } return 0; } src=findHwnd( (HWND)lp ); break;to
case WM_COMMAND: if( !lp ){ if( wp>100 ){ bbPostWin32GuiEvent( BBEVENT_MENUACTION,0,brl_win32maxgui_bb_GetMenuTag(wp-100),0,0,0,brl_win32maxgui_bb_GetMenuSource(wp-100) ); } return 0; } src=findHwnd( (HWND)lp ); break;in mod/brl.mod/win32maxgui.mod/win32gui.bmx
lines 321 to 329
from
Method CreateGadget:TGadget(gadgetclass,label$,x,y,w,h,group:TGadget,style) Local gadget:TWin32Gadget Local wgroup:TWin32Gadget Local hgroup Local g,name$ If Not group group=Desktop wgroup=TWin32Gadget(group) hgroup=wgroup.handleto
Method CreateGadget:TGadget(gadgetclass,label$,x,y,w,h,group:TGadget,style) Local gadget:TWin32Gadget Local wgroup:TWin32Gadget Local hgroup Local g,name$,tag If Not group group=Desktop wgroup=TWin32Gadget(group) hgroup=wgroup.handlelines 367 to 384
from
Case GADGET_MENUITEM If wgroup And wgroup.class=GADGET_WINDOW hgroup=bbWindowMenu(TWin32Gadget(group).handle) EndIf If wgroup And wgroup.class=GADGET_DESKTOP hgroup=0 EndIf g=bbCreateMenu(label,style,hgroup) Case GADGET_NODE Throw "chunks" Case GADGET_CANVAS g=bbCreatePanel(x,y,w,h,hgroup,style|4) End Select gadget=TWin32Gadget.Create(gadgetclass,g,wgroup) gadget.name=name Return gadgetto
Case GADGET_MENUITEM If wgroup And wgroup.class=GADGET_WINDOW hgroup=bbWindowMenu(TWin32Gadget(group).handle) EndIf If wgroup And wgroup.class=GADGET_DESKTOP hgroup=0 EndIf tag=bb_SetMenuTag(style) g=bbCreateMenu(label,tag,hgroup) Case GADGET_NODE Throw "chunks" Case GADGET_CANVAS g=bbCreatePanel(x,y,w,h,hgroup,style|4) End Select gadget=TWin32Gadget.Create(gadgetclass,g,wgroup) If gadgetclass=GADGET_MENUITEM bb_SetMenuSource tag,gadget gadget.name=name Return gadgetlines 514 to 526
from
Method SetHotKey(key,modifier) Local ev:TEvent If hotkey RemoveHotKey hotkey Select class Case GADGET_MENUITEM bbSetMenuHotKey handle,key,modifier 'decorates name only ev=CreateEvent( EVENT_MENUACTION,Null,bbMenuTag(handle) ) hotkey=SetHotKeyEvent(key,modifier,ev,findowner()) Default ev=CreateEvent( EVENT_GADGETACTION,Self ) hotkey=SetHotKeyEvent(key,modifier,ev,findowner()) End Select End Methodto
Method SetHotKey(key,modifier) Local ev:TEvent If hotkey RemoveHotKey hotkey Select class Case GADGET_MENUITEM bbSetMenuHotKey handle,key,modifier 'decorates name only ev=CreateEvent( EVENT_MENUACTION,Self,bb_GetMenuTag(bbMenuTag(handle)) ) hotkey=SetHotKeyEvent(key,modifier,ev,findowner()) Default ev=CreateEvent( EVENT_GADGETACTION,Self ) hotkey=SetHotKeyEvent(key,modifier,ev,findowner()) End Select End Methodlines 528 to 540
from
Method Free() Local kid:TGadget If parent parent.kids.Remove Self parent=Null EndIf For kid=EachIn kids kid.Free Nextto
Method Free() Local kid:TGadget If class=GADGET_MENUITEM and handle bb_UnsetMenuTag bbMenuTag(handle) If parent parent.kids.Remove Self parent=Null EndIf For kid=EachIn kids kid.Free Nextlines 958 to 984
from
Function PostWin32GuiEvent( id,handle,data,mods,x,y,extra:Object ) 'nodebug Local source:TWin32Gadget=TWin32GUIDriver.GadgetFromHandle( handle ) ' update local dimensions If id=EVENT_WINDOWSIZE And source source.UpdateSize If id=EVENT_WINDOWMOVE And source source.UpdatePos ' fill in extra field for treeview and list gadget events If id=EVENT_MENUACTION extra=TWin32Gadget.popupextra If source Select source.class Case GADGET_TREEVIEW ' data=TWin32GUIDriver.GadgetFromHandle( data ) 'integer handle extra=TWin32GUIDriver.GadgetFromHandle( data ) 'actual TGadget Case GADGET_LISTBOX,GADGET_TABBER,GADGET_TOOLBAR,GADGET_COMBOBOX If data>-1 extra=source.ItemExtra(data) Local flags=source.ItemFlags(data) If flags&GADGETITEM_TOGGLE source.SelectItem(data,2) EndIf End Select EndIf ' post it to MaxGui PostGuiEvent id,source,data,mods,x,y,extra End Functionto
Function PostWin32GuiEvent( id,handle,data,mods,x,y,extra:Object ) 'nodebug Local source:TWin32Gadget=TWin32GUIDriver.GadgetFromHandle( handle ),evsource:TGadget ' update local dimensions If id=EVENT_WINDOWSIZE And source source.UpdateSize If id=EVENT_WINDOWMOVE And source source.UpdatePos ' fill in extra field for treeview and list gadget events If id=EVENT_MENUACTION evsource=TGadget(extra) extra=TWin32Gadget.popupextra EndIf If source Select source.class Case GADGET_TREEVIEW ' data=TWin32GUIDriver.GadgetFromHandle( data ) 'integer handle extra=TWin32GUIDriver.GadgetFromHandle( data ) 'actual TGadget Case GADGET_LISTBOX,GADGET_TABBER,GADGET_TOOLBAR,GADGET_COMBOBOX If data>-1 extra=source.ItemExtra(data) Local flags=source.ItemFlags(data) If flags&GADGETITEM_TOGGLE source.SelectItem(data,2) EndIf End Select EndIf ' post it to MaxGui If Not evsource evsource=source PostGuiEvent id,evsource,data,mods,x,y,extra End Function Global bb_MenuTags:Tbb_MenuTag Global bb_StartSearch Type Tbb_MenuTag Field Prev:Tbb_MenuTag Field Succ:Tbb_MenuTag Field GUITag Field UserTag Field Source:Object EndType Function bb_SetMenuTag ( UserTag ) While bb__Find(bb_StartSearch) bb_StartSearch:+1 Wend Local tag:Tbb_MenuTag=New Tbb_MenuTag tag.Succ=bb_MenuTags tag.GUITag=bb_StartSearch bb_StartSearch:+1 bb_StartSearch:&$0FFF tag.UserTag=UserTag If bb_MenuTags bb_MenuTags.Prev=tag bb_MenuTags=tag Return tag.GUITag EndFunction Function bb_SetMenuSource ( GUITag , Source:Object ) bb__Find(GUITag).Source=Source EndFunction Function bb_GetMenuTag ( GUITag ) Return bb__Find(GUITag).UserTag EndFunction Function bb_GetMenuSource:Object ( GUITag ) Return bb__Find(GUITag).Source EndFunction Function bb_UnsetMenuTag ( GUITag ) Local tag:Tbb_MenuTag=bb__Find(GUITag) If tag=bb_MenuTags bb_MenuTags=tag.Succ If tag.Succ tag.Succ.Prev=tag.Prev If tag.Prev tag.Prev.Succ=tag.Succ EndFunction Function bb__Find:Tbb_MenuTag ( GUITag ) Local tag:Tbb_MenuTag = bb_MenuTags While tag If tag.GUITag=GUITag Return tag tag=tag.Succ Wend EndFunctionI tested and it seems to work with these changes. However they'll get overwritten as soon as you syncmod the next time.
If this really behaves different on Mac/Win32 I'd say it's a bug.
@BRL, if you want to, you can include these changes in your offical modules on the modserver. I think this could help many developers to write their code easier.
Seconded - I never really understood why menus had to be operated using CONSTANTS as oppose to EventSource()...
Thanks for seconding - how could you create dynamic menus if you have to use constant integer values to identify your menus? This is indeed a missing feature on Windows.
@Brucey: Can you confirm that this behaviour is different on Mac and Windows? If so, I'd like to post this as bug report.
@Brucey: Can you confirm that this behaviour is different on Mac and Windows? If so, I'd like to post this as bug report.
On Mac the following code generates the MenuAction event :
Note the second field, which is the "source".
Which turned out to be rather useful - until I tried running it on Windows :-)
PostGuiEvent( BBEVENT_MENUACTION,sender,[sender tag],0,0,0,0 );
Note the second field, which is the "source".
Which turned out to be rather useful - until I tried running it on Windows :-)