Is there a way to determine if a menu is dropped down in the win32 api? Something that could be used like so:
HMENU hMenu = GetMenu(hWnd);
HMENU hSubMenu = GetSubMenu(hMenu);
// Is hSubMenu dropped down?
I'm not sure of a way to operate specifically on HMENUs to see if the menu is showing (and a quick scan of the platform SDK docs didn't turn up anything specific), but you might be able to use the GetMenuItemInfo function to get a MENUITEMINFO struct relating to the menu item which owns the dropdown. If the fState member has MFS_HILITE set, that should indicate that the item is selected and the sub menu is most likely open. Correctness isn't guaranteed on my part but it's worth experimenting with.
Another possible option would be using FindWindow with the class "#32768" to find the hWnd of whatever menus may be open, and sending the MN_GETHMENU message to whichever windows you find to retrieve the HMENU and compare it to the expected value from GetSubMenu.
Related
I've created a combobox manually in my main window using CreateWindow(). Because of this it has no ID associated with it only the handle returned by CreateWindow(). When the user makes a selection from the combobox list and the combobox throws a message, how do I handle that in the WinProc WM_COMMAND code since there is no ID associated with the combobox? As far as I can tell, I must know the combobox ID to handle the message. This is especially problematic once I have more than one combobox in the main window. Surely there is something I am missing and there is a simple answer.
Okay. So what Igor Tandetnik stated is the answer.
It does have an ID - whatever you passed for hMenu parameter of CreateWindow...
This is also discussed in the following link.
What is winapi HMENU and how do i use it?
From the above link:
HMENU is a handle to a menu, e.g. as created by LoadMenu (which creates a menu from a specification in a resource).
But, the CreateWindow function re-uses the same argument for two different purposes. With a top-level window it's a menu handle, but with a child window it's the child window id, which should be in 16-bit integer range...
When creating a child window, just cast the id to HMENU.
I created menus and sub menus using the resource editor in visual studio. I now want to add items to one of the menus during run time. I was going to use the InsertMenuItem function but I don't know how to get access to the HMENU variable.
LoadMenu seems is what you need. Use it to load menu from resource editor, something like this:
HMENU yourMenu = LoadMenu( hInst, // variable where you stored your HINSTANCE
MAKEINTRESOURCE(IDM_MENU1) ); // replace IDM_MENU1 with the ID of your menu
Here are lots of useful examples, you may find very useful. Some of them address your issue, and some might be useful to you in the future. I would study the Example of Menu-Item Bitmaps section if I were you...
If you need a menu handle that is already assigned to a window then use GetMenu as member arx said. Something like this:
HMENU yourMenu = GetMenu(hWnd); // hWnd is the HWND of the window that owns your menu
Do not forget to destroy the menu when it is no longer needed ( usually upon window destruction ) with DestroyMenu.
This example might help you as well. This is very good introductory tutorial for Win32, I suggest you to read it ( just go to the home page and download both PDF and .zip file with code examples ).
As I have said before, your question is not entirely clear, so if you have further questions leave me a comment.
Hopefully this answer solved your problems. Best regards.
Ist it possible, given a HMENU, to detect if it's a popup or a drop down menu?
I want to create a (deep, modified) copy of an existing menu, and depending on this property I need to use either CreatePopupMenu or CreateMenu, respectively.
As Raymond Chen says here (with my emphasis):
CreateMenu creates a horizontal menu bar, suitable for attaching to a
top-level window. This is the sort of menu that says "File, Edit", and
so on. CreatePopupMenu creates a vertical popup menu, suitable for
use as a submenu of another menu (either a horizontal menu bar or
another popup menu) or as the root of a context menu.
If you get the two confused, you can get strange menu behavior.
Windows on rare occasions detects that you confused the two and
converts as appropriate, but I wouldn't count on Windows successfully
reading your mind.
There is no way to take a menu and ask it whether it is horizontal or
vertical. You just have to know.
Not clear with hmenu:
1) If you talk about hmenu, corresponding to the existing window (class #32768), it is sufficient to verify (via GetGUIThreadInfo) GUITHREADINFO.flags: availability GUI_INMENUMODE without GUI_POPUPMENUMODE without GUI_SYSTEMMENUMODE means that this menu - drop down.
2) If you talk about hmenu, existing in memory, we must find the root parent of this hmenu (btw, for menu there may be more than one, in contrast to the root parent window).
Then call TrackPopupMenu for found root parent and on WM_ENTERIDLE get hwnd appropriate window (class #32768) and call GetClientRect: if Rect =0, then the root parent = menubar (which can be created via LoadMenu(Indirect) or via CreateMenu), which means that the original hmenu - drop down (which can be created not only via CreatePopupMenu, but also via CreateMenu).
As for link to R.Chen. In reality the system always remembers exactly how was created hmenu in memory. But this mechanism (like so much else concerning the menu) is undocumented and Raymond obviously did not consider it necessary to uncover it...
I'm learning Win32 assembly. Have some question I search but not suitable result.
Anyone can explain for me What difference between control's window handle and controlID.
They have nothing in common. Every window has a handle, returned by CreateWindowEx(). Such a window can have a few extra properties attached, like a menu handle. The hMenu argument in CreateWindowEx(). If the window doesn't have a menu, a child window won't have one, then you can use that argument to pass an arbitrary other bit of data. It will be assigned to the GWLP_ID property (see GetWindowLongPtr). Also note the GWLP_USERDATA, an extra property that's entirely yours to use as you see fit.
Dialogs take advantage of this, a dialog template that you create in the resource editor gives you a way to number the child controls. With a helper function like GetDlgItem() to get the handle back for a control with a specific number. Which is pretty necessary for dialogs since it is Windows that create the child controls from the dialog template so you don't know the window handles for them yourself.
I've got some code that grabs the TaskBar buttons and their text from the windows TaskBar using User32.SendMessage with the TB_GETBUTTON message to retrieve a TBBUTTON structure (Win32 API via C# P/Invokes). But I'm trying to figure out how to then, once I have the handle to the button, grab the associated context menu text. There is some status information on there for a specific application that I would like to retrieve. The button text gets me some of it, but I need to the context menu text to complete it.
Any ideas?
This is not completely clear... Context menus don't have text, as such - they have menu items, each one of which will have text. By "context menu text", do you mean the text of the menu items in the taskbar button's popup/context menu? For example, "Restore", "Minimize" etc in the screenshot below?
If so, I suspect you're going about this the wrong way:
This menu doesn't belong to the button, but is the system menu of the window represented by the taskbar button. If the button has a context menu, this is probably for a grouped collection of windows, not one specific window (or even windows for one process.)
Making judgements based on the context menu of a window sounds like a dodgy approach to me, especially based on text since that will change depending on where in the world your user is located. Applications can also change the contents of this menu so there's no guarantee it will contain something you expect to be there. It would be better to check the window style, if it's minimized, etc, to find out the information that also affects the contents of the menu.
I'm going to answer this based on what your needs seem to be from the question, not what you've directly asked, since (a) it's not possible as asked and (b) I think you're trying to do something else. (As a general guideline, in a question it's good to state why you're trying to do something - and even maybe ask about that, ie 'how do I achieve X' - in case there's a better method than the one you're using. Here, X is probably 'find out information about this window' not 'get the text of the context menu', because that's probably only one possible method to get to X.) Also I think extracting data from the internals of a third-party application like Explorer (the taskbar is an Explorer window) is fragile and prone to break in future versions of Windows.
The system menu or window information (whichever one) belongs to application windows. Unless taskbar buttons are grouped (and then it's the subitems) one taskbar button corresponds to one specific window in the system. So what you want to do is find these windows. You do this by:
Using the EnumWindows function
Then for each window that is passed to the callback, checking the extended window style using GetWindowLong with GWL_EXSTYLE to see if the WS_EX_APPWINDOW bit is set
In addition, sometimes other windows are shown: these heuristics should help.
Each one of these windows is a window that should appear on the taskbar, Alt-Tab dialog, etc.
You say you're getting the text of the taskbar button - this is probably the window caption of the window, and GetWindowText is the canonical (read: probably a lot more reliable) way to get the caption of a window belonging to another process.
If you really want the popup menu, then:
Use GetSystemMenu to retrieve the handle for the system menu for the window. Applications can customise this, so if your app is doing this (and that's why you want the popup menu) ensure you pass false to the bRevert parameter
You can then get the number of menu items using GetMenuItemCount and for each one call GetMenuItemInfo to get info about each menu item. Pass true to the fByPosition parameter to indicate you're accessing the menus by position (since you know the count, you're getting item 0, 1, 2... count-1).
This fills a MENUITEMINFO structure, which (I think, I haven't ever had to code this so I haven't tested) will tell you the text associated with an item via the dwTypeData field "if the MIIM_STRING flag is set in the fMask member".
If you really want information about the window status, you can get this information using methods like IsIconic to see if it's minimized, GetWindowLong again to get other information, etc. I'd suggest you ask another SO question about how to get whatever specific information about a window for details.
Hope that helps!