Win API, Keyboard keys

I'm writing a clone to the Notepad to practice my Win API programing (so far it's super fun!) and I wanted to add the option to save the file using the keyboard shortcut, and such (like Ctrl + S for Save and etc)...
I know how to check if the user clicked on 1 key (like if the user pressed enter/escape), but not 2 and etc...

How can I do that ?

By the way, I only need to check if the keyboard has 2 + keys pressed, I've already wrote the "save" function that saves the file and it works :)

Thanks!
Last edited on
closed account (NUj6URfi)
Try using sdl keystates.
Apps like Notepad work with keyboard accelerators.

The keyboard accelerators mechanism maps keyboard sequences to a WM_COMMAND message according to entries in a table stored as a resource, so your app's WndProc just needs to know how to handle WM_COMMAND messages. You only need to handle WM_CHAR or WM_KEYDOWN/WM_KEYUP yourself if you want to do something a bit different.

Keyboard Accelerators
http://msdn.microsoft.com/en-us/library/windows/desktop/ms645526%28v=vs.85%29.aspx

Does your app have an accelerators resource?

ACCELERATORS resource
http://msdn.microsoft.com/en-us/library/windows/desktop/aa380610%28v=vs.85%29.aspx

And does your app's WinMain call LoadAccelerators and TranslateAccelerators?

LoadAccelerators function
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646370%28v=vs.85%29.aspx

TranslateAccelerator function
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646373%28v=vs.85%29.aspx

Andy

PS For example, where IDR_MAIN and the other resource IDs are taken to be defined in resource.h (And I'm using the standard convention for the command IDs, as used by MFC and WTL, like ID_FILE_NEW and ID_EDIT_COPY)

(in resource file)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//

IDR_MAIN ACCELERATORS 
BEGIN
    "N",            ID_FILE_NEW,            VIRTKEY, CONTROL
    "O",            ID_FILE_OPEN,           VIRTKEY, CONTROL
    "S",            ID_FILE_SAVE,           VIRTKEY, CONTROL
    "P",            ID_FILE_PRINT,          VIRTKEY, CONTROL
    "Z",            ID_EDIT_UNDO,           VIRTKEY, CONTROL
    "X",            ID_EDIT_CUT,            VIRTKEY, CONTROL
    "C",            ID_EDIT_COPY,           VIRTKEY, CONTROL
    "V",            ID_EDIT_PASTE,          VIRTKEY, CONTROL
    VK_BACK,        ID_EDIT_UNDO,           VIRTKEY, ALT
    VK_DELETE,      ID_EDIT_CUT,            VIRTKEY, SHIFT
    VK_INSERT,      ID_EDIT_COPY,           VIRTKEY, CONTROL
    VK_INSERT,      ID_EDIT_PASTE,          VIRTKEY, SHIFT
    VK_F6,          ID_NEXT_PANE,           VIRTKEY 
    VK_F6,          ID_PREV_PANE,           VIRTKEY, SHIFT
END


(in main .cpp file)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int APIENTRY
_tWinMain(HINSTANCE hInstance,
          HINSTANCE hPrevInstance,
          LPTSTR    lpCmdLine,
          int       nCmdShow)
{
    // register class, create window, etc

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_MAIN));

    MSG msg = {0};
    while(GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}


Last edited on
Thank you, but Im not using resources at all, since I am using Visual Studio Express, and Resource is not avilabile at this version...

How can I check if 2 buttons are pressed down?

just check inside the "case KEY_DOWN:" twice ?

I've tried this, though it doesnt work :

1
2
3
4
5
6
7
8
		case WM_KEYDOWN:
			if (wParam == VK_LCONTROL)
			{
				if (wParam == 115)
				{
					SaveAs(Edit_Handle, a);
				}
			}
Last edited on
The resource compiler is provided, so resources are available.

It's the Visual Studio resource editor which isn't available, so you have to either edit them manually or use a 3rd party editor like resedit.
http://www.resedit.net/

To do it manually,

1. create a resource file (usually your project's name + .rc) which contains

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
// what_ever_your_proj_is_called.rc

#include <winresrc.h>
#include "resource.h"

/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//

IDR_MAIN ACCELERATORS 
BEGIN
    "N",            ID_FILE_NEW,            VIRTKEY, CONTROL
    "O",            ID_FILE_OPEN,           VIRTKEY, CONTROL
    "S",            ID_FILE_SAVE,           VIRTKEY, CONTROL
    "P",            ID_FILE_PRINT,          VIRTKEY, CONTROL
    "Z",            ID_EDIT_UNDO,           VIRTKEY, CONTROL
    "X",            ID_EDIT_CUT,            VIRTKEY, CONTROL
    "C",            ID_EDIT_COPY,           VIRTKEY, CONTROL
    "V",            ID_EDIT_PASTE,          VIRTKEY, CONTROL
    VK_BACK,        ID_EDIT_UNDO,           VIRTKEY, ALT
    VK_DELETE,      ID_EDIT_CUT,            VIRTKEY, SHIFT
    VK_INSERT,      ID_EDIT_COPY,           VIRTKEY, CONTROL
    VK_INSERT,      ID_EDIT_PASTE,          VIRTKEY, SHIFT
    VK_F6,          ID_NEXT_PANE,           VIRTKEY 
    VK_F6,          ID_PREV_PANE,           VIRTKEY, SHIFT
END


2. create a header called (by convention) resource.h

1
2
3
// resource.h

#define IDR_MAINFRAME                   128  


3. add both to your project

Andy

Last edited on
Is there a chance to use the keyboard capture without resources ?
Use CreateAcceleratorTable instead of LoadAccelerators

CreateAcceleratorTable function
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646365%28v=vs.85%29.aspx

But why don't you want to use a resource?

Andy

PS You could also use WM_CHAR, etc -- but then you'd be re-inventing the wheel....
Topic archived. No new replies allowed.