[C++] How to make a program wide shortcut?

Specifically, I want escape to close a certain "dialog" window I have open, only it isn't a dialog, and there's 4-5 different procedures that can be called.

So is there a simple way to make it that when I press [Esc] whether I'm focused on my scrollbar, or one of my edit boxes, or maybe the main window that the window closes? Or do I have to add a case for each procedure for this to work?

Thanks for the help!
[Bump]
Hi meesa!

My guess would be that every specific control/window type has its own WndProc, be they edit controls, scroll bar controls, the main dialog window (which ain't a 'dialog', likely) , and what-not. So I expect you'll need code everywhere one of these window procedures is located.

I had a thought this might be an oportunity to do a PeekMessage() or something like that in the program's messaqge pump, but not all messages go through the message quene - some are sent directly to window procedures. Those would be my thoughts anyway.

Fred
Is that really the only way? I had supposed that there would be an easier way; that when people do things like program for [Ctrl]+O and [Ctrl]+S that they wouldn't be putting that same information into every procedure.

So I guess I should ask: Windows really doesn't have a way to say: "When I'm running, if X is pressed do this."?

I guess I could also use the example of Y! Messenger, if you press [Win]+Y when it is running, it opens, but if it's not, nothing happens. So how do they do that kind of system wide thing? And I only want to do it when the program is active, should there be some confusion.
Last edited on
You need to put it in the form's window procedure.

Individual controls only get things like keypresses after they have been dispatched by the form's window procedure.

What library are you using to write this? Pure Win32? Borland C++ Builder? VCL?
Well there's this:
http://msdn.microsoft.com/en-us/library/ms646309(VS.85).aspx
It's global but you shouldn't have issues making it a program-wide-only shortcut.
Duoas, I'm using pure hand-written Win32.

Opossum, I had come across that, but then I would still need to unregister the key everytime the window looses focus, which I would think would be difficult because one thing losing focus doesn't mean that the window isn't still focused in another area.

I came across this: http://msdn.microsoft.com/en-us/library/ms646284(v=VS.85).aspx
I could research it, but I figure I'll see if you guys know first. If I use that, can I set it to [Esc] instead of what they show there, and it says it focuses the window, so does that mean that I can send it to one window, and then if I ever press [Esc] that window will gain focus, and be able to process that [Esc] was just pressed, thus processing to close the window?
All you can do is try it.

I had another thought about my PeekMessage() idea. I think although I'm not 100% positive that all keyboard messages go through the program's message queene. So maybe you could actually test there. However, I'm not sure about when child window controls have focus.
Well, I didn't read far enough. :(

VK_ESCAPE, VK_SPACE, and VK_TAB are invalid hot keys.


As for using PeekMessage(), although it may work, I think I'd rather have a case in each procedure than do that so then I'm not waisting time with an if statment when the window isn't open.
I found it!

After changing my search from "shortcut" to "hotkey" I found something about keyboard accelerators (http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/31c6817a-a842-40b3-8cd2-617d69557057) which led me here: http://msdn.microsoft.com/en-us/library/ms646337(v=VS.85).aspx#creating_acc_table

After figuring out the way it worked, I have this (Spread across several files)
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
/*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. I still have that if that I didnt want to use due to that it may not always be necessary, but at least I know I'm using the method that is meant to be used for this kind of thing. Or so I would assume since the examples show things like Saving and opening things with this method, which is what I had assumed I would want to be using anyways.
Topic archived. No new replies allowed.