所以,我正在用 autohotkey 制作一个 gui..我会尝试用非“autohotkey 术语”来解释这个问题,因为它不是一种超级流行的语言。
在多显示器设置中通过将窗口拖放到屏幕顶部进行最大化时,gui 会消失。
Windows 10,多显示器设置(我朋友的 gif)~
我个人只有一个显示器,所以我一直在通过我的朋友测试这个,但这是一个混乱的电话游戏..
我回应
WM_WINDOWPOSCHANGING
并使用UpdateLayeredWindow
绘制到分层窗口
这是在 autohotkey 中编码的样子:
#Include, Gdip.ahk
#KeyHistory, 0
#SingleInstance, Force
SetControlDelay, -1
SetBatchLines, -1
SetWinDelay, -1
ListLines, Off
pToken := Gdip_Startup()
OnExit, Exit
OnMessage(0x0046, "WM_WINDOWPOSCHANGING")
OnMessage(0x0201, "WM_LBUTTONDOWN")
Gui, -DPIScale -SysMenu -Caption +hwndGuiHwnd +Resize +OwnDialogs +E0x80000
Global GuiHwnd := DllCall("msvcrt\" (A_IsUnicode?"_wcs":"_str") "toui64", "Str", GuiHwnd, "Ptr", 0, "Int", 0, "Int64")
Gui, Add, Custom, x0 y0 w30 h30 ClassStatic +hwndResizeTLHwnd +0x100
Global ResizeTLHwnd := DllCall("msvcrt\" (A_IsUnicode?"_wcs":"_str") "toui64", "Str", ResizeTLHwnd, "Ptr", 0, "Int", 0, "Int64")
Gui, Add, Custom, x348 y1 w45 h20 ClassStatic +hwndGuiCloseHwnd +0x100
Global GuiCloseHwnd := DllCall("msvcrt\" (A_IsUnicode?"_wcs":"_str") "toui64", "Str", GuiCloseHwnd, "Ptr", 0, "Int", 0, "Int64")
; ignore the msvcrt calls, they fix ~ https://www.autohotkey.com/boards/viewtopic.php?p=395906#p395906
DllCall("ShowWindow", "UInt", GuiHwnd, "Int", "10")
DrawGui(0, 0, 400, 300)
Return
Exit:
GuiEscape:
Gdip_Shutdown(pToken)
ExitApp
WM_LBUTTONDOWN(wParam, lParam, Msg, Hwnd) {
if (Hwnd = GuiHwnd)
DllCall("User32.dll\PostMessage", "Ptr", GuiHwnd, "UInt", 0xA1, "Ptr", 2, "Ptr", 1) ; 2 - HTCAPTION
}
WM_WINDOWPOSCHANGING(wParam, lParam, Msg, Hwnd) {
if (NumGet(lParam+0, 32, "UInt") & 0x3) ; 0x0001 (SWP_NOSIZE) | 0x0002 (SWP_NOMOVE)
Return
DrawGui(NumGet(lParam+0, 16, " UInt"), NumGet(lParam+0, 20, "UInt"), NumGet(lParam+0, 24, "UInt"), NumGet(lParam+0, 28, "UInt"))
}
; This is messy, written quickly just for testing
DrawGui(GuiX, GuiY, GuiW, GuiH) {
Critical
; Tooltip, % "GuiX: " GuiX "`nGuiY: " GuiY "`nGuiW: " GuiW "`nGuiH: " GuiH
BackgroundColor := Format("0x{:x}" "f0f0f0", 255)
BorderColor := Format("0x{:x}" "6598ee", 255)
BorderColor2 := Format("0x{:x}" "4d74b6", 255)
BorderSize := 8
hbm := CreateDIBSection(GuiW, GuiH)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
;---------------------- Background -----------------------;
pBrushBackground := Gdip_BrushCreateSolid(BackgroundColor)
Gdip_FillRectangle(G, pBrushBackground, 0, 0, GuiW, GuiH)
Gdip_DeleteBrush(pBrushBackground)
;---------------------------------------------------------;
;----------------------------------------------------- Border ------------------------------------------------------;
pPenBorder := Gdip_CreatePen(BorderColor, BorderSize)
Gdip_DrawRectangle(G, pPenBorder, Floor(BorderSize/2), Floor(BorderSize/2), GuiW - BorderSize, GuiH - BorderSize)
Gdip_DeletePen(pPenBorder)
pPenBorder2 := Gdip_CreatePen(BorderColor2, 1)
Gdip_DrawRectangle(G, pPenBorder2, 0, 0, GuiW - 1, GuiH - 1)
Gdip_DrawRectangle(G, pPenBorder2, BorderSize - 1, BorderSize - 1, GuiW - BorderSize*2 + 1, GuiH - BorderSize*2 + 1)
Gdip_DeletePen(pPenBorder2)
;-------------------------------------------------------------------------------------------------------------------;
;--------------------------------- Titlebar ----------------------------------;
pBrushTitlebar := Gdip_BrushCreateSolid(BorderColor)
pPenTitlebarBottom := Gdip_CreatePen(BorderColor2, 1)
Gdip_FillRectangle(G, pBrushTitlebar, 1, 1, GuiW - 2, 29)
Gdip_DrawLine(G, pPenTitlebarBottom, BorderSize, 30, GuiW - BorderSize - 1, 30)
Gdip_DeletePen(pPenTitlebarBottom)
Gdip_DeleteBrush(pBrushTitlebar)
;-----------------------------------------------------------------------------;
UpdateLayeredWindow(GuiHwnd, hdc, GuiX, GuiY, GuiW, GuiH, 255)
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
Gdip_DeleteGraphics(G)
Gdip_DisposeImage(pBitmap)
}
这是一个非常简单的例子,如果你想运行它你需要得到 Gdip.ahk
差不多就这些了!我不知道我能说清楚多少..这一切都非常混乱。
也许不知何故
UpdateLayeredWindow
失败了?..我已经阅读了很多文档,但我找不到太多关于多显示器的信息,唯一提到它的是 CreateCompatibleDC:
现有 DC 的句柄。如果此句柄为 NULL,该函数将创建一个与应用程序的当前屏幕兼容的内存 DC。
但这没有意义。
非常感谢任何帮助,我在这里失去了理智(: