How do I write multiple GetAsyncKeyState with C++ - c++

My problem is where can I add this line of code:
if( GetKeyState(VK_F2) & 0x8000 )
I tried in different ways, but when I compile and run it and press the F1 or F2 key it executes all the functions. I want to call the F1 key functions when the key is pressed and F2 key when it is pressed. I am using Visual Studio 2010 Express.
Here is my code:
switch(uMsg)
{
case WM_INITDIALOG:
{
// do something here
break;
}
case WM_TIMER:
{
if( GetKeyState(VK_F1) & 0x8000 )
if( GetKeyState(VK_F2) & 0x8000 )
{
// do something here
}
break;
}
case WM_CLOSE:
{
// do something here
}
}
return 0;

SOLVED:) well my problem is solved after trying for sometime finally i got it the problem
was that little "break;" statement please look at the code its working flawless.
Thank you so very much for your time and help appreciated
case WM_TIMER:
{
if(GetKeyState(VK_F1) & 0x8000 )
{
MessageBoxA (NULL, TEXT ("This is a call from F1 key!"), TEXT("Test F1 key"), MB_OK );
}
//break; << this was the one that was giving me the problem
if(GetKeyState(VK_F2) & 0x8000 )
{
MessageBoxA (NULL, TEXT ("This is a call from F2 key!"), TEXT("Test F2 key"), MB_OK );
}
//if(GetKeyState(VK_F3) & 0x8000 ) << i can add multi VK_ keys here
break; // << should be here
}
case WM_CLOSE:

A couple points:
Are you sure you want to poll like this? Maybe you want to be responding to notifications when the user presses these keys (WM_KEYDOWN for example) instead of polling periodically? Your code has the problem that it can easily miss if you press & release F1 between WM_TIMERs.
You should probably be using GetKeyState, as Joachim Pileborg says. GetAsyncKeyState works on the state of the keyboard at the time of the call; GetKeyState works on the state of the keyboard when the current message was sent. This tends to keep things more tightly synchronized. That said, if you're polling in WM_TIMER, it probably doesn't matter so much.
You are only checking if the return value is non-zero, which is not how this function works. The return value is a bitmask. From the documentation:
If the high-order bit is 1, the key is down; otherwise, it is up.
If the low-order bit is 1, the key is toggled. A key, such as the CAPS LOCK key, is toggled if it is turned on. The key is off and untoggled if the low-order bit is 0. A toggle key's indicator light (if any) on the keyboard will be on when the key is toggled, and off when the key is untoggled.
Thus, to check for F1:
if( GetKeyState(VK_F1) & 0x8000 )
{
...
}

Related

Does GetKeyState generate input message?

const int KEY_0 = 0x30;
void main() {
byte keyState[256];
ZeroMemory(keyState, sizeof(byte) * 255);
byte pressed = (keyState[KEY_0] & 0x80);
while (pressed == false)
{
ZeroMemory(keyState, sizeof(byte) * 255);
//GetKeyState(0); // with this line, works well. It makes GetKeyboardState(KEY_0) works.
//GetAsyncKeyState(KEY_0);
GetKeyboardState(keyState);
pressed = (keyState[KEY_0] & 0x80);
};
}
I have learn that this code does not work because GetKeyboardState() get values generated after a keyboard message is processed. As no keyboard message is generated, the loop will not stop. That is what I understand.
And MSDN says:
An application calls GetKeyState in response to a keyboard-input message. This function retrieves the state of the key when the input message was generated.
I'm confused, as the upper code with GetKeyState(0); works well, which means GetKeyState() makes a message about the keyboard?
How can I understand GetKeyState() and GetKeyboardState()?

WIN API - Programm getting stuck while a button is selected

I am creating a simple software using WINAPI that reads the data from a sensor connected to a computer via USB.
In this software, I am implementing some functions like read mode, test mode, etc.
The problem that I am facing is that I am getting stuck while I select the button for continuous reading, the code follows below:
case WM_COMMAND:
switch (wp)
{
case START_BUTTON:
printf("START_BUTTON");
while(SendDlgItemMessage(hWnd,START_BUTTON,BM_GETCHECK ,TRUE,0)== BST_CHECKED)
{
char* var = USB_Read(); //Get data from the sensor
SetWindowText(hLux, var); //Display the data
if (SendDlgItemMessage(hWnd,START_BUTTON,BM_GETCHECK ,TRUE,0)!= BST_CHECKED) //Check if the botton is no longer selected
break;
}
break;
}
break;
I know that the problem is in the while-loop, when I press it all the program gets stuck, only the data is being displayed correctly, the other controls get like frozen.
The question is: How could I display the data continuously and have access to the other controls at the same time?
You have to create a thread of execution that reads the usb while the start is checked.
So we create a thread that is started in the program initialization, which run continuosly and reads usb each time it founds the button checked.
Now in the message loop you simply check or uncheck the button.
DWORD WINAPI ThreadFunction( LPVOID lpParam )
{
(void)lpParam; //make happy compiler for unused variable
while (TRUE) //Once created the thread runs always
{
//If checked reads usb for each iteration
if(SendDlgItemMessage(hWnd,START_BUTTON,BM_GETCHECK ,0,0)== BST_CHECKED)
{
char* var = USB_Read(); //Get data from the sensor
SetWindowText(hLux, var); //Display the data
Sleep(1); //Why this? to don't have a furious CPU usage
}
}
}
.....
//Winmain
DWORD dwThreadId; //thread ID in case you'll need it
//Create and start the thread
CreateThread(
NULL, // default security attributes
0, // use default stack size
ThreadFunction, // thread function name
NULL, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier
......
case WM_COMMAND:
switch (wp)
{
case START_BUTTON:
printf("START_BUTTON");
if(SendDlgItemMessage(hWnd,START_BUTTON,BM_GETCHECK ,0,0)== BST_CHECKED)
SendDlgItemMessage(hWnd,START_BUTTON,BM_SETCHECK ,BST_UNCHECKED, 0);
else
SendDlgItemMessage(hWnd,START_BUTTON,BM_SETCHECK ,BST_CHECKED, 0);
break;
}
break;
EDIT: I modified the program to check/uncheck the radio button.
Please note the usage of the Sleep function with a minimal value of 1ms. It is used to give back control to the OS to smooth the CPU usage. If in the function that reads the usb there are enough OS synch primitives it can be omitted (check cpu usage).

My xlib code can listen to keyboard events but it fails for some windows

I have this code to listen to keyboard events of the active window:
#include<X11/Xlib.h>
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <thread>
using namespace std;
#define IR_MODE 8192
#define SHIFT_MODE 16
#define US_MODE 0
static int ErrorHandler (Display *display, XErrorEvent *error)
{
cout<< "An error ocurred. We don't know anything.";
return 0;
}
int main()
{
Display *d = XOpenDisplay(0);
if(d == 0)
{
cout<< "Cannot open display\n";
exit(0);
}
Window root = DefaultRootWindow(d);
XSetErrorHandler(ErrorHandler);
Window current_window;
int rev;
XGetInputFocus(d,&current_window,&rev);
XSelectInput(d,current_window, KeyPressMask | KeyReleaseMask | FocusChangeMask);
while(true)
{
XEvent e;
XNextEvent(d, &e);
switch(e.type)
{
case FocusOut:
XGetInputFocus(d,&current_window,&rev);
if(current_window == PointerRoot || current_window == None)
{
current_window = root;
}
XSelectInput(d,current_window, KeyPressMask | KeyReleaseMask | FocusChangeMask);
break;
case KeyPress:
{
cout<< "key pressed\n";
break;
}
case KeyRelease:
cout<< "key released\n";
break;
}
}
XCloseDisplay(d);//*/
}
It works for many windows. But it fails for some windows, specially for gnome applications, e.g. nautilus. Why does this happen and how can I solve the problem?
The program just tries to listen to keyboard without interfering anything. As if the keyboard is being tapped with a difference: the program doesn't intend to lose language layout info. When a key is pressed, some information including ASCII codes are chosen and attached to the key event according to language layout and then the key event is sent. The program needs the key event with the information attached to it. So The program does not intend to Grab keyboard. It does not care for active or focused window. It just tries to listen to keys even if the program's window is not active. There are programs which check regularly with XQueryKeymap, but I'm not going to use that. Because it uses up CPU and then it will be more than just a fair listener. Also if checking is not frequent some keys may escape.
I guess your program does not work with GTK3 windows which uses xinput2. This is true if GTK3 was built without --disable-xinput.
AFAIK XSelectInput() won't work with xinput2, you need XISelectEvents() for such windows.
Look at meta_core_select_events() function from Mutter sources. It works both for xinput2 and traditional windows. This patch may be also helpful.

How to check if an opencv window is closed

How do you check if an opencv window has been closed?
I would like to do:
cvNamedWindow("main", 1);
while(!cvWindowIsClosed("main"))
{
cvShowImage("main", myImage);
}
but these is no such cvWindowIsClosed(...) function!
What you are trying to do can be achieved with cvGetWindowHandle():
The function cvGetWindowHandle returns the native window handle (HWND in case of Win32 and GtkWidget in case of GTK+). [Qt Backend Only] qt-specific details: The function cvGetWindowHandle returns the native window handle inheriting from the Qt class QWidget.
The idea is to get the handle of the window and then use specific platform API functions to check if that handle is still valid.
EDIT:
Or you could use the tradicional cvWaitKey() approach:
char exit_key_press = 0;
while (exit_key_press != 'q') // or key != ESC
{
// retrieve frame
// display frame
exit_key_press = cvWaitKey(10);
}
Suppose you have only one image window open, then clicking the 'x' button at its corner causes the waitkey() function to return a -1 value.
Then check if the cvGetWindowHandle("name_of_the_window") function returns 0 or not. If it does return 0, then the window is actually closed.
I have tested it in OpenCV3.
But I am still not very clear on the reason why the waitkey() return -. I will much appreciate if anyone explains why this happens.
[I don't know if my answer to this question will be relevant or not after such a long time. But hopefully if anyone else gets stuck with the same issue (like me), this answer might help them out.]
Thanks.
You can use the cv::getWindowProperty method.
Do like that:
cv::namedWindow("main", WINDOW_AUTOSIZE);
while(1)
{
cv::imshow("main", myImage);
// add this IF.
if (cv::getWindowProperty("main", WND_PROP_AUTOSIZE) == -1)
break;
}
When the windows be closed the getWindowProperty will return -1.
This should do
#include <opencv2/opencv.hpp>
std::string mTitle = "title of my window";
while (cvGetWindowHandle(mTitle.c_str()))
{
// ...
}
In Python OpenCV version 3.4.2, Ubuntu Bionic, cv2.getWindowProperty('Main', cv2.WND_PROP_VISIBLE) returns a floating 0.0 (zero) when the window is closed and 1.0 (one) when it's open, whether see-able or not. Yes, still a 1.0 when it's minimized or behind another window or on a different desktop.
Just before the end of the main(), put the following code:
int main(int, char**){
.
.
.
bool visible = true;
while(visible){
waitKey(1000);
visible = getWindowProperty("Main",WND_PROP_VISIBLE) > 0;
}
return 0;
}

How to get a num lock state using C/C++?

I have read Gdk forum link which says that getting num lock state api is implemented since version 3.0. But I am using version 2.4 and I cannot update to version 3.0 as I need to support lower Linux version. Here is the discussion link:
http://mail.gnome.org/archives/commits-list/2010-July/msg00259.html
SO, is there any other way to get the num lock state using internal Linux command?
Regards,
iSight
Sample code to get the NumLock state. Let foo.c be:
#include <stdio.h>
#include <X11/Xlib.h>
int main(void) {
Display *dpy = XOpenDisplay(":0");
XKeyboardState x;
XGetKeyboardControl(dpy, &x);
XCloseDisplay(dpy);
printf("led_mask=%lx\n", x.led_mask);
printf("NumLock is %s\n", (x.led_mask & 2) ? "On" : "Off");
return 0;
}
Then this gives, tested with CentOS 5 on a Dell laptop:
gcc foo.c -o foo -lX11
foo
led_mask=2
NumLock is On
Or you could do something with popen("xset q | grep LED");.
The second bit of the mask is fairly common for NumLock, but I don't believe it is guaranteed.
Original answer: A good starting point is xev, available for about 20 years:
xev
And you can decode key events via:
foobar (XKeyEvent *bar) {
char dummy[20];
KeySym key;
KeySym keyKeypad;
XLookupString(bar, dummy, sizeof dummy, &key, 0);
keyKeypad = XKeycodeToKeysym(..., bar->keycode, NUMLOCK_Mask);
if (IsKeypadKey(keyKeypad))
...;
// ...
}
If you don't care about the Numlock state "while nothing is happening", and only when e.g. a keypress happens, the lowest overhead way is this.
For some XKeyEvent *xke
bool numlock = ((xke->state & Mod2Mask) == Mod2Mask);
For GDK, you might need something like Gdk.FilterFunc to get the xevent. Check xevent->type.
#include <Xlib.h>
XEvent = (XEvent *) &xevent // from Gdk.FilterFunc
int type = event ->type;
switch(type) {
case KeyPress:
case KeyRelease:
do_something_with((XKeyEvent *) event);
break;
}
I did some sniffing around, and I found a possible implementation with ioctl.h that polls the keyboard state and tests that against a couple of flags.
Take a look at this form post's implementation, and replace K_CAPSLOCK with K_NUMLOCK*. It's pretty fugly, but it can easily be wrapped in a function and tucked away.
*The reason for the replacement on the post was because of an old bug where caps lock and num lock were accidentally reversed. It should be fixed now.
I have checked the hard ware key code. Whenever num lock is on and pressed the number key at num pad i compare the hard ware key code which is universally constant to all manufacturer. Hence, I don't need to use ioctl.h header.
You can use this linux command to do it
{
if (num_lock == 0) system("setleds -F +num");
else if num_lock == 1) ; //do nothing
}