Is there a way to make sure the window runs it's procedure and handles it's messages even if it is inactive or minimized?
Thanks in advance.
Is there a way to make sure the window runs it's procedure and handles it's messages even if it is inactive or minimized?
Thanks in advance.
At the WinAPI level the message dispatcher (GetMessage(), TranslateMessage(), DispatchMessage() etc.) should take care of that naturally.
If there's a problem can you post the relevent code sections?
If a window has been created it will still receive messages while inactive, minimised, hidden.
here's some part of the code (from the window procedure)
as you can see, it is supposed to change the coordinates of the cursor using keyboard input. It manages the job when it is active, but when it is minimized, it won't happen.Code:case WM_KEYDOWN: switch(wParam) { case VK_UP: pCur.y=pCur.y-10; //I declared pCur as a static POINT// SetCursorPos(pCur.x,pCur.y); break; case VK_DOWN: pCur.y=pCur.y+10; SetCursorPos(pCur.x,pCur.y); break; case VK_LEFT: pCur.x=pCur.x-10; SetCursorPos(pCur.x,pCur.y); break; case VK_RIGHT: pCur.x=pCur.x+10; SetCursorPos(pCur.x,pCur.y); break; }
After i posted the question, i suddenly realised that the problem wasn't the messsages, it was about the keyboard focus. Sorry about the misinformation. Anyway, is there a way i can keep the program working, even when it is minimized?
when the window is minimised it wont have keyboard focus, you can use a hook to capture the keyboard information SetWindowsHookEx Function, Using Hooks
Yes, it is about keyboard focus. Only the foreground window can receive keyboard input.
Unfortunately making this work from the background gets just a little complex. You will need to dabble in DLL injection and global hooks, which is not the easiest of programming. Basically you need to create a DLL that contains a global keyboard hook which will intercept keystrokes and deal with them.
LowLevelKeyboardProc Callback Function (Windows)
Low level keyboard hooks don't require dlls:
For example (a to exit):Originally Posted by From your link
Code:#include <windows.h> LRESULT CALLBACK LLKeyProc(int action, WPARAM wParam, LPARAM lParam) { if(action == HC_ACTION) { PKBDLLHOOKSTRUCT pKey = (PKBDLLHOOKSTRUCT)lParam; printf("Got key press %x\n", pKey->vkCode); if(pKey->vkCode == 'a') { PostQuitMessage(0); } } return CallNextHookEx(NULL, action, wParam, lParam); } int main(int, char**) { HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, &LLKeyProc, NULL, 0); if(hook) { while(WaitMessage()) { MSG msg = {0}; while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if(msg.message == WM_QUIT) { goto exit; } TranslateMessage(&msg); DispatchMessage(&msg); } } exit: UnhookWindowsHookEx(hook); } return 0; }
Last edited by adeyblue; 04-30-2011 at 10:07 AM. Reason: Complete forgot about WaitMessage
However... if you scroll to the bottom of that page and look... the low level keyboard hook, which is what our friend needs is a global hook, requiring that it be in a DLL...
Also from the same page...
(Empahsis mine...)
SetWindowsHookEx can be used to inject a DLL into another process. A 32-bit DLL cannot be injected into a 64-bit process, and a 64-bit DLL cannot be injected into a 32-bit process. If an application requires the use of hooks in other processes, it is required that a 32-bit application call SetWindowsHookEx to inject a 32-bit DLL into 32-bit processes, and a 64-bit application call SetWindowsHookEx to inject a 64-bit DLL into 64-bit processes. The 32-bit and 64-bit DLLs must have different names.
I ran into this with a mouse hook some years back. Couldn't get the thing to work for the life or me... build a DLL and set the hook from the DLL and away it goes.
yes, msdn saysYou must place a global hook procedure in a DLL separate from the application installing the hook procedure. The installing application must have the handle to the DLL module before it can install the hook procedure. To retrieve a handle to the DLL module, call the LoadLibrary function with the name of the DLL. After you have obtained the handle, you can call the GetProcAddress function to retrieve a pointer to the hook procedure. Finally, use SetWindowsHookEx to install the hook procedure address in the appropriate hook chain. SetWindowsHookEx passes the module handle, a pointer to the hook-procedure entry point, and 0 for the thread identifier, indicating that the hook procedure should be associated with all threads in the same desktop as the calling thread.
As an example of form.... there's the DLL from that mouse hook project...
Load the DLL... call the SetMHook function and the DLL is then injected into each process. There just wasn't any other way to do it.Code:#define WIN32_LEAN_AND_MEAN #define _WIN32_WINNT 0x400 #pragma comment(linker, "/heap:128") #define MMAPI __declspec(dllexport) #include <windows.h> ///////////////////////////////////////////////////////////////// // Handle double click // BOOL RevButtons = 0; void SendClick(void) { if (!RevButtons) { mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0); mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0); mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0); mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0); } else { mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0); mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0); mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0); mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0); } } ///////////////////////////////////////////////////////////////// // Mouse mod process // int lastdir = 1; // wheel tracker BOOL mbutton = 0; // settings BOOL hysterisis = 0; HHOOK mmhook = NULL; // mouse hook handle PMSLLHOOKSTRUCT mhs; MMAPI LRESULT CALLBACK MouseTracker(int code, WPARAM wparm, LPARAM lparm) { if (code < 0) return CallNextHookEx(mmhook,code,wparm,lparm); // get struct address mhs = (PMSLLHOOKSTRUCT)lparm; // process the message switch (wparm) { case WM_MBUTTONDOWN : // replace with lbutton dblclick { if (mbutton) { SendClick(); return 1; } break; } case WM_MBUTTONUP : { if (mbutton) { return 1; } break; } case WM_MOUSEWHEEL : // drop 1 msg on wheel reverses { if (hysterisis) if (((lastdir < 0) && ((int)mhs->mouseData > 0)) || ((lastdir > 0) && ((int)mhs->mouseData < 0))) { lastdir = (int)mhs->mouseData; return 1; } } } return CallNextHookEx(mmhook,code,wparm,lparm); } ///////////////////////////////////////////////////////////////// // Enable features // MMAPI void WINAPI SetMButton(BOOL dblclk) { mbutton = (dblclk & 1); } MMAPI void WINAPI SetMWheel(BOOL rollback) { hysterisis = (rollback & 1); } ///////////////////////////////////////////////////////////////// // Set the windows hook // if goforit = 1 hook is set, 0 to release // Returns hook status 1 = active, 0 = not // HINSTANCE hdll; // dll handle MMAPI BOOL WINAPI SetMHook(BOOL goforit) { if (goforit) { if (mmhook) return 1; mmhook = SetWindowsHookEx(WH_MOUSE_LL,&MouseTracker,hdll,0); RevButtons = GetSystemMetrics(SM_SWAPBUTTON); } else { if (mmhook) { if (UnhookWindowsHookEx(mmhook)) mmhook = NULL; } } return (mmhook != NULL); } ///////////////////////////////////////////////////////////////// // DLL entry point // BOOL APIENTRY DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) { if (reason == DLL_PROCESS_ATTACH) hdll = hinst; return 1; }
Can you people not compile and run code that's in front of you? Where's the required dll? Does it not work? Can't you use Process Explorer and verify that even if you use a dll it never gets injected anywhere? Can't you put two and two together and figure, 'Gee, if the OS is gonna call me in my own process context (which doesn't happen with the other global hooks, only the LL ones), what would be the point of it injecting stuff into another process?'
EDIT:
Now I find it, paragraph under the one I quoted in my last post:
Originally Posted by msdnAh, smug mode. I can't hang around here saving your necks all day, I think I'll make a start on that ironing.Originally Posted by msdn
Proof, as if it were needed - Imageshack - 34435171.png
Last edited by adeyblue; 04-30-2011 at 03:37 PM.
Adeyblue... the guys who wrote the Operating System disagree with you... what can I say?
Last week there was a topic on key loggers. How did it work?