How to ignore a mouse click in Windows? (C++) - 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!

Related

Uninstalling keyboard hook when the user leaves the application

I am trying to detect when a user alt tabs out of my window. I have tried several messages (WM_ACTIVATE, WM_KILLFOCUS, WM_ACTIVATEAPP, WM_NCACTIVATE, WM_CANCELMODE, and WM_SYSCOMMAND checking for SC_MINIMIZE). But the same problem still occurs. The following happens.
My application is in focus, and I hold down alt and press tab.
The next window is brought forth.
I keep holding down alt and then press tab again, but this time, only tab is recognized and so I end up tabbing in the new window rather than alt tabbing again as is the usual behavior.
I am using a low level keyboard hook, and if I uninstall that this alt tabbing behavior described above works perfectly. I basically want to uninstall the keyboard hook as soon as the user leaves my window in this fashion. As soon as I release alt tab while in another window, my window receives several of the messages I look for and the hook is uninstalled. But when you hold the keys in this manner, it does not work as expected while the hook is installed.
why do you need to remove the keyboard hook? The SetWindowsHook is local to your application and not affect the other apps, therefore it already does nothing if your app doesn't have the focus.
Edit
make sure you call the next hook in your callback with CallNextHookEx to not screw up screen readers
I used the following code and it seems to be catching the focus changes, and I am not getting any problem with regard to holding down ALT or TAB in various combinations. But I didn't thoroughly test it yet.
EDIT: I read your post again and see that your problem is probably an interaction between the two different hooks. So I am also hooking the keyboard in my app, but I am using an Import Address Table hook of DispatchMessage. My hooks don't interact the way yours do, but my solution may not be appropriate for you.
bool AddHookToKeyboardFocusChanges()
{
HHOOK hhookFocusChange = NULL;
hhookFocusChange = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)CallWindowProcHook, NULL, GetCurrentThreadId()); // the last parameter makes it a local, not global hook
if(hhookFocusChange == NULL)
return false;
return true;
}
///////////////////////////////////////////////////////////////////////////////
// This is the routine that we register to be called on every call to a
// WindowProc in our application; we use it to catch WM_SETFOCUS and
// WM_KILLFOCUS messages that indicate gaining or losing keyboard input focus.
// Unlike keyboard, mouse, paint, and timer messages, the focus messages are not
// posted to the message queue. Instead they are sent directly to WindowProc.
// We must hook them here.
//
LRESULT WINAPI CallWindowProcHook(int nCode, WPARAM wParam, LPARAM lParam)
{
UINT message = ((CWPSTRUCT*)lParam)->message;
switch(message)
{
case WM_ACTIVATE:
OutputDebugString(L"Window activated.\n");
break;
case WM_SETFOCUS:
OutputDebugString(L"Window focused.\n");
break;
case WM_KILLFOCUS:
OutputDebugString(L"Window focus lost.\n");
break;
default:
break;
}
// CallNextHookEx calls the next hook in the chain.
return CallNextHookEx(NULL, nCode, wParam, lParam);
}

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.

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

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.

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

Is there a way to disable message boxes in MFC?

I have an MFC application (using a legacy library that I can't change). When the application starts, it loads a couple of drivers and shows message boxes if some drivers couldn't be loaded. The loading of the drivers and the showing of the message boxes is done by a method inside the library that can't be changed (let's call this method Init). I would like to disable those message boxes (preventing them from "popping"). Is there something I could call before calling Init to disable Message Boxes temporarily and then re-enable them after?
(Note that if it is impossible to re-enable them after, I can very well live with that, I mostly want to disable them)
Thanks to all,
Note: If someone wonders about why I would like to do that, it is because my application exposes a COM interface and will be used by other applications. The only reason it is an application is that the library I use is much more easy to use when creating an MFC application (and not a dll). When it is called by my other applications, I don't want the message boxes to show, I just want to get the errors if something goes wrong.
I am not sure whether this could work. I use it for subclassing some messageboxes not to preven them to popup and they are not from a dll.
I set a hook to capture message boxes before poping up:
HHOK hMessageBoxHook_ = SetWindowsHookEx(WH_CBT,
&CbtHookProc,
::GetModuleHandle(NULL),
GetCurrentThreadId());
The new hook procedure (CbtHookProc) would be like this:
LRESULT CALLBACK CbtHookProc( int nCode,
WPARAM wParam,
LPARAM lParam)
{
if(nCode < 0)
{
return ::CallNextHookEx( hMessageBoxHook_,
nCode,
wParam,
lParam);
}
switch(nCode)
{
case HCBT_CREATEWND: // a window is about to be created
return -1;
}
return ::CallNextHookEx( hMessageBoxHook_,
nCode,
wParam,
lParam);
}
From microsoft documentation for HCBT_CREATEWND:
If the hook procedure returns a
nonzero value, the system destroys the
window
Then after calling Init you can remove the hook and message boxes will pop up again:
::UnhookWindowsHookEx(hMessageBoxHook_);
hMessageBoxHook_ = 0;
As I told you I can't assure it works but give it a try.
One way to do this would be to hook/unhook the calls to MessageBox/MessageBoxEx/etc. and just do nothing when these calls are made. Check this guide for details on hooking API calls. In your case, I would specifically look at Import Address Table method, which is quite easy to implement and allows you to achieve the functionality you want.
You may also want to check Microsoft's own Detours library, but I'm not sure on whether it supports replacing API calls functionality.
Hope it helps.
I had the same problem when using ODBC with MFC. Everytime there was an error, a message box would pop up showing the error, which was fine if I wanted one.
However, if I didn't, I only needed to surround it with:
TRY
{
// Call error-prone method
}
CATCH ( CException, pEx )
{
// Free resources
}
END_CATCH
The message box comes from the framework not knowing how to handle the exception. Simply catch it and do as you wish with it.