Global Hotkeys

I need a good method of doing global hotkeys in c++. Does anybody know of any method or function in c++ I could use for global hotkeys? Thanks in advance!
Hot keys to do what?
Are you serious?
Hot key is a very general term, one that I don't recognise as part of everyday C++ lingo. So yes I am seriously asking you to refine your broad as a barn side question. If you are refering to the Windows Hot keys and thought that would be intuative because you posted in the Windows section then those are done in the registry. If you are refering to Macro's or anything else then I would ask for clearification.
I see now that this is a question you have been asking about for a while now. Your origional program looks like you were heading in the right direction (http://www.cplusplus.com/forum/windows/23333/). Why didn't you just bump this thread back up?

Anyway, you're traping yourself in that last while loop. Scrap it and start again, but this time instead of going into deeper while() loops just drop a if() condition into the standard event handler that tests a boolean that you toggle with your alt+key. When true run your little Move_Mouse function, else rest of event handler loop.

You act like I'm asking a novice question when you're the one who is stuck on one of the most basic concepts of event handling?
Sorry, I didn't know you were asking it that way. I also misread it as "Hotkeys do what?" and I apologize. I didn't bump it because I wanted to find out if there was another way to do hotkeys.

EDIT: What you said does not work. I want it stay at 100, 100 (I think) until the user presses ALT+w/e (I forgot). I don't know how to do that with if() statements but I did try and I got errors. Here is the code:

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "stdafx.h"


void Spin (int x, int y )
{  
	double fScreenWidth    = ::GetSystemMetrics( SM_CXSCREEN )-1; 
	double fScreenHeight  = ::GetSystemMetrics( SM_CYSCREEN )-1; 
	double fx = x*(65535.0f/fScreenWidth);
	double fy = y*(65535.0f/fScreenHeight);
	INPUT  Input={0};
	Input.type      = INPUT_MOUSE;
	Input.mi.dwFlags  = MOUSEEVENTF_MOVE|MOUSEEVENTF_ABSOLUTE;
	Input.mi.dx = fx;
	Input.mi.dy = fy;
	::SendInput(1,&Input,sizeof(INPUT));
}


int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine,
				   int nCmdShow)
{
	bool spin;
	HWND hwnd;

	RegisterHotKey(
		hwnd,
		1,
		MOD_ALT,
		0x53);  //0x53 is 's'

		if (WM_HOTKEY==1)
		spin=true;

	if (spin)
		Spin(1024, 384);

	/*
	MSG msg1 = {0};
	while (GetMessage(&msg1, NULL, 0, 0) == 1)
	{
		if (msg1.message == WM_HOTKEY)
		{
			if (GetMessage!=2)
			{
				Spin(1024, 384);
			}
		}
	} 
	*/

	RegisterHotKey(
		hwnd,
		2,
		MOD_ALT,
		0x41);  //0x41 is 'a'
		if (WM_HOTKEY==1)
		spin=false;

	if (!spin)
		return 0;

	/*
	MSG msg2 = {0};
	while (GetMessage(&msg2, NULL, 0, 0) == 2)
	{
		if (msg2.message == WM_HOTKEY)
		{
			return 0;
		}
	}
	*/
}


And here is the errors I get which quite frankly don't make sense:

Run-Time Check Failure #3 - The variable 'spin' is being used without being initialized.
Run-Time Check Failure #3 - The variable 'hwnd' is being used without being initialized.
Run-Time Check Failure #3 - The variable 'spin' is being used without being initialized.
Last edited on
Yeah they mean that the variables are being used in the program with out a value being assigned to them. Give them a default value when you declare them and you should be good.
Thank you for your reply but, I tried that and it did not work it turned on (didn't even move my mouse) then closed (I checked task manager). I changed my WinMain function to this:

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
int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine,
				   int nCmdShow)
{
	//bool spin = false;
	//HWND hwnd;

	RegisterHotKey(
		NULL,
		1,
		MOD_ALT,
		0x53);  //0x53 is 's'

		if (WM_HOTKEY==1)
		Spin(100, 100);

	/*
	MSG msg1 = {0};
	while (GetMessage(&msg1, NULL, 0, 0) == 1)
	{
		if (msg1.message == WM_HOTKEY)
		{
			if (GetMessage!=2)
			{
				Spin(1024, 384);
			}
		}
	} 
	*/

	RegisterHotKey(
		NULL,
		2,
		MOD_ALT,
		0x41);  //0x41 is 'a'
	
	if (WM_HOTKEY==2)
		return 0;

	/*
	MSG msg2 = {0};
	while (GetMessage(&msg2, NULL, 0, 0) == 2)
	{
		if (msg2.message == WM_HOTKEY)
		{
			return 0;
		}
	}
	*/
}


I'm pretty sure it has something to do with my "WM_HOTKEY==" not being recognized.
Last edited on
Keyboard notifications are usually handled by switch case statements, then the notification would toggle a boolean variable in this case. You don't seem to be using WM_HOTKEY right, try adding it as a case in your message handler.
Can't get it to work. It didn't work just putting a switch case statement in my message handler. I had to make a UINT to even use the switch case statement and even then it did nothing when I compiled it. I altered my code to look like this:

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include "stdafx.h"


void Spin (int x, int y )
{  
	double fScreenWidth    = ::GetSystemMetrics( SM_CXSCREEN )-1; 
	double fScreenHeight  = ::GetSystemMetrics( SM_CYSCREEN )-1; 
	double fx = x*(65535.0f/fScreenWidth);
	double fy = y*(65535.0f/fScreenHeight);
	INPUT  Input={0};
	Input.type      = INPUT_MOUSE;
	Input.mi.dwFlags  = MOUSEEVENTF_MOVE|MOUSEEVENTF_ABSOLUTE;
	Input.mi.dx = fx;
	Input.mi.dy = fy;
	::SendInput(1,&Input,sizeof(INPUT));
}


int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine,
				   int nCmdShow)
{



	//if (WM_HOTKEY==1)
	//Spin(1024, 384);


}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	bool spin;
	HWND hwnd;

	RegisterHotKey(
		NULL,
		1,
		NULL,
		0x53);  //0x53 is 's'

	/*RegisterHotKey(
		NULL,
		2,
		NULL,
		0x41);*/  //0x41 is 'a'

	MSG msg = {0};
	//UINT message;
	while (GetMessage(&msg, NULL, 0, 0) == 1)
	{
		switch (message)
		{
		case WM_HOTKEY:
			spin = true;
			break;
			while (spin)
			{
				Spin(1024, 384);
				return 0;
			}
		}
	}
	/*while (GetMessage(&msg, NULL, 0, 0) == 2)
	{
		switch (message)
		{
		case WM_HOTKEY:
			spin = false;
			break;
			if (!spin)
				return 0;
		}
	}*/
}


//if (WM_HOTKEY==2)
//return 0;

/*
MSG msg2 = {0};
while (GetMessage(&msg2, NULL, 0, 0) == 2)
{
if (msg2.message == WM_HOTKEY)
{
return 0;
}
}
*/


I'll try one more thing but, this just isn't working! :(
Bump, Please help!
That wont work because your window procedure(WndProc) is never called. Why don't you set up a proper WNDCLASSEX structure, and then register you window procedure with it.
I don't know? Am I missing something? Here is a proper Win32 app and I set up the hotkeys as instructed... *sigh* Anyways, here is the code:

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <windows.h>
#include <tchar.h>

// Global variables
/*int keyone = 1;*/
/*int keytwo = 2;*/

// The main window class name.
static TCHAR g_szWindowClass[] = _T("win32Spinapp");


// Foward declaration of the 'Spin' function
void Spin (int x, int y );

// Foward declaration of the Windows Procedure
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine, int nCmdShow)
{
	/*double sWidth 	= ::GetSystemMetrics( SM_CXSCREEN )-1;*/
			//Gets the screen width
	/*double sHeight	= ::GetSystemMetrics( SM_CYSCREEN )-1;*/
			//Gets the screen height

	WNDCLASSEX wc;
	HWND hwnd;
	MSG Msg;


	//Optional Pre-Step: Hotkeys To Call Your App Functions
	RegisterHotKey(
			NULL,
			1,
			NULL,
			0x53); //0x53 is 's'


	//Step 1: Registering the Window Class
	wc.cbSize        = sizeof(WNDCLASSEX);
	wc.style         = 0;
	wc.lpfnWndProc   = WndProc;
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;
	wc.hInstance     = hInstance;
	wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO);
	wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
	wc.lpszMenuName  = NULL;
	wc.lpszClassName = g_szWindowClass;
	wc.hIconSm       = LoadIcon(NULL, IDI_WINLOGO);

	if(!RegisterClassEx(&wc))
	{
		MessageBox(NULL, "Failed To Register Window!", "Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}


	// Step 2: Creating the Window
	hwnd = CreateWindowEx(
		WS_EX_CLIENTEDGE,
		g_szWindowClass,
		"Serpentine's Spin Bot V 1.1",
		WS_POPUPWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, 300, 120,
		NULL, NULL, hInstance, NULL);

	if(hwnd == NULL)
	{
		MessageBox(NULL, "Failed To Create Window!", "Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	/*::MoveWindow(hwnd, sWidth/2, sHeight/2, 300, 120, TRUE);*/
			//Moves window
	/*ShowWindow(hwnd, nCmdShow);*/
			//Shows window, in this case
			//it's hidden since commented
	/*UpdateWindow(hwnd);*/
			//Updates the window for the
			//above to take affect
//==============================================================//

	// Step 3: The Message Loop
	while(GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	return Msg.wParam;
}

// Optional Step: Your Functions Four Your App, Have Fun!
void Spin (int x, int y )
{  
	double fScreenWidth    = ::GetSystemMetrics( SM_CXSCREEN )-1; 
	double fScreenHeight  = ::GetSystemMetrics( SM_CYSCREEN )-1; 
	double fx = x*(65535.0f/fScreenWidth);
	double fy = y*(65535.0f/fScreenHeight);
	INPUT  Input={0};
	Input.type      = INPUT_MOUSE;
	Input.mi.dwFlags  = MOUSEEVENTF_MOVE|MOUSEEVENTF_ABSOLUTE;
	Input.mi.dx = fx;
	Input.mi.dy = fy;
	::SendInput(1,&Input,sizeof(INPUT));
}

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_HOTKEY:
		Spin(1820, 800);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
		break;
	}
	return 0;
}
According to MSDN, the WM_HOTKEY message must be processed in the message queue(sorry if I have mislead you).
So, your message loop should look like this:
1
2
3
4
5
6
7
8
MSG msg = {0};
while (GetMessage(&msg, NULL, 0, 0) != 0)
{
     if (msg.message == WM_HOTKEY)
    {
             //Handle WM_HOTKEY message      
     }
}


Also, I don't think that the fsModifiers argument of RegisterHotKey can be NULL, and this should be placed in your WinMain function.

Last edited on
I put it their before, just didn't know how to get it to recognize it. This will be my third time being told to do something different. I'll try it out tomorrow, thank you for your time, effort, and patience!
Topic archived. No new replies allowed.