-
Posts
7,542 -
Joined
-
Last visited
-
Days Won
96
UEZ last won the day on August 10
UEZ had the most liked content!
About UEZ

- Birthday 12/03/2007
Profile Information
-
Member Title
Never say never
-
Location
Germany
-
Interests
Computer, watching movies, football (soccer), being lazy :-)
UEZ's Achievements
-
mLipok reacted to a post in a topic:
_WinAPI_DPI UDF
-
WildByDesign reacted to a post in a topic:
_WinAPI_DPI UDF
-
argumentum reacted to a post in a topic:
_WinAPI_DPI UDF
-
I think the _WinAPI_DPI UDF is now complete enough to be released here. ;Coded by UEZ build 2026-08-12 beta #include-once #include <GDIPlus.au3> #include <StructureConstants.au3> #include <WinAPIGdi.au3> #include <WinAPISysWin.au3> #include <WinAPIsysinfoConstants.au3> #Region DPI Constants ;https://learn.microsoft.com/en-us/windows/win32/api/windef/ne-windef-dpi_awareness Global Enum $DPI_AWARENESS_INVALID = -1, $DPI_AWARENESS_UNAWARE = 0, $DPI_AWARENESS_SYSTEM_AWARE = 1, $DPI_AWARENESS_PER_MONITOR_AWARE = 2 ;https://learn.microsoft.com/en-us/windows/win32/hidpi/dpi-awareness-context ;These are pseudo-handles: formally pointers (DECLARE_HANDLE), but the values -1..-5 are ;sentinels the API maps internally. Never dereference them. Kept as plain literals on ;purpose - deriving them from the DPI_AWARENESS enum couples two unrelated enumerations. Global Const $DPI_AWARENESS_CONTEXT_UNAWARE = -1 Global Const $DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = -2 Global Const $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = -3 Global Const $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = -4 Global Const $DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = -5 ;Unified awareness levels for _WinAPI_SetDPIAwareness (version independent). ;Note the ordering is NOT "increasing awareness": GDISCALED is a variant of UNAWARE and ;deliberately sits last, so never clamp an out-of-range value to it. Global Enum $DPI_LEVEL_UNAWARE = 0, $DPI_LEVEL_SYSTEM, $DPI_LEVEL_PER_MONITOR, $DPI_LEVEL_PER_MONITOR_V2, $DPI_LEVEL_UNAWARE_GDISCALED ;Scope for _WinAPI_SetDPIAwareness Global Enum $DPI_SCOPE_PROCESS = 1, $DPI_SCOPE_THREAD = 2 ;enum PROCESS_DPI_AWARENESS (shellscalingapi.h) Global Enum $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE ;enum _MONITOR_DPI_TYPE Global Enum $MDT_EFFECTIVE_DPI = 0, $MDT_ANGULAR_DPI, $MDT_RAW_DPI Global Const $MDT_DEFAULT = $MDT_EFFECTIVE_DPI ;Windows Message Codes Global Const $WM_DPICHANGED = 0x02E0, $WM_DPICHANGED_BEFOREPARENT = 0x02E2, $WM_DPICHANGED_AFTERPARENT = 0x02E3, $WM_GETDPISCALEDSIZE = 0x02E4 ;DpiChangeBehavior Global Const $DDC_DEFAULT = 0 Global Const $DDC_DISABLE_ALL = 1 Global Const $DDC_DISABLE_RESIZE = 2 Global Const $DDC_DISABLE_CONTROL_RELAYOUT = 4 Global Const $DCDC_DEFAULT = 0 Global Const $DCDC_DISABLE_FONT_UPDATE = 1 Global Const $DCDC_DISABLE_RELAYOUT = 2 ;Internal: OS build thresholds. @OSBuild is compared against these instead of using ;hand-written Case ranges, which is where the original version left a gap. Global Const $__DPI_BUILD_VISTA = 6000 ;SetProcessDPIAware Global Const $__DPI_BUILD_WIN81 = 9600 ;SetProcessDpiAwareness, GetDpiForMonitor Global Const $__DPI_BUILD_1607 = 14393 ;SetThreadDpiAwarenessContext, GetDpiForSystem, ... Global Const $__DPI_BUILD_1703 = 15063 ;SetProcessDpiAwarenessContext, PER_MONITOR_AWARE_V2 Global Const $__DPI_BUILD_1803 = 17134 ;GetDpiFromDpiAwarenessContext, InheritWindowMonitor Global Const $__DPI_BUILD_1809 = 17763 ;UNAWARE_GDISCALED Global Const $__DPI_ERROR_ACCESS_DENIED = 5 ;Win32 ERROR_ACCESS_DENIED Global Const $__DPI_E_ACCESSDENIED = 0x80070005 ;HRESULT E_ACCESSDENIED Global Const $__DPI_DEFAULT_DPI = 96 ;USER_DEFAULT_SCREEN_DPI #EndRegion DPI Constants #Region Internal helpers ;Reads the thread's last Win32 error. Must be called immediately after the DllCall whose ;failure reason is wanted - any intervening call may overwrite it. Func __WinAPI_DPI_GetLastError() Local $aResult = DllCall("kernel32.dll", "dword", "GetLastError") If @error Or Not IsArray($aResult) Then Return 0 Return $aResult[0] EndFunc ;==>__WinAPI_DPI_GetLastError ;Best available way of reading the current DPI, degrading with the OS version. ;Returns 0 if nothing worked. Func __WinAPI_DPI_QueryCurrent() Local $iDPI = 0 If @OSBuild >= $__DPI_BUILD_1607 Then $iDPI = _WinAPI_GetDpiForSystem() If @error Then $iDPI = 0 EndIf If Not $iDPI And @OSBuild >= $__DPI_BUILD_WIN81 Then $iDPI = _WinAPI_GetDpiForMonitor() If @error Then $iDPI = 0 EndIf If Not $iDPI Then $iDPI = _WinAPI_GetDPI() ;GetDeviceCaps fallback, works on every version If @error Then $iDPI = 0 EndIf Return $iDPI EndFunc ;==>__WinAPI_DPI_QueryCurrent ;Maps a unified level (0..4) to its DPI_AWARENESS_CONTEXT pseudo-handle. Func __WinAPI_DPI_LevelToContext($iLevel) Switch $iLevel Case $DPI_LEVEL_UNAWARE Return $DPI_AWARENESS_CONTEXT_UNAWARE Case $DPI_LEVEL_SYSTEM Return $DPI_AWARENESS_CONTEXT_SYSTEM_AWARE Case $DPI_LEVEL_PER_MONITOR Return $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE Case $DPI_LEVEL_PER_MONITOR_V2 Return $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 Case Else Return $DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED EndSwitch EndFunc ;==>__WinAPI_DPI_LevelToContext #EndRegion Internal helpers #Region WinAPI DPI - queries ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-adjustwindowrectexfordpi ;The API expands an existing client RECT into a window RECT, so the rectangle is an input. ;Passing all four coordinates as 0 yields the pure frame offsets (left/top become negative). ;Returns: $tagRECT structure. @error 1 = call failed (@extended = @error), 2 = API returned FALSE. Func _WinAPI_AdjustWindowRectExForDpi($iDpi, $dwStyle, $dwExStyle = 0, $bMenu = False, $iLeft = 0, $iTop = 0, $iRight = 0, $iBottom = 0) Local $tRECT = DllStructCreate($tagRECT) $tRECT.Left = $iLeft $tRECT.Top = $iTop $tRECT.Right = $iRight $tRECT.Bottom = $iBottom ;Parameter order per MSDN: lpRect, dwStyle, bMenu, dwExStyle, dpi Local $aResult = DllCall("user32.dll", "bool", "AdjustWindowRectExForDpi", "struct*", $tRECT, "dword", $dwStyle, "bool", $bMenu, "dword", $dwExStyle, "uint", $iDpi) ;Win10 1607+ / no server support If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If Not $aResult[0] Then Return SetError(2, __WinAPI_DPI_GetLastError(), 0) Return $tRECT EndFunc ;==>_WinAPI_AdjustWindowRectExForDpi ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfofordpi ;$pvParam must be a DllStruct (or pointer) matching the requested $uiAction. Func _WinAPI_SystemParametersInfoForDpi($uiAction, $uiParam, $pvParam, $fWinIni, $iDpi) Local $aResult = DllCall("user32.dll", "bool", "SystemParametersInfoForDpi", "uint", $uiAction, "uint", $uiParam, "struct*", $pvParam, "uint", $fWinIni, "uint", $iDpi) ;Win10 1607+ / no server support If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If Not $aResult[0] Then Return SetError(2, __WinAPI_DPI_GetLastError(), 0) Return True EndFunc ;==>_WinAPI_SystemParametersInfoForDpi ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-inheritwindowmonitor Func _WinAPI_InheritWindowMonitor($hWnd, $hWndInherit) Local $aResult = DllCall("user32.dll", "bool", "InheritWindowMonitor", "hwnd", $hWnd, "hwnd", $hWndInherit) ;Win10 1803+ / Windows Server 2016+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If Not $aResult[0] Then Return SetError(2, __WinAPI_DPI_GetLastError(), 0) Return True EndFunc ;==>_WinAPI_InheritWindowMonitor ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-isvaliddpiawarenesscontext ;A result of False means "this context is not valid" - that is an answer, not an error. ;@error is only set when the call itself could not be made. Func _WinAPI_IsValidDpiAwarenessContext($iContext) Local $aResult = DllCall("user32.dll", "bool", "IsValidDpiAwarenessContext", "int_ptr", $iContext) ;Win10 1607+ / no server support If @error Or Not IsArray($aResult) Then Return SetError(1, @error, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_IsValidDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-logicaltophysicalpointforpermonitordpi Func _WinAPI_LogicalToPhysicalPointForPerMonitorDPI($hWnd, $iX, $iY) Local $tPOINT = DllStructCreate($tagPOINT) $tPOINT.x = $iX $tPOINT.y = $iY Local $aResult = DllCall("user32.dll", "bool", "LogicalToPhysicalPointForPerMonitorDPI", "hwnd", $hWnd, "struct*", $tPOINT) ;Win8.1+ / no server support If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If Not $aResult[0] Then Return SetError(2, __WinAPI_DPI_GetLastError(), 0) Return $tPOINT EndFunc ;==>_WinAPI_LogicalToPhysicalPointForPerMonitorDPI ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-physicaltologicalpointforpermonitordpi Func _WinAPI_PhysicalToLogicalPointForPerMonitorDPI($hWnd, $iX, $iY) Local $tPOINT = DllStructCreate($tagPOINT) $tPOINT.x = $iX $tPOINT.y = $iY Local $aResult = DllCall("user32.dll", "bool", "PhysicalToLogicalPointForPerMonitorDPI", "hwnd", $hWnd, "struct*", $tPOINT) ;Win8.1+ / no server support If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If Not $aResult[0] Then Return SetError(2, __WinAPI_DPI_GetLastError(), 0) Return $tPOINT EndFunc ;==>_WinAPI_PhysicalToLogicalPointForPerMonitorDPI ;GDI+ based DPI of a window (0 = desktop). Requires _GDIPlus_Startup beforehand. Func _GDIPlus_GetDPI($hGUI = 0) Local $hGfx = _GDIPlus_GraphicsCreateFromHWND($hGUI) If @error Then Return SetError(1, @error, 0) Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0) Local $iErr = @error _GDIPlus_GraphicsDispose($hGfx) ;always dispose, even on failure - the original leaked here If $iErr Or Not IsArray($aResult) Then Return SetError(2, $iErr, 0) If $aResult[0] Then Return SetError(3, $aResult[0], 0) ;GDI+ status, 0 = Ok Return $aResult[2] EndFunc ;==>_GDIPlus_GetDPI ;GetDeviceCaps based DPI. Works on every Windows version, but returns a virtualised value ;when the calling thread is DPI unaware. Func _WinAPI_GetDPI($hWnd = 0) If Not $hWnd Then $hWnd = _WinAPI_GetDesktopWindow() Local Const $hDC = _WinAPI_GetDC($hWnd) If @error Or Not $hDC Then Return SetError(1, 0, 0) Local Const $iDPI = _WinAPI_GetDeviceCaps($hDC, $LOGPIXELSX) Local Const $iErr = @error _WinAPI_ReleaseDC($hWnd, $hDC) If $iErr Or Not $iDPI Then Return SetError(2, $iErr, 0) Return $iDPI EndFunc ;==>_WinAPI_GetDPI ;https://learn.microsoft.com/en-us/windows/win32/api/shellscalingapi/nf-shellscalingapi-getdpiformonitor ;$hMonitor = 0 auto-selects the primary monitor. ;$bBothAxes = True returns a 2-element array [dpiX, dpiY] instead of dpiX only. Func _WinAPI_GetDpiForMonitor($hMonitor = 0, $iDpiType = $MDT_DEFAULT, $bBothAxes = False) If Not $hMonitor Then Local $aMonitors = _WinAPI_EnumDisplayMonitors() If @error Or Not IsArray($aMonitors) Then Return SetError(1, @error, 0) Local $aMI For $i = 1 To $aMonitors[0][0] $aMI = _WinAPI_GetMonitorInfo($aMonitors[$i][0]) If @error Or Not IsArray($aMI) Then ContinueLoop ;$aMI[2] is a flags field - test the bit, do not compare for equality If BitAND($aMI[2], 1) Then ;MONITORINFOF_PRIMARY $hMonitor = $aMonitors[$i][0] ExitLoop EndIf Next If Not $hMonitor Then Return SetError(2, 0, 0) ;no primary monitor found EndIf Local $tDpiX = DllStructCreate("uint dpiX") Local $tDpiY = DllStructCreate("uint dpiY") Local $aResult = DllCall("Shcore.dll", "long", "GetDpiForMonitor", _ ;Win8.1+ "handle", $hMonitor, _ "long", $iDpiType, _ "struct*", $tDpiX, _ "struct*", $tDpiY) If @error Or Not IsArray($aResult) Then Return SetError(3, @error, 0) If $aResult[0] <> 0 Then Return SetError(4, $aResult[0], 0) ;HRESULT check If Not $bBothAxes Then Return $tDpiX.dpiX Local $aReturn[2] = [$tDpiX.dpiX, $tDpiY.dpiY] Return $aReturn EndFunc ;==>_WinAPI_GetDpiForMonitor ;Kept for source compatibility - returns [dpiX, dpiY]. Func _WinAPI_GetDpiForMonitor2($hMonitor, $iDpiType = $MDT_EFFECTIVE_DPI) Local $aReturn = _WinAPI_GetDpiForMonitor($hMonitor, $iDpiType, True) Return SetError(@error, @extended, $aReturn) EndFunc ;==>_WinAPI_GetDpiForMonitor2 ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpiforwindow Func _WinAPI_GetDpiForWindow($hWnd) Local $aResult = DllCall("user32.dll", "uint", "GetDpiForWindow", "hwnd", $hWnd) ;Win10 1607+ / no server support If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If Not $aResult[0] Then Return SetError(2, 0, 0) ;0 = invalid hwnd Return $aResult[0] EndFunc ;==>_WinAPI_GetDpiForWindow ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpiforsystem Func _WinAPI_GetDpiForSystem() Local $aResult = DllCall("user32.dll", "uint", "GetDpiForSystem") ;Win10 1607+ / no server support If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If Not $aResult[0] Then Return SetError(2, 0, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDpiForSystem ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getthreaddpiawarenesscontext ;Returns a REAL context handle, never one of the -1..-5 sentinels. Do not compare it with ;the DPI_AWARENESS_CONTEXT_* constants directly - use _WinAPI_AreDpiAwarenessContextsEqual. Func _WinAPI_GetThreadDpiAwarenessContext() Local $aResult = DllCall("user32.dll", "int_ptr", "GetThreadDpiAwarenessContext") ;Win10 1607+ / no server support If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If Not $aResult[0] Then Return SetError(2, 0, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetThreadDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpifromdpiawarenesscontext ;MSDN: PER_MONITOR_AWARE and PER_MONITOR_AWARE_V2 contexts return 0 because the real DPI ;cannot be determined without an HWND. 0 is therefore NOT an error here. Func _WinAPI_GetDpiFromDpiAwarenessContext($iContext) Local $aResult = DllCall("user32.dll", "uint", "GetDpiFromDpiAwarenessContext", "int_ptr", $iContext) ;Win10 1803+ / Windows Server 2016+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDpiFromDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getawarenessfromdpiawarenesscontext ;Returns a DPI_AWARENESS value. 0 = DPI_AWARENESS_UNAWARE is a valid result, and the "int" ;return type keeps DPI_AWARENESS_INVALID (-1) intact instead of turning it into 4294967295. ;Note: PER_MONITOR_AWARE and PER_MONITOR_AWARE_V2 both report 2 - use ;_WinAPI_AreDpiAwarenessContextsEqual to distinguish them. Func _WinAPI_GetAwarenessFromDpiAwarenessContext($iContext) Local $aResult = DllCall("user32.dll", "int", "GetAwarenessFromDpiAwarenessContext", "int_ptr", $iContext) ;Win10 1607+ / no server support If @error Or Not IsArray($aResult) Then Return SetError(1, @error, $DPI_AWARENESS_INVALID) Return $aResult[0] EndFunc ;==>_WinAPI_GetAwarenessFromDpiAwarenessContext ;Convenience: DPI_AWARENESS of the calling thread. Func _WinAPI_GetThreadDpiAwareness() Local $iContext = _WinAPI_GetThreadDpiAwarenessContext() If @error Then Return SetError(1, @error, $DPI_AWARENESS_INVALID) Local $iAwareness = _WinAPI_GetAwarenessFromDpiAwarenessContext($iContext) If @error Then Return SetError(2, @error, $DPI_AWARENESS_INVALID) Return $iAwareness EndFunc ;==>_WinAPI_GetThreadDpiAwareness ;Convenience: does the calling thread run in the given context? Func _WinAPI_IsThreadDpiAwarenessContext($iContext) Local $iCurrent = _WinAPI_GetThreadDpiAwarenessContext() If @error Then Return SetError(1, @error, False) Local $bEqual = _WinAPI_AreDpiAwarenessContextsEqual($iCurrent, $iContext) If @error Then Return SetError(2, @error, False) Return $bEqual EndFunc ;==>_WinAPI_IsThreadDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpiawarenesscontextforprocess Func _WinAPI_GetDpiAwarenessContextForProcess($hProcess = 0) Local $aResult = DllCall("user32.dll", "int_ptr", "GetDpiAwarenessContextForProcess", "handle", $hProcess) ;Win10 1803+ / Windows Server 2016+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If Not $aResult[0] Then Return SetError(2, 0, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDpiAwarenessContextForProcess ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemdpiforprocess Func _WinAPI_GetSystemDpiForProcess($hProcess = 0) Local $aResult = DllCall("user32.dll", "uint", "GetSystemDpiForProcess", "handle", $hProcess) ;Win10 1803+ / Windows Server 2016+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If Not $aResult[0] Then Return SetError(2, 0, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetSystemDpiForProcess ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowdpiawarenesscontext Func _WinAPI_GetWindowDpiAwarenessContext($hWnd) Local $aResult = DllCall("user32.dll", "int_ptr", "GetWindowDpiAwarenessContext", "hwnd", $hWnd) ;Win10 1607+ / Windows Server 2016+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If Not $aResult[0] Then Return SetError(2, 0, 0) ;NULL = invalid window Return $aResult[0] EndFunc ;==>_WinAPI_GetWindowDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-aredpiawarenesscontextsequal ;False is a valid answer, so @error is only set when the call itself failed. Func _WinAPI_AreDpiAwarenessContextsEqual($iContextA, $iContextB) Local $aResult = DllCall("user32.dll", "bool", "AreDpiAwarenessContextsEqual", _ ;Win10 1607+ "int_ptr", $iContextA, _ "int_ptr", $iContextB) If @error Or Not IsArray($aResult) Then Return SetError(1, @error, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_AreDpiAwarenessContextsEqual ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetricsfordpi ;0 can be a legitimate metric value, so it is not treated as an error. Func _WinAPI_GetSystemMetricsForDpi($nIndex, $iDpi) Local $aResult = DllCall("user32.dll", "int", "GetSystemMetricsForDpi", "int", $nIndex, "uint", $iDpi) ;Win10 1607+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetSystemMetricsForDpi ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdialogdpichangebehavior ;Returns a DDC_* bit mask. $DDC_DEFAULT (0) is a valid result. Func _WinAPI_GetDialogDpiChangeBehavior($hWnd) Local $aResult = DllCall("user32.dll", "int", "GetDialogDpiChangeBehavior", "hwnd", $hWnd) ;Win10 1703+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, -1) Return $aResult[0] EndFunc ;==>_WinAPI_GetDialogDpiChangeBehavior ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdialogcontroldpichangebehavior ;Returns a DCDC_* bit mask. $DCDC_DEFAULT (0) is a valid result. Func _WinAPI_GetDialogControlDpiChangeBehavior($hWnd) Local $aResult = DllCall("user32.dll", "int", "GetDialogControlDpiChangeBehavior", "hwnd", $hWnd) ;Win10 1703+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, -1) Return $aResult[0] EndFunc ;==>_WinAPI_GetDialogControlDpiChangeBehavior #EndRegion WinAPI DPI - queries #Region WinAPI DPI - setters ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setprocessdpiawarenesscontext ;@extended carries GetLastError() on failure - ERROR_ACCESS_DENIED (5) means the awareness ;was already fixed (typically by the application manifest) and cannot be changed. Func _WinAPI_SetProcessDpiAwarenessContext($iContext) Local $aResult = DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", "int_ptr", $iContext) ;Win10 1703+ / Windows Server 2016+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, False) If Not $aResult[0] Then Return SetError(2, __WinAPI_DPI_GetLastError(), False) Return True EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setthreaddpiawarenesscontext ;Returns the PREVIOUS context - keep it and restore it when you are done, otherwise you ;change the behaviour of unrelated code running on the same thread. Func _WinAPI_SetThreadDpiAwarenessContext($iContext) Local $aResult = DllCall("user32.dll", "int_ptr", "SetThreadDpiAwarenessContext", "int_ptr", $iContext) ;Win10 1607+ / Windows Server 2016+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If Not $aResult[0] Then Return SetError(2, __WinAPI_DPI_GetLastError(), 0) ;NULL = invalid context Return $aResult[0] EndFunc ;==>_WinAPI_SetThreadDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness ;$iAwareness is a PROCESS_DPI_AWARENESS value (0..2), not a DPI_AWARENESS_CONTEXT. ;@extended carries the HRESULT - E_ACCESSDENIED (0x80070005) means "already set". Func _WinAPI_SetProcessDpiAwareness($iAwareness = $PROCESS_PER_MONITOR_DPI_AWARE) Local $aResult = DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $iAwareness) ;Win8.1+ / Server 2012 R2+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, False) If $aResult[0] <> 0 Then Return SetError(2, $aResult[0], False) Return True EndFunc ;==>_WinAPI_SetProcessDpiAwareness ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setprocessdpiaware Func _WinAPI_SetProcessDPIAware() Local $aResult = DllCall("user32.dll", "bool", "SetProcessDPIAware") ;Vista+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, False) If Not $aResult[0] Then Return SetError(2, __WinAPI_DPI_GetLastError(), False) Return True EndFunc ;==>_WinAPI_SetProcessDPIAware ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enablenonclientdpiscaling ;Unnecessary in PER_MONITOR_AWARE_V2 contexts - V2 scales the non-client area already. Func _WinAPI_EnableNonClientDpiScaling($hWnd) Local $aResult = DllCall("user32.dll", "bool", "EnableNonClientDpiScaling", "hwnd", $hWnd) ;Win10 1607+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, False) If Not $aResult[0] Then Return SetError(2, __WinAPI_DPI_GetLastError(), False) Return True EndFunc ;==>_WinAPI_EnableNonClientDpiScaling ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setdialogdpichangebehavior Func _WinAPI_SetDialogDpiChangeBehavior($hWnd, $iMask, $iValues) Local $aResult = DllCall("user32.dll", "bool", "SetDialogDpiChangeBehavior", "hwnd", $hWnd, "int", $iMask, "int", $iValues) ;Win10 1703+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, False) If Not $aResult[0] Then Return SetError(2, __WinAPI_DPI_GetLastError(), False) Return True EndFunc ;==>_WinAPI_SetDialogDpiChangeBehavior ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setdialogcontroldpichangebehavior Func _WinAPI_SetDialogControlDpiChangeBehavior($hWnd, $iMask, $iValues) Local $aResult = DllCall("user32.dll", "bool", "SetDialogControlDpiChangeBehavior", "hwnd", $hWnd, "int", $iMask, "int", $iValues) ;Win10 1703+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, False) If Not $aResult[0] Then Return SetError(2, __WinAPI_DPI_GetLastError(), False) Return True EndFunc ;==>_WinAPI_SetDialogControlDpiChangeBehavior ;https://learn.microsoft.com/en-us/windows/win32/api/uxtheme/nf-uxtheme-openthemedatafordpi ;The caller owns the returned HTHEME and must release it with _WinAPI_CloseThemeData. Func _WinAPI_OpenThemeDataForDpi($hWnd, $pszClassList, $iDpi) Local $aResult = DllCall("uxtheme.dll", "handle", "OpenThemeDataForDpi", "hwnd", $hWnd, "wstr", $pszClassList, "uint", $iDpi) ;Win10 1703+ If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If Not $aResult[0] Then Return SetError(2, 0, 0) Return $aResult[0] EndFunc ;==>_WinAPI_OpenThemeDataForDpi #EndRegion WinAPI DPI - setters #Region High level ; #FUNCTION# =================================================================================== ; Name ..........: _WinAPI_SetDPIAwareness ; Description ...: Sets the DPI awareness using the best method the running OS supports. ; Syntax ........: _WinAPI_SetDPIAwareness([$iAwarenessLevel = $DPI_LEVEL_PER_MONITOR[, $iMode = $DPI_SCOPE_PROCESS]]) ; Parameters ....: $iAwarenessLevel - unified level, one of $DPI_LEVEL_*: ; 0 = UNAWARE ; 1 = SYSTEM ; 2 = PER_MONITOR (default) ; 3 = PER_MONITOR_V2 (Win10 1703+) ; 4 = UNAWARE_GDISCALED (Win10 1809+) ; Raw DPI_AWARENESS_CONTEXT values (-1..-5) are also ; accepted for backwards compatibility. ; $iMode - $DPI_SCOPE_PROCESS (1, default) or $DPI_SCOPE_THREAD (2) ; Return values .: Success: the current DPI. @extended = 1 means the DPI could not be ; determined and the default of 96 was returned instead. ; Failure: 0 and @error set: ; 1 - no method available or all methods failed (@extended = last Win32 error) ; 10 - thread scope requested but the OS is older than Win10 1607 ; 11 - SetThreadDpiAwarenessContext failed (@extended = @error of the wrapper) ; Remarks .......: Call this before the first GUICreate or any other window access. ; Levels above the OS capability are silently downgraded: V2 -> PER_MONITOR, ; GDISCALED -> UNAWARE. ; In thread scope the previous context is NOT returned. If you need to ; restore it, call _WinAPI_SetThreadDpiAwarenessContext directly. ; Setting the awareness via the application manifest is more robust than ; calling this function, because windows can in principle be created before ; the first script statement runs. ; ============================================================================================== Func _WinAPI_SetDPIAwareness($iAwarenessLevel = $DPI_LEVEL_PER_MONITOR, $iMode = $DPI_SCOPE_PROCESS) ;--- Normalise the requested level --------------------------------------------------- ;Accept raw DPI_AWARENESS_CONTEXT values: -1 -> 0, -2 -> 1, ... -5 -> 4 If $iAwarenessLevel < 0 Then $iAwarenessLevel = (-$iAwarenessLevel) - 1 If $iAwarenessLevel < $DPI_LEVEL_UNAWARE Then $iAwarenessLevel = $DPI_LEVEL_UNAWARE ;Clamp to V2, NOT to GDISCALED: an out-of-range value must not silently select an ;unaware mode. This also closes the out-of-bounds crash the old context map had. If $iAwarenessLevel > $DPI_LEVEL_UNAWARE_GDISCALED Then $iAwarenessLevel = $DPI_LEVEL_PER_MONITOR_V2 ;--- Downgrade to what this OS actually supports -------------------------------------- If $iAwarenessLevel = $DPI_LEVEL_PER_MONITOR_V2 And @OSBuild < $__DPI_BUILD_1703 Then $iAwarenessLevel = $DPI_LEVEL_PER_MONITOR ;GDISCALED is an UNAWARE variant, so its fallback is UNAWARE - not PER_MONITOR If $iAwarenessLevel = $DPI_LEVEL_UNAWARE_GDISCALED And @OSBuild < $__DPI_BUILD_1809 Then $iAwarenessLevel = $DPI_LEVEL_UNAWARE Local Const $iContext = __WinAPI_DPI_LevelToContext($iAwarenessLevel) If $iMode <> $DPI_SCOPE_THREAD Then $iMode = $DPI_SCOPE_PROCESS ;--- Thread scope --------------------------------------------------------------------- If $iMode = $DPI_SCOPE_THREAD Then ;There is no legacy equivalent - per-thread awareness starts with Win10 1607 If @OSBuild < $__DPI_BUILD_1607 Then Return SetError(10, 0, 0) _WinAPI_SetThreadDpiAwarenessContext($iContext) If @error Then Return SetError(11, @error, 0) Local $iThreadDPI = __WinAPI_DPI_QueryCurrent() If Not $iThreadDPI Then Return SetError(0, 1, $__DPI_DEFAULT_DPI) Return $iThreadDPI EndIf ;--- Process scope: descending fallback chain ----------------------------------------- Local $bDone = False, $iLastError = 0 ;Step 1: SetProcessDpiAwarenessContext - Win10 1703+, the only route to V2 / GDISCALED If @OSBuild >= $__DPI_BUILD_1703 Then If _WinAPI_SetProcessDpiAwarenessContext($iContext) Then $bDone = True Else $iLastError = @extended ;ERROR_ACCESS_DENIED: the awareness is already fixed (manifest) and immutable. ;The desired state may well be active already, so accept it instead of failing. If $iLastError = $__DPI_ERROR_ACCESS_DENIED Then $bDone = True EndIf EndIf ;Step 2: SetProcessDpiAwareness - Win8.1+, knows only three levels If Not $bDone And @OSBuild >= $__DPI_BUILD_WIN81 Then Local $iLegacy Switch $iAwarenessLevel Case $DPI_LEVEL_UNAWARE, $DPI_LEVEL_UNAWARE_GDISCALED $iLegacy = $PROCESS_DPI_UNAWARE Case $DPI_LEVEL_SYSTEM $iLegacy = $PROCESS_SYSTEM_DPI_AWARE Case Else $iLegacy = $PROCESS_PER_MONITOR_DPI_AWARE ;PER_MONITOR and V2 both land here EndSwitch If _WinAPI_SetProcessDpiAwareness($iLegacy) Then $bDone = True Else $iLastError = @extended If $iLastError = $__DPI_E_ACCESSDENIED Then $bDone = True ;already set EndIf EndIf ;Step 3: SetProcessDPIAware - Vista+, system aware only. Pointless for unaware levels. If Not $bDone And @OSBuild >= $__DPI_BUILD_VISTA And $iAwarenessLevel <> $DPI_LEVEL_UNAWARE And $iAwarenessLevel <> $DPI_LEVEL_UNAWARE_GDISCALED Then If _WinAPI_SetProcessDPIAware() Then $bDone = True Else $iLastError = @extended If $iLastError = $__DPI_ERROR_ACCESS_DENIED Then $bDone = True ;already set EndIf EndIf ;Step 4: unaware is the default state of every process - nothing to call, nothing failed If Not $bDone And ($iAwarenessLevel = $DPI_LEVEL_UNAWARE Or $iAwarenessLevel = $DPI_LEVEL_UNAWARE_GDISCALED) Then $bDone = True If Not $bDone Then Return SetError(1, $iLastError, 0) ;--- Report the resulting DPI --------------------------------------------------------- Local $iDPI = __WinAPI_DPI_QueryCurrent() ;Awareness was set successfully, so a failed DPI query is not a hard error - flag it ;in @extended and hand back the 96 DPI default. If Not $iDPI Then Return SetError(0, 1, $__DPI_DEFAULT_DPI) Return $iDPI EndFunc ;==>_WinAPI_SetDPIAwareness #EndRegion High level Claude added the comments and fixed some bugs. Please test if everything is working as expected.
-
Parsix reacted to a post in a topic:
PNG in GUI
-
UEZ reacted to a post in a topic:
Png2Icon Update of 4 july 2026
-
Try: Global $sRemote = "192.168.1.50:9000" ; IP of the receiver Global $sCmd = $sFFMPEG & ' ' & $sInput & ' ' & _ '-filter_complex "[0:v]split[rec][tmp];[tmp]fps=30[net]" ' & _ '-map "[rec]" -c:v libx264 -pix_fmt yuv420p ' & $sAudioMap & '"' & $sOutFile & '" ' & _ '-map "[net]" -c:v libx264 -preset ultrafast -tune zerolatency -g 10 -an ' & _ '-fflags +nobuffer -flags +low_delay -muxdelay 0 -muxpreload 0 -flush_packets 1 ' & _ '-f tee "[f=mpegts]' & $sUDP & '|[f=mpegts]srt://' & $sRemote & '?mode=caller"'
-
What are you trying to do? Record from the webcam?
-
Last try - see above. Personally, I don't like this approach of using ffmpeg and mpv to display and record the webcam.
-
I updated the code above - the latency should be better now.
-
Made some updates - please try again.
-
Try this: ;Code by UEZ build 2026-06-27 #include <AutoItConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPIError.au3> Global $iW = 1280, $iH = 720 Global $sFFMPEG = '"...\FFMPEG\bin\ffmpeg.exe"' Global $sMPV = '"...\MPV\mpv.exe"' Global $sOutFile = "C:\Temp\WebCamRec.mkv" Global $aVid, $aAud _GetDShowDevices($sFFMPEG, $aVid, $aAud) If $aVid[0] = 0 Then Exit MsgBox(16, "Error", "No video capture device found") Global $sVideo = $aVid[1] ; first WebCam Global $sAudio = ($aAud[0] > 0) ? $aAud[1] : "" ; first micro, if available Global $bHasAudio = ($sAudio <> "") ; Input-Optionen MUESSEN vor dem -i stehen (gelten fuer den folgenden Input) Global $sInput = '-f dshow -rtbufsize 256M -video_size 1280x720 -framerate 30 -pixel_format nv12 ' & _ '-use_wallclock_as_timestamps 1 -i video="' & $sVideo & '"' If $bHasAudio Then $sInput &= ' -f dshow -use_wallclock_as_timestamps 1 -i audio="' & $sAudio & '"' Global $sAudioMap = $bHasAudio ? '-map 1:a -c:a aac -ar 48000 -ac 2 ' : '' Global $hGUI = GUICreate("WebCam + Live Preview + Record", $iW, $iH + 40, -1, -1, BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPCHILDREN)) Global $idStop = GUICtrlCreateButton("Stop", 10, $iH + 6, 80, 26) Global $hChild = GUICreate("", $iW, $iH, 0, 0, $WS_CHILD, -1, $hGUI) GUISetState(@SW_SHOW, $hChild) GUISwitch($hGUI) GUISetState(@SW_SHOW, $hGUI) Global $wid = Number($hChild) If FileExists($sOutFile) Then FileDelete($sOutFile) Global $sUDP = "udp://127.0.0.1:1234?pkt_size=1316" Global $sCmd = $sFFMPEG & ' ' & $sInput & ' ' & _ '-filter_complex "[0:v]split[rec][tmp];[tmp]fps=30[prev]" ' & _ '-map "[rec]" -c:v libx264 -pix_fmt yuv420p ' & $sAudioMap & '"' & $sOutFile & '" ' & _ '-map "[prev]" -c:v libx264 -preset ultrafast -tune zerolatency -g 10 -an ' & _ '-fflags +nobuffer -flags +low_delay -muxdelay 0 -muxpreload 0 -flush_packets 1 ' & _ '-f mpegts ' & $sUDP Global $iPID = Run($sCmd, "", @SW_HIDE, $STDIN_CHILD) Global $sMpvPipe = "\\.\pipe\mpv_preview" Global $sMpvCmd = $sMPV & ' --wid=' & $wid & ' --no-audio --no-osc --force-window=yes ' & _ '--profile=low-latency --untimed --no-cache --demuxer-readahead-secs=0 ' & _ '--vd-queue-enable=no --demuxer-lavf-o=fflags=+nobuffer ' & _ '--demuxer-lavf-format=mpegts --input-ipc-server=' & $sMpvPipe & ' "' & $sUDP & '"' Global $iPIDmpv = Run($sMpvCmd, "") While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $idStop _StopAll($iPID, $iPIDmpv) ExitLoop EndSwitch WEnd GUIDelete($hGUI) Func _GetDShowDevices($sFFMPEG, ByRef $aVideo, ByRef $aAudio) Local $sExe = StringReplace($sFFMPEG, '"', '') Local $iPID = Run('"' & $sExe & '" -hide_banner -list_devices true -f dshow -i dummy', "", @SW_HIDE, $STDERR_CHILD) Local $sOut = "" While 1 $sOut &= StderrRead($iPID) If @error Then ExitLoop WEnd Local $aV[1] = [0], $aA[1] = [0], $sType = "" Local $aLines = StringSplit(StringStripCR($sOut), @LF), $sLine, $aM For $i = 1 To $aLines[0] $sLine = $aLines[$i] If StringInStr($sLine, "(video)") Then $sType = "v" If StringInStr($sLine, "(audio)") Then $sType = "a" If StringInStr($sLine, "Alternative name") Then ContinueLoop $aM = StringRegExp($sLine, '"([^"]+)"', 1) If @error Then ContinueLoop If $sType = "v" Then _ArrayAdd_($aV, $aM[0]) ElseIf $sType = "a" Then _ArrayAdd_($aA, $aM[0]) EndIf Next $aVideo = $aV $aAudio = $aA EndFunc Func _ArrayAdd_(ByRef $a, $v) ReDim $a[$a[0] + 2] $a[0] += 1 $a[$a[0]] = $v EndFunc Func _StopAll($iPID, $iPIDmpv) If ProcessExists($iPID) Then StdinWrite($iPID, "q") StdinWrite($iPID) ProcessWaitClose($iPID, 10) If ProcessExists($iPID) Then ProcessClose($iPID) EndIf Local $h = FileOpen($sMpvPipe, 2) If $h <> -1 Then FileWrite($h, '{"command":["quit"]}' & @LF) FileClose($h) EndIf ProcessWaitClose($iPIDmpv, 2) If ProcessExists($iPIDmpv) Then ProcessClose($iPIDmpv) EndFunc mpv can be found here: https://sourceforge.net/projects/mpv-player-windows/files/ Adjust the pathes to ffmpeg and mpv!
-
Really nice screensavers. I like the falling hearts. Firework looks great, too. Well done!
-
UEZ reacted to a post in a topic:
GDI+ ScreenSavers
-
Need help with GDI+ line curve or arc
UEZ replied to WildByDesign's topic in AutoIt GUI Help and Support
Try: ... Local $hPath2 = _GDIPlus_PathCreate() _GDIPlus_PathAddArc($hPath2, $iW - 6, 0, 5, 5, 270, 90) _GDIPlus_PathAddLine($hPath2, $iW - 1, 5, $iW - 1, $iH - 6) ; button border fix <<<< need help with curve here _GDIPlus_PathAddArc($hPath2, $iW - 6, $iH - 6, 5, 5, 0, 90) Local $hPen = _GDIPlus_PenCreate(0xFFa0a0a0, 1) Local $hPen2 = _GDIPlus_PenCreate(0xFF9b9b9b, 1) _GDIPlus_GraphicsDrawPath($hBmpCtxt, $hPath, $hPen) _GDIPlus_GraphicsDrawPath($hBmpCtxt, $hPath2, $hPen2) ... -
Nice idea. Let's see who will win...
-
UEZ reacted to a post in a topic:
World Cup Mascots CrossFade
-
This is what I expected because what I understood is that "Camera" is also based on Media Foundation (Frame-Server) API.
-
You can disable "Click-through" in Tray icon -> Recorder -> WebCam settings ->Click-through. The DLL works with Media Foundation (Frame-Server) API which is probably not compatible with generic Microsoft Windows driver. Other apps may use DirectShow to display WebCam. Is Windows "Camera" built-in app working with your WebCam? You may update the drivers if available. Thanks for testing again. Coming soon a trim editor for recorded video inkl. reencode (4:2:0 (YUV) recorded video only).
-
Salut wakillion, I updated the version to AirCapRec v0.9.3 beta build 2026-06-05. Does your webcam show a picture in the Windows Camera app? Does it work in any other apps? In AirCapRec: enable Debug logging in Settings, then toggle the webcam (Ctrl+Alt+W) and send me the new AirCapRec_debug.log — it now logs the webcam state. Is it a built-in laptop cam or an external USB one? Brand/model? Does the webcam preview window show a black box in the corner (cam initialized but no image), or nothing at all? Any privacy/antivirus camera blocker active (Windows camera privacy setting, or third-party security)? I saw in the logfile a problem with your display info: It should display 4k and 300%. Please update and test again and post the log. MERCI!
-
You can create the grid manually without loading it from a file: #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) Global $g_hImage, $g_idPic Example() Func Example() Local $iW = 800, $iH = 400 ; Gui client width & height _GDIPlus_Startup() Local $xGrid = 20, $yGrid = 20 Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($xGrid, $yGrid) Local $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap), $hPen = _GDIPlus_PenCreate(0xFF000000, 2) _GDIPlus_GraphicsClear($hGfx, 0xFFFFFFFF) _GDIPlus_GraphicsDrawLine($hGfx, 0, 0, $xGrid, 0, $hPen) _GDIPlus_GraphicsDrawLine($hGfx, 0, 1, 0, $yGrid, $hPen) _GDIPlus_PenDispose($hPen) _GDIPlus_GraphicsDispose($hGfx) Local $hTexture = _GDIPlus_TextureCreate($hBitmap) _GDIPlus_BitmapDispose($hBitmap) $g_hImage = _GDIPlus_BitmapCreateFromScan0($iW, $iH) $hGfx = _GDIPlus_ImageGetGraphicsContext($g_hImage) _GDIPlus_GraphicsClear($hGfx, 0xFFFFFFFF) _GDIPlus_GraphicsFillRect($hGfx, 0, 0, $iW, $iH, $hTexture) _GDIPlus_BrushDispose($hTexture) _GDIPlus_GraphicsDispose($hGfx) Local $hGUI = GUICreate("Test Grid #2", $iW, $iH, -1, -1, $WS_OVERLAPPEDWINDOW, $WS_EX_COMPOSITED) $g_idPic = GUICtrlCreatePic("", 0, 0, $iW, $iH) GUICtrlSetResizing(-1, $GUI_DOCKAUTO) ; or $GUI_DOCKBORDERS ? Update_Pic($g_hImage) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_SIZE, "WM_SIZE") While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _GDIPlus_ImageDispose($g_hImage) _GDIPlus_Shutdown() GUIDelete() Exit EndSwitch WEnd EndFunc ;==>Example Func Update_Pic($hHandle) Local $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hHandle) Local $hPrevImage = GUICtrlSendMsg($g_idPic, 0x0172, 0, $hBitmap) ; $STM_SETIMAGE = 0x0172, $IMAGE_BITMAP = 0 If $hPrevImage Then _WinAPI_DeleteObject($hPrevImage); delete prev image if any (help file) _WinAPI_DeleteObject($hBitmap) EndFunc ;==>Update_Pic Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam) Local $hImage_resized = _GDIPlus_ImageResize($g_hImage, BitAND($lParam, 0xFFFF), BitShift($lParam, 16), 2) ; high-quality mode Update_Pic($hImage_resized) _GDIPlus_ImageDispose($hImage_resized) Return "GUI_RUNDEFMSG" EndFunc ;==>WM_SIZE
-
UEZ reacted to a post in a topic:
Testing fullscreen video capturing @ 60 FPS
-
@wakillon I can't thank you enough—you're the only tester! Indeed, 4:4:4 is flickering for me, too. Seems that I changed something without testing it. Hmmm. It's also strange that I can't see the system info section in the log file, even though you've obviously tested the latest version (AirCapRec v0.9.3 beta build 2026-06-02). I’ll include the app version number in the log so you can see which version was used. === AirCapRec session started 06-03-2026 20:19:02 === Log file: C:\_BZ25LN\Coding\FreeBASIC\__UEZ\_Tools\AirCapRec\AirCapRec_debug.log [sysinfo] Windows 10 Enterprise 25H2 (10.0 Build 26200.8390) [sysinfo] Architecture: x64 / 64-bit process [sysinfo] CPU: Intel(R) Core(TM) Ultra 5 135U (14 logical cores) [sysinfo] RAM: 15.5 GB (15892 MB) free 2.0 GB (2077 MB) (load 86%) [sysinfo] Commit/Pagefile: total 32.6 GB (33414 MB) free 7.3 GB (7504 MB) [sysinfo] Disk (EXE): C:\ free 20.5 GB (21047 MB) of 235.0 GB (240695 MB) [sysinfo] Disk (System): C:\ free 20.5 GB (21047 MB) of 235.0 GB (240695 MB) [sysinfo] Display: primary 1920x1080 virtual 1920x1080 monitors 1 DPI 96 (100%) [sysinfo] GPU: Intel(R) Graphics [sysinfo] Locale: de-DE [sysinfo] Camera(s): 1 [sysinfo] [0] Integrated Webcam [sysinfo] Uptime: 79h 19m [285548187] HighlightClicks=1 Origin=(0,0) MMCSS=1 [285548187] Audio requested: sys=1 mic=0 bitrate=128000 [285549265] Audio_Init OK [285549265] SR_Init OK: C:\_BZ25LN\Coding\FreeBASIC\__UEZ\_Tools\AirCapRec\Capture_20260603_201901.mp4 30fps CRF=32 preset=superfast tune=zerolatency audio=1 [285549265] SR_Start OK [285549281] Recording-Thread started [285549281] MMCSS AvSetMmThreadCharacteristicsW('Capture') = OK [285550609] Opening MP4: C:\_BZ25LN\Coding\FreeBASIC\__UEZ\_Tools\AirCapRec\Capture_20260603_201901.mp4 (1920x1080 @ 30fps) [285550609] MP4Min_Open OK [285555625] Ring stats: produced=72 dropped=60 consumed=70 filled=2 encFrames=149 repeated=50 duped=29 [285560671] Ring stats: produced=191 dropped=130 consumed=189 filled=2 encFrames=300 repeated=73 duped=38 [285561000] SR_Stop called - video frames=310 audio frames=443 [285561000] Final ring stats: produced=198 dropped=132 consumed=197 filled=1 [285561046] Recording-Thread done: total frames=311 repeated=74 realDuration=10.41174930002308s [285567296] HighlightClicks=1 Origin=(0,0) MMCSS=1 [285567296] Audio requested: sys=1 mic=0 bitrate=128000 [285567296] Audio_Init OK [285567296] SR_Init OK: C:\_BZ25LN\Coding\FreeBASIC\__UEZ\_Tools\AirCapRec\Capture_20260603_201922.mp4 30fps CRF=32 preset=superfast tune=zerolatency audio=1 [285567296] SR_Start OK [285567296] Recording-Thread started [285567296] MMCSS AvSetMmThreadCharacteristicsW('Capture') = OK [285567312] Opening MP4: C:\_BZ25LN\Coding\FreeBASIC\__UEZ\_Tools\AirCapRec\Capture_20260603_201922.mp4 (1920x1080 @ 30fps) [285567312] MP4Min_Open OK [285572312] Ring stats: produced=135 dropped=51 consumed=133 filled=2 encFrames=149 repeated=16 duped=0 [285577312] Ring stats: produced=263 dropped=98 consumed=263 filled=0 encFrames=299 repeated=36 duped=0 [285577718] SR_Stop called - video frames=311 audio frames=481 [285577718] Final ring stats: produced=276 dropped=102 consumed=274 filled=2 [285577781] Recording-Thread done: total frames=312 repeated=37 realDuration=10.45726320001995s [285582031] Drained 0 leftover slot(s) before cleanup === session ended === Thanks so much for your feedback! Edit: 4:4:4 flicker bug found and fixed -> new version uploaded