Teamviewers Quickconnect 按钮是如何实现的?
对于那些不知道我在说什么的人:http://www.teamviewer.com/images/presse/quickconnect_en.jpg
For those of you who do not know what I am talking about: http://www.teamviewer.com/images/presse/quickconnect_en.jpg
Teamviewer 将该按钮覆盖在所有窗口上,以便您可以快速与其他人共享一个窗口.我想要任何关于实现类似东西的想法――如果你有示例代码,甚至更好(特别是按钮――而不是共享).我对 C++ 和 QT 感兴趣……但如果有其他语言/库,我会对好的解决方案感兴趣.
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.
谢谢.
推荐答案
要在外部窗口中绘制按钮或其他东西,您需要将代码注入到外部进程中.检查 SetWindowsHookEx方法:
To draw buttons or other stuff in foreign windows, you need to inject code into the foreign processes. Check the SetWindowsHookEx method for that:
您很可能想为 WH_CALLWNDPROCRET 安装一个钩子并注意 WM_NCPAINT 消息.这将是绘制按钮的正确位置.但是,我不确定是否可以在非客户区中放置窗口,因此在最坏的情况下,您必须手动"绘制按钮.
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".
只需从您的主应用程序(或从 DLL 中)调用它
Just call this from your main application (or from within a DLL)
SetWindowsHookEx(WH_CALLWNDPROCRET, myCallWndRetProc, hModule, 0);
请注意,myCallWndRetProc 必须驻留在 DLL 中,而 hModule 是此 DLL 的模块句柄.
Note that myCallWndRetProc must reside within a DLL and hModule is the Module-HANDLE for this DLL.
您的 myCallWndRetProc 可能如下所示:
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());
安装全局钩子会将 DLL 注入所有进程,这使得调试变得非常困难,并且您的 DLL 在使用时可能会被写保护.
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.
相关文章