如何在无边界的窗口中保持阴影

时间:2019-04-15 12:09:49

标签: qt go winapi borderless frameless

我正在尝试在Windows中使用Qt在无边界窗口上添加阴影。 在启动应用程序时,我成功地完成了工作,请参阅以下文章。

但是我遇到了以下问题:如果停用并重新激活应用程序,阴影将消失( 换句话说,请单击其他应用程序,然后再次单击我的应用程序。)

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

我正在尝试用Go bindings来提高Qt 这是代码段:

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

1 个答案:

答案 0 :(得分:1)

WM_NCCALCSIZE

  

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

还有:

  

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

从Windows Vista开始,仅返回0不会影响扩展框架,只会删除标准框架。

编辑:

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