From: Glenn L. <pe...@ne...> - 2004-01-02 18:07:46
|
On approximately 1/2/2004 9:38 AM, came the following characters from the keyboard of Johan Lindstrom: > At 18:06 2004-01-02, Glenn Linderman wrote: > >> In the above description you mention "right click-menu" But none of >> your example code attempts to capture the "_RightClick" event. So I'm >> not quite sure what you are asking. > > > The button was just the easiest way to get a minimal test case, since > the menu itself came out fine I didn't figure that would make any > difference. Modulo the confusion :) > > With your fix it works fine. Thanks! > > >>> Any reports of other applications that broke popup-menus? Any ideas >>> from the developers? >> >> >> There are two problems with defining locally scoped menus: one, is >> that they are gone before they can be used (not sure what 558 did >> differently to make that work), > > > This is kind of weird. I didn't go for the global var, in my test case I > stuck it in a hash to keep it in scope. But IIRC, that's exactly what > the %Win32::GUI::Menus hash is for. Huh? I think %Menus is used for lookup of commands when they arrive, and are not part of the menu of the current window. Whether it has other purposes or effects, I haven't yet figured out. > Another thing I just tried was this: > > > $winMain->TrackPopupMenu($mnuPopup->{popup}, > $winMain->Left + $btnMenu->Left + 20, > $winMain->Top + $btnMenu->Top + 20, > ); > print "TRACKED\n"; > Win32::GUI::DoEvents(); > print "Done events\n"; > > > This prints: > TRACKED > align left selected > Done events > > which means the WM_COMMAND is put in the message queue and then I force > it to be handled before the menu goes out of scope. Without the > DoEvents(), the menu goes out of scope, and the WM_COMMAND is processed > in the next message loop with no menu to be found. > > Well, at least it's interesting :) Yep. That is interesting. >> and the second is that it consumes $MenuIdCounter values which never >> get returned. Now that is a "big" number (for some definitions of >> "big"), but even so, if a program repeatedly defines and destroys >> menus, and loops on that long enough, it will "run out" and the >> counter will "overflow" and "wrap around", and get back to reusing >> numbers that may be in use for less dynamic menus, and things could >> get confused. I think the effect would be that the less dynamic menus >> would get > > > I think, with the code not-so-fresh in my mind, that if it really wraps, > the Win32::GUI::Menus hash will be overwritten with the new menu > handles, so that will work out fine. Not that it will wrap (isn't it a > long?) Yes it is really big, so it shouldn't wrap soon. Yes the Menus hash would be overwritten, but any static hashes created early in the program, and expected to still function at the end, would be wiped out along the way. >> By putting your menu definition inside another _Click routine (and I >> didn't fix that, above, but moving it all up where the $mnuPopup >> variable is now declared would do so) you are effectively dynamically >> defining the menu just before popping it up. Now that the variable is >> more global, the > > > Which I have to do, since they are truly context sensitive. And I'm > willing to live with the minor resource waste. I haven't figured out how much resource is wasted, hopefully it is minor. But because it is presently unkonwn to me, I'd really rather not take the chance that it causes problems for someone on a memory constrained machine... or someone that leaves the program running for days or weeks... those sorts of problems are extremely hard to figure out when and if they happen. Dynamic menus can be handled via Change. One can keep a cache of menus of various ordinal size, and choose the one of the appropriate size, and change the content dynamically. One could even dynamically eval the _Click methods to do the right thing, dynamically. This would keep the counter from wrapping, and any other resource leakage would be minimized. It would require replacing Win32::GUI::Menu->new calls with something that does the above, of course, which would be a little complex to write at first, but probably as easy to use in the code as Win32::GUI::Menu->new. For your application, that may be overkill. For my applications, the menus aren't all that dynamic, but for one of them I had the choice of either dynamically recreating the same static menu over and over again (which would have made some other things easier, perhaps), or working a little harder to make them static and reuse them. Because of the leakage issue, and because my program would be making heavy use of the menus, and because the menus have many entries, it seemed possible that the leakage could be a problem, so I worked a little harder to reuse them. -- Glenn -- http://nevcal.com/ =========================== The best part about procrastination is that you are never bored, because you have all kinds of things that you should be doing. |