PostMessage / SendMessage without interference from modifier keys - c++

I'm trying to post/send a message to some hwnd without the interference from modifier keys (ctrl, alt, shift).
Basically i want to send F1 message (without ctrl) to hwnd while im pressing ctrl (like Example 2) but with SendMessage\PostMessage.
I tried use SendInput to set up the CTRL key, post the message and set down the CTRL key back, but it fails 50% of time.
Example 1: Code with SendMessageA:
HWND hwnd = FindWindowA(0, "Notepad");
if (GetKeyState(VK_CONTROL) < -1) // if CTRL is pressed
{
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0); // up the CTRL key
SendMessageA(hwnd, WM_KEYDOWN, VK_F1, 0); // send F1 keydown
keybd_event(VK_CONTROL, 0, 0, 0); // down the CTRL key
}
else
{
SendMessageA(hwnd, WM_KEYDOWN, VK_F1, 0); // send F1 keydown
}
Theoretically this code would solve the problem, but it sometimes sends the message with the CTRL pressed and sometimes not.
Example 2: Same code with SendInput (but these works fine)
HWND hwnd = FindWindowA(0, "Notepad");
if (GetKeyState(VK_CONTROL) < -1) // if CTRL is pressed
{
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0); // up the CTRL key
keybd_event(VK_F1, 0, 0, 0); // send F1 keydown
keybd_event(VK_CONTROL, 0, 0, 0); // down the CTRL key back
}
else
{
keybd_event(VK_F1, 0, 0, 0); // send F1 keydown
}

Related

After check GetKeyState() in main message loop, application freezes until the second press of the same button

I need to create stop action event in main message loop.(ListBox after press VK_RIGHT moves down - and I don't want it to happen).
Another problem is application freezes until I press right arrow again.
What is happening, why set focus on VK_RIGHT stops widnow from getting messages?
I have Listbox. I want to press VK_RIGHt to move selection to another control(window - here I want it o be hEdit2(in future it will be probaly another ListBox)) But when I do it, cursor of selection moves down - so I added if(GetKeyState(VK_RIGHT)){} And it works but after changing focus to another control application freezes (UNTIL I PRESS ANOTHER TIME VK_RiGHT). wtf?
LRESULT SelIndex;
int rozmiar;
HWND hTmp;
// main message loop
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
// this always works
if ((HWND)msg.hwnd == hWndExit) { return 0; }
// this never tried I guess everything
if ((HWND)msg.hwnd == hWndList) {
SetForegroundWindow(hWndList); hTmp=SetFocus(hWndList); SendMessage(hWndList, WM_SETFOCUS, (WPARAM)hTmp, 0);
AttachThreadInput(GetCurrentThreadId(), GetWindowThreadProcessId(GetAncestor(hWndList, GA_ROOT), NULL), TRUE);
SendMessage(hWndList, WM_UPDATEUISTATE, MAKEWPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 0);
}
if (GetKeyState(VK_RIGHT)) {
SelIndex = SendMessage(hWndList, LB_GETCURSEL, 0, 0L);
rozmiar = (int)SendMessage(hWndList, LB_GETCOUNT, 0, 0);
// SendMessage(hEdit2, WM_SETFOCUS, (WPARAM)hWndList, 0);
// hTmp = SetFocus(hEdit2);
SetForegroundWindow(hEdit2);
if(SelIndex<rozmiar-1){ SendMessage(hWndList, LB_SETCURSEL, SelIndex-1, 0L); }
else { SendMessage(hWndList, LB_SETCURSEL, SelIndex, 0L); }
}
DispatchMessage(&msg);
}
}
/////////////////////////////////////////////////////////////////////////////////

auto click with C++

I write a simple cpp file when your left mouse button down it will click after 50 milliseconds and it works with many windows but when I click in the Tencent Gaming Buddy(an android emulator) it is not working - so how could I get the left mouse button down when I click here is my code
while (true)
{
Sleep(50);
if ((GetKeyState(VK_LBUTTON) & 0x80) != 0)
{
if (GetCursorPos(&p))
{
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
}
}
if ((GetKeyState(VK_RBUTTON) & 0x80) != 0)
{
break;
}
}
GetKeyState() relies on the internal key state machine of the calling thread, and does not work without an active message loop to update that state, which this code does not have. Use GetAsyncKeyState() instead.
Also, mouse_event() is deprecated, use SendInput() instead

C++ Simulating key presses only once

I have tried everything I found in google but nothing works. I want to press A for 5 seconds, but everything presses it only once.It just releases it immediately. Pressing multiple times is not the answer because the key must be pressed for atleast 30ms.
const int KEYEVENT_KEYUP = 0x02;
keybd_event(0x41, 0, 0, 0);
Sleep(5000);
keybd_event(0x41, 0, KEYEVENT_KEYUP, 0);

Send "button pressed" message to UnityWndClass

I have 3D game and i need to press buttons in this game from another application. Spy++ says that window of the game is UnityWndClass. When i pressing buttons in game, window recives only mouse messages like WM_SETCURSOR, WM_LBUTTONDOWN etc, but when i try to send WM_LBUTTONDOWN and WM_LBUTTONUP with coordinates of the button from another window nothing happend. Why? Any ideas how to press buttons?
WM_SETCURSOR is for changing the cursor image of your own window. WM_LBUTTONDOWN and WM_LBUTTONUP are notification messages sent after mouse click. WM_LBUTTONXXX messages are probably not handled by the main Window procedure.
To fake mouse input, you can use mouse_event or SendInput. For example, this moves cursor to x=10 / y=10 and and clicks left mouse.
int x = 10 * 65536 / GetSystemMetrics(SM_CXSCREEN);
int y = 10 * 65536 / GetSystemMetrics(SM_CYSCREEN);
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x, y, 0, 0);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
Or use SendInput for multiple calls (see comments)
INPUT input[3];
for (int i = 0; i < 3; i++)
{
memset(&input[i], 0, sizeof(INPUT));
input[i].type = INPUT_MOUSE;
}
input[0].mi.dx = x;
input[0].mi.dy = y;
input[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
input[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
input[2].mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(3, input, sizeof(INPUT));
Window should be at least visible and preferably be active. You can use SetForegroundWindow. See this example to make sure window is visible and active.
Other alternatives:
Use Spy++ to get information about the button which you want to press.
For example, if this was Windows Calculator, you can spy on calculator's buttons, it shows calculator button 2 has ID set to 0x84. You can send WM_COMMAND with WPARAM set to 0x84 to simulate button press.
HWND hwnd = FindWindow(0, L"Calculator");
if (IsWindow(hwnd))
{
//this should put "234" in to calculator's edit box
SendMessage(hwnd, WM_COMMAND, 0x84, 0);
SendMessage(hwnd, WM_COMMAND, 0x85, 0);
SendMessage(hwnd, WM_COMMAND, 0x86, 0);
}

RegisterHotKey without a modifier in c++

This piece of code registers 2 global hotkeys under Windows for SHIFT+F5 and SHIFT+F6 it works fine in all cases, including the case that a completely other application has the focus like for example a game.
enum{ KEY_F5 = 1, KEY_F6 = 2 };
RegisterHotKey(0, KEY_F5, MOD_SHIFT, VK_F5);
RegisterHotKey(0, KEY_F6, MOD_SHIFT, VK_F6);
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
{
PeekMessage(&msg, NULL, 0, 0, 0);
switch (msg.message){
case WM_HOTKEY:
if (msg.wParam == KEY_F5){
// code
}
else if (msg.wParam == KEY_F6){
// code
}
}
}
But if i replace
RegisterHotKey(0, KEY_F5, MOD_SHIFT, VK_F5);
RegisterHotKey(0, KEY_F6, MOD_SHIFT, VK_F6);
by
RegisterHotKey(0, KEY_F5, 0, VK_F5);
RegisterHotKey(0, KEY_F6, 0, VK_F6);
because my goal is it two have F5 and F6 as hotkeys without having to press SHIFT always, it only works if my program has the focus not if some other has. How can i achieve to have only F? as global hotkey like for example TS3 does. It must work even if the application doesn't have the focus.
Try use MOD_NOREPEAT instead of MOD_SHIFT. I also don't see any necessity of using "PeakMessage". Since you already call GetMessage(), PeakMessage is really redundant.