0x6*_*C74 3 c++ winapi keypress
我对这个问题的解决方法仅在几个程序中才是正确的。为什么它不是通用的?
适用于:
不幸的是,在某些情况下什么也没发生(即使我在执行程序之前单击了文本框区域):
即使使用SendMessage而不是PostMessage,GetLastError始终返回0.您能指出我的错误吗?
#include <Windows.h>
#include <iostream>
int main()
{
HWND hCurrentWindow;
Sleep(5000);
hCurrentWindow = GetForegroundWindow();
std::cout<<"GO!!!\n";
for(int i=0; i<500; i++) //simulate 500 keystrokes of 'E'.
{
PostMessage(hCurrentWindow,WM_KEYDOWN,0x45,NULL);
PostMessage(hCurrentWindow,WM_KEYUP,0x45,NULL);
}
std::cout<<GetLastError()<<std::endl;
system("Pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Maximus建议后的更新
#include <Windows.h>
#include <iostream>
int main()
{
HWND hCurrentWindow;
Sleep(5000);
hCurrentWindow = GetForegroundWindow();
if(!hCurrentWindow)
std::cout<<"Failed get set the window handle\n";
std::cout<<"GO!!!\n";
for(int i=0; i<500; i++)
{
PostMessage(hCurrentWindow,WM_KEYDOWN,0x45,0x45);
PostMessage(hCurrentWindow,WM_KEYUP,0x45,0x45);
}
std::cout<<GetLastError()<<std::endl;
system("Pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
效果没有差别。
Rob Kennedy的评论和Hans Passant的回答后的更新
#include <Windows.h>
#include <iostream>
int main()
{
HWND hCurrentWindow;
DWORD procID;
GUITHREADINFO currentWindowGuiThreadInfo;
Sleep(5000);
hCurrentWindow = GetForegroundWindow();
if(!hCurrentWindow)
std::cout<<"Failed get main the window handle\n";
GetWindowThreadProcessId(hCurrentWindow,&procID);
GetGUIThreadInfo(procID,¤tWindowGuiThreadInfo);
hCurrentWindow = currentWindowGuiThreadInfo.hwndFocus;
if(!hCurrentWindow)
std::cout<<"Failed get the child window handle\n";
std::cout<<"GO!!!\n";
for(int i=0; i<500; i++)
{
PostMessage(hCurrentWindow,WM_KEYDOWN,0x45, MapVirtualKey(0x45,MAPVK_VK_TO_VSC));
PostMessage(hCurrentWindow,WM_KEYUP,0x45, MapVirtualKey(0x45,MAPVK_VK_TO_VSC));
}
std::cout<<GetLastError()<<std::endl;
system("Pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,每次都发送“透明”消息。GetLastError()说:
ERROR_INVALID_WINDOW_HANDLE
Run Code Online (Sandbox Code Playgroud)1400 (0x578) Invalid window handle.
GetLastError()“已修复”
int main()
{
HWND hCurrentWindow;
DWORD procID;
GUITHREADINFO currentWindowGuiThreadInfo;
Sleep(5000);
hCurrentWindow = GetForegroundWindow();
if(!hCurrentWindow)
std::cout<<"Failed get main the window handle\n";
GetWindowThreadProcessId(hCurrentWindow,&procID);
GetGUIThreadInfo(procID,¤tWindowGuiThreadInfo);
hCurrentWindow = currentWindowGuiThreadInfo.hwndFocus;
if(!hCurrentWindow)
std::cout<<"Failed get the child window handle\n";
std::cout<<"GO!!!\n";
for(int i=0; i<500; i++)
{
if(!PostMessage(hCurrentWindow,WM_KEYDOWN,0x45, MapVirtualKey(0x45,MAPVK_VK_TO_VSC))) std::cout<<GetLastError()<<std::endl;
if(!PostMessage(hCurrentWindow,WM_KEYUP,0x45, MapVirtualKey(0x45,MAPVK_VK_TO_VSC))) std::cout<<GetLastError()<<std::endl;
}
system("Pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
...输出1400数千次 除此之外,没有任何改变。
当您将消息发布到错误的窗口时,这当然会发生。记事本肯定是这种情况。它不只有一个窗口,您可以在Spy ++中看到。GetForegroundWindow()返回一个顶级窗口,即记事本的框架窗口。在该框架窗口内部有一个子窗口,一个EDIT控件。该窗口需要获取消息。
您需要跳过几个步骤才能获得该窗口,GetFocus()函数返回具有焦点的窗口,但是仅当您从拥有该窗口的进程中调用该窗口时,该函数才起作用。当您在进程外执行此操作时,必须首先调用GetWindowThreadProcessId()以获取拥有前台窗口的线程的ID。然后,您必须调用GetGUIThreadInfo(),它返回的GUITHREADINFO.hwndFocus是您需要的窗口句柄。
这仍然不是没有问题,您无法控制进程的键盘状态。换句话说,Shift,Ctrl和Alt键以及任何死键(例如某些键盘布局上的Alt + Gr)的状态。支持发送WM_CHAR以键入密钥。
| 归档时间: |
|
| 查看次数: |
16691 次 |
| 最近记录: |