【问题标题】:how to keep shadow in borderless window如何在无边框窗口中保持阴影
【发布时间】:2019-04-15 12:09:49
【问题描述】:

我正在尝试在 Windows 中使用 Qt 在无边框窗口上投下阴影。 我在启动应用的时候成功掉了阴影,参考下面的文章。

但是我遇到了如果应用程序被停用和重新激活,阴影会消失的问题( 也就是说,单击其他应用程序,然后再次单击我的应用程序。)

也许我的实现还不够好。 如果您对此问题有一些想法,我很高兴。

我正在尝试使用 Go bindings 改进 Qt 这是代码sn-p:

package qframelesswindow

import (
    "unsafe"

    "github.com/therecipe/qt/core"
    "github.com/therecipe/qt/widgets"

    win "github.com/akiyosi/w32"
)

func (f *QFramelessWindow) SetNativeEvent(app *widgets.QApplication) {
    filterObj := core.NewQAbstractNativeEventFilter()
    filterObj.ConnectNativeEventFilter(func(eventType *core.QByteArray, message unsafe.Pointer, result int) bool {
        msg := (*win.MSG)(message)
        lparam := msg.LParam
        hwnd := msg.Hwnd
        var uflag uint
        uflag = win.SWP_NOZORDER | win.SWP_NOOWNERZORDER | win.SWP_NOMOVE | win.SWP_NOSIZE | win.SWP_FRAMECHANGED
        var nullptr win.HWND
        shadow := &win.MARGINS{0, 0, 0, 1}

        switch msg.Message {
        case win.WM_CREATE:
            style := win.WS_POPUP | win.WS_THICKFRAME | win.WS_MINIMIZEBOX | win.WS_MAXIMIZEBOX | win.WS_CAPTION
            win.SetWindowLong(hwnd, win.GWL_STYLE, uint32(style))

            win.DwmExtendFrameIntoClientArea(hwnd, shadow)
            win.SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, uflag)

            return true

        case win.WM_NCCALCSIZE:
            if msg.WParam == 1 {
                // this kills the window frame and title bar we added with WS_THICKFRAME and WS_CAPTION
                result = 0
                return true
            }
            return false

        case win.WM_GETMINMAXINFO:
            mm := (*win.MINMAXINFO)((unsafe.Pointer)(lparam))
            mm.PtMinTrackSize.X = int32(f.minimumWidth)
            mm.PtMinTrackSize.Y = int32(f.minimumHeight)
            return true

        default:
        }
        return false
    })
    app.InstallNativeEventFilter(filterObj)
}

所有源代码都在我的存储库中; akiyosi/goqtframelesswindow

【问题讨论】:

    标签: qt go winapi borderless


    【解决方案1】:

    WM_NCCALCSIZE:

    如果 wParam 为 TRUE,应用程序应返回零或组合 以下值。(在文档中)

    还有:

    当 wParam 为 TRUE 时,直接返回 0 而不处理 NCCALCSIZE_PARAMS 矩形将导致客户区调整为 窗口的大小,包括窗框。这将删除 窗口中的窗口框架和标题项,只留下 显示客户区。

    从 Windows Vista 开始,简单地返回 0 不会影响扩展帧,只会删除标准帧。

    编辑:

    使用DWL_MSGRESULT 而不是result = 0 设置返回值。

    【讨论】:

    • 标准框架包括扩展框架?我按照建议修复了如下代码,但问题无法解决。 case win.WM_NCCALCSIZE: if msg.WParam == 1 { result = 0 return true } else { result = int(win.DefWindowProc(hwnd, win.WM_NCCALCSIZE, wparam, lparam)) } return false
    • return win.DefWindowProc(hwnd, win.WM_NCCALCSIZE, wparam, lparam); 而不是 return true/false
    • win.DefWindowProc() 是 uintptr 类型,返回类型应该是 bool,所以,我尝试以下但不工作。 case win.WM_NCCALCSIZE: ret := win.DefWindowProc(msg.Hwnd, win.WM_NCCALCSIZE, msg.WParam, msg.LParam) if ret == 1 { return true } else { return false }
    • DWL_MSGRESULT而不是result = 0设置返回值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 2012-09-03
    • 2012-02-15
    • 2018-08-29
    相关资源
    最近更新 更多