Problem in handling the WM_KEYDOWN message.

Hey.

I've created a window class which should print "Control key pressed" each time the control key is being pressed.
To do that , I need to handle the WM_KEYDOWN message.

This is what I wrote

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#define _WIN32_WINNT 0x0501
#define WINVER 0x0501
#include <windows.h>
#include <iostream>

using namespace std;

LRESULT APIENTRY MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_KEYDOWN:
        if (VK_CONTROL==wParam)
            cout<<"Control key pressed"<<endl;
        break;
        case WM_DESTROY:
        PostQuitMessage(0);
        break;
        default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    MSG Msg;
    const char lpcszClassName[] = "myWindowClass";
    WNDCLASSEX  WindowClassEx;
    //Registering the Window Class
    ZeroMemory(&WindowClassEx, sizeof(WNDCLASSEX));
    /*********/
    WindowClassEx.cbSize        = sizeof(WNDCLASSEX);
    WindowClassEx.lpfnWndProc   = MainWndProc;
    WindowClassEx.hInstance     = hInstance;
    WindowClassEx.lpszClassName = lpcszClassName;
    /*********/
    if (RegisterClassEx(&WindowClassEx) != 0)
    {
        // Create a _MESSAGE ONLY_ window
        if (CreateWindowEx(0, lpcszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, hInstance, NULL) != NULL)
        cout<<"Window created sucusessfully"<<endl;
        else
        UnregisterClass(lpcszClassName, hInstance);
    }
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
     return (int)Msg.wParam;
}


*as you can see , my window is a message-only window.

My code doesn't work, I don't know why.

Any suggestions ?
This has me baffled, however, I kinda have a solution...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#define _WIN32_WINNT 0x0501
#define WINVER 0x0501
#include <windows.h>
#include <iostream>

using namespace std;

LRESULT APIENTRY MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_KEYDOWN:
        if (VK_CONTROL==wParam)
            cout<<"Control key pressed"<<endl;
        break;
        case WM_DESTROY:
        PostQuitMessage(0);
        break;
        default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    HWND hwnd; // new line
    MSG Msg;
    const char lpcszClassName[] = "myWindowClass";
    WNDCLASSEX  WindowClassEx;
    //Registering the Window Class
    ZeroMemory(&WindowClassEx, sizeof(WNDCLASSEX));
    /*********/
    WindowClassEx.cbSize        = sizeof(WNDCLASSEX);
    WindowClassEx.lpfnWndProc   = MainWndProc;
    WindowClassEx.hInstance     = hInstance;
    WindowClassEx.lpszClassName = lpcszClassName;
    /*********/
    if (RegisterClassEx(&WindowClassEx) != 0)
    {
        // Create a _MESSAGE ONLY_ window
	hwnd = CreateWindowEx(0, lpcszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, hInstance, NULL);
        if (hwnd != NULL)
        cout<<"Window created sucusessfully"<<endl;
        else
        UnregisterClass(lpcszClassName, hInstance);
    }
    ShowWindow(hwnd,nCmdShow);
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
     return (int)Msg.wParam;
}


Note the additions of "HWND hwnd;" & then "hwnd = Create..."

Now... this works for me but only when I first execute the program, & the console window top doesn't turn blue (for active window), but it is on top of all others... I will keep trying to solve this properly...
Thank you , it worked.
But as you said , this code works only if the focus is on program's window.
Is there anyway to do it when the focus isn't on the specific window ?
(i.e. to print "Control key pressed" whenever the user presses the Control key , even if the focus isn't on the specific window I've created)
If you mean when for example, the console is minised I suggest you look here:
http://msdn.microsoft.com/en-us/library/ms646293(VS.85).aspx - for the MSDN documentation about the GetAsyncKeyState function
& also here - http://www.cplusplus.com/forum/windows/6632/ - for another thread about this function.
I know about the GetAsyncKeyState function.
I am working on a program right now, and I need to create a message-only window there.
So how should I use the GetAsyncKeyState function there? I mean , It need to be used in a loop , and I can't use it in the message loop..
Well one way (seeing as we are using WIN API for this) is to use the Windows function to multi-thread our program, basically make it do more than one thing "at once" (well, pretty much at once).

This can be achieved using the function CreateThread (http://msdn.microsoft.com/en-us/library/ms682453(VS.85).aspx ).

I made this example & I hope it helps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<windows.h> // include windows library
#include<stdio.h>
HANDLE hThread1; // make this global - could be useful
DWORD dThread1ID; // ID for the thread
DWORD WINAPI GetKeys(LPVOID lParam) // your function for the thread
{
while(1)
{
if(GetAsyncKeyState(VK_LEFT)) // test for character being pressed, used LEFT (arrow key) as an example
{
// do something
printf("http://www.cplusplus.com\n"); // for example print this cool website address
}
Sleep(1); // stop the loop using too much CPU usage
}
return 0; // hopefully never reach here
}
int main()
{
// create the thread with handle thread1;
hThread1=CreateThread(NULL, // default security attributes
                     0, // use default stack size
                     GetKeys, // function name for the thread
                     0, // arguments to the thread - don't really need any here, so 0
                     0, // use default creation flags
                     &dThread1ID); // returns the thread identifier here
if(dThread1ID!=NULL) // if the thread is working
{
// do something
printf("thread working"); // like tell the user thread is working
}
getchar(); // just pause the main thread (for this example, won't need in your windows)
return 0;
}


Let me know if you need anything else
Last edited on
It worked. Thank you very very much.
No problems mate - any time =)
Topic archived. No new replies allowed.