PDA

Click to See Complete Forum and Search --> : Popup Menus


MountainDew
Nov 16th, 2001, 12:35 PM
I have a program that places an Icon in the System Tray. When you click on it, it displays a popup menu. The problem I am having is that if you click outside of the popup menu it stays open. Currently, I am using the trackpopupmenu api call. Is there a way to make the menu disappear if you click anywhere outside of the menu? Also, does anyone know how to add icons to the menu?

basicallyvisual
Nov 16th, 2001, 03:51 PM
Attached is a zip file containing 2 sets of code. One is a good example of using a systray icon without the subclassing from Steve McMahon of www.vbaccelerator.com.

The other is an old piece of code that will read your IE Favorites menu and display it with IE icons. This example involves subclassing. I haven't looked at this code for a while so there are no guarantees that it's 'bugless'. An easier way to use icons in VB menus is from, again, VBAccelerator and can be found on the Controls page of the Code section on that site. This uses basically the same method as the menu sample but adds a whole bunch of neat tricks. I recommend you check it out.

If you have any questions about all of this, just let me know.

MountainDew
Nov 19th, 2001, 02:25 PM
I downloaded that code you sent and it seems to do what I want, but there is one problem. When I run the code for the VB editor and stop the execution of the code with the Stop button, it crashes Visual Basic with a Invalid Page Fault in MSVBVM60.DLL. I does this on both my Home PC and work PC. I've pinpointed it down to one line of code. If I comment it out, it won't crash, but unfortunately then the code doesn't do anything. Any suggestions? (I am using SP5)

With cIM
.Attach mfrmMDITest.hwnd <---- THIS IS THE LINE
.ImageList = ilsIcons
....

basicallyvisual
Nov 20th, 2001, 02:10 PM
The most likely reason for this occurring is that the cIconMenu class is subclassing mfrmMDITest. The Attach() sub of cIconMenu calls Steve's Subtimer component (SSubTmr6.dll) that is referenced in that class - the 'Implements ISubclass' line in the Declares. The Subtimer component is what is responsible for subclassing the window (hWnd) that is passed to it. It basically 'takes control' of the window from VB.

As is noted in the documentation for SSubTmr6.dll, you have to return control of the window to VB before your app stops running or you could end up with a nasty crash - as you've seen. The way to do this is to make sure that you close your app down with either its Exit procedure or the Close button its system menu. This way, the Form is unloaded, the class is terminated, the Detach sub of cIconMenu is called and VB regains its control of mfrmMDITest so it can shut itself down properly.

In this particular case, the Detach sub is called when cIconMenu receives the WM_DESTROY msg in the ISubclass_WindowProc() function. Sometimes you will see the subtimer's DetachMessage() function called in Form_QueryUnload() and sometimes in Class_Terminate(). Regardless, control has to be returned to VB before you stop your app.

This is one of the problems when debugging a subclassed window. Steve's control makes it a lot easier to do this. The menu sample that I sent will crash a WHOLE lot more when being debugged. If you need to stop while debugging and can't (or don't want to) run the code to completion, you can type cIM.Detach in the code while stopped at your breakpoint. If you then step over this statement, it might properly return control to VB and you might be able to use the IDE stop button without crashing VB. It's worth a try.

The whole subclassing thing is discussed in greater detail at Steve's site in the Code\Code Libraries\Subclassing Without the Crashes sections. If this info wasn't particularly helpful, let me know and I'll try to explain it a little better.