Click to See Complete Forum and Search --> : Menu


Raseena K
June 25th, 2001, 11:28 PM
How can I trap the Event generated by a menu, which is created at runtime in Visual Basic 6.

I have created a menu at runtime using the Load function for the Menu Control Array element. This menu is now attached to a different Form using the AppendMenu API Function . How can I trap the event generated by this menu in the new Form?

Code used to populate and attach the menu to the new form is given below

HndlMenu = GetMenu(Forms(0).hwnd)
frmdiaTime.mnuMainPopupMenu.Visible = true
HndlMenu = GetSubMenu(HndlMenu, 8)
for intCount = 1 to GetMenuItemCount(HndlMenu) - 1
Unload Forms(0).mnuPopupReports(intCount)
next
intCount = 0
'Populate the reports menu of the MDI Form
While Not rsReports.EOF
If intCount > 0 then Load Forms(0).mnuPopupReports(intCount)
Forms(0).mnuPopupReports(intCount).Caption = rsReports!Text
Forms(0).mnuPopupReports(intCount).Tag = rsReports!ReportID
Forms(0).mnuPopupReports(intCount).Visible = true
intCount = intCount + 1
rsReports.MoveNext
Wend

'get the handle to the MdiForm's main menu
HndlMenu = GetMenu(Forms(0).hwnd)
'get the handle to the reports submenu (popup)
HndlPopup = GetSubMenu(HndlMenu, 8)

'get the menu container forms' main menu bar

HndlMenu = GetMenu(frmMenuContainer.hwnd)
'get the first submenu
HndlSubMenu = GetSubMenu(HndlMenu, 0)
'Attach the Report popup menu
returnvalue = InsertMenu(HndlSubMenu, 0, MF_POPUP, HndlPopup, "Reports")
'Redraw the menu bar
SetMenu frmMenuContainer.hwnd, HndlMenu



How can I trap the event of the new appended menu in the form frmMenuContainer

Clearcode
June 26th, 2001, 03:17 AM
You will need to subclass the container form and intercept any WM_COMMAND messages. This will tell you when a menu is clicked.

Then you need to get the menu ID from the lParam of that message and convert it to find out what actual menu was pressed.

HTH,
D.

-------------------------------------------------
Ex. Datis: Duncan Jones
Merrion Computing Ltd
http://www.merrioncomputing.com

Raseena K
June 27th, 2001, 11:37 PM
How can I subclass the form.
I've heard taht subclassing with AddressOf operator is dangerous. And I don't have the licence to use dwsbc.ocx control.
How can I create an OCX control which can be used for subclassing.

Clearcode
June 28th, 2001, 02:49 AM
Subclassing with the AddressOf is not as dangerous as it is made out to be so long as you are more disciplined than usual in VB.
Firstly you must have Option Explicit specified in the bas file that contains your subclassing proc.
Secondly you should not breakpoint any part of the subclassing loop if you can avoid it. This means that you will need to be more reliant on the immediates window and Debug.Print for debugging.
There is a fairly comprehensive subclassing example on my site called EventVb.OCX - I'd recommend you download the source code for this from the zip file in http://www.merrioncomputing.com/Download/index.htm - best of all, it has no license requirement.

Hope this helps,
Duncan

-------------------------------------------------
Ex. Datis: Duncan Jones
Merrion Computing Ltd
http://www.merrioncomputing.com

Raseena K
June 28th, 2001, 05:02 AM
Could you please tell me more about the WindowMessageFired event of the VBEventWindow control

Clearcode
June 28th, 2001, 05:46 AM
The WindowMessageFired event is triggered whenever the window that you have subclassed receives a window message (other than those that I have provided their own event for).

The parameters are:
msg As WindowMessages - This tells you which message was received. WindowMessages is an enumerated type which contains all the standard window messages.

ByVal wParam As Long - This is the wParam that was sent along with the message. The content and meaning of this value depends on the message. See the Micorosoft MSDN documentation at http://msdn.microsoft.com for the message you are interested in.

ByVal lParam As Long - This is the lParam that was sent along with the message. The content and meaning of this value depends on the message. See the Micorosoft MSDN documentation at http://msdn.microsoft.com for the message you are interested in.

Cancel As Boolean - Setting this value to TRUE tells the control that you do not want this message to be passed on to the subclassed window for processing.

ProcRet As Long - For some windows messages you can alter the behaviour of a window by altering what it returns. Top override the default return value you change this variable.

To tell the control which window to subclass you set it's hWnd property. Most typically you would want it to subclass the form it was placed on so in the form load event you start the subclasser thus:

private Sub Form_Load()

me.VBEventWindow1.hWnd = me.hWnd

End Sub




Note that API calls do not generate standard VB run time errors if they fail. For this reason I have added another event called ApiError to the VBEventWindow control that is triggered if an error occurs in the API side. You should probably put code in that event to notify the user if an error occurs.

As you wish to process the WM_COMMAND message in order to know that a menu was pressed, your event code might look like:

private Sub VBEventWindow1_WindowMessageFired(byval msg as WindowMessages, byval wParam as Long, byval lParam as Long, Cancel as Boolean, ProcRet as Long)

If msg = WM_COMMAND then
'\\ A menu or command button was fired...
'\\ See MSDN help on WM_COMMAND on how to determine which one...
End If

End Sub




Hope that helps a bit,
Duncan

-------------------------------------------------
Ex. Datis: Duncan Jones
Merrion Computing Ltd
http://www.merrioncomputing.com

fValli
June 28th, 2001, 08:34 PM
The easiest way is using a call to the TrackPopupMenu() API insted of using PopupMenu.
It will retun the menu-item identifier of the item that the user selected.
For more info take a look to the Plataform SDK TrackPopupMenu() API reference.


private Const TPM_RETURNCMD = &H100

private Declare Function TrackPopupMenu _
Lib "user32" (byval hMenu as Long, byval wFlags as Long, _
byval x as Long, byval y as Long, byval nReserved as Long, _
byval hwnd as Long, lprc as Long) as Long

...
'Some code extra code to get the hMenu and
'the mouse position and assign it to x, y



Select Case TrackPopupMenu(hSubMenu, TPM_RETURNCMD, x, y, 0, hwnd, 0)
Case idItem1
...
Case idItemN
...
End Select


...








I hope this helps

Fabian

John G Duffy
June 29th, 2001, 08:25 AM
There are more than a few examples of how to do this on
Http://www.Planet-Source-Code.com/vb
Search on "Dynamic Menu Control" or "Menu Popup" (Without the quotes of course) to view and download the samples. Both work and I am sure there are more working samples out there.

John G

Raseena K
July 1st, 2001, 11:58 PM
Thanxs for the reply,
I'd already tried this menthod. It has a problem, If I am attaching a menuItem to an already existing SubMenu, it does not fire the event handlers of the other menuitems which are added at design time. For every menu the function will just return the MenuItemID. I want a method by which I can handle the menu events for those loaded at runtime as well as fire the event handlers for the design time menuItems.
Regards
Raseena

Raseena K
July 2nd, 2001, 03:42 AM
Thank you so much for your great help. My problem is solved now

Raseena K
July 8th, 2001, 11:57 PM
Hai,
I've placed the VBEventWindow Control to the Mdi form of the application. When I am subclassing the MDI Form it is working fine. But when I am subclassing other forms using the same control some times it gives an error. Message : Object with block variable not set at the statement VBEventWindow.ParenForm = frm.hWnd . This statement is placed in the standard module of the application. And the control is not able to recognize the events in this case.
Regards
Raseena

Clearcode
July 9th, 2001, 02:38 AM
Unfortunately in VB Versions 5 and 6, only a form or a class module may have a variable declared as WithEvents.
It is probably the case that your module needs to know which form or class module the VBEventWindow control is on therefore if it was on the form MDIForm1 then you need your code to read:

MDIForm1.VBEventWindow1.ParentForm = frm.hWnd




Note that each control can only subclass one window at a time so setting the ParentForm memeber from one form's hWnd to another stops subclassing the former. However you can have multiple instances of the control active at one time if you need multiple forms subclassed at the same time.

Hope this helps,
Duncan

-------------------------------------------------
Ex. Datis: Duncan Jones
Merrion Computing Ltd
http://www.merrioncomputing.com