06-01-2002, 06:25 PM
i've used the hand's ocde on owner drawn menus, and i was just wondering if there is a way to detect if the mouse is over a top level menu.
i need this so i can create a roll over effect for top level menus, just like those in the submenus...
06-01-2002, 07:10 PM
You can trap the 'WM_MOUSEMOVE' message of the menu, and
compare the screen-coordinates of the mouse with the RECT
coordinates of the top-level menu.
andPrivate Type POINTAPI
x As Long
y As Long
End TypeThose are all you'll need to add.
06-01-2002, 07:53 PM
i tried your solution but it didn't work it just made my program crash, i even tried other variations of GetCurrentPos and so on and it still made it crash.
i also tried using the different state constants : ODS_FOCUS, ODS_GRAYED and compare it to menu state and it still didn't work.
06-02-2002, 12:03 AM
I don't have your solution, but I can tell you that when you are trying to debug or have some code that don't work within a project that has subclassing(ODmenus), it will kill/crash the IDE. I would suggest commenting out the 3 or so lines for the time being in the form load event that has to deal with starting ODMenues, then debugging the code that VolteFace has suggested. This will then let your errors through with out crashing your program :)
06-04-2002, 07:48 AM
i tried your solution of getting the screen coordinates but i could'nt concieve a way of getting them because a menu item doesn't have such properties needed, or alteast i didn't see any.
anyway i was just wondering what messages does the top level menu item pass when the mouse is over them? so i can just set the effects from there.
06-04-2002, 08:25 AM
My recommendation is you pull out SPY++ and start checking it out. That's how I do most of my subclassing work.
I have not worked on this issue yet, but I do have it on my to-do list. The other thing I don't understand is what you mean by "Roll over" effect.
If you read the OD Menu tutorial (http://www.elitevb.com/content.asp?id=9) on EliteVB, you would know that windows sends two messages to an ownerdrawn menu of importance - WM_DRAWITEM and WM_MEASUREITEM. The WM_DRAWITEM message passes a pointer to a structure which has all the information you could possibly need about the menu item, including whether it is selected or not. The way that menus work, if it is selected then the mouse is over it. You can draw the top level menu differently if the ODS_SELECTED bit is set.
Likewise, if the item had the ODS_SELECTED bit, but doesn't have it afterwards, you know that the mouse left the menu's area. Either way it doesn't much matter. You just handle the drawing based on the ODS_SELECTED style bit.
Top level menus only function well as ownerdrawn on individual forms. As soon as you try to do top level OD menus in an MDI environment, the whole game changes... and my module will not be able to help you there. All kinds of other messages start getting thrown to handle menu negotiation and MDIChild status.
06-04-2002, 10:09 AM
the hand : what i meant by roll over effect is to make the top level menu change state when the mouse is over it.
the ODS_SELECTED is only triggered when a top level menu is clicked, the rollover effect using ODS_SELECTED only works with submenus.
now i'm trying to find a way to know if the mouse is over a top level menu, so i can isolate that toplevel menu and change its appearance when the mouse hovers on it
06-04-2002, 10:37 AM
As in when the mouse is over it, but the submenus are not displayed yet. OK... I understand now. Sorry for being dense. I will see if I can come up with something.
06-04-2002, 11:51 AM
Just an update.
I think I have a gameplan to do what you want. I'm working on the code right now, but if you want to try to do it yourself, here's what I had in mind:
Subclass and intercept the WM_NCHITTEST message Check to see if the hit type is a menu If its a menu, use the MenuItemFromPoint() API function to get the menu item Set the style as "highlighted" with the HiliteMenuItem() API function
Both the MenuItemFromPoint and HiliteMenuItem declarations I got from MSDN and translated into VB. There may even be some sites out there that already have them as VB.
Anyways, if you can hold on until I finish my example, I'll post it tonight. Otherwise, good luck!
06-04-2002, 02:05 PM
Actually, it's a lot simpler than that.
First, add the following declare to the list:Private Const ODS_HOTLIGHT = &H40 'whether a toplevel item is hovered overThen, go to the bottom of the module, where the
drawMnuBitmap_MenuBarMenu: label is.
Right above this: If (aDIS.itemState And ODS_SELECTED) = ODS_SELECTED Then
' If its a selected item, paint the background with the systems 'Highlighted' color
aBrush = CreateSolidBrush(GetSysColor(13))
FillRect aDIS.hdc, aDIS.rcItem, aBrush
' Also make the text print out in the highlighted text color
SetTextColor aDIS.hdc, GetSysColor(14)Add this: If (aDIS.itemState And ODS_HOTLIGHT) = ODS_HOTLIGHT Then
' If the menu-item is hovered over, then pop it up
DrawEdge aDIS.hdc, aDIS.rcItem, BDR_RAISEDINNER, BF_RECTand make the next line an ElseIf. :p It works for me, and to change
the hover effect, just change the DrawEdge to whatever you need.
06-04-2002, 05:47 PM
Hmmm. Very odd volte... I couldn't get your code to work on XP with my project. I think I must have done something wrong... is there also a hottracking style you need to set in the MakeTopMenusOD subroutine?
Anyways, I figured this example project might be worthwhile anyways because it doesn't require a full OD implementation. You can use this approach with normal menus as well.
I ended up canning the "MenuItemFromPoint" API declaration. It is declared wrong everywhere, including in the API Viewer, with "ByVal ptPoint As POINTAPI" as one of the arguments. VB does not like UDTs passed as ByVal... removing the ByVal resulted in a "Bad Calling Convention" error, and trying to worm it into a long pointer was fruitless as well. So I wrote my own **** function using GetMenuItemRect.
Anyhoo... here it is, for those interested. I'll write a little excerpt and post it on EliteVB sometime soon as well.
06-04-2002, 05:51 PM
Nope, the only things involved are in my post.. I am using the
version off of EliteVB; is that the one you're using? I can post
the project if you'd like, with your permission.
06-04-2002, 06:06 PM
Nah. Don't worry about it.
I'm going to try it with the version from EliteVB.
06-04-2002, 06:18 PM
Oh yeah... and here's another weird thing. XP automatically does the hottracking with top level menus, while my NT system does not. I think the implementation I posted might be necessary only for older operating systems.
06-07-2002, 08:24 AM
thanks for the help, the hand, volte... i wasn't able to reply coz my ISP had to do some re-cabling in our area.
anyway i'm gonna try both techniques. although i use win2k, hopefully what volte suggested would work... as well as the hand.
by the way i also tried using OD Menus on an MDI form, and the problem i had is that when you use a window list, the OD menus formatting doesn't take effect on submenus generated by the windowlist... hhmm... that's what i'm also trying to figure out.
anyway thanks again:D
06-07-2002, 09:34 AM
I will be posting the module which will take care of your MDI problems as well as add bitmaps to toolbar buttonmenus :) (hopefully this weekend).
It won't let you change top level menus in an MDI form... that is a nightmare with all of the WM_MDI messages that are flying around... YET. But I'm working on it.
06-07-2002, 10:12 AM
on other things regarning menus, how do you specify an action for an appended sub menu. just like that of EVBFC where when you click on the taskbar there are two appended menus.
You must add the menus using API, give them a unique ID, and then subclass for the WM_SYSCOMMAND or WM_COMMAND messages. Based on the ID passed in the wParam argument, you invoke whatever procedure you want, or invoke the default process.
06-07-2002, 10:21 AM
thanks for the info...
:D i accidentally deleted my previous post... oppssyy
06-07-2002, 10:26 AM
thanks for the info...
:D i accidentally deleted my previous post... oppssyy
06-08-2002, 11:24 AM
I posted the version that works with MDI forms and toolbars on EliteVB.
Find it here: http://www.elitevb.com/source/odmenus2.zip
06-08-2002, 11:53 AM
thanks for the update i'll go check it out...:D
06-08-2002, 03:59 PM
the hand : just a quick question, yet again, i've analyzed your OD menus code from the 1 and 2nd version. and i was just wondering how do you set OD menus for window lists? in the first ver. of OD menus it didn't work however on the 2nd ver. it did. just wondering what did you change/add in order for that to work with regards to the window list.
but anyway, great code on ver 2 of OD menus, i learned some neat tricks from your code, thanks a lot man!