Click here to Skip to main content
Click here to Skip to main content

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

By , 26 Jul 2010
Rate this:
Please Sign up or sign in to vote.

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

__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

__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

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)

About the Author

kim.david.hauser
Software Developer (Senior)
Switzerland Switzerland
programmer and software junkie since 1991 zurich switzerland
Follow on   Twitter   Google+

Comments and Discussions

 
GeneralMy vote of 5 PinmemberGPUToaster8-Sep-10 2:08 

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

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

| Advertise | Privacy | Mobile
Web04 | 2.8.140421.2 | Last Updated 26 Jul 2010
Article Copyright 2007 by kim.david.hauser
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid