鼠标穿透

场景:鼠标穿透窗口解决办法

鼠标穿透窗口
1.有两个窗口,分别是窗口A和窗口B,窗口B被A覆盖了。我想实现鼠标在窗口A上面的操作,实际上操作的是窗口B。

2.目前我知道有种方法,就是将窗口A样式设置成WS_EX_LAYERED|WS_EX_TRANSPARENT样式,使得窗口A为半透明,就可以实现鼠标在窗口A上面的动作,实际上操作的是窗口B。但是这种方法有个问题,窗口A会变成半透明,可是我不想让窗口A变成半透明。

3.除了上面这种方法外,还有没有其他的方法能实现这样的鼠标穿透的效果呢?并且不能使得窗口A变成半透明。

------解决方案--------------------
不懂帮顶啊
------解决方案--------------------
响应窗口A的WM_NCHITTEST消息,直接返回HTTRANSPARENT
------解决方案--------------------
帮顶
------解决方案--------------------
获得鼠标指针位置,这个不用我教吧?GetWindow 获得下面一个窗体的句柄,然后SendMessage WM_LBUTTONDOWN和WM_LBUTTONUP
------解决方案--------------------
窗口A 下面有N 个窗口,鼠标可能同时对应着若干个窗口, 所以各个窗口还是有一个Z-order 问题。
那么既然顶层窗口不用,就取下一个包含鼠标的Z 序最高的窗口, 系统api 不知道有没有, 如果没有
那就自己编一个吧。 稍微复杂点, 不过还是可以实现的。
------解决方案--------------------
找到B窗口,直接给他发消息
------解决方案--------------------
一直向下穿透,一直GetWindow GW_NEXT ,直到hDesktop

hDesktop=::GetDesktopWindow();


------解决方案--------------------
探讨
一直向下穿透,一直GetWindow GW_NEXT ,直到hDesktop

hDesktop=::GetDesktopWindow();

 

------解决方案--------------------
看下这两个函数SetCapture(); ReleaseCapture();
------解决方案--------------------
探讨
引用:
有一个办法。
用GetWindow和findwindow找到窗口A和B
然后当在A上点击鼠标时,在鼠标处理事件中,用sendMessage把鼠标消息传到窗口B中。这样B就能自动处理鼠标事件,而A对鼠标不会有响应。可能需要重载A中所有与鼠标有关的消息处理函数。可能需要禁用菜单什么的。
给你个页面,可能有帮助。


关键是我得不到窗口B的句柄啊

------解决方案--------------------
用SetCapture和ReleaseCapture,就可以解决你的问题
------解决方案--------------------
你这个问题其实很好解决,设置成WS_EX_LAYERED|WS_EX_TRANSPARENT样式,变成半透明了?SetLayeredWindowAttributes(hWnd,0,255,LWA_ALPHA);把透明度设成255就不透明了。
------解决方案--------------------
探讨
请问lint2008和Tr0j4n。

用GetWindow得到下一个窗口后,比如是窗口B,是不是要通过GetWindowRect获得窗口B的矩形,然后用PtInRect判断鼠标是不是在窗口B上。可是,如果窗口B是不规则窗体呢,那就没办法得到窗口B的范围,也就没办法判断鼠标是不是在窗口B里面了。

------解决方案--------------------
NCHITTEST HTTRANSPARENT

=====================================
Skin++ 让界面与逻辑彻底分离
精彩界面制作视频演示
www.uipower.com
------解决方案--------------------
探讨
请问lint2008和Tr0j4n。

用GetWindow得到下一个窗口后,比如是窗口B,是不是要通过GetWindowRect获得窗口B的矩形,然后用PtInRect判断鼠标是不是在窗口B上。可是,如果窗口B是不规则窗体呢,那就没办法得到窗口B的范围,也就没办法判断鼠标是不是在窗口B里面了。

------解决方案--------------------
探讨
引用:
你这个问题其实很好解决,设置成WS_EX_LAYERED|WS_EX_TRANSPARENT样式,变成半透明了?SetLayeredWindowAttributes(hWnd,0,255,LWA_ALPHA);把透明度设成255就不透明了。


你说的方法我已经实现了。但我不希望底层窗体时半透明的,所以不能采用这种方法。

------解决方案--------------------
你的情况用Hook做比较合适了
mouseMsgHook = SetWindowsHookEx(WH_MOUSE, GetMouseProc, hInstance, GetCurrentThreadId());

LRESULT CALLBACK GetMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode == HC_ACTION)
{
MSG *msg = (MSG*)lParam;
if(wParam & PM_REMOVE)
KeyboardHook::instance->handleHook(msg->message, msg->hwnd, msg->wParam, msg->lParam);
}

return CallNextHookEx(mouseMsgHook, nCode, wParam, lParam);
}


handleHook(UINT msg, HWND hwnd, WPARAM wParam, LPARAM lParam)
{
.....
}
Hook这个instance的所有消息,然后在回调函数里边判断是A窗口的鼠标消息。
截完以后发给窗口B,用SendMessage发WM_LBUTTONX和WM_MOUSEMMOVE消息就可以了

======================================= 
C++程序做UI方法的革命,用flash打造超炫UI 
http://flash4ui.googlepages.com
------解决方案--------------------
是的,Hook的message是对这个instance所有窗口都hook的。if(wParam & PM_REMOVE)判断是从消息队列中取出并删除消息。看看MSDN的PM_REMOVE解释你就知道了呵呵。



======================================= 
C++程序做UI方法的革命,用flash打造超炫UI 
http://flash4ui.googlepages.com
------解决方案--------------------
探讨
引用:

没搞懂你意思,你是不希望窗体半透明还是不希望窗体带半透明属性?如果不希望窗体半透明,可以通过调整ALPHA值使窗口不透明。如果不希望窗体带半透明属性,那就比较麻烦了,需要检测自己覆盖了哪些窗口,然后PtInRect检测鼠标是在哪个窗口上,如果是不规则窗口,需要GetWindowRgn,然后PtInRegion检测,再向找到的窗口发送鼠标信息。

楼上的WindowFromPoint是不起作用的,因为你要找的是被覆盖的窗口,想鼠标穿透的时候这个函数返回的一定是你的窗口的句柄。


(1)我不希望窗体带半透明属性。
(2)是的,WindowFromPoint在这里使用不上。

------解决方案--------------------
响应窗口A的WM_NCHITTEST消息,直接返回HTTRANSPARENT
------解决方案--------------------
SetWindowsHookEx 的最后一个参数dwThreadId,如果要hook特定线程就指定线程ID,如果指定为0,那就Hook这个进程的所有线程输入。
所以如果你要Hook进程内的全部线程消息,把这个参数设成0就ok了。


======================================= 
C++程序做UI方法的革命,用flash打造超炫UI 
http://flash4ui.googlepages.com

------解决方案--------------------
利用HOOK技术,截获鼠标消息,将鼠标消息转发给下面的A窗口.
------解决方案--------------------
A 和 B同一个父窗口么, 消息到A前经过共同的父窗口时, 处理一下就行了!

新软件介绍

一些效果图: