win32实现两个透明窗口联动

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/czhhxx/article/details/53914220

在上一篇博客中,我已经完成了一个对某个颜色值透明的win32窗口,存在一个很大的缺陷:透明部分是无法响应鼠标消息的,这就导致窗口无法拖动。在查阅了大量资料也没有发现详细的解决方法后,决定记载一下我的解决方法。
首先确定了一下方案为建立一个接近透明的窗口填充这个对某个颜色值透明的窗口,当鼠标点击到接近透明的子窗口时,将消息转发给父窗口,父窗口再处理拖动消息并移动子窗口。
创建两个窗口的代码如下:

    //对黑色透明的父窗口
    HWND hWnd = CreateWindowEx(WS_EX_LAYERED, NULL, NULL, WS_POPUP | WS_VISIBLE, 0, 0, 200, 200, NULL, NULL, hInst, 0);
    SetLayeredWindowAttributes(hWnd, 0, 255, LWA_COLORKEY);
    //透明度为1的底层子窗口
    HWND hWndBottom = CreateWindowEx(WS_EX_LAYERED, NULL, NULL, WS_POPUP | WS_VISIBLE, 0, 0, 200, 200, hWnd, NULL, hInst, 0);
    SetLayeredWindowAttributes(hWndBottom, 0, 1, LWA_ALPHA);

这样就创建了一个半透明窗口和一个对黑色透明的窗口,并且他们的窗口是重叠在一起的。接下来处理窗口消息。首先处理父窗口的:

    //接收窗口正在移动的消息,并移动子窗口使父窗口子窗口的位置保持一致
    case WM_WINDOWPOSCHANGING:
        WINDOWPOS * winPos = (WINDOWPOS*)wParam;
        MoveWindow(hWndBottom, winPos->x, winPos->y, winPos->cx, winPos->cy);
        break;
    //使父窗口能被拖动
    case WM_NCHITTEST:
        return HTCAPTION;

接下来处理子窗口的消息:

    //将子窗口收到的鼠标左键按下消息发给父窗口,让父窗口移动
    case WM_LBUTTONDOWN:
        SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
        break;

这样两个窗口就实现了联动,当鼠标点击到了父窗口的不透明部分时,父窗口移动的同时move子窗口,让两个窗口重叠,当点击到父窗口的透明部分时,实际上是点击到了半透明子窗口上,此时子窗口将消息发给父窗口处理,两个窗口同时移动。
有一个缺陷在于当使用win7的window基本主题时,半透明窗口会失效,必须使用透明风格的主题才有效果。

展开阅读全文

没有更多推荐了,返回首页