Click here to Skip to main content
15,881,248 members
Articles / Programming Languages / C++

Middle Mouse Button (or Wheel) to Doubleclick (VC6)

Rate me:
Please Sign up or sign in to vote.
4.67/5 (17 votes)
26 Jul 2010CPOL2 min read 83.7K   2K   34   19
This is a small but handy tool I'm using every day. It converts a middle mouse button click in to a left mouse button double click.

Config GUI

  • Displays function state
  • Enables / disables doubleclick function
  • Chooses whether to confirm exit of the application
Screenshot - MBtn2DblClickVC.jpg

Introduction

Once I had a logitech mouse and everything was fine!

Logitech provided you with a handy application called EMEXEC.exe, which would allow you to set up the behavior of the available buttons. The function I most used was the converter for the middle mouse button/wheel which would turn a single click from the specific button into a left mouse button double click. But what if you uninstalled mouseware, or what if you have to work on a machine without LogiMouse. You're not able to install MouseWare until you have a LogiMouse connected. Pretty soon I began to miss this cool feature from Logitech and said to myself that I am going to write a tool which implements exactly this feature. And here we go....

Problem

The trickiest part I was facing was that the application had to get the clicks from all the other applications running at this time. Therefore a global mousehook had to be set and that might be a little bit tricky. You have to place the code for the mousehook callback in a external DLL with a custom code-segment. I used MouseHook.cpp - I found this a while ago while surfing the web, but I don't remember where I got it from (sorry!). If this is your MouseHook.cpp, please drop a line.

Setting up the MouseHook

C++
__declspec(dllexport) BOOL setMyHook(HWND hWnd) {
    if(hWndServer != NULL)
        return FALSE; // already hooked!
    
    hook = SetWindowsHookEx(WH_MOUSE_LL,
        (HOOKPROC)msghook,
               hInst,
               0);
    if(hook != NULL) { /* success */
        hWndServer = hWnd;
        return TRUE;
    } /* success */

    return FALSE; // failed to set hook
} // setMyHook

...
//Hook-Function:

...

static LRESULT CALLBACK msghook(UINT nCode, WPARAM wParam, LPARAM lParam) {
    if(nCode < 0) { /* pass it on */
        CallNextHookEx(hook, nCode, wParam, lParam);
        return 0;
    } /* pass it on */
    
    if(wParam == WM_MBUTTONUP ){
        PostMessage(hWndServer, UWM_MBTNCLICK, 0, 0);
    }
    
    return CallNextHookEx(hook, nCode, wParam, lParam);
} // msghook

Clearing the Hook

C++
__declspec(dllexport) BOOL clearMyHook(HWND hWnd) {
    if(hWnd != hWndServer || hWnd == NULL)
        return FALSE;
    
    BOOL unhooked = UnhookWindowsHookEx(hook);
    
    if(unhooked)
        hWndServer = NULL;
    
    return unhooked;
} // clearMyHook

Converting the Click

C++
BEGIN_MESSAGE_MAP(CMBtn2DblClickDlg, CDialog)
    ON_REGISTERED_MESSAGE(UWM_MBTNCLICK, OnMyMbtnClick)

....
LRESULT CMBtn2DblClickDlg::OnMyMbtnClick(WPARAM wParam, LPARAM lParam) {
    CPoint pt;
    GetCursorPos(&pt);
    
    // width
    int cx = GetSystemMetrics(SM_CXSCREEN);
    // height
    int cy = GetSystemMetrics(SM_CYSCREEN);
  
    //Reformat screen coordinates
    int x2 = ( 65535 * pt.x ) / cx;
    int y2 = ( 65535 * pt.y ) / cy;
 
    INPUT input[2];
    
    input[0].type = INPUT_MOUSE;
    input[0].mi.dx = x2;
    input[0].mi.dy = y2;
    input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN;
    input[0].mi.mouseData   = 0L; 
    input[0].mi.time        = 0L; 
    input[0].mi.dwExtraInfo = 0L;

    input[1].type = INPUT_MOUSE;
    input[1].mi.dx = x2;
    input[1].mi.dy = y2;
    input[1].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP;
    input[1].mi.mouseData   = 0L; 
    input[1].mi.time        = 0L; 
    input[1].mi.dwExtraInfo = 0L;
    
    SendInput( 1, &input[0], sizeof(input[0]));
    SendInput( 1, &input[1], sizeof(input[1]));

    Sleep(40);
    
    SendInput( 1, &input[0], sizeof(input[0]));
    SendInput( 1, &input[1], sizeof(input[1]));
    
    return 0;
} // MBtn2DblClickDlg::OnMyMouseMove

Credits

  • CReadOnlyEdit by Kevin Bond
  • CRegistry by Shane Martin
  • CSimpleTray by T1TAN / SprdSoft Inc.
  • CWinStartup (by unknown)

I hope this article is useful to anyone or helps to understand how mousehooks work. If you are interested in the source of a good MouseHook DLL, I'd recommend you to download this source since the original location of MouseHookManager is gone and I couldn't find it on the net anymore so far. So hope you enjoy and all the best - hope you'll be reading my next articles as well.

Cheers, Kim

History

  • 9th July, 2007: Initial post
  • 15th April, 2010: Corrected a bug with the persitence of Registry settings enabled at startup and other config settings
  • 24th July, 2010: Updated the source and application so they work with Windows 7 on x64 systems

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Switzerland Switzerland
programmer and software junkie since 1991 zurich switzerland

Comments and Discussions

 
Questionmfc100d.dll is missing? Pin
Noxolos12-Mar-13 3:37
Noxolos12-Mar-13 3:37 
QuestionEnable after re-boot ? Pin
FunnySurfnow14-Aug-11 5:24
FunnySurfnow14-Aug-11 5:24 
GeneralMy vote of 5 Pin
GPUToaster™8-Sep-10 2:08
GPUToaster™8-Sep-10 2:08 
GeneralMy vote of 4 Pin
Sharjith2-Aug-10 9:49
professionalSharjith2-Aug-10 9:49 
Generalhave a look at Pin
Tibor Blazko19-Apr-10 19:49
Tibor Blazko19-Apr-10 19:49 
GeneralHook Procedure alternative Pin
Frank_Cheng14-Apr-10 12:38
Frank_Cheng14-Apr-10 12:38 
GeneralMany thanks! Pin
fishophile30-Jun-09 10:51
fishophile30-Jun-09 10:51 
QuestionThank you.. Pin
f.eskafi30-Apr-09 17:11
f.eskafi30-Apr-09 17:11 
AnswerRe: Thank you.. Pin
f.eskafi1-May-09 3:57
f.eskafi1-May-09 3:57 
Generalleft-handed issue [modified] Pin
Hatod6-Nov-07 22:33
Hatod6-Nov-07 22:33 
QuestionLoad enabled? Pin
cdo53-Sep-07 4:05
cdo53-Sep-07 4:05 
AnswerRe: Load enabled? Pin
kim.david.hauser4-Sep-07 3:11
kim.david.hauser4-Sep-07 3:11 
GeneralRe: Load enabled? Pin
cdo54-Sep-07 4:05
cdo54-Sep-07 4:05 
GeneralRe: Load enabled? Pin
Jalle9-Jan-10 22:18
Jalle9-Jan-10 22:18 
Questiongood work, but got a general problem of 'WH_MOUSE_LL' Pin
Michael ZY9-Aug-07 16:56
Michael ZY9-Aug-07 16:56 
AnswerRe: good work, but got a general problem of 'WH_MOUSE_LL' Pin
Hatod6-Nov-07 22:04
Hatod6-Nov-07 22:04 
Generalgood :) Pin
Hatod30-Jul-07 6:11
Hatod30-Jul-07 6:11 
GeneralRe: good :) Pin
kim.david.hauser5-Aug-07 21:43
kim.david.hauser5-Aug-07 21:43 
Generalwell done Pin
toxcct9-Jul-07 8:08
toxcct9-Jul-07 8:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.