在多显示器设置上最大化(航空捕捉)分层窗口的问题

问题描述 投票:0回答:0

所以,我正在用 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。

但这没有意义。

非常感谢任何帮助,我在这里失去了理智(:

winapi autohotkey gdi
© www.soinside.com 2019 - 2024. All rights reserved.