-
[RESOLVED] [C++] Win32 Program Wide Keyboard Shortcut
I have a window with some settings in it, and I want to be able to close that window via the [Esc] key. However, since I don't want to put that response into every procedure that I have, and since I know I don't have to, I decided I'd find out how it's supposed to be done.
In my research, I found something about registering keystrokes, and I found something about hooks, and although I'm sure I don't want to register anything, I wasn't sure if hooks was the way to go or not, or if there was a simplier method. Hence I come to those more experenced than I.
So what is the proper way to go about this?
Thanks!
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
Is this a Win32 GUI app or Win32 Console app?
For a Win32 GUI you will need to add a case to your message loop for the ESC key. When the ESC key is pressed, tie up your loose ends and exit the application.
For a Win32 Console it is a little different. Unless you want to put a condition check in every function(which you already said you don't) you will have to spawn another thread to wait for the ESC key to be pressed, and when that condition is met, tie up your loose ends and exit the application. You could add other keystrokes to this second thread which would eventually turn into a message loop like in the Win32 GUI.
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
It's a GUI, but it could be on about 5 different window procedures, so do I have to put 5 different cases?
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
If you can exit your application correctly from just one of the windows procedures then add the case to that and do your work there. I don't see why you wouldn't be able to exit the app from your top level window proc, but if you can't for whatever reason, add the case where it is needed.
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
That's part of the reason I posted. However, once one of my edit boxes gets clicked, or my scrollbar gets moved, the top level window is no longer gettings the messages.
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
Handle WM_COMMAND in your dialog procedure and check if wParam is IDCANCEL.
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
I don't have a dialog procedure... or I don't think I do (Still new at this) Everything is made from windows.
Here is a shortened structure:
Code:
//Fonts
HFONT arial18=CreateFont(18,0,0,0,400,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY,FF_DONTCARE,_T("Arial"));
/*2 other fonts here*/
//Variables
//Class 1
RegisterClassEx(&win);
//I tried putting it here, but once I change focus to the scroll bar or something, it doesn't work.
//Main Window
vSet=CreateWindowEx(WS_EX_DLGMODALFRAME,className,_T("Settings"),
WS_CAPTION|WS_SYSMENU|WS_VISIBLE|DS_MODALFRAME,
CW_USEDEFAULT,CW_USEDEFAULT,300,396,hwnd,0,hIns,0);
//Class 2
RegisterClassEx(&scroll);
/*Just some more setup here*/
//Sub class so Page Up/Down can be used
vScrollContentProc=(WNDPROC)SetWindowLong(vScrollContent, GWL_WNDPROC, (long)VSCSubClass);
//Writting the boxes...
//Write Characters and width/amount boxes.
for(int i=32, j=2001; i<=90; i++, j++){
/*Only boring you with one window creation*/
hEdit=CreateWindowEx(0,_T("Edit"),_T(""),editBox,140,yv,43,20,
vScrollContent,(HMENU)++j,hIns,0);
fnEditWndProc=(WNDPROC)SetWindowLong(hEdit, GWL_WNDPROC, (long)fnEditSubClass);
SendMessage(hEdit, WM_SETFONT, (WPARAM)times16, true);
LoadString(GetModuleHandle(0), j+1000, string, 5);
SetDlgItemText(vScrollContent, j, string);
//Increase the count so the next row is in the right spot
yv+=yn;
}
/*Seting up the scrolling and some titles*/
return 0;
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
You have a window procedure for your main window, right?
Handle WM_COMMAND there.
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
Correct, I tried putting a WM_COMMAND case on my main window's procedure, and nothing happened. When escape is pressed nothing is sent to WM_COMMAND.
How is it that programs can use things like [Alt]+F4, [Ctrl]+O, [Ctrl]+S, and so on no matter where in the program you're focused? Surely they don't have hundreds of cases for one key combination? (And yes, I realize I'm not working with combinations)
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
Can you post your project? (remove temporary files like the NCB)
-
1 Attachment(s)
Re: [C++] Win32 Program Wide Keyboard Shortcut
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
You can do something as follows for your message loop:
Code:
while(GetMessage(&msg, NULL, 0, 0) > 0){
if (msg.message == WM_KEYDOWN &&
LOWORD(msg.wParam) == VK_ESCAPE)
MessageBox(hwnd, _T("Cancel"), _T(""), MB_OK);
if(!IsDialogMessage(glbWin.vScrollContent, &msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
of course, instead of displaying a messagebox, forward the escape command to the correct window.
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
Okay, thanks. Is that a common practice for that kind of thing? It seems odd having that there when that window and any others like it (If there are any) will hardly ever be open.
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
Also, I was thinking about it, and that wouldn't work, as I am probably going to want Esc to do something else on the main main window.
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
I have no idea if that is the normal way to do this.
I'm using MFC most of the time.
And I use dialogs which probably work differently internally.
Maybe you can switch to use dialogs and a dialogproc for your dialogs besides your main window?
Anyway, if you do handle it as I showed above, you can always just forward this escape capturing to the window that has currenty focus and let it handle the escape however it wants.
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
Thanks for all your help then.
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
I found it!
With the help of http://www.cplusplus.com/forum/windows/36860 I changed my search from "shortcut" to "hotkey" I found something about keyboard accelerators (http://social.msdn.microsoft.com/For...2-617d69557057) which led me here: http://msdn.microsoft.com/en-us/libr...ting_acc_table
After figuring out the way it worked, I have this (Spread across several files)
Code:
/*Keyboard Accelerators*/
ShortAccel ACCELERATORS {
VK_ESCAPE, IDA_ESC, VIRTKEY
}
/*---*/
//Load accelerators
HACCEL haccel;
haccel=LoadAccelerators(hinst, _T("ShortAccel"));
if(!haccel) //Make sure it loaded
MessageBox(hwnd, _T("Unable to load accelerator table"), _T("Error"), MB_ICONERROR);
while(GetMessage(&msg, NULL, 0, 0) > 0){
if(!TranslateAccelerator(FindWindow(_T("SettingsWindow"),_T("Settings")),haccel,&msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
/*---*/
#define IDA_ESC 4001
/*---*/
LRESULT fnSettingsProc_OnCommand(lpWndEventArgs wea){
switch(LOWORD(wea->wParam)){
case IDA_ESC: //Name given in accelerator table
DestroyWindow(wea->hwnd);
break;
}
return 0;
}
It works prefectly.
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
You may be surprised, but code suggested by Mark hardly differs much from the last code you showed. What translate accelerator does is sending WM_COMMAND with corresponding id in case virtual key can be found in the table.
Code:
while(GetMessage(&msg, NULL, 0, 0) > 0){
if (msg.message == WM_KEYDOWN &&
LOWORD(msg.wParam) == VK_ESCAPE)
SendMessage(FindWindow(_T("SettingsWindow"),_T("Settings")), WM_COMMAND, IDA_ESC, 0);
if(!IsDialogMessage(glbWin.vScrollContent, &msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
I see what you mean. I think I'll stick with the method I found though, as it is easier to expand.
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
...and you're 100% right. My point was just to make a bond between what you've found yourself and what you've been told of before. :)
-
Re: [C++] Win32 Program Wide Keyboard Shortcut
And that I do appreciate. I wouldn't have known that is how it worked if it wasn't for your telling me. :)
-
Re: [RESOLVED] [C++] Win32 Program Wide Keyboard Shortcut
Quote:
Originally Posted by
Marc G
You can do something as follows for your message loop:
Code:
while(GetMessage(&msg, NULL, 0, 0) > 0){
if (msg.message == WM_KEYDOWN &&
LOWORD(msg.wParam) == VK_ESCAPE)
MessageBox(hwnd, _T("Cancel"), _T(""), MB_OK);
if(!IsDialogMessage(glbWin.vScrollContent, &msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
of course, instead of displaying a messagebox, forward the escape command to the correct window.
This can done in the window callback handler. ie: in WindowProc. And for removing that behavior instead of showing a msgbox just drop the value bu setting a NULL.
Code:
LRESULT CALLBACK wndProc (HWND hW, UINT msg, WPARAM wP, LPARAM lP)
{
switch (msg)
{
case WM_KEYDOWN:
{
if (wParam == VK_ESCAPE)
wParam = NULL;
}
}
return 0;
}
just an alternative for the above code.
-
Re: [RESOLVED] [C++] Win32 Program Wide Keyboard Shortcut
Quote:
just an alternative for the above code.
No, it's not. The code in the message loop works with focus set anywhere in the app. Unlike your "alternative" which requires to have a focus on the particular window.