Winapi 为什么从全局热键处理程序中调用PostMessage时没有效果?
我正在编写的GUI应用程序确实会向另一个窗口发送按键事件,即Winapi 为什么从全局热键处理程序中调用PostMessage时没有效果?,winapi,Winapi,我正在编写的GUI应用程序确实会向另一个窗口发送按键事件,即cmd.exe PostMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0); 当在诸如WM\u CREATE、WM\u KEYUP等事件上完成时,事件会正常发送(在cmd.exe中出现一行新行) 然后,我用注册表快捷键设置了一个全局快捷键。在WM_热键处理程序中,我成功地接收到按键,但PostMessage不再有效 如何解决这个问题 完整示例,尽可能缩小: #include <iostream>
cmd.exe
PostMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0);
当在诸如WM\u CREATE
、WM\u KEYUP
等事件上完成时,事件会正常发送(在cmd.exe
中出现一行新行)
然后,我用注册表快捷键设置了一个全局快捷键。在WM_热键
处理程序中,我成功地接收到按键,但PostMessage
不再有效
如何解决这个问题
完整示例,尽可能缩小:
#include <iostream>
#include <Windows.h>
using namespace std;
const char g_szClassName[] = "myWindowClass";
BOOL CALLBACK enumWindows(HWND hwnd, LPARAM lParam) {
char winTitle[1024*10];
GetWindowText(hwnd, winTitle, sizeof(winTitle));
if (strstr(winTitle, "cmd.exe") != NULL) {
cout << "Sending a message to window " << hwnd << ": " << winTitle << endl;
PostMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0);
}
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_CREATE:
// register hotkey ctrl+alt+s
RegisterHotKey(hwnd, 100, MOD_ALT | MOD_CONTROL, 'S');
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
EnumWindows(enumWindows, 0);
PostQuitMessage(0);
break;
case WM_HOTKEY:
// hotkey ctrl+alt+s fired
EnumWindows(enumWindows, 0);
break;
case WM_KEYUP:
EnumWindows(enumWindows, 0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
// just init stuff, do not waste your time
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wc);
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, "Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
#包括
#包括
使用名称空间std;
const char g_szClassName[]=“myWindowClass”;
BOOL回调枚举窗口(HWND-HWND,LPARAM-LPARAM){
字符winTitle[1024*10];
GetWindowText(hwnd、winTitle、sizeof(winTitle));
if(strstr(winTitle,“cmd.exe”)!=NULL){
coutRaymond Chen已经记录了为什么这不能按您期望的方式工作(PostMessage
工作正常,但另一个窗口的响应取决于实际的键盘状态,正如我在评论中所猜测的)。参见他的博文:
Raymond Chen已经记录了为什么这不能按您期望的方式工作(PostMessage
工作正常,但另一个窗口的响应取决于实际的键盘状态,正如我在评论中所猜测的)。参见他的博客帖子:
也许WM_KEYDOWN
处理程序会检查热键启动时按下的其他键的状态?伪造输入并出错是错误的。使用官方自动化界面可能会更成功:。也许WM_KEYDOWN
处理程序会检查按下的其他键的状态在热键触发的那一瞬间被激活?伪造输入,并做错事,是错误的。使用官方自动化界面可能会更成功:。