|
-
June 11th, 2008, 05:28 PM
#1
Detect what key has been pressed (even if not focused)
Hello, I am pretty new with C++ but I managed to make a simple desktop game. I have a problem, how can I detect what key is pressed (even if the window is not focused).
I am asking this becouse I don't have a window, the "players" are drawed directly on the desktop, and I need it to detect WHAT key has been pressed (global) .
So I need a function similar to this :
getKeyPress()
This will return what key has been pressed .
Can someone please help me with this ?
-
June 11th, 2008, 05:56 PM
#2
Re: Detect what key has been pressed (even if not focused)
You need to use the win32 api function RegisterHotKey(...)
This will send the window you specify a WM_HOTKEY message.
s
-
June 12th, 2008, 01:21 AM
#3
Re: Detect what key has been pressed (even if not focused)
If I'm not wrong, you're looking for:
GetAsyncKeyState()
-
June 12th, 2008, 01:31 AM
#4
Re: Detect what key has been pressed (even if not focused)
No. That function just tells you the state of a specified key. What the OP wants is a way to be notified if a key is pressed. RegisterHotKey() is the correct function.
s
-
June 12th, 2008, 07:27 AM
#5
Re: Detect what key has been pressed (even if not focused)
Thank you very much. I will look in to this
(I was looking for RegisterHotKey(...) )
-
June 12th, 2008, 09:45 AM
#6
Re: Detect what key has been pressed (even if not focused)
Hello, I tried to solve this but I can't do it. I am not that good with win32, and I know that this may seem lazy, but I am not, I just can't do it.
Can someone give me an example of a function that returns the key that is holded globaly (ascii value) ?
I would appreciate this a lot. Thank you again
-
June 13th, 2008, 12:22 AM
#7
Re: Detect what key has been pressed (even if not focused)
This is pretty simple. Although getasynckeystate() normally works good enough for moving of objects, but to be specific to when a key is pressed and released, it is not that good and so you need to use another api called SetWindowsHookEx() and using the WH_KEYBOARD or WH_KEYBOARD_LL for the idHook parameter. This will call a function that you specify and give you the list of vkcodes that was pressed. Now vkcodes aren't character codes nor scan codes. They really should be translated into character code and lower cased when certain keys aren't pressed. For ex. the shift key or caps. Perhaps someone else can better explain this to you or I can help you aswell, but like you requested, here is some code that will do the trick
Code:
#include <iostream>
#include <windows.h>
using namespace std;
HHOOK hooked = 0;
LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam)
{
KBDLLHOOKSTRUCT* ABoutKeyboard = (KBDLLHOOKSTRUCT*)lParam;
cout << "Recieved key" << ABoutKeyboard->vkCode << endl;
return CallNextHookEx ( hooked, nCode , wParam, lParam );
}
int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{
hooked = SetWindowsHookEx(WH_KEYBOARD_LL, &LowLevelKeyboardProc, hThisInstance, NULL);
if (hooked == NULL)
{
cout << "Error" << endl;
}
MSG messages;
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return messages.wParam;
}
If this helped you, tell me 
Also I will let you figure out if the key was pressed or released. You will receive both, but I haven't done any extra work. Visit msdn to look at what else the function gets passed. http://msdn.microsoft.com/en-us/libr...85(VS.85).aspx
Last edited by Joeman; June 3rd, 2010 at 02:36 PM.
-
June 13th, 2008, 09:24 AM
#8
Re: Detect what key has been pressed (even if not focused)
There isn't a callback function with RegisterHotKey(), it sends a WM_HOTKEY to your registered Window.
There are many ways to get keystrokes, the most popular is to do Windows hooks. The problem there is that it is very complicated and you GPF a lot developing it. RegisterHotKey() was a very good suggestion for a beginning programmer.
Are you using the Windows API directly, using MFC, or using some other package system (.NET, Borland, etc.)?
No one can give a relevant example without knowing what you are using...
-Erik
Last edited by egawtry; June 13th, 2008 at 09:28 AM.
-
June 13th, 2008, 04:23 PM
#9
Re: Detect what key has been pressed (even if not focused)
Hello, thank you all for your help again.
Joeman manage to do EXACTLY what I need.
Thank you again so much
-
June 14th, 2008, 06:14 PM
#10
Re: Detect what key has been pressed (even if not focused)
Joeman, I need help from you again. I want to make a DLL from this code so I can share it with a friend (that only knows to programm in dark basic).
DarkBasic cand get the value of a function from a dll only if it's double.
How can I make this ? I tried in the past 2 days a lot of things, but I just can't do it. Here is a good dll example (it returns the sum of 2 numbers) :
#define export extern "C" __declspec (dllexport)
export double sum(double a, double b)
{
return(double)a+b;
}
Now, I want a function for the dll that is -1 if no key is pressed, and the ASCII value of the key pressed, if the key is pressed (any key). The console app works perfect,but how can I convert it to a dll ?
I tried this :
export LRESULT CALLBACK LowLevelKeyboardProc(......
but the problem is that I need it double, and not LRESULT CALLBACK.
I don't have any clue on how I can get the code ABoutKeyboard->vkCode exported from another function . Something like :
export double GetKey()
{
if (ABoutKeyboard->vkCode==0) // if no key is pressed, return -1
return -1
return ABoutKeyboard->vkCode;
}
How can I do this ? Thank you again so much for the help. This is the best forum I found regarding programming
-
June 15th, 2008, 11:08 PM
#11
Re: Detect what key has been pressed (even if not focused)
I am really confused on why you are tying to do this.
I don't know darkbasic, but are you sure you need to do all that just to get good input from the keyboard? This keyboard hook gets called by the os and not by someone that request it at anytime. What you are asking me to do is rely these key states to a function he has in his project in dark basic. Now I am not sure you can do this for darkbasic, but you can do this in c++ easily. All you need to do is pass a function to the main dll to register it to receive these calls when they are sent from the os. I could do this for you, but I would like to see you get better and not just copy and paste all the time 
I also think darkbasic would provide simple input from the keyboard if they can make a program language for game making.
Is there another way to do this instead of using c++ to get the keys in darkbasic or are you tring to do an alternative?
-
June 16th, 2008, 07:11 PM
#12
Re: Detect what key has been pressed (even if not focused)
Hello, I guess you were right. I managed to do it by myself, and thank you for this. I learned some good things from this .
Here is how I done it :
HHOOK hooked = 0;
int key,notsafe=0;
#define export extern "C" __declspec (dllexport)
export double GetLastKey()
{
if(notsafe)
return (double) 0;
return (double) key;
}
LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam)
{
KBDLLHOOKSTRUCT* ABoutKeyboard = (KBDLLHOOKSTRUCT*)lParam;
notsafe = 1;
key = ABoutKeyboard->vkCode;
notsafe = 0;
return CallNextHookEx ( hooked, nCode , wParam, lParam );
}
export double init(double h)
{
HWND handle=(HWND)(int)h;
HINSTANCE hInstance = (HINSTANCE)GetWindowLong(handle, GWL_HINSTANCE);
hooked = SetWindowsHookEx(WH_KEYBOARD_LL, &LowLevelKeyboardProc, hInstance,0);
MSG messages;
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return 1;
}
I have one last problem. When I call GetLastKey, I get the key that is holded, and even if a key is not holded, I still recieve the last key code of the last holded key.
I don't know how to make it return a char like this :
"0" if no key is holded
"p65" if a is pressed
"r65" if a is released
How can I get if a key (globaly) is pressed/released ? I studyed the MSDN a little but didn't find any good ways to do it .
Hope you can help again, I am stuck
-
June 17th, 2008, 02:32 AM
#13
Re: Detect what key has been pressed (even if not focused)
I do see a couple of mistakes in your code. I am glad you showed initiative and I am more than willing to help. I few of your mistakes is on the nosafe variable with the if statement. What you have done is put a lock on when that key is being changed, but there is no need to. You haven't figured out if it was pressed or released yet and I will get into that.
It sounds to me like you could use GetKeyState or GetKeyboardState function from microsoft instead of doing this, but I will continue on. 
I rewrote my first post's code. I added the function to change the vkcode to a char code and check to see if it was pressed or released. Also I have added a double function to return the current key that is being pressed. I called it GetLastKey to reference it to your same function(GetLastKey).
Code:
#include <iostream>
#include <windows.h>
#include <ctype.h>
#define MAPVK_VK_TO_CHAR 2
using namespace std;
HHOOK hooked = 0;
char Key = 0;
bool Locked = false;
double GetLastKey(){
while(Locked){}
return (double)Key;
}
char TranslateVKeyToChar( int KeyCode ){
char Key = (char)MapVirtualKey(KeyCode, MAPVK_VK_TO_CHAR);
Key = tolower(Key);
if((GetKeyState(VK_CAPITAL) & 0x1) && !( (GetKeyState(VK_SHIFT) & 0x80) >> 7) ){ Key = toupper(Key);}
if(!(GetKeyState(VK_CAPITAL) & 0x1) && ( (GetKeyState(VK_SHIFT) & 0x80) >> 7) ){ Key = toupper(Key);}
if((GetKeyState(VK_SHIFT) & 0x80) >> 7 ){
if( Key == '1' ){ Key = '!'; }
if( Key == '2' ){ Key = '@'; }
if( Key == '3' ){ Key = '#'; }
if( Key == '4' ){ Key = '$'; }
if( Key == '5' ){ Key = '%'; }
if( Key == '6' ){ Key = '^'; }
if( Key == '7' ){ Key = '&'; }
if( Key == '8' ){ Key = '*'; }
if( Key == '9' ){ Key = '('; }
if( Key == '0' ){ Key = ')'; }
if( Key == '-' ){ Key = '_'; }
if( Key == '=' ){ Key = '+'; }
if( Key == '[' ){ Key = '{'; }
if( Key == ']' ){ Key = '}'; }
if( Key == ';' ){ Key = ':'; }
if( (int)Key == 39 ){ Key = char(34); } // ' to "
if( (int)Key == 92 ){ Key = char(124); } // \ to |
if( Key == ',' ){ Key = '<'; }
if( Key == '.' ){ Key = '>'; }
if( Key == '/' ){ Key = '?'; }
// you can also make a few key additions here.
}
return Key;
}
LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam)
{
Locked = true;
KBDLLHOOKSTRUCT* ABoutKeyboard = (KBDLLHOOKSTRUCT*)lParam;
Key = TranslateVKeyToChar(ABoutKeyboard->vkCode);
if( wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN ){
cout << "Key " << Key << " pressed" << endl;
}else{
cout << "Key " << Key << " released" << endl;
Key = 0;
}
Locked = false;
return CallNextHookEx ( hooked, nCode , wParam, lParam );
}
int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{
hooked = SetWindowsHookEx(WH_KEYBOARD_LL, &LowLevelKeyboardProc, hThisInstance, NULL);
if (hooked == NULL)
{
cout << "Error" << endl;
}
MSG messages;
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return messages.wParam;
}
Did I leave anything out. Did I forget something you asked? I think I covered it. All you have to do now is start placing my new code into yours and getting it dll ready
-
June 17th, 2008, 06:24 PM
#14
Re: Detect what key has been pressed (even if not focused)
Hello, this was almost exactly what I need. I modified the code a bit and now it's perfect.
I didn't need to convert from ascii to char (65=a) . I just needed the key pressed or released returned as char. Eg :
"p65" = pressed 65
I needed this so I can know if a key is pressed or released.
Anyways, you are really good, and I appreciate your help A LOT !
thank you again
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|