C++ 为什么向应用程序发送击键时会收到额外消息?

C++ 为什么向应用程序发送击键时会收到额外消息?,c++,winapi,C++,Winapi,我将CTRL+A和CTRL+C发送到应用程序(以便复制内容)。 为此,我编写了一些C++代码,看起来不错。 事实上,我在spy++上看到,我的代码生成并发送到应用程序的消息与在键盘上手动输入CTRL+A和CTRL+C时应用程序接收到的消息完全相同(除了frepeat值)。。。除了我的代码之外,应用程序在末尾接收两条额外的WM_CHAR消息,分别表示“A”和“B” 因为我不发送这些WM_CHAR消息,只发送WM_KEYDOWN和WM_keydup,所以我有点困惑。顺便说一句,未选择任何内容,也未复

我将CTRL+A和CTRL+C发送到应用程序(以便复制内容)。 为此,我编写了一些C++代码,看起来不错。 事实上,我在spy++上看到,我的代码生成并发送到应用程序的消息与在键盘上手动输入CTRL+A和CTRL+C时应用程序接收到的消息完全相同(除了frepeat值)。。。除了我的代码之外,应用程序在末尾接收两条额外的WM_CHAR消息,分别表示“A”和“B”

因为我不发送这些WM_CHAR消息,只发送WM_KEYDOWN和WM_keydup,所以我有点困惑。顺便说一句,未选择任何内容,也未复制任何内容(即使之前已选择)

这是我的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_);
HWND-hTargetWindow=(HWND)0x280908;

LPARAM lparam1=0x00000001 |(LPARAM)(0x1D你在做错误的事情,在你做
VK\u控件
上的
WM\u-KEYUP
之前,先在
VK\u-CONTROL
上做
WM\u-KEYUP
上做
WM\u-KEYUP
上做
WM\u-KEYUP>,然后再做
C
。把它们颠倒过来,应该没问题。

它们是通过Windows发送的。通常检查起来比手动跟踪上下更容易。当然se也告诉了你很多。这是由于应用程序使用了
TranslateMessage
。很抱歉,我不明白这一点?什么是TranslateMessage?你只是伪造了消息,实际上没有更改线程的键盘状态。线程的CTRL键仍然向上。所以程序的TranslateMessage()是call会看到您在不按下CTRL键的情况下键入A和C,因此会为它们生成WM_CHAR消息。您需要AttachThreadInput()和SetKeyboardState()来修改状态。或者使用SendInput()。@KarlZorn是每个“我的第一个窗口”的一部分程序。@HansPassant他们有一个按钮来标记一个应该是注释的答案,但没有一个按钮来标记一个应该是答案的注释…好的,正如我在你的答案后面的帖子中所解释的,我已经尝试颠倒“CTRL+a”的顺序来测试这是否会改变任何东西,但是如果先用相同的顺序测试,并且ese额外的WM_字符总是用于提高可读性,我建议您将注释放在代码块之外。
// 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 ();