响应窗口A的WM_NCHITTEST消息,直接返回HTTRANSPARENT

解决方案 »

  1.   


    非常感谢您的意见。我按照你的方法试了,窗口A是不能响应鼠标的事件了,可是根本操作不了下层窗口B。我猜,是不是鼠标的消息已经被窗口A捕获了,所以根本传不到窗口B,造成窗口B没有被操作到。
      

  2.   

    获得鼠标指针位置,这个不用我教吧?GetWindow 获得下面一个窗体的句柄,然后SendMessage WM_LBUTTONDOWN和WM_LBUTTONUP
      

  3.   

    或者说假设窗口A下面有好几个窗口,有没有什么方法可以找到鼠标位置对应着窗口A下面的哪个窗口呢。如果能够找到,那我把窗口A捕获的鼠标消息转发给那个窗口就可以实现鼠标穿透效果了。可是,我不知道该怎么找。
      

  4.   

    窗口A 下面有N 个窗口,鼠标可能同时对应着若干个窗口, 所以各个窗口还是有一个Z-order 问题。
    那么既然顶层窗口不用,就取下一个包含鼠标的Z 序最高的窗口, 系统api 不知道有没有, 如果没有
    那就自己编一个吧。 稍微复杂点, 不过还是可以实现的。
      

  5.   

    有一个办法。
    用GetWindow和findwindow找到窗口A和B
    然后当在A上点击鼠标时,在鼠标处理事件中,用sendMessage把鼠标消息传到窗口B中。这样B就能自动处理鼠标事件,而A对鼠标不会有响应。可能需要重载A中所有与鼠标有关的消息处理函数。可能需要禁用菜单什么的。
    给你个页面,可能有帮助。
    http://cache.baidu.com/c?m=9f65cb4a8c8507ed4fece763104c8c711923d030678197027fa3c215cc790b161421a5f027251603ce95223a54b2121abdaf2b7860082ae79d9988408ab8982d2f8f2664711f8d1218d91fb8cb317f877fce4eacf259b1b5b165d5ec8193880815dd52756df0839c2e0103cb1fe76237f4d29e5f645e07caeb27648f4e0129885244a137fdf7411a108086ca2a49d45cd17610e7b845b62962b704d46b0c5237b74dc11f205127903f3089402a7593&p=9f7ac64ad7921fe008e2947e4f0c&user=baidu#baidusnap0
      

  6.   


    GetWindow只能获得窗口A下面Z序的下一个窗口。可是,如果鼠标的位置并不在这下一个窗口里面,那么仍然实现不了我要的效果。我要的是鼠标位置相对应的窗口A下面的那个窗口。
      

  7.   

    一直向下穿透,一直GetWindow GW_NEXT ,直到hDesktophDesktop=::GetDesktopWindow();   
      

  8.   

    看下这两个函数SetCapture(); ReleaseCapture();
      

  9.   


    你认真查了MSDN么?
    先得到当前窗口的句柄设为hwndCur;
    用hWndNext = GetWindow( hwndCur, GW_HWNDNEXT);就能得到
    认真看下Getwindow,它就是得到与当前窗口有一定关系(比如说在前在后)的窗口的句柄。 
      

  10.   

    不好意思。之前没注意到你有些GetWindow,以为你只写了FindWindow,抱歉!
      

  11.   

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

  12.   

    用SetCapture和ReleaseCapture,就可以解决你的问题
      

  13.   

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

  14.   


    在windows下,窗口应该都是矩形吧。只要是标准的windows窗口。
    另外,如果是MFC窗口,你就直接把鼠标单击,双击之类的事件,完全照样地sendmessage给这个窗口就不用管了,让系统自动对这些消息响应。如果窗口是不规则的,一般这种窗口会提供这种检测是否在窗口内的函数吧?
    即使没有,只要它有处理鼠标响应的机制,你就直接把鼠标消息传给它就什么都不用管了。
    你到底在做什么?
      

  15.   

    NCHITTEST  HTTRANSPARENT=====================================
    Skin++ 让界面与逻辑彻底分离
    精彩界面制作视频演示
    www.uipower.com
      

  16.   

    HWND WindowFromPoint(POINT Point);
      

  17.   


    没搞懂你意思,你是不希望窗体半透明还是不希望窗体带半透明属性?如果不希望窗体半透明,可以通过调整ALPHA值使窗口不透明。如果不希望窗体带半透明属性,那就比较麻烦了,需要检测自己覆盖了哪些窗口,然后PtInRect检测鼠标是在哪个窗口上,如果是不规则窗口,需要GetWindowRgn,然后PtInRegion检测,再向找到的窗口发送鼠标信息。楼上的WindowFromPoint是不起作用的,因为你要找的是被覆盖的窗口,想鼠标穿透的时候这个函数返回的一定是你的窗口的句柄。
      

  18.   


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

  19.   

    你的情况用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
      

  20.   


    请问为什么要做if(wParam & PM_REMOVE)这个判断呢?我有试过鼠标左击,那么按道理系统产生一个WM_LBUTTONDOWN,可是鼠标钩子竟然会被系统调用10多次,而且每一次都同样是WM_LBUTTONDOWN消息。是不是跟我没做if(wParam & PM_REMOVE)这个判断有关系呢?我的代码如下:
    //设置鼠标钩子void YtInitMouseHook(HWND hWnd)
    {
        //判断是否已经安装
        g_hMouse = SetWindowsHookEx(WH_MOUSE,(HOOKPROC)MouseHook, g_hInstance, 0);
    }//鼠标事件处理
    static LRESULT CALLBACK MouseHook(int code, WPARAM wParam, LPARAM lParam)
    {
        if(code < 0)
            return ::CallNextHookEx(g_hMouse, code, wParam, lParam);    LPMOUSEHOOKSTRUCT pMouseHook=(LPMOUSEHOOKSTRUCT)lParam;    if(WM_LBUTTONDOWN==wParam)
            MessageBox(NULL,TEXT("标题"),TEXT("提示内容"),MB_OK);    return ::CallNextHookEx(g_hMouse, code, wParam, lParam);
    }当鼠标左击一次后,MessageBox的内容会被弹出10多次。
      

  21.   

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

  22.   


    我貌似讲错了。那么。就使用GetWindowRect吧,判断鼠标坐标是否在B的Rect中。
      

  23.   

    响应窗口A的WM_NCHITTEST消息,直接返回HTTRANSPARENT
      

  24.   


    我需要用全局HOOK,不是单独属于某个线程的钩子。我看你上面贴的代码,只是设置了针对于某个线程的钩子。你的代码是mouseMsgHook = SetWindowsHookEx(WH_MOUSE, GetMouseProc, hInstance, GetCurrentThreadId()); 
      

  25.   


    钩子是在消息还没到线程消息队列的前面就进行拦截的,那为什么用PM_REMOVE可以从消息队列中删除了。我想问下,你这边提到的“消息队列”是系统消息队列,还是线程消息队列。谢谢。
      

  26.   

    SetWindowsHookEx 的最后一个参数dwThreadId,如果要hook特定线程就指定线程ID,如果指定为0,那就Hook这个进程的所有线程输入。
    所以如果你要Hook进程内的全部线程消息,把这个参数设成0就ok了。
    ======================================= 
    C++程序做UI方法的革命,用flash打造超炫UI 
    http://flash4ui.googlepages.com
      

  27.   

    利用HOOK技术,截获鼠标消息,将鼠标消息转发给下面的A窗口.
      

  28.   

    A 和 B同一个父窗口么, 消息到A前经过共同的父窗口时, 处理一下就行了!新软件介绍一些效果图:
      

  29.   

    http://zhidao.baidu.com/question/71883431.html貌似没那么麻烦吧,一个SetWindowLong直接解决问题