WildByDesign Posted 8 hours ago Posted 8 hours ago I am trying to learn from the Microsoft tutorial: Custom Window Frame Using DWM - Win32 apps | Microsoft Learn I have never had trouble with extending the frame into the client area. But I have always got stuck on Removing the Standard Frame section and so I move onto other things and try again every few weeks. This section mentions: Quote To remove the standard window frame, you must handle the WM_NCCALCSIZE message, specifically when its wParam value is TRUE and the return value is 0. By doing so, your application uses the entire window region as the client area, removing the standard frame. The results of handling the WM_NCCALCSIZE message are not visible until the client region needs to be resized. Until that time, the initial view of the window appears with the standard frame and extended borders. To overcome this, you must either resize your window or perform an action that initiates a WM_NCCALCSIZE message at the time of window creation. This can be accomplished by using the SetWindowPos function to move your window and resize it. The following code demonstrates a call to SetWindowPos that forces a WM_NCCALCSIZE message to be sent using the current window rectangle attributes and the SWP_FRAMECHANGED flag. I have some familiarity with SetWindowPos thanks to @pixelsearch from some other help topics in recent months. However, I have no experience with WM_NCCALCSIZE or how to handle that message in AutoIt. Here is my current example: expandcollapse popup#include <GUIConstantsEx.au3> #include <WinAPIGdi.au3> ; DPI DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -4) Example() Func Example() ; Create a GUI with various controls. Local $hGUI = GUICreate("Example", 400, 400) Local $idOK = GUICtrlCreateButton("OK", 310, 370, 85, 25) ; set background color to black GUISetBkColor(0x000000) ; apply dark titlebar _WinAPI_DwmSetWindowAttribute__($hGUI, 20, 1) ; extend frame into client area _WinAPI_DwmExtendFrameIntoClientArea($hGUI, _WinAPI_CreateMargins(-1, -1, -1, -1)) ; Display the GUI. GUISetState(@SW_SHOW, $hGUI) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $idOK ExitLoop EndSwitch WEnd ; Delete the previous GUI and all controls. GUIDelete($hGUI) EndFunc ;==>Example Func _WinAPI_DwmSetWindowAttribute__($hwnd, $attribute = 34, $value = 0x00FF00, $valLen = 4) Local $aCall = DllCall('dwmapi.dll', 'long', 'DwmSetWindowAttribute', 'hwnd', $hWnd, 'dword', $attribute, 'dword*', $value, 'dword', $valLen) If @error Then Return SetError(@error, @extended, 0) If $aCall[0] Then Return SetError(10, $aCall[0], 0) Return 1 EndFunc ;==>_WinAPI_DwmSetWindowAttribute__ Thank you for any assistance with this.
Solution WildByDesign Posted 6 hours ago Author Solution Posted 6 hours ago After some more research and help from the AutoIt forum gods of past generations, I have got the removal of the standard frame done successfully now. I used WM_NCHITTEST to make the entire window draggable since it would be impossible now without the standard frame. This all leaves the window control buttons non-functional but that is expected. Those will also need some WM_NCHITTEST work but this is for another step for another day. Since this solves my problem, I will mark as solution. Updated example: expandcollapse popup#include <GUIConstantsEx.au3> #include <WinAPIGdi.au3> #include <WindowsConstants.au3> #include <WinAPISysWin.au3> Global $hGUI DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext", "HWND", "DPI_AWARENESS_CONTEXT" - 4) Example() Func Example() $hGUI = GUICreate("My GUI", 300, 200) Local $idEndBtn = GUICtrlCreateButton("End", 110, 140, 70, 20) _WinAPI_DwmSetWindowAttribute__($hGUI, 20, 1) _WinAPI_DwmExtendFrameIntoClientArea($hGUI, _WinAPI_CreateMargins(-1, -1, -1, -1)) GUIRegisterMsg(0x0083, "INTERNAL_WM_NCCALCSIZE") GUIRegisterMsg($WM_NCHITTEST, "_MY_NCHITTEST") ; SetWindowPos _WinAPI_SetWindowPos($hGUI, $HWND_TOP, 0, 0, 0, 0, BitOR($SWP_FRAMECHANGED, $SWP_NOACTIVATE, $SWP_NOMOVE, $SWP_NOSIZE, $SWP_NOZORDER)) GUISetState(@SW_SHOW) Local $idMsg ; Loop until the user exits. While 1 $idMsg = GUIGetMsg() Switch $idMsg Case $idEndBtn, $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd EndFunc ;==>Example Func _WinAPI_DwmSetWindowAttribute__($hwnd, $attribute = 34, $value = 0x00FF00, $valLen = 4) Local $aCall = DllCall('dwmapi.dll', 'long', 'DwmSetWindowAttribute', 'hwnd', $hWnd, 'dword', $attribute, 'dword*', $value, 'dword', $valLen) If @error Then Return SetError(@error, @extended, 0) If $aCall[0] Then Return SetError(10, $aCall[0], 0) Return 1 EndFunc ;==>_WinAPI_DwmSetWindowAttribute__ Func INTERNAL_WM_NCCALCSIZE($hWnd, $Msg, $wParam, $lParam) If $hWnd = $hGUI Then Return 0 EndIf Return 'GUI_RUNDEFMSG' EndFunc ;==>INTERNAL_WM_NCCALCSIZE ; Original code - Prog@ndy Func _MY_NCHITTEST($hWnd, $uMsg, $wParam, $lParam) Switch $hWnd Case $hGUI Local $aPos = WinGetPos($hWnd) ; Check if mouse is over top 50 pixels If Abs(BitAND(BitShift($lParam, 16), 0xFFFF) - $aPos[1]) < 1200 Then Return $HTCAPTION EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_MY_NCHITTEST
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now