查看完整版本: [-- 无边框窗口如何保留系统原生窗口特效 --]

QTCN开发网 -> 其它技术开发讨论区 -> 无边框窗口如何保留系统原生窗口特效 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

鹤舞九天 2019-12-06 21:54

无边框窗口如何保留系统原生窗口特效

[attachment=21138]

如上图,这是win10系统窗口拖到顶部自动最大化时的一个半透明动效。
我用Qt去掉窗口边框,自己实现鼠标事件,也能让窗口到顶部最大化,但是这样做,这个效果就没了。
但是看上图这个,明明不是系统的原生窗口,怎么还有特效呢,Qt能做到么?
而且感觉不像是自己仿的系统特效,因为它装到win7上就是win7的特效,放到win10上就是win10的特效,明显是跟随系统的,应该是在去掉边框的同时还保留了系统某些边框特点,一直没想明白是怎么做到的。哪位大神能有思路么?

玖零儛 2019-12-09 09:18
你可以重写widget的nativeEvent函数,捕获WM_NCHITTEST消息,在你认为是标题的区域返回给系统HTCAPTION,系统就以为那块儿就是标题栏,相关特性就会触发了

笑颜 2019-12-09 09:29
https://github.com/xiaoyanLG/FramelessWidget 这里有个demo

keep_a_cat 2020-01-09 11:12
m_mousePos//当鼠标移动到边框时,将这个变量改成对于的属性(HTCAPTION)标题栏就行了

bool VTK3DModelEditor::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    MSG* msg = (MSG*)message;
    switch (msg->message) {

    case WM_NCHITTEST:
    {
        initMousePos();
        switch (m_mousePos)
        {
        case MousePos_Cap:
            *result = HTCAPTION;
            return true;
        case MousePos_Top:
            *result = HTTOP;
            return true;
        case MousePos_Bom:
            *result = HTBOTTOM;
            return true;
        case MousePos_Left:
            *result = HTLEFT;
            return true;
        case MousePos_Right:
            *result = HTRIGHT;
            return true;
        case MousePos_TopLeft:
            *result = HTTOPLEFT;
            return true;
        case MousePos_TopRight:
            *result = HTTOPRIGHT;
            return true;
        case MousePos_BomLeft:
            *result = HTBOTTOMLEFT;
            return true;
        case MousePos_BomRight:
            *result = HTBOTTOMRIGHT;
            return true;
        case MousePos_None:
        default:
            break;
        }
    }
    break;
    case WM_NCCALCSIZE:
        return true;

    case WM_GETMINMAXINFO:
    {
        static int flag = 3;
        if (::IsZoomed(msg->hwnd)) {
            if (flag == 1)
            {
                *result = ::DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
                return true;
            }
            flag = 1;
            RECT frame = { 0, 0, 0, 0 };
            AdjustWindowRectEx(&frame, WS_OVERLAPPEDWINDOW, FALSE, 0);
            frame.left = abs(frame.left);
            frame.top = abs(frame.bottom);
            this->setContentsMargins(frame.left, frame.top, frame.right, frame.bottom);
        }
        else {
            if (flag == 0)
            {
                *result = ::DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
                return true;
            }
            flag = 0;
            this->setContentsMargins(0, 0, 0, 0);
        }

        *result = ::DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
        return true;
    }
    break;
    }

    return QWidget::nativeEvent(eventType, message, result);
}


查看完整版本: [-- 无边框窗口如何保留系统原生窗口特效 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled