我有一些代码,使用 User32.SendMessage 和 TB_GETBUTTON 消息从 Windows 任务栏中获取任务栏按钮及其文本,以检索 TBBUTTON 结构(通过 C# P/Invokes 的 Win32 API)。但我试图弄清楚如何在获得按钮的句柄后获取关联的上下文菜单文本。那里有一些我想检索的特定应用程序的状态信息。按钮文本让我得到了一些,但我需要上下文菜单文本来完成它。
有什么想法吗?
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?
发布评论
评论(1)
这并不完全清楚......上下文菜单没有文本,因此 - 它们有菜单项,每个菜单项都有文本。 “上下文菜单文本”是指任务栏按钮的弹出/上下文菜单中菜单项的文本吗?例如下面截图中的“恢复”、“最小化”等?
如果是这样,我怀疑您的处理方式错误:
我将根据问题中您的需求来回答这个问题,而不是您直接提出的问题,因为(a)这是不可能的,(b)我认为您正在尝试做其他事情。 (作为一般准则,在一个问题中最好说明为什么你要尝试做某事 - 甚至可能会问这个问题,即“我如何实现 X” - 以防有比你现在的方法更好的方法这里,X可能是“查找有关此窗口的信息”而不是“获取上下文菜单的文本”,因为这可能只是访问 X 的一种可能方法。)我也认为提取数据来自像资源管理器(任务栏是资源管理器窗口)这样的第三方应用程序的内部结构很脆弱,并且在未来版本的 Windows 中容易损坏。
系统菜单或窗口信息(无论哪一个)都属于应用程序窗口。除非任务栏按钮被分组(然后是子项),否则一个任务栏按钮对应于系统中的一个特定窗口。所以你要做的就是找到这些窗口。您可以通过以下方式执行此操作:
EnumWindows
函数GetWindowLong
使用GWL_EXSTYLE
来查看WS_EX_APPWINDOW
位已设置< /a>这些窗口中的每一个都是应该出现在任务栏、Alt-Tab 对话框等上的窗口。
您说您正在获取任务栏按钮的文本 - 这可能是窗口的窗口标题,并且
GetWindowText
是获取属于另一个进程的窗口标题的规范(阅读:可能更可靠)方法。如果您确实想要弹出菜单,则:
GetSystemMenu
检索窗口系统菜单的句柄。应用程序可以对此进行自定义,因此,如果您的应用程序正在执行此操作(这就是您想要弹出菜单的原因),请确保将false
传递给bRevert
参数您可以使用
GetMenuItemCount
并为每个调用GetMenuItemInfo
获取有关每个菜单项的信息。将true
传递给fByPosition
参数以指示您正在按位置访问菜单(因为您知道计数,所以您将获得项目 0、1、2...计数-1)。MENUITEMINFO
结构,(我想,我从来没有编写过这个代码,所以我没有测试过)将通过以下方式告诉您与项目关联的文本dwTypeData
字段“如果在 fMask 成员中设置了 MIIM_STRING 标志”。如果您确实想要有关窗口状态的信息,可以使用
IsIconic
查看是否最小化,GetWindowLong
再次获取其他信息等。我建议你问另一个关于如何获取有关窗口的特定信息以获取详细信息的问题。希望有帮助!
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:
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:
EnumWindows
functionGetWindowLong
withGWL_EXSTYLE
to see if theWS_EX_APPWINDOW
bit is setEach 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:
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 passfalse
to thebRevert
parameterYou can then get the number of menu items using
GetMenuItemCount
and for each one callGetMenuItemInfo
to get info about each menu item. Passtrue
to thefByPosition
parameter to indicate you're accessing the menus by position (since you know the count, you're getting item 0, 1, 2... count-1).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 thedwTypeData
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!