获取特定任务栏按钮的上下文菜单文本

发布于 2024-11-16 18:24:08 字数 221 浏览 2 评论 0 原文

我有一些代码,使用 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

傲世九天 2024-11-23 18:24:09

这并不完全清楚......上下文菜单没有文本,因此 - 它们有菜单项,每个菜单项都有文本。 “上下文菜单文本”是指任务栏按钮的弹出/上下文菜单中菜单项的文本吗?例如下面截图中的“恢复”、“最小化”等?

任务栏按钮及其弹出菜单

如果是这样,我怀疑您的处理方式错误:

  1. 此菜单不属于按钮,而是任务栏按钮所代表的窗口的系统菜单。如果按钮有上下文菜单,则这可能适用于一组窗口的分组,而不是一个特定的窗口(甚至不是一个进程的窗口)。
  2. 根据窗口的上下文菜单进行判断对我来说听起来像是一种狡猾的方法,尤其是基于文本,因为它会根据您的用户所在的世界位置而变化。应用程序还可以更改此菜单的内容,因此不能保证它会包含您期望的内容。最好检查窗口样式,是否最小化等,以找出也影响菜单内容的信息。

我将根据问题中您的需求来回答这个问题,而不是您直接提出的问题,因为(a)这是不可能的,(b)我认为您正在尝试做其他事情。 (作为一般准则,在一个问题中最好说明为什么你要尝试做某事 - 甚至可能会问这个问题,即“我如何实现 X” - 以防有比你现在的方法更好的方法这里,X可能是“查找有关此窗口的信息”而不是“获取上下文菜单的文本”,因为这可能只是访问 X 的一种可能方法。)我也认为提取数据来自像资源管理器(任务栏是资源管理器窗口)这样的第三方应用程序的内部结构很脆弱,并且在未来版本的 Windows 中容易损坏。

系统菜单或窗口信息(无论哪一个)都属于应用程序窗口。除非任务栏按钮被分组(然后是子项),否则一个任务栏按钮对应于系统中的一个特定窗口。所以你要做的就是找到这些窗口。您可以通过以下方式执行此操作:

这些窗口中的每一个都是应该出现在任务栏、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?

Taskbar button and its popup menu

If so, I suspect you're going about this the wrong way:

  1. 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.)
  2. 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:

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文