keep a formless application from closing for a keyboard hook - c++

I am working on a c++ win32 program that involves a keyboard hook. The application is a win32 project with no user interface whatsoever. I need to keep the application from closing without using causing the hook to not work or use up a bunch of system resources. I used to use a message box but I need the application to be completely invisible.
Any help would be appreciated!
If you have any questions just ask.

I think what you need is message only window
(MSDN says) A message-only window enables you to send and receive messages. It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages. The window simply dispatches messages.

Do you really need windows?
The MSDN LowLevelKeyboardProc page recommends using a simple message loop.
Just insert this snippet after the hook call.
// message loop to keep the keyboard hook running
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

A better way would be to add an loop that keeps going around.
bool shouldExit = false;
do
{
//some code to handle events
shouldExit = handleEvents();
//sleep for a small bit so we dont take up 100% cpu
sleep(500);
}
while (!shouldExit);

Related

Window message WM_SIZING sending incessantly when window resizing

I make small game and have some problem with low priority window messages, that incessantly sending from system and block running game logic's code.
I create my message loop something like this:
bool Window::SystemRoutineAndCheckQuit() {
::MSG msg;
while( ::PeekMessage( &msg, nullptr, 0, 0, PM_REMOVE ) ) {
if( msg.message == WM_QUIT ) {
::UnregisterClass( registeredClassName, ::GetModuleHandle( nullptr ) );
DLOG( lg ) << "Exit from system loop" << DLOG_END;
return false;
}
::TranslateMessage( &msg );
::DispatchMessage( &msg );
}
return true;
}
//....
while( window.SystemRoutineAndCheckQuit() ) {
// do all render and logic
}
I.e. before every frame I wanna process all messages from windows and then, when queue will empty do all logic. I notice when window resizing I get same message WM_SIZING again and again and queue never will empty when mouse button still press (even when size of window don't change from previos call I receive message with same window coordinates). So it block execute my code.
Is there any other messages, that keep windows message queue don't empty and what is the best way to process all messages without some low priority, like WM_SIZING?
I test it on Windows 8.
PS: I need resize window, so I don't wanna disallow it by change style.
EDIT: sorry for incorrect description problem, but found what real happened (and why my previously attempt to fix it by limit number of processed messages, or by break message process when get same message two times in sequence will not success). From PeekMessage I get message WM_NCLBUTTONDOWN and after this message program don't return from ::DispatchMessage and block continue execution of thread until mouse will be released. And when program in DispatchMessage, my handler get repeatly WM_SIZING or WM_MOVING (independently what return from message handler function (result of DefWindowProc, TRUE (message was processed) or 0).
You could just process N messages before each frame.. where N is a limit you set between 1-10. That way you can process a reasonable number of events, then get onto your actual game logic.
It's conceivable that Windows may just generate the 'window sizing' message continually when the queue is empty, to make sure applications are aware the window is being resized.
(Maybe MS think applications might not know, maybe there's nothing else the user can do.. so MS want to hammer that single message.)
When DefWindowProc handles WM_SYSCOMMAND with either SC_MOVE or SC_SIZE in the wParam, it enters a loop until the user stops it by releasing the mouse button, or pressing either enter or escape. It does this because it allows the program to render both the client area (where your widgets or game or whatever is drawn) and the borders and caption area by handling WM_PAINT and WM_NCPAINT messages (you should still receive these events in your Window Procedure).
It works fine for normal Windows apps, which do most of their processing inside of their Window Procedure as a result of receiving messages. It only effects programs which do processing outside of the Window Procedure, such as games (which are usually fullscreen and not affected anyway).
However, there is a way around it: handle WM_SYSCOMMAND yourself, resize or move yourself. This requires a good deal of effort, but may prove to be worth it. Alternatively, you could use setjmp/longjmp to escape from the Window Procedure when WM_SIZING is sent, or Windows Fibers along the same lines; these are hackish solutions though.
I solved it (using the first method) this past weekend, if you're interested I have released the code to the public domain on sourceforge. Just make sure to read the README, especially the caveat section. Here it is: https://sourceforge.net/projects/win32loopl/

Why must SetWindowsHookEx be used with a windows message queue

I've been trying some things with hooks, and I don't understand why hooks must be used with a message queue
hook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(hook);
Why doesn't something like this work ?
hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, 0);
cin >> aKey;
UnhookWindowsHookEx(hook);
Using boost threads, and a barrier doesn't work either. Why can't the waiting between the hook and unhook be done in another manner ?
EDIT:
I did a mistake when I created this sample, I create a WH_KEYBOARD_LL hook, not WH_KEYBOARD, (I don't think it makes a big difference)
Also the loop never executes only waits on the GetMessage function.
The loop executes only when I post the quit message PostThreadMessage(id, WM_QUIT, 2323, NULL); so I don't understand what does it do beside waiting, is there some internal processing ?
RELATED:
C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup
How can I set up a CBT hook on a Win32 console window?
The low-level hooks, WH_KEYBOARD_LL and WH_MOUSE_LL are different from all the other hooks. They don't require a DLL to be injected into the target process. Instead, Windows calls your hook callback directly, inside your own process. To make that work, a message loop is required. There is no other mechanism for Windows to make callbacks on your main thread, the callback can only occur when you've called Get/PeekMessage() so that Windows is in control.
A global hook like WH_KEYBOARD is very different. It requires a DLL and the callback occurs within the process that processes the keyboard message. You need some kind of inter-process communication to let your own program be aware of this. Named pipes are the usual choice. Which otherwise of course requires that this injected process pumps a message loop. It wouldn't get keyboard messages otherwise.
Favor a low-level hook, they are much easier to get going. But do pump or it won't work. And beware of timeouts, if you're not responsive enough then Windows will kill your hook without notice.
Understanding the low-level mouse and keyboard hook (win32)
Windows Hooks hook the Windows message loop: http://msdn.microsoft.com/en-us/library/ms644959#wh_keyboardhook
The WH_KEYBOARD hook enables an application to monitor message traffic
for WM_KEYDOWN and WM_KEYUP messages about to be returned by the
GetMessage or PeekMessage function. You can use the WH_KEYBOARD hook
to monitor keyboard input posted to a message queue.
Console applications don't pump messages themselves - the console process does. So it won't work unless the process has a message loop.
See:
How can I set up a CBT hook on a Win32 console window?
C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup

Can I use my own message loop in windows?

I am building a C++ program, on windows, using Visual Studio. It relies on a COM base API, that sends windows message for notification.
To process those messages, I see two possibilities:
Create a windows form and call doModal on it which should process the messages, but since I don't want to use any UI, it's not what I want to do
make my own loop for processing messages
I don't know what is best, or if there is another way to process the messages (there is probably a windows function that can launch the loop)
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
It is not just for your own benefit, COM requires you to create a message loop. COM needs it to handle apartment threaded COM servers, an expensive word for "components that don't support multi-threading". The vast majority of them don't.
It is best to create a window, it doesn't have to be visible. That gives you a HWND that you can use in your SendMessage() calls. The window procedure you write can process the messages. From there, it gets to be easy to create a minimal user interface, with Shell_NotifyIcon for example. Always nice when you can display a notification when something goes wrong. So much better then an event in a log that nobody ever looks at.
Yes, you can. Every thread can have one message loop and you don't need any windows to receive messages or send them (see PostThreadMessage).
There is nothing wrong with using this method if your application is event-driven.

Should I use DirectInput or Windows message loop?

I'm working on a C++ DirectX 2D game and I need keyboard and mouse input.
Wikipedia says:
Microsoft recommends that new applications make use of the Windows message loop for keyboard and mouse input instead of DirectInput
So how should I use it?
I have a GameScreen class whice take care of the drawing and the updating(game logic), I call the Draw and the Update methods inside a windows message loop.
Thanks
Since you pretty much have to run a message pump in order to have a window, you might as well use that pump to handle keyboard and mouse input as well. It's entirely up to your pump whether you hand keyboard events on to a child window, you can handle them in the pump if you prefer.
Your typical message pump looks like this:
while (GetMessage(&msg, NULL, 0, 0))
{
if (WM_QUIT == msg.message)
break;
TranslateMessage(&msg); // post a WM_CHAR message if this is a WM_KEYDOWN
DispatchMessage(&msg); // this sends messages to the msg.hwnd
}
For a game, your pump might look more like this
while (true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD))
{
bool fHandled = false;
if (msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST)
fHandled = MyHandleMouseEvent(&msg);
else if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST)
fHandled = MyHandleKeyEvent(&msg);
else if (WM_QUIT == msg.message)
break;
if ( ! fHandled)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
// if there are no more messages to handle right now, do some
// game slice processing.
//
}
}
Of course, your actual pump will likely be even more complex than that, possibly with a MsgWaitForMultipleObjects so that you can wake periodically even if there a no messages to process, but immediatelly when there are messages.
DirectInput has been deprecated for good reasons. As fas as I know, it creates an extra thread and just queries Windows' Raw Input interface. For best performance, I'd use Raw Input directly.
If performance is not an issue for you (and I guess that's the case for a 2D game on current hardware), follow Microsoft's advice and use window messages, as described by John Knoeller.
FYI: Re John Knoeller's answer... a simplistic message pump looks like this:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
The WM_QUIT test that he included can NEVER be true because GetMessage returns zero when a WM_QUIT is received. However, testing for WM_QUIT in a PeekMessage loop is required because PeekMessage returns true/false whether a message was returned or not. Since GetMessage blocks until a message is returned, so it can have a different return value.
If the game has a single window, than as far as I can tell the distinction is purely a matter of taste. If however, you have (or are planning to have, or cannot positively rule out the option of having in the future) multiple windows, then windows messaging can get tiresome.
Problem is that by default keyboard/mouse messages are routed only to the window currently in focus, and typically in games you want to be able to switch focus (to a hi-score view, enemies on radar view or whatever) and still maintain interactivity. The easy solution would be for every module which requires keyboard/mouse input to query for it directly, and not rely on message forwarding - hence, DirectInput.
I can't say much about your specific scenario, of course - just my 2c.
Yes, the MSDN post is correct. Using windows messages you can use the multilanguage support (for any kind of keyboard the user may be using)/personal settings of the user (mouse right button instead of left), etc.. that you have to discard away to use DirectInput/XInput.
Only use those 2 for the gamepad/joystick support. For the rest just use the windows messages.
For the details i agree with the John Knoeller answer.
Use the-only use directinput under special circumstances
The nice thing about the Windows message loop used with getmessage is that it uses 0% cpu usage. If you are doing unprocessor intensive things such as waiting for a key from the user, collecting data from the user such as in a database or a tax program, or even a word processor, it makes sense just to use the Windows message with getmessage. I the all the above programs date is the process when the user presses a key.
All that the Windows message loop needs to process keys is for that program to be switched to. The mouse does not even need to be in the window.
Special circumstances-use directinput
If you need to:
1) Know when a key is pressed and released. You also may not want repeating keys detected as keypresses.
2) Process keys in the background when another program is switched to.
If either of the above is true, then use directinput.
If you're just collecting data from the user, then you will need to use the sleep command to suspend execution of the program. You want the program to have 0% cpu usage in the task manager if the program is just sitting there waiting for keys from the user.
Use the sleep function putting the program to sleep until you want to poll direct input for keys.
Therefore direct input just wastes programming time if you are doing a simple ordinary task of collecting keys from the user as you can see.
XInput is definitly the way to go. Low-Latency input is crucial to gameing and XInput ( replacement of DirectInput in the new DirectXSDKs ) is designed for exactly these use-cases.
Further you have support for gamecontrollers, joysticks, etc out of the box.

CDialog not Receiving Windows Messages in ActiveX Control

I have an ActiveX control in MFC that manipulates images and I am trying to add TWAIN scanning functionality to it.
I need to be able to receive a Windows Message back from the TWAIN driver that tells my control when an image has been scanned, so I have created a CDialog and I pass the HWND of the Dialog to the driver.
ALl the sample code I have seen on the net then uses PreTranslateMessage to capture the message from TWAIN, but in my ActiveX control this method is never being called.
Does anyone know how I can get the messages for that Dialog? I have also tried using PeekMessage with no success.
Many Thanks
You don't need to create a CDialog. You just need any window to process the messages. Anything dealing with TWAIN is best handled in its own thread. So, create a new thread for MFC (via CWinThread or AfxBeginThread). In that thread, create a CWnd. The HWND of this CWnd is the one you will pass with all the calls to the DSM, etc. Each thread has its own message queue, so set one up in there. Communicate with that thread via PostMessage, SendMessage, PostThreadMessage, etc. Assuming you post a message MY_SPECIAL_MESSAGE to signal to being acquiring an image, your message loop should look something like this:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
if (msg.message == MY_SPECIAL_MESSAGE)
{
GetImageFromTWAIN();
}
else if (!ProcessTWAINMessage(&msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Definitely look at the source code in the TWAIN development kit to see how this all works in detail. TWAIN is a tricky creature.
Trust me, this is the best approach. You can do it all in a single thread using your main thread's message queue, but it's to be avoided.