- Offizieller Beitrag
Hi,
ich möchte verhindern, dass ein Fenster seine Größe ändert bei folgenden Aktionen:
- an Titelleiste greifen - an den seitlichen Desktoprand ziehen (Fenster bekommt halbe Bildschirmgröße, dockt am seitlichen Rand an)
- an oberen/unteren Fensterrand greifen - an den oberen/unteren Desktoprand ziehen (Fenster bekommt volle Bildschirmhöhe)
- Doppelklick Titel (Fenster wird maximiert) - das habe ich gelöst durch Auswertung: $_iMsg = $WM_NCLBUTTONDBLCLK And $_iwParam = $HTCAPTION
Leider friert mein Winspector Spy beim Loggen von Messages ein, sodass ich das nicht nachverfolgen kann.
Ich habe getestet, ob es eine Kombination mit WM_NCLBUTTONDOWN ist. Dass die Maustaste gedrückt ist am Fensterrand (zum Ziehen) kann ich damit auch erkennen. Nun fehlt mir aber der nächste Schritt. Die oben angeführten Ereignisse treten ja erst auf, wenn mit der gezogenen Maus der Bildschirmrand berührt wird. Ich kann mir nicht vorstellen, dass ich hier permanent berechnen muss, ob Mausposition mit Bildschirmrand übereinstimmt. Da sollte doch eigentlich eine Nachricht gesendet werden mit den Infos: Mouse hold-down moved-to Border (links,rechts,oben,unten).
Bin für Anregungen dankbar.
EDIT:
Ich habe mal aus meinem Projekt den Code in ein einzelnes minimales Skript gezogen, zum besseren Verständnis:
;-- TIME_STAMP 2020-11-08 13:54:24
#include <GUIConstantsEx.au3>
#include <WinAPISysWin.au3>
#include <WinAPIConv.au3>
#include <WindowsConstants.au3>
Opt('MustDeclareVars', 1)
OnAutoItExitRegister("_HookCleanUp")
Global Const $WMSZ_BOTTOM = 6 ; Bottom edge
Global Const $WMSZ_BOTTOMLEFT = 7 ; Bottom-left corner
Global Const $WMSZ_BOTTOMRIGHT = 8 ; Bottom-right corner
Global Const $WMSZ_LEFT = 1 ; Left edge
Global Const $WMSZ_RIGHT = 2 ; Right edge
Global Const $WMSZ_TOP = 3 ; Top edge
Global Const $WMSZ_TOPLEFT = 4 ; Top-left corner
Global Const $WMSZ_TOPRIGHT = 5 ; Top-right corner
Global Const $SC_MOVE = 0xF010
Global Const $SC_MINIMIZE = 0xF020
Global Const $SC_MAXIMIZE = 0xF030
Global $g_hSizeHook, $g_hSizeProc = Null
Global $g_aWnd[100][5] = [[0]] ; [[counter],[hWnd,widthMin,heightMin,widthMax,heightMax], ..]
; --------------------------------------------------------------------------------------------------
Global $hGui = GUICreate('Sizing', 400, 300, -1, -1, BitOR($WS_SYSMENU, $WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX))
; Höhe und Breite in den Grenzen änderbar
_GuiMinMax($hGui, 200, 150, 800, 500)
; nur Höhe änderbar (min: 150, max: ohne Limit)
; !!! Wird Breite oder Höhe in Min auf "-1" gesetzt MUSS der korrespondierende Wert in Max auch "-1" sein. Sonst Änderung nur einmalig.
;~ _GuiMinMax($hGui, -1, 150, -1, 0) ; "0": keine Limitierung, "-1": keine Größenänderung möglich!
; nur Breite änderbar (min: 150, max: 900)
;~ _GuiMinMax($hGui, 200, -1, 900, -1)
GUISetState()
While True
Switch GUIGetMsg()
Case -3
Exit
EndSwitch
WEnd
; --------------------------------------------------------------------------------------------------
Func _GuiMinMax($_hWnd, $_wMin=-1, $_hMin=-1, $_wMax=-1, $_hMax=-1)
_SizeHook($_hWnd)
Local $index = -1
For $i = 1 To $g_aWnd[0][0]
If $g_aWnd[$i][0] = $_hWnd Then
$index = $i
ExitLoop
EndIf
Next
If $index = -1 Then Return
If $_wMin > -1 Then $g_aWnd[$index][1] = $_wMin
If $_hMin > -1 Then $g_aWnd[$index][2] = $_hMin
If $_wMax > -1 Then $g_aWnd[$index][3] = $_wMax
If $_hMax > -1 Then $g_aWnd[$index][4] = $_hMax
EndFunc
Func _SizeHook($_hWnd)
If $g_aWnd[0][0] = UBound($g_aWnd) -1 Then ReDim $g_aWnd[UBound($g_aWnd) +100][5]
For $i = 1 To $g_aWnd[0][0]
If $g_aWnd[$i][0] = $_hwnd Then Return
Next
$g_aWnd[0][0] += 1
$g_aWnd[$g_aWnd[0][0]][0] = $_hWnd
$g_aWnd[$g_aWnd[0][0]][1] = -1
$g_aWnd[$g_aWnd[0][0]][2] = -1
$g_aWnd[$g_aWnd[0][0]][3] = -1
$g_aWnd[$g_aWnd[0][0]][4] = -1
If $g_hSizeProc = Null Then $g_hSizeProc = DllCallbackRegister('_SizeWindowProc', 'ptr', 'hwnd;uint;wparam;lparam')
$g_hSizeHook = _WinAPI_SetWindowLong($_hWnd, $GWL_WNDPROC, DllCallbackGetPtr($g_hSizeProc))
EndFunc
Func _HookCleanUp()
If $g_hSizeProc = Null Then Return
For $i = 1 To $g_aWnd[0][0] ; reset to default window procedure
If WinExists($g_aWnd[$i][0]) Then _WinAPI_SetWindowLong($g_aWnd[$i][0], $GWL_WNDPROC, $g_hSizeHook)
Next
DllCallbackFree($g_hSizeProc)
EndFunc
Func _SizeWindowProc($_hWnd, $_iMsg, $_iwParam, $_ilParam)
If ($_iMsg <> $WM_SIZING And _ ; Sent to a window that the user is resizing.
$_iMsg <> $WM_SYSCOMMAND And _ ; A window receives this message when the user ... or when the user chooses the maximize button, minimize button, restore button, or close button.
$_iMsg <> $WM_NCLBUTTONDBLCLK) Then _ ; Posted when the user double-clicks the left mouse button while the cursor is within the nonclient area of a window.
Return _WinAPI_CallWindowProc($g_hSizeHook, $_hWnd, $_iMsg, $_iwParam, $_ilParam)
Local $index = -1
For $i = 1 To $g_aWnd[0][0]
If $g_aWnd[$i][0] = $_hWnd Then
$index = $i
ExitLoop
EndIf
Next
If $index = -1 Then Return _WinAPI_CallWindowProc($g_hSizeHook, $_hWnd, $_iMsg, $_iwParam, $_ilParam) ; default window processing
Local $iW_Wnd = _WinAPI_GetWindowWidth($_hWnd), $iH_Wnd = _WinAPI_GetWindowHeight($_hWnd)
Local $wMin = $g_aWnd[$index][1]
Local $hMin = $g_aWnd[$index][2]
Local $wMax = $g_aWnd[$index][3]
Local $hMax = $g_aWnd[$index][4]
If $_iMsg = $WM_SIZING Then ; message before the size will changed
Local $tRect = DllStructCreate("struct; long Left;long Top;long Right;long Bottom; endstruct", $_ilParam)
Local $iW = $tRect.Right - $tRect.Left
Local $iH = $tRect.Bottom - $tRect.Top
$wMin = $wMin = 0 ? $iW : ($wMin = -1 ? $iW_Wnd : $wMin) ; "0": free sizeable, "-1": no sizeable in this direction, otherwise the min value
$hMin = $hMin = 0 ? $iH : ($hMin = -1 ? $iH_Wnd : $hMin)
$wMax = $wMax = 0 ? $iW : ($wMax = -1 ? $iW_Wnd : $wMax) ; "0": free sizeable, "-1": no sizeable in this direction, otherwise the max value
$hMax = $hMax = 0 ? $iH : ($hMax = -1 ? $iH_Wnd : $hMax)
Local $bCorrect_wMin = ($iW < $wMin) ; True: set $tRect.Left & $tRect.Right to $wMin related by starting point of sizing ($_iwParam)
Local $bCorrect_hMin = ($iH < $hMin) ; True: set $tRect.Bottom & $tRect.Top to $hMin related by starting point of sizing ($_iwParam)
Local $bCorrect_wMax = ($iW > $wMax) ; True: set $tRect.Left & $tRect.Right to $wMax related by starting point of sizing ($_iwParam)
Local $bCorrect_hMax = ($iH > $hMax) ; True: set $tRect.Bottom & $tRect.Top to $hMax related by starting point of sizing ($_iwParam)
Switch $_iwParam ; The edge of the window that is being sized.
Case $WMSZ_BOTTOM ; Bottom edge changing height by $tRect.Bottom
If $bCorrect_hMin Then $tRect.Bottom = $tRect.Top + $hMin
If $bCorrect_hMax Then $tRect.Bottom = $tRect.Top + $hMax
Case $WMSZ_BOTTOMLEFT ; Bottom-left corner changing height and/or width by $tRect.Bottom and/or $tRect.Left
If $bCorrect_hMin Then $tRect.Bottom = $tRect.Top + $hMin
If $bCorrect_hMax Then $tRect.Bottom = $tRect.Top + $hMax
If $bCorrect_wMin Then $tRect.Left = $tRect.Right - $wMin
If $bCorrect_wMax Then $tRect.Left = $tRect.Right - $wMax
Case $WMSZ_BOTTOMRIGHT ; Bottom-right corner changing height and/or width by $tRect.Bottom and/or $tRect.Right
If $bCorrect_hMin Then $tRect.Bottom = $tRect.Top + $hMin
If $bCorrect_hMax Then $tRect.Bottom = $tRect.Top + $hMax
If $bCorrect_wMin Then $tRect.Right = $tRect.Left + $wMin
If $bCorrect_wMax Then $tRect.Right = $tRect.Left + $wMax
Case $WMSZ_LEFT ; Left edge changing width by $tRect.Left
If $bCorrect_wMin Then $tRect.Left = $tRect.Right - $wMin
If $bCorrect_wMax Then $tRect.Left = $tRect.Right - $wMax
Case $WMSZ_RIGHT ; Right edge changing width by $tRect.Right
If $bCorrect_wMin Then $tRect.Right = $tRect.Left + $wMin
If $bCorrect_wMax Then $tRect.Right = $tRect.Left + $wMax
Case $WMSZ_TOP ; Top edge changing height by $tRect.Top
If $bCorrect_hMin Then $tRect.Top = $tRect.Bottom - $hMin
If $bCorrect_hMax Then $tRect.Top = $tRect.Bottom - $hMax
Case $WMSZ_TOPLEFT ; Top-left corner changing height and/or width by $tRect.Top and/or $tRect.Left
If $bCorrect_hMin Then $tRect.Top = $tRect.Bottom - $hMin
If $bCorrect_hMax Then $tRect.Top = $tRect.Bottom - $hMax
If $bCorrect_wMin Then $tRect.Left = $tRect.Right - $wMin
If $bCorrect_wMax Then $tRect.Left = $tRect.Right - $wMax
Case $WMSZ_TOPRIGHT ; Top-right corner changing height and/or width by $tRect.Top and/or $tRect.Right
If $bCorrect_hMin Then $tRect.Top = $tRect.Bottom - $hMin
If $bCorrect_hMax Then $tRect.Top = $tRect.Bottom - $hMax
If $bCorrect_wMin Then $tRect.Right = $tRect.Left + $wMin
If $bCorrect_wMax Then $tRect.Right = $tRect.Left + $wMax
EndSwitch
ElseIf $_iMsg = $WM_NCLBUTTONDBLCLK And $_iwParam = $HTCAPTION Then ; DBLCLICK on title bar, default: maximize window
Local $aWin = WinGetPos($_hWnd)
If $wMax > -1 Or $hMax > -1 Then ; a max value is set, resize the window to this value
; resize to max
WinMove($_hWnd, '', $aWin[0], $aWin[1], ($wMax > -1 ? $wMax : $aWin[2]), ($hMax > -1 ? $hMax : $aWin[3]))
Return 0 ; avoid default window processing
Else ; allow default window processing
Return _WinAPI_CallWindowProc($g_hSizeHook, $_hWnd, $_iMsg, $_iwParam, $_ilParam)
EndIf
Else ; WM_SYSCOMMAND
; if min/max is set (> -1): minimize/maximize only by this values
Local $aWin = WinGetPos($_hWnd)
Switch $_iwParam
Case $SC_MINIMIZE ; default processing
;
Case $SC_MAXIMIZE
If $wMax > -1 Or $hMax > -1 Then
WinMove($_hWnd, '', $aWin[0], $aWin[1], ($wMax > -1 ? $wMax : $aWin[2]), ($hMax > -1 ? $hMax : $aWin[3]))
Return 0 ; avoid default Window processing
EndIf
EndSwitch
EndIf
Return _WinAPI_CallWindowProc($g_hSizeHook, $_hWnd, $_iMsg, $_iwParam, $_ilParam) ; default Window processing
EndFunc
Alles anzeigen