c++: How to catch mouse clicks wherever they happen - c++

I am stuck with an application I am writing where I need to monitor for mouse clicks.
The clicks may happen anywhere on the screen and not inside the app window, and for each click I must pass a message (perform an action or something).
I looked around and read some suggestions like using
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
but I was unsuccessful.
Does anyone have an idea on how to implement what I need?

You need to set a mouse hook as described in MSDN.
Note that in your case the hook would need to be global. This means that you need to implement a handler function in a DLL, which will be loaded into all processes in the system which receive mouse message. Such DLL will communicate with your main application using some interprocess communication (IPC) mechanism like shared memory or via Windows messages posted (not sent) from the DLL to the main application.
You can use the source code from this CodeProject article as a guide.
Update: as per Chris' correction, I should note that above applies to "regular" mouse hook which is synchronous. Low-level hook doesn't need to be located in the DLL, but it has certain limitations which are described in the corresponding MSDN article.

well I don't really know if you solved your problem. I hope so.
But I was in the same trouble today and searching I found a way really easy to do it.
So here you are:
int keyPressed(int key){
return (GetAsyncKeyState(key) & 0x8000 != 0);
}
int main(){
while(1){
if(keyPressed(VK_LBUTTON)){
printf("%s\n","Click izquierdo");
}
if(keyPressed(VK_RBUTTON)){
printf("%s\n","Click Derecho");
}
}
return 0;
}
the key of this solution is the function GetAsyncKeyState(key), where key anyone of the codes that appears here https://msdn.microsoft.com/en-us/library/dd375731(VS.85).aspx

You could use SetWindowsHookEx
Here's a small sample:
#define _WIN32_WINNT 0x0500
#include <windows.h>
HHOOK MouseHook;
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam){
PKBDLLHOOKSTRUCT k = (PKBDLLHOOKSTRUCT)(lParam);
POINT p;
if(wParam == WM_RBUTTONDOWN)
{
// right button clicked
GetCursorPos(&p);
}
}
void StayAlive(){
while(_getch() != 27) { }
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd){
FreeConsole();
MouseHook = SetWindowsHookEx(WH_MOUSE_LL,MouseHookProc,hInstance,0);
StayAlive();
UnhookWindowsHookEx(MouseHook);
return 0;
}

LRESULT CALLBACK WndProc(...), as it name suggests is a (specific) window (message) processor where you can analyze and respond to messages on the queue that were deferred by the system to your custom definition of the callback for further processing.
Since you want to detect and act on mouse clicks anywhere on the screen, as chris suggested in the comments, one way is to hook yourself into the system by calling SetWindowsHookEx() which is quite verbose in its very definition - it allows you to track stuff happening on the system and relay that information back to your application.
This is the syntax which you need to employ in order to get yourself
HHOOK WINAPI SetWindowsHookEx(
__in int idHook,
__in HOOKPROC lpfn,
__in HINSTANCE hMod,
__in DWORD dwThreadId
);
It takes in a specific hook id, which are basically little #defines which tell the function what kind of messages you wish to receive from all over the system, you pass it a callback just like the WndProc, but this time it's meant to process the incoming messages regarding across the system. hMod simply refers to the handle to the application or the DLL in which the just mentioned proc function callback is located in. The last one relates to threads currently running on the system, setting this to 0 or NULL retrieves messages for all existing threads.
Important:
Do note that Aurus' example call to the SetWindowsHookEx is process-specific which a fancy word relating it to an actual application, instead of a DLL which can be appended to multiple processes across the system ( a global one ) and return information to your application. It would be prudent to take the time and effort to investigate Eugene's recommended method instead of this forceful approach useful only for experiments. It's a bit "harder", but the reward is worthwhile.
Less work is not always better or preferable.

Related

How to ignore a mouse click in Windows? (C++)

I am trying to make a program that sits in the background that can ignore mouse clicks - outside of the program.
How do I tell Windows this through c++?
I already made the program recognize the mouse click. Just not how to ignore it.
The reason I need to do this is because my mouse has a flaw where it accidentally double-clicks (or more) when I only click one time.
So basically, when the program register that I click with the mouse, it will let the first click through, but then disable that button (ignoring every following clicks) for ~200 milliseconds.
If possible, I would like to avoid using any external libraries. Only the standard ones that comes with Visual Studio.
Thank you very much for reading!
You can use a low-level mouse hook:
// Variable to store the hook handle
HHOOK miHook;
// This is the hook procedure
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if(nCode == HC_ACTION) {
MSLLHOOKSTRUCT &msll = *(reinterpret_cast<MSLLHOOKSTRUCT*>(lParam)); // In there is more context if you need it
if(wParam == WM_LBUTTONDOWN) {
// Do your logic here
if(letsIgnoreThisClick) {
return -1; // This will make the click be ignored
}
}
}
return CallNextHookEx(miHook, nCode, wParam, lParam); // Important! Otherwise other mouse hooks may misbehave
}
// This is how you install the hook
miHook = SetWindowsHookEx(WH_MOUSE_LL, reinterpret_cast<HOOKPROC>(&LowLevelMouseProc), hInstance, 0);
// And this is how you would remove the hook again
UnhookWindowsHookEx(miHook);
This code example can't be used as-is of course, but has to be adjusted to your needs and the individual parts have to be put in the right locations in your code.
Please also read the remarks section for SetWindowsHookEx. You are probably going to need to create a DLL where your function is located (you can load it from your main code). The hInstance in my example has to be the instance handle of the module which contains the hook procedure. Also you need to pump messages in order for your hook to work correctly!

How is Teamviewers Quickconnect button accomplished?

For those of you who do not know what I am talking about:
http://www.teamviewer.com/images/presse/quickconnect_en.jpg
Teamviewer overlays that button on all windows to allow you to quickly share a window with someone else. I would like any ideas on implementing something similar -- if you have example code, even better (specifically, the button -- not the sharing). I am interested in C++ and QT... but I would be interested in good solutions in other languages/libraries if there are any.
Thanks.
To draw buttons or other stuff in foreign windows, you need to inject code into the foreign processes.
Check the SetWindowsHookEx method for that:
You most probably want to install a hook for WH_CALLWNDPROCRET and watch out for the WM_NCPAINT message. This would be the right place to draw your button.
However, I'm not really sure, if you can place a window within a Non-Client-Area, so in the worst case, you'd have to paint the button "manually".
Just call this from your main application (or from within a DLL)
SetWindowsHookEx(WH_CALLWNDPROCRET, myCallWndRetProc, hModule, 0);
Note that myCallWndRetProc must reside within a DLL and hModule is the Module-HANDLE for this DLL.
Your myCallWndRetProc could look like:
LRESULT CALLBACK myCallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HT_ACTION) {
CWPRETSTRUCT* cwpret = (CWPRETSTRUCT*)lParam;
if (cwpret->message == WM_NCPAINT) {
// The non-client area has just been painted.
// Now it's your turn to draw your buttons or whatever you like
}
}
return CallNextHookEx(0, nCode, wParam, lParam);
}
When starting with your implementation, I'd suggest, you just create a simple dialog application and hook your own process only:
SetWindowsHookEx(WH_CALLWNDPROCRET, myCallWndRetProc, NULL, GetCurrentThreadId());
Installing a global hook injects the DLL into all processes, which makes debugging pretty hard, and your DLL may be write-protected while it's in use.

Keyboard hooking alt-tab causing strange behavior?

I want to disallow the user of my application from using alt-tab. I'm trying to solve this by using a low level keyboard hook.
Setting it up works perfectly, the callback procedure is triggered when I press the key combination etc. The weird thing that happens is that I can alt-tab out of the application but then alt-tabbing is disabled, completely. I switch applications with the mouse and try alt-tabbing but nothing happens. I switch back to my application and alt-tab again and it switches the application, but only one step. When out of my application the alt-tab isn't working anymore.
I've tried different scenarios, first I thought it had something to do with the debugger in VS2010 but no, running it with out the debugger gives the same results.
Have I completely misunderstood this hook procedure, is it meant to only catch stuff happening when the application isn't in focus?
osman.hpp :
static HHOOK m_hhook;
static LRESULT CALLBACK lowLevelKeyboardProc( int key, WPARAM wParam, LPARAM lParam );
osman.cpp :
HHOOK OSMan::m_hhook;
/*
* pseudo init code
*/
void OSMan::init()
{
m_hHook = SetWindowsHookEx( WH_KEYBOARD_LL, (HOOKPROC)lowLevelKeyboardProc, 0, 0 );
}
LRESULT CALLBACK OSMan::lowLevelKeyboardProc( int key, WPARAM wParam, LPARAM lParam )
{
KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam;
switch (key)
{
case HC_ACTION:
{
if (pkbhs->vkCode == VK_TAB && pkbhs->flags & LLKHF_ALTDOWN)
return 1;
}
default:
break;
}
return CallNextHookEx( m_hHook, key, wParam, lParam);
}
edit:
added code.
If you want to disable alt+tab correctly, you should just register the hotkey via RegisterHotKey(0,0,MOD_ALT,VK_TAB); and then handle (well, more ignore) the message that this generates, this allows you to make it application local, not worry about Windows hook chains and allows you to easily enable or disable it on the fly.
Although for a game, the idTech 4 input handling code has a vast array of the input gems.
You are installing a System Wide hook, that is why you have disabled the use of Alt-TAB on the whole system.
You can't use a WH_KEYBOARD_LL you must use a WH_KEYBOARD hook, and make it process specific.
The params of the SetWindowsHookEx will change if you make your hook process specific.
Here is an overview of the params :
dwThreadId [in]
Type: DWORD
The identifier of the thread with which the hook procedure is to be associated.
If this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread.
PS : in reply to comment :
The hook only is installed after the process got one appropriate event. While hooking onto keyboard messages, you will have to send at least one keyboard message before the hook is installed.
Work Around
Maybe you want to work around this issue by using the ShowWindow function ?
Here is the doc : http://www.pinvoke.net/default.aspx/user32.showwindow
cf : http://www.codeproject.com/Articles/4610/Three-Ways-to-Inject-Your-Code-into-Another-Proces
cf http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx
and
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644959(v=vs.85).aspx#wh_keyboardhook

Generating Mouse & Keyboard input from one application to another

I have worked with the win32 API and the DirectX API for interpreting input from the user, but haven't found much in the way of generating input that matches original user input.
My goal is to make a program that will run transparently in the background, minimized, or in the quicklaunch area and have that program artificially implant keyboard and mouse input for a third party, full screen application.
I've found some commands for verifying which window has focus, and some code samples for checking the process name or ID of said application, but not as much on generating input via directx or anything else, to simulate legitimate input.
Any suggestions would be much appreciated, I want it to register as close to real input as possible to help facilitate automated testing.
My apologies in advance if this question is too general or "under-researched", I'm just not quite sure where to start on this one!
The program will be in either C++ or C# due to my familiarity with those languages.
I have done this:
One app to act as an global keyboard_hock, and then i did send matching patterns to an second app, direct in memory - i used examples from All-in-one code framework examples you can download, lock for CSFileMappingServer & CSFileMappingClient (get / set) to memory from two separete processes. And CSWindowsHook project to catch global keyboard events
I was a litle quick, but to send virtual keyboard you can use:
BOOL
WINAPI
PostMessageA(
__in_opt HWND hWnd,
__in UINT Msg,
__in WPARAM wParam,
__in LPARAM lParam);
But the winow you send to has to be in focus, you can use:
BOOL
WINAPI
BringWindowToTop(
__in HWND hWnd);
And to get HWIND to the running app, you can use:
HWND
WINAPI
FindWindowA(
__in_opt LPCSTR lpClassName,
__in_opt LPCSTR lpWindowName);

Notification when Windows Dialog is opened

I want to do some processing when a particular dialog is opened but I am not able to find any way to get notification when that dialog is opened.
Is there any way to get notification in application for opening of a particular windows dialog?
The only available information about the dialog is its title and its unique.
The general solution is to use windows hooks, filter to WH_CBT, filter to WM_CREATE, or something like that, get the window text and see if it is the one of your interest.
One more important point: in hook you should use SetWindowLongPtr() to set window process to your own function, that will actually receive WM_CREATE event. In all calls this function should call the original window procedure.
You can also use a CBT Hook to watch window creation messages. You'll have access to the CREATSTRUCT used to create the actual window, eg, the title and class name. You can prevent the window from being created in your hook, modify the size, etc.
EDIT: sorry didn't notice that you don't have the code yourself but only the title. So I think the other posts solution is what you need
The event handling in win32 applications is done via a so called windows procedure which is a callback function with the following signature:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
This callback gets called by windows every time there is a message for windows which are registered with this callback function. One of the first messages send to a new window is the WM_CREATE message.
If you are creating your windows "by hand" with win32 API, then there should be a static callback function like the one below where you can filter for the WM_CREATE message.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch( message )
{
case WM_CREATE:
// do what ever you want
return 0;
case default:
return DefWndProc( hwnd, message, wParam, lParam );
}
}
If you use MFC dialogs (CDialog) then you can overwrite the function CDialog::OnInitDialog().
OK, the way to do this is to use SetWindowsHookEx(WH_SYSMSGFILTER,...)
You'll be getting a lot more callbacks than you really need. and global hooks are a real drain on system performance (they can force the system to serialize things that would normally run independently)
be sure to read the Remarks, especially this part:
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.
Your hook must live in a dll, and the dll will end up loaded into other process's address space, so you won't it won't have access to your procees's address space, you will have to set up some sort of interprocess communication between your hook and your app.
On the whole I'd say this sounds like a really bad idea.