GTK3 - 如何将窗口发送到后台

Posted

技术标签:

【中文标题】GTK3 - 如何将窗口发送到后台【英文标题】:GTK3 - How to send a window to the background 【发布时间】:2018-09-05 11:49:12 【问题描述】:

我正在尝试将一个窗口发送到后台,但SetKeepBelow 对窗口没有影响。有什么办法可以做到这一点?我正在使用 golang 和 gotk3,但如果需要,我可以添加其他绑定。

另一个选项可能是使用这个:https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowpos

但我不确定如何准确,因为我无法从 gtk 中检索窗口句柄。

【问题讨论】:

对我来说听起来像是XY Problem。你真正想要完成什么? “将窗口发送到后台” 对您意味着什么?是否要在两个窗口之间建立固定关系? 我想要 gtk 桌面窗口类型提示的行为。窗户应该都留在后面。这是一个便签应用程序,我只是不想将我的桌面用作我的“黑板”来粘贴便笺。 这不是受支持的方案。无论您选择实施哪种解决方案都将是一种或另一种方式。 在 Linux 上与 SetTypeHint(gdk.WINDOW_TYPE_HINT_DESKTOP) 一起使用。对我来说似乎很支持。或者你的意思是Windows不支持它?我可以用 java swing 和 javafx aswel(在 Windows 上)来做到这一点。 这个问题被标记为windows,所以很明显我指的是那个平台。在该平台上,这不是受支持的方案。无论您选择哪种解决方案都将是一个黑客,在路上或另一个。 Windows Desktop Gadgets 是您可以找到的最接近您正在寻找的东西,但这些已经从 Windows 8 中停止。 【参考方案1】:

所以,我找到了一个解决方案,就像问题的 cmets 中提到的那样,这很 hacky!但是,我不想让这个问题悬而未决。所以我正在做的是使用窗口的SetWindowPos 函数来在z 轴上移动它。但是,为了能够这样做,您首先需要指向hWnd 的指针,我正在使用FindWindowA 检索它,它带有一个类名和一个窗口标题,因为我不知道这个类,我正在传递nil。传递nil 会导致该函数仅按窗口标题搜索。 Ofc 此解决方案仅在您的窗口具有唯一标题时才有效!

package main

import (
    "unsafe"

    "github.com/gotk3/gotk3/gdk"
    "github.com/gotk3/gotk3/gtk"
    "golang.org/x/sys/windows"
)

var (
    mod                  = windows.NewLazyDLL("user32.dll")
    setWindowPosFunction = mod.NewProc("SetWindowPos")
    findWindowFunction   = mod.NewProc("FindWindowA")
)

//ToBackground moves the window to the background, preserving its size and position
func ToBackground(hwnd uintptr, gtkWindow *gtk.Window) error 
    x, y := gtkWindow.GetPosition()
    width, height := gtkWindow.GetSize()
    _, _, err := setWindowPosFunction.Call(hwnd, uintptr(1), uintptr(x), uintptr(y), uintptr(width), uintptr(height), 0)

    if err != nil && err.Error() == "The operation completed successfully." 
        return nil
    

    return err


func main() 
    gtk.Init(nil)

    window, _ := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
    window.SetTypeHint(gdk.WINDOW_TYPE_HINT_UTILITY)
    title := "unique-identifier"
    window.SetTitle(title)
    window.SetPosition(gtk.WIN_POS_CENTER)

    window.ShowAll()

    titleAsByteArray := []byte(title)
    hwnd, _, windowRetrieveError := findWindowFunction.Call(0, uintptr(unsafe.Pointer(&titleAsByteArray[0])))
    if windowRetrieveError != nil &&  windowRetrieveError.Error() != "The operation completed successfully." 
        panic(windowRetrieveError)
    

    toBackgroundError := ToBackground(hwnd, window)
    if toBackgroundError != nil 
        panic(toBackgroundError)
    

    gtk.Main()

【讨论】:

以上是关于GTK3 - 如何将窗口发送到后台的主要内容,如果未能解决你的问题,请参考以下文章

如何将键盘事件发送到 Pywin32 中的不同窗口?

如何将 GTK2 像素图移植到 GTK3_

将击键发送到特定窗口(在后台),但同时做其他事情[重复]

在弹出窗口中从 iframe 向后台脚本发送消息

如何在后台将检测到的 Beacon 信息的详细信息发送到服务器?

如何在后台模式下获取当前位置并在后台模式下继续将该位置发送到服务器