C Windows-我们可以从鼠标点击某个东西推断出什么;可点击“;?
正如标题所示,我在问,点击屏幕可以发现什么 更准确地说,是否可以检测到对精确元素的单击(可以是用于在通用浏览器上打开新选项卡的C Windows-我们可以从鼠标点击某个东西推断出什么;可点击“;?,c,windows,winapi,user-interface,C,Windows,Winapi,User Interface,正如标题所示,我在问,点击屏幕可以发现什么 更准确地说,是否可以检测到对精确元素的单击(可以是用于在通用浏览器上打开新选项卡的+符号,或者是打开的Office文档上的文件,然后另存为…元素)并返回某种类型的已单击内容字符串 通过使用Win32 API,我能够检测鼠标左键是否已被单击: for(character=1; character<=222; character++) { if(GetAsyncKeyState(character) == -32767) {
+
符号,或者是打开的Office文档上的文件
,然后另存为…
元素)并返回某种类型的已单击内容字符串
通过使用Win32 API,我能够检测鼠标左键是否已被单击:
for(character=1; character<=222; character++) {
if(GetAsyncKeyState(character) == -32767) {
...
switch(character) {
case VK_LBUTTON: ...; break;
...
}
}
}
然而,我不知道点击了什么
你会发现,获取鼠标点击的坐标对我来说毫无用处,除非我知道屏幕上可以点击的所有东西的坐标
我检查了WindowsUI自动化,但大部分都是用C语言编写的,而且,就我个人而言,我更喜欢用C语言编写
很多人告诉我使用web中的一个程序,但正如我所说的,我更喜欢只使用C,而不包括一些外部库
那么:有没有办法通过使用Windows API来确定我是在某些文本编辑器上单击了“新建文件”,还是在VLC上单击了“播放”?我不是Windows专家,但阅读文档是一种可行的方法:
TCHAR lpClassName[64];
HWND foreground = GetForegroundWindow();
int ret;
ret = GetClassName(foreground, (LPTSTR)lpClassName, 64);
if(ret == 0) {
// GetLastError and friends...
}
通过这种方式,您应该获得以前使用RegisterClass()
或RegisterClassEx()注册的窗口类的名称。该字符串应该告诉您有关窗口性质的更多信息
注意:由于我不知道/获取Win32数据类型,上面使用的字符数组和/或GetClassName()
的长度参数可能是错误的
您可以使用GetClassInfo()
从类中获得更多信息。如需一般参考,请阅读MSDN 您可以在鼠标光标下控制(子)窗口的句柄、文本和类名,逻辑如下:
HWND hWndF = GetForegroundWindow();
if (hWndF != NULL)
{ HWND hWndC;
TCHAR szClassName[64], szWindowText[256];
POINT pt;
GetClassName(hWndF, szClassName, _countof(szClassName)); // main window
GetWindowText(hWndF, szWindowText, _countof(szWindowText)); // main window
GetCursorPos(&pt); // in screen coordinates
ScreenToClient(hWndF, &pt); // in client coordinates of main window
hWndC = ChildWindowFromPointEx(hWndF, pt, CWP_ALL);
if (hWndC != NULL && hWndC != hWndF)
{ GetClassName(hWndC, szClassName, _countof(szClassName)); // child window
GetWindowText(hWndC, szWindowText, _countof(szWindowText)); // child window
}
}
您可以从C使用UI自动化,但这并不是说它会很有趣。无论如何,您都需要这样做,因为Win32通常不知道当您单击时会发生什么。只有应用程序知道这一点。MSDN文档编写得很糟糕;找不到像样的例子。唉,所以我不会用一个文件就把它写出来。c?MSDN文档很好。你只需要知道如何从C中下载COM,一个更为简洁的方法是使用C++。你能加深“C如何使用COM”句吗?为什么你会认为这会产生不同的答案?您已经被告知要使用,但答案没有更改。直到现在,我才设法获取与窗口关联的菜单栏元素数…如果我能够获取已单击菜单栏的哪个元素,那将是一种改进。您是否尝试获取子窗口?也许你点击了标签外的一点。不管怎样,只要菜单是用标签完成的,您就应该在屏幕上找到这些标签(“静态”控件)作为窗口(除非菜单再次关闭)。如果没有任何帮助,您可以使用GetMenu()
和friends toGetMenuItemRect()
,这将告诉您屏幕上的菜单位置,您应该能够匹配鼠标单击。但是,我也不认为这是必要的……window类并没有告诉您它的本质。它是一个字符串,由RegisterClass[Ex]
的调用方(即提供特定窗口类的工具)任意选择。除了32770
(dialog)和您可以在特殊情况下使用的标准控制类之外,您对这些信息无能为力。例如,您无法查询已接受的控件特定消息。子窗口的szWindowText
始终为空…如果我获取一个HMENU处理程序并获取菜单的选定项,该怎么办?您只能使用上述逻辑来获取有关子窗口的信息,Humanu不是一个窗口——也要注意,某些应用程序中的一些花哨工具栏在API意义上不是真正的窗口——看起来UI自动化是唯一的出路……那么PeekMessage
呢?我可以用它来捕获WM_命令
并对其进行分析您不能使用peek消息来处理属于另一个线程的消息…如果我hook
这些消息会怎么样?
HWND hWndF = GetForegroundWindow();
if (hWndF != NULL)
{ HWND hWndC;
TCHAR szClassName[64], szWindowText[256];
POINT pt;
GetClassName(hWndF, szClassName, _countof(szClassName)); // main window
GetWindowText(hWndF, szWindowText, _countof(szWindowText)); // main window
GetCursorPos(&pt); // in screen coordinates
ScreenToClient(hWndF, &pt); // in client coordinates of main window
hWndC = ChildWindowFromPointEx(hWndF, pt, CWP_ALL);
if (hWndC != NULL && hWndC != hWndF)
{ GetClassName(hWndC, szClassName, _countof(szClassName)); // child window
GetWindowText(hWndC, szWindowText, _countof(szWindowText)); // child window
}
}