I am trying to create a simple mouse hook to detect if the mouse is moving, but for some reason when I run the program, the mouse doesnt function at all until I stop the process.
Here is my code:
#include <windows.h>
HHOOK g_hMouse;
LRESULT CALLBACK MouseHook(int nCode, WPARAM wParam, LPARAM lParam)
{
printf("MOUSE EVENT!\n");
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int main()
{
g_hMouse = SetWindowsHookEx(WH_MOUSE_LL, MouseHook, NULL, NULL);
while (1) {
Sleep(2);
}
return 0;
}
Any help would be appreciated.
Thanks.
WM_MOUSE_LL hooks require that the thread that installed it keeps pumping messages; so you'll need a GetMessage/DispatchMessage loop here. Details for this are in the MSDN docs for WM_MOUSE_LL:
This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop.
If you just want to try something quick when experimenting/debugging, replace your Sleep() with a call to MessageBox(...), which will block your code so you can do testing, but it runs its own message loop, so the hook will run.
Related
In some circumstances when I call DoModal on one of my ATL::CDialogImpl<...> dialogs, I get the wait cursor flashing up for a few milliseconds. It's very annoying and not very aesthetically pleasing, not to mention after days of experimentation I've failed to identify the cause given my dialog initialisation is very fast.
So I was wondering if there's a way to hook into the message queue and identify when the cursor is changed to IDC_WAIT (it's not changed to that anywhere in my software, or anywhere in WTL as far as I can see), then simply have that message ignored. As an experiment I did the following:
DWORD thread_id, pid;
thread_id = ::GetWindowThreadProcessId(m_hWnd, &pid);
hook = SetWindowsHookExW(WH_GETMESSAGE, GetMsgProc, nullptr, thread_id);
and then my GetMsgProc as follows:
LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
{
auto m = reinterpret_cast<MSG*>(lParam);
if (m->message == WM_SETCURSOR)
{
// Change cursor
::SetCursor(Global_Cursors.Get().Cursor(Resource_Cursors::Arrow));
// Ignore the message.
m->message = WM_NULL;
}
return CallNextHookEx(hook, code, wParam, lParam);
}
Interestingly I never get a WM_SETCURSOR message, though I do get lots of others. What mistake have I made here?
I have two devices that create keyboard input, one of them is a real keyboard and the other uses SendInput() to send Injected keyboard input. I am modifying an existing program that uses a hook to send the keyboard message only to its own window and blocks the input globally to other programs. However I do not want the Injected input to be blocked, and I also don't want the program to process the Injected input.
I used a WH_KEYBOARD_LL hook to determine if the input is Injected, Then I used a global WH_KEYBOARD hook to send the message only to the window if it is the real keyboard. What I am looking for is a way to sendMessage() to everything except the main window. I couldn't find a method in the documentation to do this though, so I decided to pass the hook farther down.
// WH_KEYBOARD
static LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
if (code < 0) {
return CallNextHookEx(hookHandle, code, wParam, lParam);
}
//Report the event to the main window, but do not pass it to the hook chain
if (realKeyboard) {
SendMessage(hwndServer, WM_HOOK, wParam, lParam);//only listen to real keyboard, block emulated one
}
else {
//what i want is to sendMessage to everythng except the main window
return CallNextHookEx(hookHandle, code, wParam, lParam); //let injected keyboard passthrough
//however we want to ignore injected inputs in the main window(keyboard program).
}
return 1;
}
I created a local WH_GETMESSAGE hook using GetCurrentThreadId(), to see if I could ignore the injected input there.
// WH_GETMESSAGE
static LRESULT CALLBACK GetMessageProc(int code, WPARAM wParam, LPARAM lParam) {
if (code < 0) {
return CallNextHookEx(hookHandle, code, wParam, lParam);
}
if (!realKeyboard) {
MSG * info = (MSG *)lParam;
info->message = WM_NULL;
}
return CallNextHookEx(hookHandle, code, wParam, lParam);
}
I read somewhere that info->message = WM_NULL; would work to block the message but it doesn't seem to have an effect. I also Tried creating a message loop something like this but it didn't work either.
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
if(IsRealKeyboard()){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Any ideas how I can ignore the injected message only in the main window and let it through to the rest of the system?
You could use RAW INPUT in the target window and process the WM_INPUT message, then get the Raw Input buffer via GetRawInputData.
I have written an application to hook some procedure onto a new process to monitor mouse down events and to disable mouse down events on the new process. As of now, I am able to capture to mouse down events coming to this process and I am trying to disable all mouse down events as a POC. This is what I am doing currently in the hook procedure.
extern "C" __declspec(dllexport) LRESULT __stdcall meconnect(int code, WPARAM wParam, LPARAM lParam) {
if (code >= 0) {
LPMSG msg = (LPMSG)lParam;
if (msg->message == WM_LBUTTONDOWN) {
OutputDebugString(L"Mouse down event happened \n");
return false;
}
}
return(CallNextHookEx(NULL, code, wParam, lParam));
}
When I perform mouse down event, I am getting the log message that I have written. But I also expect that click event to be blocked since I am returning false. but it does not happen so and click event proceed as a normal click. How could I disable mouse down event. Thanks in advance for any help on this
This is how I call setWindowsHookEx
HHOOK handle = SetWindowsHookEx(WH_GETMESSAGE, addr, dll, threadID);
The reason you are supposed to call CallNextHookEx during your hook routine is so that the message can be passed on to any other hooks that might be installed. Failing to do so does not prevent the message from being seen by the application that received it.
The documentation for WM_NULL explains how to block the message:
For example, if an application has installed a WH_GETMESSAGE hook and wants to prevent a message from being processed, the GetMsgProc callback function can change the message number to WM_NULL so the recipient will ignore it.
The corrected code should therefore look something like this:
extern "C" __declspec(dllexport) LRESULT __stdcall meconnect(int code, WPARAM wParam, LPARAM lParam) {
if (code >= 0) {
LPMSG msg = (LPMSG)lParam;
if (msg->message == WM_LBUTTONDOWN) {
OutputDebugString(L"Mouse down event happened \n");
msg->message = WM_NULL;
return false;
}
}
return(CallNextHookEx(NULL, code, wParam, lParam));
}
However, this may cause inconsistent behaviour if other hooks are present, because whether another hook sees WM_LBUTTONDOWN or WM_NULL will depend on the order of the hook chain, which is unpredictable. It might be preferable to try something like this:
extern "C" __declspec(dllexport) LRESULT __stdcall meconnect(int code, WPARAM wParam, LPARAM lParam) {
if (code >= 0) {
LPMSG msg = (LPMSG)lParam;
int result = CallNextHookEx(NULL, code, wParam, lParam);
if (msg->message == WM_LBUTTONDOWN) {
OutputDebugString(L"Mouse down event happened \n");
msg->message = WM_NULL;
}
return result;
}
return(CallNextHookEx(NULL, code, wParam, lParam));
}
So I am trying to make a message box appear when a user presses a button on his/her keyboard using Hooks.
The hook is getting installed correctly because there are no errors, but it seems like the KeyboardProc Callback function is not getting called because the message box that is supposed to show up when it is called never shows up.
There are no errors btw that show up and I am programming this in a desktop app.
Here is the code regarding the hook and the callback function:
LRESULT CALLBACK KeyboardProc(
int nCode, WPARAM keyState, LPARAM keyInfo) {
LRESULT reValue = 0;
MessageBox(hWnd, L"Testing", L"Test", MB_OK);//This is the msg box that isnt showing up
if (nCode < 0) {
reValue = CallNextHookEx(keyboardHook, nCode, keyState, keyInfo);
}
return reValue;
};
keyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, hInstance, 0);
You need to run a message loop to process the calls. From the remakrs on the KeyboardProc callback function description: "The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop."
The following code works fine. It gives out the message when the user presses a key. But there are certain things I am not aware of. What is the role of Message Loop here ? I read that calling SetWindowsHookEx(...) registers a function with the windows and windows calls the appropriate function automatically when a event of registered type happens. No doubt that i don't see the output if don't give the message loop it's space.
#include<iostream>
#include <windows.h>
using namespace std;
HINSTANCE hinst = NULL;
static HHOOK handleKeyboardHook = NULL;
static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
void setWinHook() {
handleKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc,NULL, 0);
if(handleKeyboardHook == NULL) {
cout << "is NULL";
} else {
cout << "is not NULL";
}
cout<<("Inside function setWinHook !");
}
static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
cout << ("You pressed a key !\n");
return CallNextHookEx(handleKeyboardHook, nCode, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
handleKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
EDIT
Does exiting the program (closing the console window) unregister the hook ?
EDIT 2
what role does Dispatch Message play here ? According to doc it dispatches a message to window procedure,but here even if i exclude that,it doesn't effect the output.
All events in Windows, even the low-level keyboard event used in your example, is sent using the normal message events. So for the program to be able to sense keyboard events, it has to use an event loop processing messages.
Without a loop, the program would exit immediately, and the hook would be removed at once too. You cannot register a hook and exit — the system would become a mess if buggy programs were leaving too many forgotten hooks after them. Once your process dies, the hook is scheduled for removal.
I don't remember about low-level keyboard hook, but callbacks of many other hooks are only called inside GetMessage/PeekMessage, and not on some other thread, so just an infinite loop won't suffice — it has to be a message loop.
"what role does Dispatch Message play here ? According to doc it dispatches a message to window procedure,but here even if i exclude that,it doesn't effect the output."
DispatchMessage is pretty useless cos console window doesnt receive much messages.
Only message received is when window loses focus.