为什么当我向一个应用程序发送按键时,会收到额外的信息?

问题描述 投票:1回答:2

我正在向一个应用程序发送CTRL+A和CTRL+C(很明显是为了复制内容),为此我写了一些C++代码,看起来似乎没有问题。

事实上,我在spy++上看到,我的代码产生的信息和发送给应用程序的信息与应用程序在键盘上手动输入CTRL+A和CTRL+C时收到的信息完全一样(期待自由值)......除了我的代码,应用程序在最后收到两个额外的WM_CHAR信息'A'和'B'。

因为我没有发送这些WM_CHAR消息,而只是发送WM_KEYDOWN和WM_KEYUP,所以我有点疑惑。顺便说一下,没有任何东西被选中,也没有任何东西被复制(即使之前被选中了)。

这是我的C++代码。

HWND hTargetWindow=(HWND) 0x280908;


LPARAM lparam1 = 0x00000001 | (LPARAM)(0x1D << 16); 
LPARAM lparam2 = 0x00000001 | (LPARAM)(0x1E << 16);  
LPARAM lparam3 = 0x00000001 | (LPARAM)(0x2E << 16); 

LPARAM lparam1_ = lparam1 | (LPARAM)(0x1 << 31); 
LPARAM lparam2_ = lparam2 | (LPARAM)(0x1 << 31); 
LPARAM lparam3_ = lparam3 | (LPARAM)(0x1 << 31); 

PostMessage(hTargetWindow, WM_KEYDOWN, VK_CONTROL, lparam1);
PostMessage(hTargetWindow, WM_KEYDOWN, VK_A, lparam2);


PostMessage(hTargetWindow, WM_KEYUP, VK_CONTROL, lparam1_);
PostMessage(hTargetWindow, WM_KEYUP, VK_A, lparam2_);


PostMessage(hTargetWindow, WM_KEYDOWN, VK_CONTROL, lparam1);
PostMessage(hTargetWindow, WM_KEYDOWN, VK_C, lparam3);

PostMessage(hTargetWindow, WM_KEYUP, VK_C, lparam3_);
PostMessage(hTargetWindow, WM_KEYUP, VK_CONTROL, lparam1_);

和这里分别是

a)手动输入CTRL+A CTRL+C时收到的信息。enter image description hereb)这里的CTRL+A CTRL+C时收到的信息是由我的C+代码发送的。

enter image description here

我将把KEYUP事件的frepeat设为1,但我怀疑这是否会改变什么,所以我还是把问题贴出来。

那么为什么我的代码会额外发送这两条信息呢?

先谢谢你的提示。

增加了7:09:05 p.m.(GMT + 2:00):

CTRL+A的KEYUP和KEYDOWN是反过来的(CTRL+C序列是一样的),但这是因为我也试过这样解决问题。 我也试过很多次正确的组合。

这是spy++时,下键和上键的顺序是完全一样的,这并没有改变什么。

enter image description here

c++ winapi
2个回答
0
投票

你做事情的顺序不对,做的是... WM_KEYUP 关于 VK_A 在你做之前 WM_KEYUP 关于 VK_CONTROL. 同样的是 C. 逆转这些,它应该是罚款。


0
投票
// Send [CTRL-A] to select the entire text in a Notepad window, even if Notepad is out of focus,
// without bringing the Notepad window into focus.
// Works with Notepad, but not with Command Prompt window.
BYTE gucKeybStateCur [256] = {'\0'};
// hwN = Find Notepad HWND
AttachThreadInput (GetWindowThreadProcessId (hwN, NULL), GetCurrentThreadId (), TRUE);
GetKeyboardState ((PBYTE) &gucKeybStateCur);
gucKeybStateCur [VK_CONTROL] |= 0x80;
SetKeyboardState ((LPBYTE) &gucKeybStateCur);
PostMessage (hwN, WM_KEYDOWN, (WPARAM) 0x00000041, (LPARAM) 0x001E0001);
PostMessage (hwN, WM_KEYUP, (WPARAM) 0x00000041, (LPARAM) 0xC01E0001);
GetKeyboardState ((PBYTE) &gucKeybStateCur);
gucKeybStateCur [VK_CONTROL] &= 0x0F;
SetKeyboardState ((LPBYTE) &gucKeybStateCur);
AttachThreadInput (GetWindowThreadProcessId (hwN, NULL), GetCurrentThreadId (), FALSE);

// Send [CTRL-C] to interrupt a batch file running in a Command Prompt window, even if the Command Prompt window is not visible,
// without bringing the Command Prompt window into focus.
// [CTRL-C] will have an effect on the batch file, but not on the Command Prompt  window itself -- in other words,
// [CTRL-C] will not have the same visible effect on a Command Prompt window that isn't running a batch file at the moment
// as bringing a Command Prompt window that isn't running a batch file into focus and pressing [CTRL-C] on the keyboard.
ulong ulProcessId = 0UL;
// hwC = Find Command Prompt window HWND
GetWindowThreadProcessId (hwC, (LPDWORD) &ulProcessId);
AttachConsole ((DWORD) ulProcessId);
SetConsoleCtrlHandler (NULL, TRUE);
GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0UL);
SetConsoleCtrlHandler (NULL, FALSE);
FreeConsole ();
© www.soinside.com 2019 - 2024. All rights reserved.