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

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);
}
}
/////////////////////////////////////////////////////////////////////////////////

Related

RegisterHotKey() not detecting keypress

So, I am trying to write a program that detects when the keycombination Control + C is pressed, I have read that the best way to do this is to use RegisterHotKey(). I have never used this before though so I am a little confused since my code isnt working. This is the solution I found online but it doesn't work. I have looked at the documentation but that hasn't helped either. this is my code:
AutoClicker::AutoClicker()
{
clicker = std::thread(&AutoClicker::Clicker, this);
enum {KEY_C = 1};
RegisterHotKey(0, KEY_C, MOD_CONTROL, 0x5A);
MSG msg;
while (GetMessage(&msg, 0, 0, 0)) {
PeekMessage(&msg, NULL, 0, 0, 0);
switch (msg.message)
{
case WM_HOTKEY:
if (msg.wParam == KEY_C)
{
printf("1 Pressed");
}
}
}
}

Continue update&render whilst handling windowproc messages

I've created a win32 C++ app that uses direct2d to plot stuff in a window. In a loop as shown below, I call render and update whilst also peeking at any messages. But when ever I have WM_COMMAND that lets WindowProc call a MessageBox() or DiaLogBox(), my update&render loop no longer gets executed and the plot window freezes. Is there a simple fix with another loop structure or do I need to enter the, for me, unknown world of multithreading?
while (message.message != WM_QUIT)
{
if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
DispatchMessage(&message);
else
{
Update();
BeginDraw();
Render();
EndDraw();
}
}
EDIT: By popular demand I have changed above "ugly" mechanism in to another approach, yet with the same issue
bool runGame = true;
while (runGame)
{
while (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
DispatchMessage(&message);
if (message.message == WM_QUIT)
runGame = false;
}
Update();
BeginDraw();
Render();
EndDraw();
}

PostMessage / SendMessage without interference from modifier keys

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
}

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

Can't quit TrackPopupMenu

I'm trying to create a popup menu which appear while typing on an edit control to show suggestion. The problem is I can't continue typing as the popup wouldn't disappear. The only way is to click outside the popup. It's every inconvenient if every character you typed you have to click outside to keep writing.
I've tried SetForeGround before calling TrackPopupMenu but it didn't work.
if (HIWORD(wParam) == EN_CHANGE)
{
HMENU suggest = CreatePopupMenu();
WCHAR text[50];
GetWindowText(tagTxt, text, 50);
if (wcslen(text) > 0)
{
for (int i = 0; i < Tag.size(); i++)
{
if (wcsncmp(Tag[i].tagName, text, wcslen(text)) == 0)
AppendMenu(suggest, MF_STRING, NULL, Tag[i].tagName);
}
POINT curPoint;
GetCursorPos(&curPoint);
SetForegroundWindow(hWnd);
UINT code = TrackPopupMenu(suggest,TPM_RETURNCMD | TPM_NONOTIFY, curPoint.x, curPoint.y, 0, hWnd, NULL);
SendMessage(hWnd, WM_NULL, 0, 0);
}
}