首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ChangeWindowMessageFilterEx()返回错误代码5

ChangeWindowMessageFilterEx()返回错误代码5
EN

Stack Overflow用户
提问于 2019-09-12 13:24:45
回答 3查看 645关注 0票数 0

我想获取窗口中复选框的状态。

所以我使用了SendMessage(hwnd, BM_GETCHECK, NULL, NULL),但它总是返回0。为了了解原因,我使用了GetLastError(),它返回5。

Microsoft's documentation中,它表示“当一条消息被UIPI阻塞时,用GetLastError检索的最后一个错误被设置为5(拒绝访问)”。

因此,经过一些研究之后,我使用了ChangeWindowMessageFilterEx(hwnd, BM_GETCHECK, MSGFLT_ALLOW, 0)来绕过权限问题。

但是ChangeWindowMessageFilterEx()也给出了错误代码5并返回false。

但是,当我使用ChangeWindowMessageFilter()时,它返回true并给出错误代码0。但是SendMessage(hwnd, BM_GETCHECK, NULL, NULL)仍然给出了错误代码5。

方法1

代码语言:javascript
复制
status = ChangeWindowMessageFilterEx(hwnd, BM_GETCHECK, MSGFLT_ALLOW, 0); //returns false
error = ::GetLastError(); // gives error code 5
chk_state = SendMessage(hwnd, BM_GETCHECK, NULL, NULL);

方法2

代码语言:javascript
复制
status = ChangeWindowMessageFilter(BM_GETCHECK, MSGFLT_ADD); //returns true
error = ::GetLastError() // gives error code 0
chk_state = SendMessage(hwnd, BM_GETCHECK, NULL, NULL);
error = ::GetLastError(); // gives error code 5   

我在这里做错了什么?

EN

回答 3

Stack Overflow用户

发布于 2019-09-19 14:07:38

有两种方法可以获取此场景的复选框的状态。

  1. 以与目标程序相同或更高的完整性级别运行您的程序,例如,在提升模式下运行程序可能会有所帮助,因为大多数程序都是在高完整性下运行的。您还可以在清单中指定级别,如下所示(请参阅/MANIFESTUAC)

在程序的应用程序清单中使用特殊安全属性的UI自动化程序可以使用跨权限级别对SendMessage的/MANIFESTUAC:level=_level

  • Bypass UIPI限制。以下是UIAccess程序的应用程序清单条目的示例。

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" UIAccess="true" /> </requestedPrivileges> </security> </trustInfo>

通过在requestedPrivileges属性中指定UIPI,应用程序声明了一个要求,即绕过对跨权限级别发送窗口消息的UIPI限制。在以UIAccess权限启动应用程序之前,Windows Vista会执行以下策略检查。

  • 应用程序必须具有数字签名,该数字签名可以使用链接到本地计算机受信任根证书颁发机构证书存储中的受信任根的数字证书进行验证。
  • 应用程序必须安装在只有管理员才能写入的本地文件夹应用程序目录中,如程序文件目录。UI自动化应用程序允许的目录为:

代码语言:javascript
复制
- _%ProgramFiles% and its subdirectories._
- _%WinDir% and its subdirectories, except a few subdirectories that are excluded because standard users have write access._

有关详细信息,请参阅文档:

Mandatory Integrity Control

,但现在唯一的问题是复选框状态仅在将鼠标悬停在该元素上后才会检索到。我正在试着找到一个解决方案。无论如何,如果你能阐明这一点,那就太好了。

我们可以通过windows处理程序来获取元素,而不是在鼠标悬停之后获取元素。下面是获取复选框状态的代码,供您参考:

代码语言:javascript
复制
CoInitialize(NULL);

IUIAutomation * UIAutomation;
InitializeUIAutomation(&UIAutomation);

IUIAutomationElement *targetIUIAutomationElement;

UIAutomation->ElementFromHandle((UIA_HWND)0x513F8,&targetIUIAutomationElement);

VARIANT checkboxState;
targetIUIAutomationElement->GetCurrentPropertyValue(UIA_ToggleToggleStatePropertyId,&checkboxState);
if(checkboxState.lVal== ToggleState_Off)
    std::cout << "The check box is not checked...\n";
else if(checkboxState.lVal == ToggleState_On)
    std::cout << "The check box is checked...\n";
else
    std::cout << "The checkbox is in indeterminate...\n";
票数 0
EN

Stack Overflow用户

发布于 2019-09-24 14:29:14

最后找到了另一种获取复选框状态的方法。inspect.exe是救世主。感谢@Rita Han - MSFT推荐inspect.exe。由于更改权限/访问或绕过UIPI限制有点复杂,我们决定使用UIAutomation。我们使用UIAutomation检索了设置窗口中的所有数据!

票数 0
EN

Stack Overflow用户

发布于 2019-09-12 13:41:59

如果您只想询问复选框的状态,而不是使用SendMessage,那么您可以只检查可访问性树。也就是说,使用与屏幕阅读器相同的API。

AccessibleObjectFromWindow and friends开始。

票数 -4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57900192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档