Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 375
Daniel Placek Avatar asked Aug 16 '12 23:08

Daniel Placek


1 Answers

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.

like image 118
Mark Avatar answered Oct 01 '22 01:10

Mark