Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 10/30/2025 in Posts

  1. Released Peace version 1.6.8.11. It now support VST plugins by controlling and using Equalizer APO's Configuration Editor. The Peace AutoEQ interface now includes OPRA by Roon (collaborators such as Oratory1990). A new import interface has been created for better import. And a theme can be installed directly from within Peace through a new theme installation interface.
    3 points
  2. Hello! I'm working on a new GUI builder that I have been making great progress on! A helpful forum member ioa747 answered a question I had which started me on my journey, and now I'd like to present to you an alpha version of the software. As of now only Form and Button works in a rudimentary fashion. To run this, open Guiscape.au3 and go from there! I'd love to hear your feedback and suggestions. 🙂 Latest versions will be on Github from now on. https://github.com/matthewrg/Guiscape Guiscape.zip Downloads: 35
    2 points
  3. Thank you! 🥰 It's a problem I'm in the middle of working on. I got side quested with this DPI stuff. 😂 I learned a lot and now I have something to bring into my future projects! Updated at GitHub because I made some oopsies!
    2 points
  4. TheSaint

    Kobo Cover Fixer

    REMOVED the Kobo Cover Fixer v2-4.zip update download, due to a serious bug. It will be replaced soon as, but right now I am still testing, which isn't easy in my circumstances, which is no doubt how the issue slipped through. Basically the Restore feature worked in the wrong direction copy wise, and probably the Clone feature did too. I am presuming they originally worked in the right directions or I would have noticed before now. So likely this is the result of a recent new feature I added, and which I might have been interrupted in when implementing. Due to the flaky nature of the USB connection to my Kobo device, which may be a device hardware issue or just driver related, testing and troubleshooting for me, are a challenge. In essence, I only get a small window of time to operate in. Basically my device needs to be flat, and I get roughly an hour before it is charged after connecting to my PC. Once the device battery is charged, the Kobo device gets stuck in a connect/disconnect loop, so almost impossible to work with. You might think an hour would be sufficient time, and it is if all goes to plan. However it doesn't leave much leeway for testing latest changes or troubleshooting. This is chiefly because I have a lot of ebooks on my Kobo device ... just shy of a thousand, of which somewhat less than a hundred are side-loaded ebooks. It takes a good while checking the images for all those ebooks, especially when doing visual comparison, as happens when a mismatch between the clone folder on my PC and the images folder on the Kobo device. Anyway, BIG APOLOGIES to the six downloaders of v2.4, who may have been or might be, impacted by the wrong direction copy issue ... hopefully their cover sources remain. I discovered this issue a couple of hours ago and are already working on a fix, perhaps already fixed. Luckily right now, I am just about to start reading a physical trade paperback, so my Kobo device won't be needed for reading for a couple of days or so. In an effort to deal with this more quickly, I have temporarily set my Kobo device to never go to sleep, so the battery can get flatter quicker, and I can do some final testing, hopefully in a few hours or tomorrow. P.S. I'd been following my latest instructions to ensure I didn't miss anything in regard to them, so the good news is they passed up to where I needed to troubleshoot the copy issue, so up until just before I needed to run the Clone feature ... after restoring the cover images in my Clone folder from my Images Backup folder ... so glad I had that. NOTE TO SELF - I should suggest using the BACKUP IMAGES option before running the 'Clone' feature ... certainly on first use. Having that backup has saved my bacon a few times. So I should amend those newly created instructions.
    2 points
  5. ...developing GUI stuff is a pain. Mostly because you'd need at least 2 monitors and at least on with scaling as otherwise, you can't clearly see what it looks like. On the other hand, that would be a pain to code without an stablished UDF for it. Therefore, since we don't have a stablish UDF ( that I know of ) forget the HiDPI stuff and make the GUI editor without that into consideration. If "GuiCtrls_HiDpi" (UDF in progress) or another UDF comes along or, "New and improved: AutoIt v3.4.0.0. Now with HiDPI" comes into existence, then patching the editor shouldn't be a big deal. Santa Claus/Saint Nicholas/Saint Nick/Father Christmas/Kris Kringle/bearded dude: I wish for a "dark/light mode, DPI aware" all in one UDF 😇 TIA
    2 points
  6. https://github.com/matthewrg/Guiscape
    2 points
  7. Because working with multiple monitors was required during the development of ImageSearchUDF , this UDF was created UDF: #include-once #include <WinAPIGdi.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> ; =============================================================================================================================== ; Title .........: Monitor UDF ; Description ...: Provides advanced monitor management and multi-monitor utilities. ; Author ........: Dao Van Trong - TRONG.PRO ; Version .......: 2.1 ; Modified ......: Fixed bugs, added features, improved error handling, Windows XP compatibility ; Compatibility .: Windows XP SP2 and later (most functions) ; Windows 8.1+ required for GetDpiForMonitor API (automatic fallback on older systems) ; =============================================================================================================================== ; FUNCTIONS SUMMARY ; =============================================================================================================================== ; _Monitor_GetList() - Enumerate connected monitors and fill global info. ; _Monitor_GetCount() - Return total number of monitors. ; _Monitor_GetPrimary() - Get index of the primary monitor. ; _Monitor_GetInfo($iMonitor) - Get detailed info about a monitor. ; _Monitor_GetBounds($iMonitor, ...) - Get full monitor rectangle (including taskbar). ; _Monitor_GetWorkArea($iMonitor, ...) - Get working area of a monitor (excluding taskbar). ; _Monitor_GetDisplaySettings($iMonitor) - Get current display mode. ; _Monitor_GetResolution($iMonitor) - Get monitor resolution. ; _Monitor_GetFromPoint([$x, $y]) - Get monitor from screen point or mouse. ; _Monitor_GetFromWindow($hWnd) - Get monitor containing a specific window. ; _Monitor_GetFromRect(...) - Get monitor overlapping a given rectangle. ; _Monitor_GetVirtualBounds() - Get bounding rectangle of the entire virtual screen. ; _Monitor_ToVirtual($iMonitor, $x, $y) - Convert local monitor coordinates to virtual coordinates. ; _Monitor_FromVirtual($iMonitor, $x, $y)- Convert from virtual to local monitor coordinates. ; _Monitor_IsVisibleWindow($hWnd) - Check if a window is top-level visible. ; _Monitor_MoveWindowToScreen(...) - Move a window to specific monitor (center if unspecified). ; _Monitor_MoveWindowToAll(...) - Move a visible window across all monitors. ; _Monitor_EnumAllDisplayModes($iMonitor)- Enumerate all available display modes. ; _Monitor_ShowInfo([$bShowMsgBox = 1, $iTimeout = 10]) - Show all monitor information. ; _Monitor_Refresh() - Refresh monitor list (reload from system). ; _Monitor_IsConnected($iMonitor) - Check if monitor is still connected. ; _Monitor_GetDPI($iMonitor) - Get DPI scaling for a monitor. ; _Monitor_GetOrientation($iMonitor) - Get display orientation (0, 90, 180, 270 degrees). ; _Monitor_GetLayout() - Get current display layout configuration. ; _Monitor_SaveLayout($sFilePath) - Save current layout to file. ; _Monitor_LoadLayout($sFilePath) - Load layout from file. ; _Monitor_GetLayoutDescription() - Get text description of current layout. ; _Monitor_ApplyLayoutHorizontal() - Arrange monitors horizontally (side by side). ; _Monitor_ApplyLayoutVertical() - Arrange monitors vertically (stacked). ; _Monitor_ApplyLayoutGrid([$iCols = 2[, $iRows = 2]]) - Arrange monitors in grid layout. ; =============================================================================================================================== ;~ ; Constants for SystemMetrics (define if not available, compatible with Windows XP) ;~ If Not IsDeclared("SM_CMONITORS") Then Global $SM_CMONITORS = 80 ;~ If Not IsDeclared("SM_XVIRTUALSCREEN") Then Global $SM_XVIRTUALSCREEN = 76 ;~ If Not IsDeclared("SM_YVIRTUALSCREEN") Then Global $SM_YVIRTUALSCREEN = 77 ;~ If Not IsDeclared("SM_CXVIRTUALSCREEN") Then Global $SM_CXVIRTUALSCREEN = 78 ;~ If Not IsDeclared("SM_CYVIRTUALSCREEN") Then Global $SM_CYVIRTUALSCREEN = 79 ;~ ; Monitor flags (define if not available) ;~ If Not IsDeclared("MONITOR_DEFAULTTONULL") Then Global $MONITOR_DEFAULTTONULL = 0 ;~ If Not IsDeclared("MONITOR_DEFAULTTOPRIMARY") Then Global $MONITOR_DEFAULTTOPRIMARY = 1 ;~ If Not IsDeclared("MONITOR_DEFAULTTONEAREST") Then Global $MONITOR_DEFAULTTONEAREST = 2 ;~ ; EnumDisplaySettings mode (define if not available) ;~ If Not IsDeclared("ENUM_CURRENT_SETTINGS") Then Global $ENUM_CURRENT_SETTINGS = -1 ;~ If Not IsDeclared("ENUM_REGISTRY_SETTINGS") Then Global $ENUM_REGISTRY_SETTINGS = -2 ;~ ; Window constants (define if not available, compatible with Windows XP) ;~ If Not IsDeclared("GWL_STYLE") Then Global $GWL_STYLE = -16 ;~ If Not IsDeclared("GWL_EXSTYLE") Then Global $GWL_EXSTYLE = -20 ;~ If Not IsDeclared("WS_VISIBLE") Then Global $WS_VISIBLE = 0x10000000 ;~ If Not IsDeclared("WS_CHILD") Then Global $WS_CHILD = 0x40000000 ;~ If Not IsDeclared("WS_EX_TOOLWINDOW") Then Global $WS_EX_TOOLWINDOW = 0x00000080 #Region --- Global Variables --- ; =============================================================================================================================== ; Global Monitor Information Array ; =============================================================================================================================== ; $__g_aMonitorList[][] structure: ; ; [0][0] = Number of monitors detected ; [0][1] = Virtual desktop Left coordinate (combined area) ; [0][2] = Virtual desktop Top coordinate ; [0][3] = Virtual desktop Right coordinate ; [0][4] = Virtual desktop Bottom coordinate ; [0][5] = Virtual desktop Width ; [0][6] = Virtual desktop Height ; ; For each monitor index i (1..$__g_aMonitorList[0][0]): ; [i][0] = Monitor handle (HMONITOR) ; [i][1] = Left coordinate of monitor ; [i][2] = Top coordinate of monitor ; [i][3] = Right coordinate of monitor ; [i][4] = Bottom coordinate of monitor ; [i][5] = IsPrimary (1 if primary, 0 otherwise) - FIXED: Now stores actual flag ; [i][6] = Device name string (e.g. "\\.\DISPLAY1") ; ; =============================================================================================================================== Global $__g_aMonitorList[1][7] = [[0, 0, 0, 0, 0, 0, ""]] #EndRegion --- Global Variables --- #Region --- OS Compatibility Functions --- ; #FUNCTION# ==================================================================================================================== ; Name...........: __Monitor_IsWindowsVersionOrGreater ; Description....: Check if running on Windows version or greater (internal function) ; Syntax.........: __Monitor_IsWindowsVersionOrGreater($iMajor, $iMinor = 0) ; Parameters.....: $iMajor - Major version number (e.g., 6 for Vista, 10 for Windows 10) ; $iMinor - [optional] Minor version number. Default is 0 ; Return values..: True if OS version is equal or greater, False otherwise ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Internal function for OS compatibility checking. Uses GetVersionEx API directly for accurate ; version detection, works on all AutoIt versions (even old ones where @OSVersion may be inaccurate). ; Windows XP = 5.1, Vista = 6.0, Win7 = 6.1, Win8 = 6.2, Win8.1 = 6.3, Win10 = 10.0 ; ================================================================================================================================ Func __Monitor_IsWindowsVersionOrGreater($iMajor, $iMinor = 0) ; Use GetVersionEx API directly (works on all Windows versions and all AutoIt versions) ; This is more reliable than @OSVersion which may not be accurate on old AutoIt versions ; Define OSVERSIONINFOEX structure ; dwOSVersionInfoSize, dwMajorVersion, dwMinorVersion, dwBuildNumber, dwPlatformId, ; szCSDVersion[128], wServicePackMajor, wServicePackMinor, wSuiteMask, wProductType, wReserved Local $tOSVI = DllStructCreate("dword;dword;dword;dword;dword;wchar[128];ushort;ushort;ushort;byte;byte") If @error Then Return False ; Set structure size (first field) DllStructSetData($tOSVI, 1, DllStructGetSize($tOSVI)) ; Call GetVersionExW (Unicode version, available from Windows 2000+) Local $aRet = DllCall("kernel32.dll", "bool", "GetVersionExW", "struct*", $tOSVI) If @error Or Not IsArray($aRet) Or Not $aRet[0] Then ; Fallback: Try ANSI version GetVersionExA (available from Windows 95+) ; Note: ANSI version uses char[128] instead of wchar[128] Local $tOSVIA = DllStructCreate("dword;dword;dword;dword;dword;char[128];ushort;ushort;ushort;byte;byte") If Not @error Then DllStructSetData($tOSVIA, 1, DllStructGetSize($tOSVIA)) $aRet = DllCall("kernel32.dll", "bool", "GetVersionExA", "struct*", $tOSVIA) If @error Or Not IsArray($aRet) Or Not $aRet[0] Then ; Last resort: Use @OSVersion as fallback (but this may be inaccurate) Return __Monitor_FallbackOSVersionCheck($iMajor, $iMinor) EndIf ; Use ANSI version data Local $iOSMajor = DllStructGetData($tOSVIA, 2) Local $iOSMinor = DllStructGetData($tOSVIA, 3) ; Compare versions If $iOSMajor > $iMajor Then Return True If $iOSMajor = $iMajor And $iOSMinor >= $iMinor Then Return True Return False Else ; Last resort: Use @OSVersion as fallback Return __Monitor_FallbackOSVersionCheck($iMajor, $iMinor) EndIf EndIf ; Get version from structure (Unicode version) Local $iOSMajor = DllStructGetData($tOSVI, 2) Local $iOSMinor = DllStructGetData($tOSVI, 3) ; Handle Windows 10/11: GetVersionEx may return 6.3 for compatibility ; Check build number to distinguish Windows 10/11 from 8.1 Local $iBuildNumber = DllStructGetData($tOSVI, 4) If $iOSMajor = 6 And $iOSMinor = 3 And $iBuildNumber >= 10000 Then ; Windows 10/11 (build number >= 10000) $iOSMajor = 10 $iOSMinor = 0 EndIf ; Compare versions If $iOSMajor > $iMajor Then Return True If $iOSMajor = $iMajor And $iOSMinor >= $iMinor Then Return True Return False EndFunc ;==>__Monitor_IsWindowsVersionOrGreater ; #FUNCTION# ==================================================================================================================== ; Name...........: __Monitor_FallbackOSVersionCheck ; Description....: Fallback OS version check using @OSVersion macro (internal function) ; Syntax.........: __Monitor_FallbackOSVersionCheck($iMajor, $iMinor) ; Parameters.....: $iMajor - Major version number ; $iMinor - Minor version number ; Return values..: True if OS version is equal or greater, False otherwise ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Used only when GetVersionEx API fails. Less reliable than API call. ; ================================================================================================================================ Func __Monitor_FallbackOSVersionCheck($iMajor, $iMinor) ; Fallback to @OSVersion (may be inaccurate on old AutoIt versions, but better than nothing) Local $sOSVersion = @OSVersion Local $iOSMajor = 5, $iOSMinor = 1 ; Default to XP If StringInStr($sOSVersion, "WIN_11") Then $iOSMajor = 10 $iOSMinor = 0 ElseIf StringInStr($sOSVersion, "WIN_10") Then $iOSMajor = 10 $iOSMinor = 0 ElseIf StringInStr($sOSVersion, "WIN_8") Then ; Use @OSBuild to distinguish 8.0 vs 8.1 (8.1 has build >= 9600) If @OSBuild >= 9600 Then $iOSMajor = 6 $iOSMinor = 3 ; Windows 8.1 Else $iOSMajor = 6 $iOSMinor = 2 ; Windows 8 EndIf ElseIf StringInStr($sOSVersion, "WIN_7") Then $iOSMajor = 6 $iOSMinor = 1 ElseIf StringInStr($sOSVersion, "WIN_VISTA") Then $iOSMajor = 6 $iOSMinor = 0 ElseIf StringInStr($sOSVersion, "WIN_XP") Then $iOSMajor = 5 $iOSMinor = 1 ElseIf StringInStr($sOSVersion, "WIN_2003") Then $iOSMajor = 5 $iOSMinor = 2 EndIf ; Compare versions If $iOSMajor > $iMajor Then Return True If $iOSMajor = $iMajor And $iOSMinor >= $iMinor Then Return True Return False EndFunc ;==>__Monitor_FallbackOSVersionCheck ; #FUNCTION# ==================================================================================================================== ; Name...........: __Monitor_IsWindows8_1OrGreater ; Description....: Check if running on Windows 8.1 or greater (internal function) ; Syntax.........: __Monitor_IsWindows8_1OrGreater() ; Parameters.....: None ; Return values..: True if Windows 8.1 or greater, False otherwise ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Internal function for checking if GetDpiForMonitor API is available ; ================================================================================================================================ Func __Monitor_IsWindows8_1OrGreater() ; Windows 8.1 = version 6.3, but GetVersionEx may return 6.3 for Windows 10/11 too ; We need to check build number: Windows 8.1 = build 9600-9999, Windows 10+ = build >= 10000 ; Use GetVersionEx API directly Local $tOSVI = DllStructCreate("dword;dword;dword;dword;dword;wchar[128];ushort;ushort;ushort;byte;byte") If Not @error Then DllStructSetData($tOSVI, 1, DllStructGetSize($tOSVI)) Local $aRet = DllCall("kernel32.dll", "bool", "GetVersionExW", "struct*", $tOSVI) If Not @error And IsArray($aRet) And $aRet[0] Then Local $iOSMajor = DllStructGetData($tOSVI, 2) Local $iOSMinor = DllStructGetData($tOSVI, 3) Local $iBuildNumber = DllStructGetData($tOSVI, 4) ; Windows 8.1 = 6.3 with build 9600-9999 ; Windows 10+ = 6.3 (or 10.0) with build >= 10000 If $iOSMajor = 6 And $iOSMinor = 3 Then ; Check build number If $iBuildNumber >= 10000 Then Return True ; Windows 10 or later (>= 8.1) ElseIf $iBuildNumber >= 9600 Then Return True ; Windows 8.1 EndIf ElseIf $iOSMajor >= 10 Or ($iOSMajor = 6 And $iOSMinor >= 3) Then Return True ; Windows 8.1 or later EndIf EndIf EndIf ; Fallback to version check Return __Monitor_IsWindowsVersionOrGreater(6, 3) EndFunc ;==>__Monitor_IsWindows8_1OrGreater #EndRegion --- OS Compatibility Functions --- ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetFromPoint ; Description....: Get the monitor index from a screen coordinate or current mouse position ; Syntax.........: _Monitor_GetFromPoint([$iX = -1 [, $iY = -1]]) ; Parameters.....: $iX - [optional] X coordinate in virtual screen coordinates. Default is -1 (use mouse position) ; $iY - [optional] Y coordinate in virtual screen coordinates. Default is -1 (use mouse position) ; Return values..: Success - Monitor index (1..N) ; Failure - 0, sets @error to non-zero: ; |@error = 1 - Invalid parameters or MouseGetPos failed ; |@error = 2 - Monitor not found at specified coordinates ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: If both $iX and $iY are -1 (default), function uses current mouse position. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_GetList, _Monitor_GetFromWindow, _Monitor_GetFromRect ; ================================================================================================================================ Func _Monitor_GetFromPoint($iX = -1, $iY = -1) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() ; Use WinAPI function if available If $iX = -1 Or $iY = -1 Then Local $aMouse = MouseGetPos() If @error Then Return SetError(1, 0, 0) $iX = $aMouse[0] $iY = $aMouse[1] EndIf Local $tPoint = DllStructCreate($tagPOINT) If @error Then Return SetError(1, 0, 0) DllStructSetData($tPoint, "X", $iX) DllStructSetData($tPoint, "Y", $iY) ; _WinAPI_MonitorFromPoint is available from Windows 2000+ (compatible with XP) Local $hMonitor = _WinAPI_MonitorFromPoint($tPoint, $MONITOR_DEFAULTTONEAREST) If @error Then ; Fallback to coordinate checking if WinAPI call fails $hMonitor = 0 EndIf ; Find index in our list For $i = 1 To $__g_aMonitorList[0][0] If $__g_aMonitorList[$i][0] = $hMonitor Then Return $i Next ; Fallback to coordinate checking For $i = 1 To $__g_aMonitorList[0][0] If $iX >= $__g_aMonitorList[$i][1] _ And $iX < $__g_aMonitorList[$i][3] _ And $iY >= $__g_aMonitorList[$i][2] _ And $iY < $__g_aMonitorList[$i][4] Then Return $i EndIf Next Return SetError(2, 0, 0) EndFunc ;==>_Monitor_GetFromPoint ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetFromWindow ; Description....: Get the monitor index that contains the specified window ; Syntax.........: _Monitor_GetFromWindow($hWnd [, $iFlag = $MONITOR_DEFAULTTONEAREST]) ; Parameters.....: $hWnd - Window handle or title string. Can be HWND or window title ; $iFlag - [optional] Monitor flag. Default is $MONITOR_DEFAULTTONEAREST ; Can be: $MONITOR_DEFAULTTONULL, $MONITOR_DEFAULTTOPRIMARY, $MONITOR_DEFAULTTONEAREST ; Return values..: Success - Monitor index (1..N) ; Failure - 0, sets @error to non-zero: ; |@error = 1 - Invalid window handle or window not found ; |@error = 2 - WinAPI MonitorFromWindow call failed ; |@error = 3 - Monitor handle not found in internal list ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Function accepts both window handles and window titles. Automatically converts title to handle. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_GetList, _Monitor_GetFromPoint, _Monitor_GetFromRect ; ================================================================================================================================ Func _Monitor_GetFromWindow($hWnd, $iFlag = $MONITOR_DEFAULTTONEAREST) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() If Not IsHWnd($hWnd) Then $hWnd = WinGetHandle($hWnd) If Not $hWnd Then Return SetError(1, 0, 0) ; _WinAPI_MonitorFromWindow is available from Windows 2000+ (compatible with XP) Local $hMonitor = _WinAPI_MonitorFromWindow($hWnd, $iFlag) If @error Or Not $hMonitor Then Return SetError(2, 0, 0) For $i = 1 To $__g_aMonitorList[0][0] If $__g_aMonitorList[$i][0] = $hMonitor Then Return $i Next Return SetError(3, 0, 0) EndFunc ;==>_Monitor_GetFromWindow ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetFromRect ; Description....: Get the monitor index that has the largest intersection with the specified rectangle ; Syntax.........: _Monitor_GetFromRect($iLeft, $iTop, $iRight, $iBottom [, $iFlag = $MONITOR_DEFAULTTONEAREST]) ; Parameters.....: $iLeft - Left coordinate of the rectangle in virtual screen coordinates ; $iTop - Top coordinate of the rectangle in virtual screen coordinates ; $iRight - Right coordinate of the rectangle in virtual screen coordinates ; $iBottom - Bottom coordinate of the rectangle in virtual screen coordinates ; $iFlag - [optional] Monitor flag. Default is $MONITOR_DEFAULTTONEAREST ; Can be: $MONITOR_DEFAULTTONULL, $MONITOR_DEFAULTTOPRIMARY, $MONITOR_DEFAULTTONEAREST ; Return values..: Success - Monitor index (1..N) ; Failure - 0, sets @error to non-zero: ; |@error = 1 - DllStructCreate failed or WinAPI MonitorFromRect call failed ; |@error = 2 - Monitor not found in internal list ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Coordinates should be in virtual screen coordinate system (can span multiple monitors). ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_GetList, _Monitor_GetFromPoint, _Monitor_GetFromWindow ; ================================================================================================================================ Func _Monitor_GetFromRect($iLeft, $iTop, $iRight, $iBottom, $iFlag = $MONITOR_DEFAULTTONEAREST) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() Local $tRect = DllStructCreate($tagRECT) If @error Then Return SetError(1, 0, 0) DllStructSetData($tRect, "Left", $iLeft) DllStructSetData($tRect, "Top", $iTop) DllStructSetData($tRect, "Right", $iRight) DllStructSetData($tRect, "Bottom", $iBottom) ; _WinAPI_MonitorFromRect is available from Windows 2000+ (compatible with XP) Local $hMonitor = _WinAPI_MonitorFromRect($tRect, $iFlag) If @error Or Not $hMonitor Then Return SetError(1, 0, 0) For $i = 1 To $__g_aMonitorList[0][0] If $__g_aMonitorList[$i][0] = $hMonitor Then Return $i Next Return SetError(2, 0, 0) EndFunc ;==>_Monitor_GetFromRect ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetWorkArea ; Description....: Get working area of a specific monitor (excluding taskbar and system bars) ; Syntax.........: _Monitor_GetWorkArea($iMonitor, ByRef $left, ByRef $top, ByRef $right, ByRef $bottom) ; Parameters.....: $iMonitor - Monitor index (1..N) ; $left - [out] Left coordinate of work area (virtual screen coordinates) ; $top - [out] Top coordinate of work area (virtual screen coordinates) ; $right - [out] Right coordinate of work area (virtual screen coordinates) ; $bottom - [out] Bottom coordinate of work area (virtual screen coordinates) ; Return values..: Success - 1 ; Failure - 0, sets @error to non-zero: ; |@error = 1 - Invalid monitor index ; |@error = 2 - WinAPI GetMonitorInfo call failed ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Work area excludes taskbar and other system bars. Use _Monitor_GetBounds() for full monitor area. ; All coordinates are in virtual screen coordinate system. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_GetBounds, _Monitor_GetInfo, _Monitor_GetList ; ================================================================================================================================ Func _Monitor_GetWorkArea($iMonitor, ByRef $left, ByRef $top, ByRef $right, ByRef $bottom) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() If $iMonitor < 1 Or $iMonitor > $__g_aMonitorList[0][0] Then Return SetError(1, 0, 0) Local $hMonitor = $__g_aMonitorList[$iMonitor][0] ; _WinAPI_GetMonitorInfo is available from Windows 2000+ (compatible with XP) Local $aInfo = _WinAPI_GetMonitorInfo($hMonitor) If @error Or Not IsArray($aInfo) Then Return SetError(2, 0, 0) Local $tWorkArea = $aInfo[1] If Not IsDllStruct($tWorkArea) Then Return SetError(2, 0, 0) $left = DllStructGetData($tWorkArea, "Left") $top = DllStructGetData($tWorkArea, "Top") $right = DllStructGetData($tWorkArea, "Right") $bottom = DllStructGetData($tWorkArea, "Bottom") Return 1 EndFunc ;==>_Monitor_GetWorkArea ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetBounds ; Description....: Get full bounds of a specific monitor (including taskbar and all system areas) ; Syntax.........: _Monitor_GetBounds($iMonitor, ByRef $left, ByRef $top, ByRef $right, ByRef $bottom) ; Parameters.....: $iMonitor - Monitor index (1..N) ; $left - [out] Left coordinate of monitor (virtual screen coordinates) ; $top - [out] Top coordinate of monitor (virtual screen coordinates) ; $right - [out] Right coordinate of monitor (virtual screen coordinates) ; $bottom - [out] Bottom coordinate of monitor (virtual screen coordinates) ; Return values..: Success - 1 ; Failure - 0, sets @error = 1 (Invalid monitor index) ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Returns the full physical bounds of the monitor including all system bars (taskbar, etc.). ; All coordinates are in virtual screen coordinate system. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; For usable area excluding taskbar, use _Monitor_GetWorkArea() instead. ; Related........: _Monitor_GetWorkArea, _Monitor_GetInfo, _Monitor_GetList ; ================================================================================================================================ Func _Monitor_GetBounds($iMonitor, ByRef $left, ByRef $top, ByRef $right, ByRef $bottom) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() If $iMonitor < 1 Or $iMonitor > $__g_aMonitorList[0][0] Then Return SetError(1, 0, 0) $left = $__g_aMonitorList[$iMonitor][1] $top = $__g_aMonitorList[$iMonitor][2] $right = $__g_aMonitorList[$iMonitor][3] $bottom = $__g_aMonitorList[$iMonitor][4] Return 1 EndFunc ;==>_Monitor_GetBounds ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetInfo ; Description....: Get detailed information about a monitor ; Syntax.........: _Monitor_GetInfo($iMonitor) ; Parameters.....: $iMonitor - Monitor index (1..N) ; Return values..: Success - Array with 11 elements: ; |[0] - Monitor handle (HMONITOR) ; |[1] - Left coordinate of monitor bounds (virtual screen coordinates) ; |[2] - Top coordinate of monitor bounds (virtual screen coordinates) ; |[3] - Right coordinate of monitor bounds (virtual screen coordinates) ; |[4] - Bottom coordinate of monitor bounds (virtual screen coordinates) ; |[5] - Left coordinate of work area (virtual screen coordinates) ; |[6] - Top coordinate of work area (virtual screen coordinates) ; |[7] - Right coordinate of work area (virtual screen coordinates) ; |[8] - Bottom coordinate of work area (virtual screen coordinates) ; |[9] - IsPrimary flag (1 = Primary, 0 = Secondary) ; |[10] - Device name string (e.g., "\\.\DISPLAY1") ; Failure - 0, sets @error to non-zero: ; |@error = 1 - Invalid monitor index ; |@error = 2 - WinAPI GetMonitorInfo call failed ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This is the most comprehensive function to get all monitor information at once. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_GetList, _Monitor_GetBounds, _Monitor_GetWorkArea, _Monitor_GetPrimary ; ================================================================================================================================ Func _Monitor_GetInfo($iMonitor) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() If $iMonitor < 1 Or $iMonitor > $__g_aMonitorList[0][0] Then Return SetError(1, 0, 0) Local $hMonitor = $__g_aMonitorList[$iMonitor][0] ; _WinAPI_GetMonitorInfo is available from Windows 2000+ (compatible with XP) Local $aInfo = _WinAPI_GetMonitorInfo($hMonitor) If @error Or Not IsArray($aInfo) Then Return SetError(2, 0, 0) Local $tMonitorRect = $aInfo[0] Local $tWorkRect = $aInfo[1] If Not IsDllStruct($tMonitorRect) Or Not IsDllStruct($tWorkRect) Then Return SetError(2, 0, 0) Local $aResult[11] $aResult[0] = $hMonitor $aResult[1] = DllStructGetData($tMonitorRect, "Left") $aResult[2] = DllStructGetData($tMonitorRect, "Top") $aResult[3] = DllStructGetData($tMonitorRect, "Right") $aResult[4] = DllStructGetData($tMonitorRect, "Bottom") $aResult[5] = DllStructGetData($tWorkRect, "Left") $aResult[6] = DllStructGetData($tWorkRect, "Top") $aResult[7] = DllStructGetData($tWorkRect, "Right") $aResult[8] = DllStructGetData($tWorkRect, "Bottom") $aResult[9] = ($aInfo[2] <> 0) ; IsPrimary $aResult[10] = $aInfo[3] ; DeviceName Return $aResult EndFunc ;==>_Monitor_GetInfo ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetDisplaySettings ; Description....: Get display settings for a monitor (resolution, color depth, refresh rate, etc.) ; Syntax.........: _Monitor_GetDisplaySettings($iMonitor [, $iMode = $ENUM_CURRENT_SETTINGS]) ; Parameters.....: $iMonitor - Monitor index (1..N) ; $iMode - [optional] Display mode index. Default is $ENUM_CURRENT_SETTINGS ; Use $ENUM_CURRENT_SETTINGS to get current active settings ; Use index number (0..N) to enumerate available modes ; Return values..: Success - Array with 5 elements: ; |[0] - Width (pixels) ; |[1] - Height (pixels) ; |[2] - Bits per pixel (color depth) ; |[3] - Refresh rate (Hz) ; |[4] - Display mode flags ; Failure - 0, sets @error to non-zero: ; |@error = 1 - Invalid monitor index ; |@error = 2 - GetInfo failed (could not get device name) ; |@error = 3 - WinAPI EnumDisplaySettings call failed ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Use $ENUM_CURRENT_SETTINGS to get the currently active display mode. ; Use _Monitor_EnumAllDisplayModes() to get all available display modes. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_GetResolution, _Monitor_EnumAllDisplayModes, _Monitor_GetList ; ================================================================================================================================ Func _Monitor_GetDisplaySettings($iMonitor, $iMode = $ENUM_CURRENT_SETTINGS) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() If $iMonitor < 1 Or $iMonitor > $__g_aMonitorList[0][0] Then Return SetError(1, 0, 0) Local $sDevice = $__g_aMonitorList[$iMonitor][6] If $sDevice = "" Then Local $aInfo = _Monitor_GetInfo($iMonitor) If @error Then Return SetError(2, 0, 0) $sDevice = $aInfo[10] EndIf ; _WinAPI_EnumDisplaySettings is available from Windows 95+ (fully compatible with XP) Local $aSettings = _WinAPI_EnumDisplaySettings($sDevice, $iMode) If @error Or Not IsArray($aSettings) Then Return SetError(3, 0, 0) Return $aSettings EndFunc ;==>_Monitor_GetDisplaySettings ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetResolution ; Description....: Get the current resolution (width and height) of a monitor ; Syntax.........: _Monitor_GetResolution($iMonitor) ; Parameters.....: $iMonitor - Monitor index (1..N) ; Return values..: Success - Array with 2 elements: ; |[0] - Width in pixels ; |[1] - Height in pixels ; Failure - 0, sets @error to non-zero: ; |@error = 1 - Invalid monitor index ; |@error = 2 - GetDisplaySettings failed ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This is a convenience function that returns only width and height from display settings. ; For full display settings (color depth, refresh rate, etc.), use _Monitor_GetDisplaySettings(). ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_GetDisplaySettings, _Monitor_GetInfo, _Monitor_GetList ; ================================================================================================================================ Func _Monitor_GetResolution($iMonitor) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() If $iMonitor < 1 Or $iMonitor > $__g_aMonitorList[0][0] Then Return SetError(1, 0, 0) Local $aSettings = _Monitor_GetDisplaySettings($iMonitor) If @error Then Return SetError(2, @error, 0) Local $aResult[2] = [$aSettings[0], $aSettings[1]] Return $aResult EndFunc ;==>_Monitor_GetResolution ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetPrimary ; Description....: Get the index of the primary monitor ; Syntax.........: _Monitor_GetPrimary() ; Parameters.....: None ; Return values..: Success - Monitor index (1..N) of the primary monitor ; Failure - 0, sets @error = 1 (No primary monitor found) ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Primary monitor is the monitor that contains the taskbar by default in Windows. ; Function first checks cached IsPrimary flags, then falls back to querying system if needed. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_GetList, _Monitor_GetInfo, _Monitor_GetCount ; ================================================================================================================================ Func _Monitor_GetPrimary() If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() ; Use cached IsPrimary flag if available For $i = 1 To $__g_aMonitorList[0][0] If $__g_aMonitorList[$i][5] = 1 Then Return $i Next ; Fallback: query from system For $i = 1 To $__g_aMonitorList[0][0] Local $aInfo = _Monitor_GetInfo($i) If Not @error And $aInfo[9] = 1 Then Return $i Next Return SetError(1, 0, 0) EndFunc ;==>_Monitor_GetPrimary ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetCount ; Description....: Returns the total number of connected monitors ; Syntax.........: _Monitor_GetCount() ; Parameters.....: None ; Return values..: Success - Number of monitors (>= 1) ; Failure - 0, sets @error = 1 (Enumeration failed) ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Function first tries GetSystemMetrics API for fastest response. ; Falls back to cached monitor list if API call fails. ; Automatically validates and refreshes monitor list if count mismatch detected. ; Related........: _Monitor_GetList, _Monitor_Refresh, _Monitor_GetPrimary ; ================================================================================================================================ Func _Monitor_GetCount() ; Try GetSystemMetrics first (compatible with Windows XP and later) ; Note: SM_CMONITORS is available from Windows 2000+ Local $aRet = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_CMONITORS) If @error Or Not IsArray($aRet) Or $aRet[0] < 1 Then ; Fallback to our cached list If $__g_aMonitorList[0][0] = 0 Then If _Monitor_GetList() = -1 Then Return SetError(1, 0, 0) EndIf Return $__g_aMonitorList[0][0] Else ; Validate count matches our list (refresh if needed) If $__g_aMonitorList[0][0] <> $aRet[0] Then _Monitor_GetList() EndIf Return $aRet[0] EndIf EndFunc ;==>_Monitor_GetCount ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetVirtualBounds ; Description....: Get bounding rectangle of all monitors combined (the "virtual screen") ; Syntax.........: _Monitor_GetVirtualBounds() ; Parameters.....: None ; Return values..: Success - Array with 4 elements: ; |[0] - Left coordinate of virtual screen ; |[1] - Top coordinate of virtual screen ; |[2] - Width of virtual screen in pixels ; |[3] - Height of virtual screen in pixels ; Failure - 0, sets @error = 1 (DllCall failed) ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Virtual screen is the bounding rectangle that encompasses all connected monitors. ; Function uses GetSystemMetrics API. Falls back to cached virtual bounds if API fails. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_GetList, _Monitor_GetBounds, _Monitor_GetCount ; ================================================================================================================================ Func _Monitor_GetVirtualBounds() ; GetSystemMetrics for virtual screen is available from Windows 2000+ ; All SM_*VIRTUALSCREEN constants are supported on Windows XP and later Local $aL = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_XVIRTUALSCREEN) Local $aT = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_YVIRTUALSCREEN) Local $aW = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_CXVIRTUALSCREEN) Local $aH = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_CYVIRTUALSCREEN) ; Validate all calls succeeded (comprehensive error checking for XP compatibility) Local $bError = False If @error Then $bError = True If Not IsArray($aL) Or Not IsArray($aT) Or Not IsArray($aW) Or Not IsArray($aH) Then $bError = True If $bError Then ; Fallback to cached virtual bounds If $__g_aMonitorList[0][0] = 0 Then If _Monitor_GetList() = -1 Then Return SetError(1, 0, 0) EndIf Local $aRet[4] = [$__g_aMonitorList[0][1], $__g_aMonitorList[0][2], $__g_aMonitorList[0][5], $__g_aMonitorList[0][6]] Return $aRet EndIf ; Validate returned values are reasonable If $aL[0] < -32768 Or $aT[0] < -32768 Or $aW[0] < 1 Or $aH[0] < 1 Then ; Invalid values, use fallback If $__g_aMonitorList[0][0] = 0 Then If _Monitor_GetList() = -1 Then Return SetError(1, 0, 0) EndIf Local $aRet[4] = [$__g_aMonitorList[0][1], $__g_aMonitorList[0][2], $__g_aMonitorList[0][5], $__g_aMonitorList[0][6]] Return $aRet EndIf Local $a[4] = [$aL[0], $aT[0], $aW[0], $aH[0]] Return $a EndFunc ;==>_Monitor_GetVirtualBounds ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_ToVirtual ; Description....: Convert local monitor coordinates to virtual screen coordinates ; Syntax.........: _Monitor_ToVirtual($iMonitor, $x, $y) ; Parameters.....: $iMonitor - Monitor index (1..N) ; $x - X coordinate in local monitor coordinates (0-based from monitor's left edge) ; $y - Y coordinate in local monitor coordinates (0-based from monitor's top edge) ; Return values..: Success - Array with 2 elements [X, Y] in virtual screen coordinates ; Failure - 0, sets @error = 1 (Invalid monitor index) ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Local coordinates are relative to the monitor (0,0 is top-left of that monitor). ; Virtual coordinates are absolute in the virtual screen coordinate system. ; Coordinate validation is optional (currently commented out for flexibility). ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_FromVirtual, _Monitor_GetBounds, _Monitor_GetList ; ================================================================================================================================ Func _Monitor_ToVirtual($iMonitor, $x, $y) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() If $iMonitor < 1 Or $iMonitor > $__g_aMonitorList[0][0] Then Return SetError(1, 0, 0) ; Optional: Validate coordinates are within monitor bounds Local $iWidth = $__g_aMonitorList[$iMonitor][3] - $__g_aMonitorList[$iMonitor][1] Local $iHeight = $__g_aMonitorList[$iMonitor][4] - $__g_aMonitorList[$iMonitor][2] If $x < 0 Or $y < 0 Or $x > $iWidth Or $y > $iHeight Then ; Return SetError(2, 0, 0) ; Uncomment if strict validation needed EndIf Local $aRet[2] = [$__g_aMonitorList[$iMonitor][1] + $x, $__g_aMonitorList[$iMonitor][2] + $y] Return $aRet EndFunc ;==>_Monitor_ToVirtual ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_FromVirtual ; Description....: Convert virtual screen coordinates back to local monitor coordinates ; Syntax.........: _Monitor_FromVirtual($iMonitor, $x, $y) ; Parameters.....: $iMonitor - Monitor index (1..N) ; $x - X coordinate in virtual screen coordinates ; $y - Y coordinate in virtual screen coordinates ; Return values..: Success - Array with 2 elements [X, Y] in local monitor coordinates (0-based) ; Failure - 0, sets @error to non-zero: ; |@error = 1 - Invalid monitor index ; |@error = 2 - Coordinates are not within the specified monitor's bounds ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Local coordinates are relative to the monitor (0,0 is top-left of that monitor). ; Virtual coordinates are absolute in the virtual screen coordinate system. ; Function validates that coordinates are actually on the specified monitor. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_ToVirtual, _Monitor_GetBounds, _Monitor_GetList ; ================================================================================================================================ Func _Monitor_FromVirtual($iMonitor, $x, $y) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() If $iMonitor < 1 Or $iMonitor > $__g_aMonitorList[0][0] Then Return SetError(1, 0, 0) ; Validate coordinates are on this monitor If $x < $__g_aMonitorList[$iMonitor][1] Or $x >= $__g_aMonitorList[$iMonitor][3] _ Or $y < $__g_aMonitorList[$iMonitor][2] Or $y >= $__g_aMonitorList[$iMonitor][4] Then Return SetError(2, 0, 0) EndIf Local $aRet[2] = [$x - $__g_aMonitorList[$iMonitor][1], $y - $__g_aMonitorList[$iMonitor][2]] Return $aRet EndFunc ;==>_Monitor_FromVirtual ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_IsVisibleWindow ; Description....: Check if a window is visible and is a top-level window (not a child window or tool window) ; Syntax.........: _Monitor_IsVisibleWindow($hWnd) ; Parameters.....: $hWnd - Window handle or title string. Can be HWND or window title ; Return values..: Success - True if window is visible and top-level, False otherwise ; Failure - False, sets @error = 1 (Invalid window handle) ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Function checks for: WS_VISIBLE flag, not WS_CHILD, and not WS_EX_TOOLWINDOW. ; Accepts both window handles and window titles. Automatically converts title to handle. ; This is useful for filtering which windows should be moved between monitors. ; Related........: _Monitor_MoveWindowToScreen, _Monitor_GetFromWindow ; ================================================================================================================================ Func _Monitor_IsVisibleWindow($hWnd) If Not IsHWnd($hWnd) Then $hWnd = WinGetHandle($hWnd) If Not $hWnd Or Not WinExists($hWnd) Then Return SetError(1, 0, False) ; _WinAPI_GetWindowLong is available from Windows 95+ (fully compatible with XP) Local $style = _WinAPI_GetWindowLong($hWnd, $GWL_STYLE) If @error Then Return SetError(1, 0, False) If BitAND($style, $WS_VISIBLE) = 0 Then Return False If BitAND($style, $WS_CHILD) <> 0 Then Return False Local $ex = _WinAPI_GetWindowLong($hWnd, $GWL_EXSTYLE) If @error Then Return False If BitAND($ex, $WS_EX_TOOLWINDOW) <> 0 Then Return False Return True EndFunc ;==>_Monitor_IsVisibleWindow ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_MoveWindowToScreen ; Description....: Move a visible window to a specific monitor (centered if coordinates not specified) ; Syntax.........: _Monitor_MoveWindowToScreen($vTitle [, $sText = "" [, $iMonitor = -1 [, $x = -1 [, $y = -1 [, $bUseWorkArea = True]]]]]) ; Parameters.....: $vTitle - Window title or handle. Can be HWND, title string, or class string ; $sText - [optional] Window text (for matching with title). Default is "" ; $iMonitor - [optional] Target monitor index (1..N). Default is -1 (uses monitor 1) ; $x - [optional] X position on monitor. Default is -1 (centers horizontally) ; $y - [optional] Y position on monitor. Default is -1 (centers vertically) ; $bUseWorkArea - [optional] Use work area instead of full bounds. Default is True ; Return values..: Success - 1 ; Failure - 0, sets @error to non-zero: ; |@error = 1 - Window not visible or not top-level ; |@error = 2 - Invalid monitor index or GetWorkArea/GetBounds failed ; |@error = 3 - WinGetPos failed (could not get window position/size) ; |@error = 4 - Window too large to fit on monitor ; |@error = 5 - WinMove failed ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: If both $x and $y are -1, window is centered on the monitor. ; If $bUseWorkArea is True, positioning is relative to work area (excludes taskbar). ; Function ensures window stays within monitor bounds (adjusts if necessary). ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_MoveWindowToAll, _Monitor_IsVisibleWindow, _Monitor_GetWorkArea, _Monitor_GetBounds ; ================================================================================================================================ Func _Monitor_MoveWindowToScreen($vTitle, $sText = "", $iMonitor = -1, $x = -1, $y = -1, $bUseWorkArea = True) Local $hWnd = IsHWnd($vTitle) ? $vTitle : WinGetHandle($vTitle, $sText) If Not _Monitor_IsVisibleWindow($hWnd) Then Return SetError(1, 0, 0) If $iMonitor = -1 Then $iMonitor = 1 If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() If $iMonitor < 1 Or $iMonitor > $__g_aMonitorList[0][0] Then Return SetError(2, 0, 0) Local $aWinPos = WinGetPos($hWnd) If @error Or Not IsArray($aWinPos) Then Return SetError(3, 0, 0) Local $iLeft, $iTop, $iRight, $iBottom If $bUseWorkArea Then If Not _Monitor_GetWorkArea($iMonitor, $iLeft, $iTop, $iRight, $iBottom) Then Return SetError(2, @error, 0) Else If Not _Monitor_GetBounds($iMonitor, $iLeft, $iTop, $iRight, $iBottom) Then Return SetError(2, @error, 0) EndIf Local $iWidth = $iRight - $iLeft Local $iHeight = $iBottom - $iTop ; Check if window fits on monitor If $aWinPos[2] > $iWidth Or $aWinPos[3] > $iHeight Then Return SetError(4, 0, 0) EndIf If $x = -1 Or $y = -1 Then $x = $iLeft + ($iWidth - $aWinPos[2]) / 2 $y = $iTop + ($iHeight - $aWinPos[3]) / 2 Else $x += $iLeft $y += $iTop ; Ensure window stays within bounds If $x + $aWinPos[2] > $iRight Then $x = $iRight - $aWinPos[2] If $y + $aWinPos[3] > $iBottom Then $y = $iBottom - $aWinPos[3] If $x < $iLeft Then $x = $iLeft If $y < $iTop Then $y = $iTop EndIf WinMove($hWnd, "", $x, $y) If @error Then Return SetError(5, 0, 0) Return 1 EndFunc ;==>_Monitor_MoveWindowToScreen ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_MoveWindowToAll ; Description....: Move a visible window sequentially across all monitors with a delay between moves ; Syntax.........: _Monitor_MoveWindowToAll($vTitle [, $sText = "" [, $bCenter = True [, $iDelay = 1000]]]) ; Parameters.....: $vTitle - Window title or handle. Can be HWND, title string, or class string ; $sText - [optional] Window text (for matching with title). Default is "" ; $bCenter - [optional] Center window on each monitor. Default is True ; If False, window is positioned at (50, 50) on each monitor ; $iDelay - [optional] Delay in milliseconds between moves. Default is 1000 ; Return values..: Success - 1 ; Failure - 0, sets @error = 1 (Window not visible or not top-level) ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This is a demonstration function that moves a window to each monitor in sequence. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Useful for testing multi-monitor setups or demonstrating window movement. ; Related........: _Monitor_MoveWindowToScreen, _Monitor_IsVisibleWindow, _Monitor_GetCount ; ================================================================================================================================ Func _Monitor_MoveWindowToAll($vTitle, $sText = "", $bCenter = True, $iDelay = 1000) Local $hWnd = IsHWnd($vTitle) ? $vTitle : WinGetHandle($vTitle, $sText) If Not _Monitor_IsVisibleWindow($hWnd) Then Return SetError(1, 0, 0) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() For $i = 1 To $__g_aMonitorList[0][0] If $bCenter Then _Monitor_MoveWindowToScreen($hWnd, "", $i) Else _Monitor_MoveWindowToScreen($hWnd, "", $i, 50, 50) EndIf Sleep($iDelay) Next Return 1 EndFunc ;==>_Monitor_MoveWindowToAll ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_EnumAllDisplayModes ; Description....: Enumerate all available display modes for a monitor ; Syntax.........: _Monitor_EnumAllDisplayModes($iMonitor) ; Parameters.....: $iMonitor - Monitor index (1..N) ; Return values..: Success - 2D array with display modes: ; |[0][0] - Number of modes found ; |[n][0] - Width in pixels for mode n ; |[n][1] - Height in pixels for mode n ; |[n][2] - Bits per pixel (color depth) for mode n ; |[n][3] - Refresh rate in Hz for mode n ; |[n][4] - Display mode flags for mode n ; Failure - 0, sets @error to non-zero: ; |@error = 1 - Invalid monitor index ; |@error = 2 - GetInfo failed (could not get device name) ; |@error = 3 - No display modes found ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Returns all supported display modes for the specified monitor. ; Use _Monitor_GetDisplaySettings() to get only the current active mode. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_GetDisplaySettings, _Monitor_GetResolution, _Monitor_GetList ; ================================================================================================================================ Func _Monitor_EnumAllDisplayModes($iMonitor) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() If $iMonitor < 1 Or $iMonitor > $__g_aMonitorList[0][0] Then Return SetError(1, 0, 0) Local $aInfo = _Monitor_GetInfo($iMonitor) If @error Then Return SetError(2, 0, 0) Local $sDevice = $aInfo[10] Local $aModes[1][5] $aModes[0][0] = 0 Local $iIndex = 0 While True Local $aMode = _WinAPI_EnumDisplaySettings($sDevice, $iIndex) If @error Then ExitLoop ReDim $aModes[$aModes[0][0] + 2][5] $aModes[0][0] += 1 $aModes[$aModes[0][0]][0] = $aMode[0] $aModes[$aModes[0][0]][1] = $aMode[1] $aModes[$aModes[0][0]][2] = $aMode[2] $aModes[$aModes[0][0]][3] = $aMode[3] $aModes[$aModes[0][0]][4] = $aMode[4] $iIndex += 1 WEnd If $aModes[0][0] = 0 Then Return SetError(3, 0, 0) Return $aModes EndFunc ;==>_Monitor_EnumAllDisplayModes ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetList ; Description....: Enumerate all connected monitors and fill the global monitor list with their information ; Syntax.........: _Monitor_GetList() ; Parameters.....: None ; Return values..: Success - Number of monitors detected (>= 1) ; Failure - -1, sets @error = 1 (WinAPI EnumDisplayMonitors call failed) ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This is the core function that initializes the monitor list. Most other functions call this ; automatically if the list is not initialized (when $__g_aMonitorList[0][0] = 0). ; Populates the global array $__g_aMonitorList with monitor handles, coordinates, and device names. ; Also stores virtual desktop bounds and IsPrimary flags for each monitor. ; Related........: _Monitor_Refresh, _Monitor_GetCount, _Monitor_GetInfo ; ================================================================================================================================ Func _Monitor_GetList() ; _WinAPI_EnumDisplayMonitors is available from Windows 2000+ (compatible with XP) Local $aMonitors = _WinAPI_EnumDisplayMonitors() If @error Or Not IsArray($aMonitors) Or $aMonitors[0][0] = 0 Then Return SetError(1, 0, -1) EndIf ReDim $__g_aMonitorList[$aMonitors[0][0] + 1][7] $__g_aMonitorList[0][0] = $aMonitors[0][0] Local $l_aVirtual = _Monitor_GetVirtualBounds() Local $l_vRight = $l_aVirtual[0] + $l_aVirtual[2] Local $l_vBottom = $l_aVirtual[1] + $l_aVirtual[3] $__g_aMonitorList[0][1] = $l_aVirtual[0] $__g_aMonitorList[0][2] = $l_aVirtual[1] $__g_aMonitorList[0][3] = $l_vRight $__g_aMonitorList[0][4] = $l_vBottom $__g_aMonitorList[0][5] = $l_aVirtual[2] $__g_aMonitorList[0][6] = $l_aVirtual[3] For $i = 1 To $aMonitors[0][0] Local $hMonitor = $aMonitors[$i][0] Local $tRect = $aMonitors[$i][1] $__g_aMonitorList[$i][0] = $hMonitor $__g_aMonitorList[$i][1] = DllStructGetData($tRect, "Left") $__g_aMonitorList[$i][2] = DllStructGetData($tRect, "Top") $__g_aMonitorList[$i][3] = DllStructGetData($tRect, "Right") $__g_aMonitorList[$i][4] = DllStructGetData($tRect, "Bottom") ; Get additional info - FIXED: Store IsPrimary flag correctly ; _WinAPI_GetMonitorInfo is available from Windows 2000+ (compatible with XP) Local $aInfo = _WinAPI_GetMonitorInfo($hMonitor) If Not @error And IsArray($aInfo) Then ; FIXED: Store IsPrimary flag (0 or 1) instead of pointer $__g_aMonitorList[$i][5] = ($aInfo[2] <> 0) ? 1 : 0 ; IsPrimary flag $__g_aMonitorList[$i][6] = $aInfo[3] ; Device name Else ; Safe fallback if GetMonitorInfo fails (shouldn't happen on XP, but safe anyway) $__g_aMonitorList[$i][5] = 0 $__g_aMonitorList[$i][6] = "" EndIf Next Return $__g_aMonitorList[0][0] EndFunc ;==>_Monitor_GetList ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_ShowInfo ; Description....: Display monitor coordinates and detailed information in a message box and console ; Syntax.........: _Monitor_ShowInfo([$bShowMsgBox = 1 [, $iTimeout = 10]]) ; Parameters.....: $bShowMsgBox - [optional] Show message box. Default is 1 (True) ; $iTimeout - [optional] Message box timeout in seconds. Default is 10 ; Return values..: Success - String containing formatted monitor information ; Failure - Empty string "", sets @error = 1 (Enumeration failed) ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Displays comprehensive information about all monitors including bounds, work areas, ; resolutions, refresh rates, and device names. Information is written to console and ; optionally shown in a message box. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Useful for debugging and displaying system monitor configuration. ; Related........: _Monitor_GetList, _Monitor_GetInfo, _Monitor_GetDisplaySettings ; ================================================================================================================================ Func _Monitor_ShowInfo($bShowMsgBox = 1, $iTimeout = 10) If $__g_aMonitorList[0][0] = 0 Then If _Monitor_GetList() = -1 Then Return SetError(1, 0, "") EndIf Local $sMsg = "> Total Monitors: " & $__g_aMonitorList[0][0] & @CRLF & @CRLF $sMsg &= StringFormat("+ Virtual Desktop: " & @CRLF & "Left=%d, Top=%d, Right=%d, Bottom=%d, Width=%d, Height=%d", $__g_aMonitorList[0][1], $__g_aMonitorList[0][2], $__g_aMonitorList[0][3], $__g_aMonitorList[0][4], $__g_aMonitorList[0][5], $__g_aMonitorList[0][6]) & @CRLF & @CRLF For $i = 1 To $__g_aMonitorList[0][0] Local $aInfo = _Monitor_GetInfo($i) If @error Then ContinueLoop Local $aSettings = _Monitor_GetDisplaySettings($i) Local $sResolution = @error ? "N/A" : $aSettings[0] & "x" & $aSettings[1] & " @" & $aSettings[3] & "Hz" $sMsg &= StringFormat("+ Monitor %d: %s%s\n", $i, $aInfo[9] ? "(Primary) " : "", $aInfo[10]) $sMsg &= StringFormat(" Bounds: L=%d, T=%d, R=%d, B=%d (%dx%d)\n", _ $aInfo[1], $aInfo[2], $aInfo[3], $aInfo[4], _ $aInfo[3] - $aInfo[1], $aInfo[4] - $aInfo[2]) $sMsg &= StringFormat(" Work Area: L=%d, T=%d, R=%d, B=%d (%dx%d)\n", _ $aInfo[5], $aInfo[6], $aInfo[7], $aInfo[8], _ $aInfo[7] - $aInfo[5], $aInfo[8] - $aInfo[6]) $sMsg &= " Resolution: " & $sResolution & @CRLF & @CRLF Next ConsoleWrite($sMsg) If $bShowMsgBox Then MsgBox(64 + 262144, "Monitor Information", $sMsg, $iTimeout) Return $sMsg EndFunc ;==>_Monitor_ShowInfo ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_Refresh ; Description....: Refresh the monitor list by reloading information from the system ; Syntax.........: _Monitor_Refresh() ; Parameters.....: None ; Return values..: Success - Number of monitors detected (>= 1) ; Failure - -1, sets @error = 1 (Refresh failed, _Monitor_GetList failed) ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Resets the monitor list and re-enumerates all monitors from the system. ; Useful when monitors are hot-plugged or display configuration changes. ; This forces a complete refresh of all monitor information. ; Related........: _Monitor_GetList, _Monitor_GetCount, _Monitor_IsConnected ; ================================================================================================================================ Func _Monitor_Refresh() ; Reset the list $__g_aMonitorList[0][0] = 0 Local $iResult = _Monitor_GetList() If $iResult = -1 Then Return SetError(1, 0, -1) Return $iResult EndFunc ;==>_Monitor_Refresh ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_IsConnected ; Description....: Check if a monitor is still connected and its handle is still valid ; Syntax.........: _Monitor_IsConnected($iMonitor) ; Parameters.....: $iMonitor - Monitor index (1..N) ; Return values..: Success - True if monitor is connected and valid, False if disconnected ; Failure - False, sets @error = 1 (Invalid monitor index) ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Verifies that the monitor handle is still valid by querying GetMonitorInfo. ; Useful for detecting when a monitor has been unplugged or disconnected. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_Refresh, _Monitor_GetList, _Monitor_GetCount ; ================================================================================================================================ Func _Monitor_IsConnected($iMonitor) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() If $iMonitor < 1 Or $iMonitor > $__g_aMonitorList[0][0] Then Return SetError(1, 0, False) ; Check if monitor handle is still valid Local $hMonitor = $__g_aMonitorList[$iMonitor][0] ; _WinAPI_GetMonitorInfo is available from Windows 2000+ (compatible with XP) Local $aInfo = _WinAPI_GetMonitorInfo($hMonitor) Return (Not @error And IsArray($aInfo)) EndFunc ;==>_Monitor_IsConnected ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetDPI ; Description....: Get DPI (Dots Per Inch) scaling information for a monitor ; Syntax.........: _Monitor_GetDPI($iMonitor) ; Parameters.....: $iMonitor - Monitor index (1..N) ; Return values..: Success - Array with 3 elements: ; |[0] - X DPI value ; |[1] - Y DPI value ; |[2] - Scaling percentage (typically 100, 125, 150, 175, 200, etc.) ; Failure - 0, sets @error to non-zero: ; |@error = 1 - Invalid monitor index ; |@error = 2 - DPI query failed (fallback uses default 96 DPI) ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Tries to use GetDpiForMonitor API (Windows 8.1+) for accurate DPI values. ; Falls back to GetDeviceCaps (Windows XP compatible) if GetDpiForMonitor is not available. ; On Windows XP/Vista/7/8, function uses GetDeviceCaps which works reliably. ; Scaling percentage is calculated as (DPI / 96) * 100. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Compatible with Windows XP SP2 and later. ; Related........: _Monitor_GetInfo, _Monitor_GetDisplaySettings, _Monitor_GetList ; ================================================================================================================================ Func _Monitor_GetDPI($iMonitor) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() If $iMonitor < 1 Or $iMonitor > $__g_aMonitorList[0][0] Then Return SetError(1, 0, 0) Local $hMonitor = $__g_aMonitorList[$iMonitor][0] Local $iDPI_X = 96, $iDPI_Y = 96 ; Try to get DPI using GetDpiForMonitor (Windows 8.1+ only) ; Check OS version first to avoid loading shcore.dll on older systems If __Monitor_IsWindows8_1OrGreater() Then ; Check if shcore.dll exists before calling (Windows 8.1+) Local $hShCore = DllOpen("shcore.dll") If $hShCore <> -1 Then DllClose($hShCore) Local $aRet = DllCall("shcore.dll", "long", "GetDpiForMonitor", "handle", $hMonitor, "int", 0, "uint*", 0, "uint*", 0) If Not @error And IsArray($aRet) And $aRet[0] = 0 Then $iDPI_X = $aRet[3] $iDPI_Y = $aRet[4] Local $iScaling = Round(($iDPI_X / 96) * 100) Local $aResult[3] = [$iDPI_X, $iDPI_Y, $iScaling] Return $aResult EndIf EndIf EndIf ; Fallback: Use GetDeviceCaps (compatible with Windows XP and later) Local $hDC2 = DllCall("user32.dll", "handle", "GetDC", "hwnd", 0) If Not @error And IsArray($hDC2) And $hDC2[0] Then Local $aDPI_X = DllCall("gdi32.dll", "int", "GetDeviceCaps", "handle", $hDC2[0], "int", 88) ; LOGPIXELSX Local $aDPI_Y = DllCall("gdi32.dll", "int", "GetDeviceCaps", "handle", $hDC2[0], "int", 90) ; LOGPIXELSY If Not @error And IsArray($aDPI_X) And IsArray($aDPI_Y) And $aDPI_X[0] > 0 And $aDPI_Y[0] > 0 Then $iDPI_X = $aDPI_X[0] $iDPI_Y = $aDPI_Y[0] EndIf DllCall("user32.dll", "bool", "ReleaseDC", "hwnd", 0, "handle", $hDC2[0]) EndIf Local $iScaling = Round(($iDPI_X / 96) * 100) Local $aResult[3] = [$iDPI_X, $iDPI_Y, $iScaling] Return $aResult EndFunc ;==>_Monitor_GetDPI ; #FUNCTION# ==================================================================================================================== ; Name...........: _Monitor_GetOrientation ; Description....: Get the display orientation (rotation angle) for a monitor ; Syntax.........: _Monitor_GetOrientation($iMonitor) ; Parameters.....: $iMonitor - Monitor index (1..N) ; Return values..: Success - Orientation angle in degrees: ; |0 - Landscape (normal) ; |90 - Portrait (rotated 90° clockwise) ; |180 - Landscape flipped (rotated 180°) ; |270 - Portrait flipped (rotated 270° clockwise / 90° counter-clockwise) ; Failure - -1, sets @error to non-zero: ; |@error = 1 - Invalid monitor index ; |@error = 2 - GetDisplaySettings failed (could not query display mode) ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Orientation is extracted from display mode flags. ; Most monitors typically return 0 (landscape) unless rotated in Windows display settings. ; Function automatically calls _Monitor_GetList() if monitor list is not initialized. ; Related........: _Monitor_GetDisplaySettings, _Monitor_GetInfo, _Monitor_GetList ; ================================================================================================================================ Func _Monitor_GetOrientation($iMonitor) If $__g_aMonitorList[0][0] = 0 Then _Monitor_GetList() If $iMonitor < 1 Or $iMonitor > $__g_aMonitorList[0][0] Then Return SetError(1, 0, -1) Local $aSettings = _Monitor_GetDisplaySettings($iMonitor) If @error Then Return SetError(2, 0, -1) ; DisplayMode field contains orientation information ; DM_DISPLAYORIENTATION values: 0=0°, 1=90°, 2=180°, 3=270° Local $iOrientation = 0 If IsArray($aSettings) And UBound($aSettings) > 4 Then ; Check display mode flags for orientation Local $iDisplayMode = $aSettings[4] ; Orientation is stored in bits 8-9 of display mode $iOrientation = BitAND(BitShift($iDisplayMode, 8), 3) * 90 EndIf Return $iOrientation EndFunc ;==>_Monitor_GetOrientation EG: ; ================================================================================================== ; MonitorUDF_Examples.au3 ; Interactive example tester for MonitorUDF.au3 UDF ; Fixed: Array index bug in FuncTest_10, improved error handling ; ================================================================================================== #include <GUIConstantsEx.au3> #include <ButtonConstants.au3> #include <WindowsConstants.au3> #include <GuiListBox.au3> #include <GuiEdit.au3> #include <Array.au3> #include "Monitor_UDF.au3" ; Updated include name ; ================================================================================================== ; Create GUI ; ================================================================================================== Global $GUI_W = 860, $GUI_H = 600 Global $hGUI = GUICreate("MonitorUDF - Examples (by TRONG.PRO)", $GUI_W, $GUI_H, -1, -1) GUISetBkColor(0xF5F5F5, $hGUI) ; Title GUICtrlCreateLabel("MonitorUDF Example Launcher", 12, 10, 400, 24) GUICtrlSetFont(-1, 12, 800, 0, 'Segoe UI', 5) ; Buttons column 1 - 6 buttons (1-6) Local $x1 = 12, $y1 = 48, $bw = 260, $bh = 36, $gap = 8 Global $iBtn1 = GUICtrlCreateButton("1. Enumerate monitors", $x1, $y1 + ($bh + $gap) * 0, $bw, $bh) Global $iBtn2 = GUICtrlCreateButton("2. Move Notepad -> Monitor #2 (center)", $x1, $y1 + ($bh + $gap) * 1, $bw, $bh) Global $iBtn3 = GUICtrlCreateButton("3. Move Notepad -> Monitor #2 @ (100,100)", $x1, $y1 + ($bh + $gap) * 2, $bw, $bh) Global $iBtn4 = GUICtrlCreateButton("4. Which monitor is mouse on?", $x1, $y1 + ($bh + $gap) * 3, $bw, $bh) Global $iBtn5 = GUICtrlCreateButton("5. Show virtual desktop bounds", $x1, $y1 + ($bh + $gap) * 4, $bw, $bh) Global $iBtn6 = GUICtrlCreateButton("6. Convert coords (local <-> virtual)", $x1, $y1 + ($bh + $gap) * 5, $bw, $bh) ; Buttons column 2 - 6 buttons (7-12) Local $x2 = $x1 + $bw + 12 Global $iBtn7 = GUICtrlCreateButton("7. Show monitor info (MsgBox)", $x2, $y1 + ($bh + $gap) * 0, $bw, $bh) Global $iBtn8 = GUICtrlCreateButton("8. Check if Notepad is visible", $x2, $y1 + ($bh + $gap) * 1, $bw, $bh) Global $iBtn9 = GUICtrlCreateButton("9. Create small GUI on each monitor", $x2, $y1 + ($bh + $gap) * 2, $bw, $bh) Global $iBtn10 = GUICtrlCreateButton("10. Move all visible windows -> primary", $x2, $y1 + ($bh + $gap) * 3, $bw, $bh) Global $iBtn11 = GUICtrlCreateButton("11. Refresh monitor list", $x2, $y1 + ($bh + $gap) * 4, $bw, $bh) Global $iBtn12 = GUICtrlCreateButton("12. Check monitor connected", $x2, $y1 + ($bh + $gap) * 5, $bw, $bh) ; Buttons column 3 - 6 buttons (13-17, but layout for 6) Local $x3 = $x2 + $bw + 12 Global $iBtn13 = GUICtrlCreateButton("13. Get DPI scaling", $x3, $y1 + ($bh + $gap) * 0, $bw, $bh) Global $iBtn14 = GUICtrlCreateButton("14. Get display orientation", $x3, $y1 + ($bh + $gap) * 1, $bw, $bh) Global $iBtn15 = GUICtrlCreateButton("15. Enumerate display modes", $x3, $y1 + ($bh + $gap) * 2, $bw, $bh) Global $iBtn16 = GUICtrlCreateButton("16. Get monitor from rect", $x3, $y1 + ($bh + $gap) * 3, $bw, $bh) Global $iBtn17 = GUICtrlCreateButton("17. Get monitor from window", $x3, $y1 + ($bh + $gap) * 4, $bw, $bh) ; Controls: log edit, clear, auto-demo, close Local $logX = 12, $logY = $y1 + ($bh + $gap) * 6 Local $logW = $GUI_W - 24, $logH = 180 Global $idLog = GUICtrlCreateEdit("", $logX, $logY, $logW, $logH, BitOR($ES_READONLY, $WS_HSCROLL, $WS_VSCROLL, $ES_MULTILINE)) GUICtrlSetFont($idLog, 9) Global $idFuncTest__ClearLog = GUICtrlCreateButton("Clear Log", 12, $logY + $logH + 10, 120, 28) Global $idFuncTest__RunAllDemo = GUICtrlCreateButton("Auto Demo (Run 1..17)", 150, $logY + $logH + 10, 220, 28) Global $idFuncTest__Close = GUICtrlCreateButton("Close", $GUI_W - 120, $logY + $logH + 10, 100, 28) Global $pidNotepad = 0 GUISetState(@SW_SHOW) ; Keep a list of created GUIs for Example 10 so we can close them later Global $Msg, $g_createdGUIs[0] ; FIXED: Initialize as empty array Global $g_bAutoMode = False ; Track if running in auto demo mode Global $g_hNotepadWindows[0] ; Track all notepad windows created ; ================================================================================================== ; Main loop ; ================================================================================================== While 1 $Msg = GUIGetMsg() Switch $Msg Case $GUI_EVENT_CLOSE, $idFuncTest__Close ; close any GUIs created in example 10 For $i = 0 To UBound($g_createdGUIs) - 1 If IsHWnd($g_createdGUIs[$i]) Then GUIDelete($g_createdGUIs[$i]) Next ExitLoop Case $idFuncTest__ClearLog GUICtrlSetData($idLog, '', '') Case $idFuncTest__RunAllDemo $g_bAutoMode = True ReDim $g_hNotepadWindows[0] FuncTest_1() Sleep(1000) FuncTest_2() Sleep(2000) FuncTest_3() Sleep(2000) FuncTest_4() Sleep(1500) FuncTest_5() Sleep(1000) FuncTest_6() Sleep(1000) FuncTest_7() Sleep(1000) FuncTest_8() Sleep(2000) FuncTest_9() Sleep(1000) FuncTest_10() Sleep(1000) FuncTest_11() Sleep(1000) FuncTest_12() Sleep(1000) FuncTest_13() Sleep(1000) FuncTest_14() Sleep(1000) FuncTest_15() Sleep(1000) FuncTest_16() Sleep(1000) FuncTest_17() Sleep(2000) ; Cleanup all created windows _CleanupAllWindows() $g_bAutoMode = False Case $iBtn1 FuncTest_1() Case $iBtn2 FuncTest_2() Case $iBtn3 FuncTest_3() Case $iBtn4 FuncTest_4() Case $iBtn5 FuncTest_5() Case $iBtn6 FuncTest_6() Case $iBtn7 FuncTest_7() Case $iBtn8 FuncTest_8() Case $iBtn9 FuncTest_9() Case $iBtn10 FuncTest_10() Case $iBtn11 FuncTest_11() Case $iBtn12 FuncTest_12() Case $iBtn13 FuncTest_13() Case $iBtn14 FuncTest_14() Case $iBtn15 FuncTest_15() Case $iBtn16 FuncTest_16() Case $iBtn17 FuncTest_17() EndSwitch Sleep(5) WEnd GUIDelete() Exit 0 ; ================================================================================================== ; Helper: append to log (with timestamp) ; ================================================================================================== Func _Log($s) ConsoleWrite($s & @CRLF) ; Format: DD/MM/YYYY HH:MM:SS Local $sDate = StringFormat("%02d/%02d/%04d", @MDAY, @MON, @YEAR) Local $sTime = StringFormat("%02d:%02d:%02d", @HOUR, @MIN, @SEC) Local $t = $sDate & " " & $sTime Local $cur = GUICtrlRead($idLog) If $cur = "" Then GUICtrlSetData($idLog, "[" & $t & "] " & $s) Else GUICtrlSetData($idLog, $cur & @CRLF & "[" & $t & "] " & $s) EndIf ; move caret to end _GUICtrlEdit_LineScroll($idLog, 0, _GUICtrlEdit_GetLineCount($idLog)) EndFunc ;==>_Log ; ================================================================================================== ; Helper: Cleanup all created windows (Notepad and GUIs) ; ================================================================================================== Func _CleanupAllWindows() ; Close all Notepad windows Local $aList = WinList("[CLASS:Notepad]") For $i = 1 To $aList[0][0] If $aList[$i][0] <> "" Then Local $hWnd = WinGetHandle($aList[$i][0]) If $hWnd Then WinClose($hWnd) EndIf Next Sleep(300) ; Force close any remaining Notepad processes While ProcessExists("notepad.exe") ProcessClose("notepad.exe") Sleep(100) WEnd ; Close all created GUIs For $i = 0 To UBound($g_createdGUIs) - 1 If IsHWnd($g_createdGUIs[$i]) Then GUIDelete($g_createdGUIs[$i]) Next ReDim $g_createdGUIs[0] ReDim $g_hNotepadWindows[0] EndFunc ;==>_CleanupAllWindows ; ================================================================================================== ; Helper: Track Notepad window ; ================================================================================================== Func _TrackNotepadWindow($hWnd) If $hWnd Then Local $n = UBound($g_hNotepadWindows) ReDim $g_hNotepadWindows[$n + 1] $g_hNotepadWindows[$n] = $hWnd EndIf EndFunc ;==>_TrackNotepadWindow Func FuncTest_1() _Log('+ TEST 1: Enumerate monitors -----------------------\') ; Enumerate monitors _Monitor_GetList() Local $cnt = _Monitor_GetCount() If @error Then Local $sMsg = "TEST 1: FAILED" & @CRLF & "ERROR - Failed to enumerate monitors" & @CRLF & "@error=" & @error _Log("---> Example 1: ERROR - Failed to enumerate monitors") If Not $g_bAutoMode Then MsgBox(48, "Example 1", $sMsg, 3) Return EndIf _Log("---> Example 1: Monitors detected: " & $cnt) Local $sResults = "Total Monitors: " & $cnt & @CRLF & @CRLF For $i = 1 To $cnt Local $a = _Monitor_GetInfo($i) If @error Then _Log(" Monitor " & $i & ": ERROR getting info") $sResults &= "Monitor #" & $i & ": ERROR" & @CRLF Else Local $sPrimary = $a[9] ? " [PRIMARY]" : "" _Log(" Monitor " & $i & ": Device=" & $a[10] & " Bounds=(" & $a[1] & "," & $a[2] & ")-(" & $a[3] & "," & $a[4] & ") Work=(" & $a[5] & "," & $a[6] & ")-(" & $a[7] & "," & $a[8] & ") Primary=" & $a[9]) $sResults &= "Monitor #" & $i & $sPrimary & ": " & $a[10] & @CRLF & _ " Bounds: " & $a[1] & "," & $a[2] & " to " & $a[3] & "," & $a[4] & @CRLF & _ " Work Area: " & $a[5] & "," & $a[6] & " to " & $a[7] & "," & $a[8] & @CRLF EndIf Next Local $sMsg = "TEST 1: SUCCESS" & @CRLF & @CRLF & $sResults If Not $g_bAutoMode Then MsgBox(64, "Example 1", $sMsg, 8) _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_1 Func FuncTest_2() _Log('+ TEST 2: Move Notepad to monitor #2 centered ------\') ; Move Notepad to monitor #2 centered $pidNotepad = Run("notepad.exe") If Not WinWaitActive("[CLASS:Notepad]", "", 5) Then _Log("---> Example 2: Notepad did not start / focus") Local $sMsg = "TEST 2: FAILED" & @CRLF & "Notepad did not start / focus" If Not $g_bAutoMode Then MsgBox(48, "Example 2", $sMsg, 3) Else Sleep(1000) Local $hWnd = WinGetHandle("[CLASS:Notepad]") _TrackNotepadWindow($hWnd) _Monitor_GetList() Local $cnt = _Monitor_GetCount() If $cnt < 2 Then Local $sMsg = "TEST 2: SKIPPED" & @CRLF & "Need at least 2 monitors" & @CRLF & "Current: " & $cnt & " monitor(s)" _Log("---> Example 2: Need at least 2 monitors") If Not $g_bAutoMode Then MsgBox(64, "Example 2", $sMsg, 3) Else Local $iResult = _Monitor_MoveWindowToScreen("[CLASS:Notepad]", "", 2, -1, -1, True) If @error Then Local $sMsg = "TEST 2: FAILED" & @CRLF & "ERROR moving window" & @CRLF & "@error=" & @error _Log("---> Example 2: ERROR moving window: @error=" & @error) If Not $g_bAutoMode Then MsgBox(48, "Example 2", $sMsg, 3) Else Local $sMsg = "TEST 2: SUCCESS" & @CRLF & "Notepad moved to Monitor #2" & @CRLF & "Position: Centered" _Log("---> Example 2: Notepad moved to monitor #2 (centered)") If Not $g_bAutoMode Then MsgBox(64, "Example 2", $sMsg, 3) EndIf EndIf EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_2 Func FuncTest_3() _Log('+ TEST 3: Move Notepad to monitor #2 at (100,100 ----\)') ; Move Notepad to monitor #2 at (100,100) $pidNotepad = Run("notepad.exe") If Not WinWaitActive("[CLASS:Notepad]", "", 5) Then Local $sMsg = "TEST 3: FAILED" & @CRLF & "Notepad did not start / focus" _Log("---> Example 3: Notepad did not start / focus") If Not $g_bAutoMode Then MsgBox(48, "Example 3", $sMsg, 3) Else Sleep(1000) Local $hWnd = WinGetHandle("[CLASS:Notepad]") _TrackNotepadWindow($hWnd) _Monitor_GetList() Local $cnt = _Monitor_GetCount() If $cnt < 2 Then Local $sMsg = "TEST 3: SKIPPED" & @CRLF & "Need at least 2 monitors" & @CRLF & "Current: " & $cnt & " monitor(s)" _Log("---> Example 3: Need at least 2 monitors") If Not $g_bAutoMode Then MsgBox(64, "Example 3", $sMsg, 3) Else Local $iResult = _Monitor_MoveWindowToScreen("[CLASS:Notepad]", "", 2, 100, 100, True) If @error Then Local $sMsg = "TEST 3: FAILED" & @CRLF & "ERROR moving window" & @CRLF & "@error=" & @error _Log("---> Example 3: ERROR moving window: @error=" & @error) If Not $g_bAutoMode Then MsgBox(48, "Example 3", $sMsg, 3) Else Local $sMsg = "TEST 3: SUCCESS" & @CRLF & "Notepad moved to Monitor #2" & @CRLF & "Position: (100, 100)" _Log("---> Example 3: Notepad moved to monitor #2 at (100,100)") If Not $g_bAutoMode Then MsgBox(64, "Example 3", $sMsg, 3) EndIf EndIf EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_3 Func FuncTest_4() _Log('+ TEST 4: Which monitor is mouse on ------------------\') ; Automatically move mouse to each monitor and test _Monitor_GetList() Local $cnt = _Monitor_GetCount() If $cnt < 1 Then Local $sMsg = "TEST 4: SKIPPED" & @CRLF & "No monitors detected" _Log("---> Example 4: No monitors detected") If Not $g_bAutoMode Then MsgBox(64, "Example 4", $sMsg, 3) Else Local $aResults = "" Local $sCurrentPos = MouseGetPos() Local $iOrigX = $sCurrentPos[0], $iOrigY = $sCurrentPos[1] _Log("---> Example 4: Testing " & $cnt & " monitor(s)") For $i = 1 To $cnt ; Get monitor center Local $iLeft, $iTop, $iRight, $iBottom _Monitor_GetBounds($i, $iLeft, $iTop, $iRight, $iBottom) Local $iCenterX = $iLeft + ($iRight - $iLeft) / 2 Local $iCenterY = $iTop + ($iBottom - $iTop) / 2 ; Move mouse to center of monitor MouseMove($iCenterX, $iCenterY, 0) Sleep(200) ; Check which monitor mouse is on Local $m = _Monitor_GetFromPoint() If @error Then _Log(" Monitor " & $i & ": ERROR - @error=" & @error) $aResults &= "Monitor " & $i & ": ERROR" & @CRLF Else Local $aInfo = _Monitor_GetInfo($i) Local $sDevice = @error ? "N/A" : $aInfo[10] Local $sStatus = ($m = $i) ? "CORRECT" : "WRONG (detected #" & $m & ")" _Log(" Monitor " & $i & " (" & $sDevice & "): Mouse detected on #" & $m & " - " & $sStatus) $aResults &= "Monitor #" & $i & " (" & $sDevice & "): #" & $m & " - " & $sStatus & @CRLF EndIf Sleep(300) Next ; Restore original mouse position MouseMove($iOrigX, $iOrigY, 0) Local $sMsg = "TEST 4: COMPLETE" & @CRLF & @CRLF & "Mouse Position Test Results:" & @CRLF & $aResults _Log("---> Example 4: Test complete, mouse restored to original position") If Not $g_bAutoMode Then MsgBox(64, "Example 4", $sMsg, 5) EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_4 Func FuncTest_5() _Log('+ TEST 5: Virtual desktop bounds -----------------------\') ; Virtual desktop bounds Local $aV = _Monitor_GetVirtualBounds() If @error Then Local $sMsg = "TEST 5: FAILED" & @CRLF & "ERROR getting virtual bounds" & @CRLF & "@error=" & @error _Log("---> Example 5: ERROR getting virtual bounds: @error=" & @error) If Not $g_bAutoMode Then MsgBox(48, "Example 5", $sMsg, 3) Else Local $sMsg = "TEST 5: SUCCESS" & @CRLF & @CRLF & "Virtual Desktop Bounds:" & @CRLF & _ "Left: " & $aV[0] & @CRLF & _ "Top: " & $aV[1] & @CRLF & _ "Width: " & $aV[2] & @CRLF & _ "Height: " & $aV[3] & @CRLF & @CRLF & _ "Right: " & ($aV[0] + $aV[2]) & @CRLF & _ "Bottom: " & ($aV[1] + $aV[3]) _Log("---> Example 5: Virtual bounds L=" & $aV[0] & " T=" & $aV[1] & " W=" & $aV[2] & " H=" & $aV[3]) If Not $g_bAutoMode Then MsgBox(64, "Example 5", $sMsg, 5) EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_5 Func FuncTest_6() _Log('+ TEST 6: Convert coords example (local -> virtual -> back) --\') ; Convert coords example (local -> virtual -> back) _Monitor_GetList() Local $mon = _Monitor_GetCount() If $mon < 1 Then Local $sMsg = "TEST 6: SKIPPED" & @CRLF & "No monitors detected" _Log("---> Example 6: No monitors detected") If Not $g_bAutoMode Then MsgBox(64, "Example 6", $sMsg, 3) Else Local $sResults = "" For $i = 1 To $mon Local $xLocal = 50, $yLocal = 100 Local $aV = _Monitor_ToVirtual($i, $xLocal, $yLocal) If @error Then _Log("---> Example 6: Monitor " & $i & " ERROR converting to virtual: @error=" & @error) $sResults &= "Monitor #" & $i & ": ERROR (to virtual)" & @CRLF Else Local $aBack = _Monitor_FromVirtual($i, $aV[0], $aV[1]) If @error Then _Log("---> Example 6: Monitor " & $i & " ERROR converting from virtual: @error=" & @error) $sResults &= "Monitor #" & $i & ": ERROR (from virtual)" & @CRLF Else Local $bMatch = (Abs($aBack[0] - $xLocal) < 1) And (Abs($aBack[1] - $yLocal) < 1) _Log("---> Example 6: Mon " & $i & " local(" & $xLocal & "," & $yLocal & ") -> virtual(" & $aV[0] & "," & $aV[1] & ") -> back(" & $aBack[0] & "," & $aBack[1] & ")") $sResults &= "Monitor #" & $i & ": (" & $xLocal & "," & $yLocal & ") -> (" & $aV[0] & "," & $aV[1] & ") -> (" & $aBack[0] & "," & $aBack[1] & ")" & _ ($bMatch ? " ✓" : " ✗") & @CRLF EndIf EndIf Next Local $sMsg = "TEST 6: COMPLETE" & @CRLF & @CRLF & "Coordinate Conversion Test:" & @CRLF & $sResults If Not $g_bAutoMode Then MsgBox(64, "Example 6", $sMsg, 5) EndIf _Log('- End --------------------------------------------------------/') EndFunc ;==>FuncTest_6 Func FuncTest_7() _Log('+ TEST 7: Show detailed info via MsgBox (calls UDF) ------\') ; Show detailed info via MsgBox (calls UDF) _Monitor_GetList() Local $sResult = _Monitor_ShowInfo(1, 8) If @error Then Local $sMsg = "TEST 7: FAILED" & @CRLF & "ERROR showing info" & @CRLF & "@error=" & @error _Log("---> Example 7: ERROR showing info: @error=" & @error) If Not $g_bAutoMode Then MsgBox(48, "Example 7", $sMsg, 3) Else Local $sMsg = "TEST 7: SUCCESS" & @CRLF & @CRLF & "Detailed monitor information displayed above." _Log("---> Example 7: _Monitor_ShowInfo() called successfully") If Not $g_bAutoMode Then MsgBox(64, "Example 7", $sMsg, 3) EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_7 Func FuncTest_8() _Log('+ TEST 8: Start notepad, check visible ---------------\') ; Start notepad, check visible $pidNotepad = Run("notepad.exe") If Not WinWaitActive("[CLASS:Notepad]", "", 5) Then Local $sMsg = "TEST 8: FAILED" & @CRLF & "Notepad did not start/focus" _Log("---> Example 8: Notepad did not start/focus") If Not $g_bAutoMode Then MsgBox(48, "Example 8", $sMsg, 3) Else Sleep(1000) Local $h = WinGetHandle("[CLASS:Notepad]") _TrackNotepadWindow($h) Local $b = _Monitor_IsVisibleWindow($h) If @error Then Local $sMsg = "TEST 8: FAILED" & @CRLF & "ERROR checking visibility" & @CRLF & "@error=" & @error _Log("---> Example 8: ERROR checking visibility: @error=" & @error) If Not $g_bAutoMode Then MsgBox(48, "Example 8", $sMsg, 3) Else Local $sTitle = WinGetTitle($h) Local $sMsg = "TEST 8: SUCCESS" & @CRLF & @CRLF & "Window: " & ($sTitle = "" ? "[No Title]" : $sTitle) & @CRLF & _ "Handle: " & $h & @CRLF & _ "Visible: " & ($b ? "YES ✓" : "NO ✗") _Log("---> Example 8: Notepad handle " & $h & " visible? " & ($b ? "Yes" : "No")) If Not $g_bAutoMode Then MsgBox(64, "Example 8", $sMsg, 3) EndIf EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_8 Func FuncTest_9() _Log('+ TEST 9: Create small GUI on each monitor -------------\') ; Create small GUI on each monitor _Monitor_GetList() ; close previously created For $i = 0 To UBound($g_createdGUIs) - 1 If IsHWnd($g_createdGUIs[$i]) Then GUIDelete($g_createdGUIs[$i]) Next ReDim $g_createdGUIs[0] ; reset Local $created = 0 For $i = 1 To _Monitor_GetCount() Local $a = _Monitor_GetInfo($i) If @error Then _Log(" Monitor " & $i & ": ERROR getting info") ContinueLoop EndIf Local $h = GUICreate("Monitor #" & $i & " - " & $a[10], 260, 120, $a[1] + 40, $a[2] + 40) GUICtrlCreateLabel("Monitor " & $i & ($a[9] ? " (Primary)" : ""), 10, 12, 240, 20) GUISetState(@SW_SHOW, $h) ; store to close later __ArrayAdd($g_createdGUIs, $h) $created += 1 Next Local $sMsg = "TEST 9: SUCCESS" & @CRLF & @CRLF & "Created " & $created & " GUI window(s)" & @CRLF & @CRLF If $created > 0 Then $sMsg &= "One GUI created on each monitor:" & @CRLF For $i = 1 To _Monitor_GetCount() Local $a = _Monitor_GetInfo($i) If Not @error Then Local $sPrimary = $a[9] ? " [PRIMARY]" : "" $sMsg &= " Monitor #" & $i & $sPrimary & ": " & $a[10] & @CRLF EndIf Next $sMsg &= @CRLF & "Windows will be closed when you close the launcher." Else $sMsg &= "No GUIs were created." EndIf _Log("---> Example 9: Created " & $created & " GUI(s) on monitors. Use Close to exit (they will be closed).") If Not $g_bAutoMode Then MsgBox(64, "Example 9", $sMsg, 5) _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_9 Func FuncTest_10() _Log('+ TEST 10: Move all visible windows to primary ----------\') ; Move all visible windows to primary _Monitor_GetList() Local $prim = _Monitor_GetPrimary() If $prim = 0 Or @error Then Local $sMsg = "TEST 10: FAILED" & @CRLF & "Primary monitor not found or error" & @CRLF & "@error=" & @error _Log("---> Example 10: Primary monitor not found or error") If Not $g_bAutoMode Then MsgBox(48, "Example 10", $sMsg, 3) Else Local $aList = WinList() Local $moved = 0 Local $aInfo = _Monitor_GetInfo($prim) Local $sDevice = @error ? "N/A" : $aInfo[10] For $i = 1 To $aList[0][0] If $aList[$i][0] <> "" Then ; FIXED: Use correct array index - WinList()[i][0] is title, need to get handle from title Local $h = WinGetHandle($aList[$i][0]) ; FIXED: Changed from [1] to [0] If Not @error And $h Then If _Monitor_IsVisibleWindow($h) Then Local $iResult = _Monitor_MoveWindowToScreen($h, "", $prim) If Not @error Then $moved += 1 EndIf EndIf EndIf Next Local $sMsg = "TEST 10: SUCCESS" & @CRLF & @CRLF & _ "Moved " & $moved & " visible window(s)" & @CRLF & _ "to Primary Monitor #" & $prim & @CRLF & _ "Device: " & $sDevice _Log("---> Example 10: Moved " & $moved & " visible windows to primary monitor #" & $prim) If Not $g_bAutoMode Then MsgBox(64, "Example 10", $sMsg, 4) EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_10 Func FuncTest_11() _Log('+ TEST 11: Refresh monitor list ----------------------\') ; Refresh monitor list Local $cntBefore = _Monitor_GetCount() _Log("---> Example 11: Monitors before refresh: " & $cntBefore) Local $cntAfter = _Monitor_Refresh() If @error Then Local $sMsg = "TEST 11: FAILED" & @CRLF & "ERROR refreshing monitor list" & @CRLF & "@error=" & @error _Log("---> Example 11: ERROR refreshing: @error=" & @error) If Not $g_bAutoMode Then MsgBox(48, "Example 11", $sMsg, 3) Else Local $sChangeInfo = "" If $cntBefore <> $cntAfter Then _Log(" --> Monitor count changed! (was " & $cntBefore & ", now " & $cntAfter & ")") $sChangeInfo = @CRLF & "⚠ CHANGE DETECTED! ⚠" & @CRLF & "Before: " & $cntBefore & " monitor(s)" & @CRLF & "After: " & $cntAfter & " monitor(s)" Else _Log(" --> Monitor count unchanged") $sChangeInfo = @CRLF & "Count unchanged: " & $cntAfter & " monitor(s)" EndIf Local $sMsg = "TEST 11: SUCCESS" & @CRLF & @CRLF & "Monitor list refreshed" & $sChangeInfo _Log("---> Example 11: Monitors after refresh: " & $cntAfter) If Not $g_bAutoMode Then MsgBox(64, "Example 11", $sMsg, 4) EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_11 Func FuncTest_12() _Log('+ TEST 12: Check if monitors are connected -----------\') ; Check if monitors are still connected _Monitor_GetList() Local $cnt = _Monitor_GetCount() If $cnt < 1 Then Local $sMsg = "TEST 12: SKIPPED" & @CRLF & "No monitors detected" _Log("---> Example 12: No monitors detected") If Not $g_bAutoMode Then MsgBox(64, "Example 12", $sMsg, 3) Else _Log("---> Example 12: Checking connection status for " & $cnt & " monitor(s):") Local $sResults = "" Local $iConnected = 0, $iDisconnected = 0 For $i = 1 To $cnt Local $bConnected = _Monitor_IsConnected($i) If @error Then _Log(" Monitor " & $i & ": ERROR checking connection: @error=" & @error) $sResults &= "Monitor #" & $i & ": ERROR" & @CRLF Else Local $sStatus = $bConnected ? "CONNECTED ✓" : "DISCONNECTED ✗" Local $aInfo = _Monitor_GetInfo($i) Local $sDevice = @error ? "N/A" : $aInfo[10] _Log(" Monitor " & $i & " (" & $sDevice & "): " & ($bConnected ? "CONNECTED" : "DISCONNECTED")) $sResults &= "Monitor #" & $i & " (" & $sDevice & "): " & $sStatus & @CRLF If $bConnected Then $iConnected += 1 Else $iDisconnected += 1 EndIf EndIf Next Local $sMsg = "TEST 12: COMPLETE" & @CRLF & @CRLF & "Connection Status:" & @CRLF & _ "Connected: " & $iConnected & @CRLF & _ "Disconnected: " & $iDisconnected & @CRLF & @CRLF & _ $sResults If Not $g_bAutoMode Then MsgBox(64, "Example 12", $sMsg, 5) EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_12 Func FuncTest_13() _Log('+ TEST 13: Get DPI scaling for monitors -------------\') ; Get DPI scaling for each monitor _Monitor_GetList() Local $cnt = _Monitor_GetCount() If $cnt < 1 Then Local $sMsg = "TEST 13: SKIPPED" & @CRLF & "No monitors detected" _Log("---> Example 13: No monitors detected") If Not $g_bAutoMode Then MsgBox(64, "Example 13", $sMsg, 3) Else _Log("---> Example 13: DPI information for " & $cnt & " monitor(s):") Local $sResults = "" For $i = 1 To $cnt Local $aDPI = _Monitor_GetDPI($i) If @error Then _Log(" Monitor " & $i & ": ERROR getting DPI: @error=" & @error) $sResults &= "Monitor #" & $i & ": ERROR" & @CRLF Else Local $aInfo = _Monitor_GetInfo($i) Local $sDevice = @error ? "N/A" : $aInfo[10] _Log(" Monitor " & $i & " (" & $sDevice & "):") _Log(" DPI X: " & $aDPI[0] & ", DPI Y: " & $aDPI[1]) _Log(" Scaling: " & $aDPI[2] & "%") $sResults &= "Monitor #" & $i & " (" & $sDevice & "):" & @CRLF & _ " DPI X: " & $aDPI[0] & ", DPI Y: " & $aDPI[1] & @CRLF & _ " Scaling: " & $aDPI[2] & "%" & @CRLF EndIf Next Local $sMsg = "TEST 13: COMPLETE" & @CRLF & @CRLF & "DPI Information:" & @CRLF & $sResults If Not $g_bAutoMode Then MsgBox(64, "Example 13", $sMsg, 6) EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_13 Func FuncTest_14() _Log('+ TEST 14: Get display orientation -------------------\') ; Get display orientation for each monitor _Monitor_GetList() Local $cnt = _Monitor_GetCount() If $cnt < 1 Then Local $sMsg = "TEST 14: SKIPPED" & @CRLF & "No monitors detected" _Log("---> Example 14: No monitors detected") If Not $g_bAutoMode Then MsgBox(64, "Example 14", $sMsg, 3) Else _Log("---> Example 14: Display orientation for " & $cnt & " monitor(s):") Local $sOrientationNames[4] = ["Landscape (0°)", "Portrait (90°)", "Landscape Flipped (180°)", "Portrait Flipped (270°)"] Local $sResults = "" For $i = 1 To $cnt Local $iOrientation = _Monitor_GetOrientation($i) If @error Then _Log(" Monitor " & $i & ": ERROR getting orientation: @error=" & @error) $sResults &= "Monitor #" & $i & ": ERROR" & @CRLF Else Local $aInfo = _Monitor_GetInfo($i) Local $sDevice = @error ? "N/A" : $aInfo[10] Local $sOrientationName = "Unknown" If $iOrientation >= 0 And $iOrientation <= 270 Then Local $iIndex = Int($iOrientation / 90) If $iIndex >= 0 And $iIndex < 4 Then $sOrientationName = $sOrientationNames[$iIndex] EndIf _Log(" Monitor " & $i & " (" & $sDevice & "): " & $iOrientation & "° (" & $sOrientationName & ")") $sResults &= "Monitor #" & $i & " (" & $sDevice & "): " & $iOrientation & "°" & @CRLF & _ " " & $sOrientationName & @CRLF EndIf Next Local $sMsg = "TEST 14: COMPLETE" & @CRLF & @CRLF & "Display Orientation:" & @CRLF & $sResults If Not $g_bAutoMode Then MsgBox(64, "Example 14", $sMsg, 5) EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_14 Func FuncTest_15() _Log('+ TEST 15: Enumerate all display modes ---------------\') ; Enumerate all display modes for all monitors (auto mode) or selected monitor _Monitor_GetList() Local $cnt = _Monitor_GetCount() If $cnt < 1 Then Local $sMsg = "TEST 15: SKIPPED" & @CRLF & "No monitors detected" _Log("---> Example 15: No monitors detected") If Not $g_bAutoMode Then MsgBox(64, "Example 15", $sMsg, 3) Else Local $sAllResults = "" Local $iTotalModes = 0 ; In auto mode, test all monitors. Otherwise, ask user Local $bTestAll = $g_bAutoMode Local $aTestMonitors[1] = [1] ; Default to monitor 1 If Not $bTestAll And $cnt > 1 Then Local $sInput = InputBox("Example 15", "Select monitor to test (1-" & $cnt & ") or 0 for all:", "0", "", 250, 150) If Not @error And StringIsDigit($sInput) Then Local $iInput = Int($sInput) If $iInput = 0 Then $bTestAll = True ElseIf $iInput >= 1 And $iInput <= $cnt Then ; Test single monitor $bTestAll = False $aTestMonitors[0] = $iInput EndIf EndIf EndIf ; If testing all, create array of all monitor indices If $bTestAll Then ReDim $aTestMonitors[$cnt] For $i = 0 To $cnt - 1 $aTestMonitors[$i] = $i + 1 Next EndIf ; Test each monitor For $iMonitorIndex = 0 To UBound($aTestMonitors) - 1 Local $iTestMonitor = $aTestMonitors[$iMonitorIndex] Local $aModes = _Monitor_EnumAllDisplayModes($iTestMonitor) If @error Then _Log("---> Example 15: Monitor " & $iTestMonitor & " ERROR enumerating modes: @error=" & @error) $sAllResults &= "Monitor #" & $iTestMonitor & ": ERROR" & @CRLF Else Local $aInfo = _Monitor_GetInfo($iTestMonitor) Local $sDevice = @error ? "N/A" : $aInfo[10] $iTotalModes += $aModes[0][0] _Log("---> Example 15: Monitor " & $iTestMonitor & " (" & $sDevice & ") has " & $aModes[0][0] & " display mode(s):") Local $sModesList = "" Local $iShowCount = ($aModes[0][0] > 5) ? 5 : $aModes[0][0] For $i = 1 To $iShowCount Local $sModeInfo = $aModes[$i][0] & "x" & $aModes[$i][1] & " @ " & $aModes[$i][3] & "Hz, " & $aModes[$i][2] & " bpp" _Log(" Mode " & $i & ": " & $sModeInfo) $sModesList &= " " & $sModeInfo & @CRLF Next If $aModes[0][0] > 5 Then _Log(" ... and " & ($aModes[0][0] - 5) & " more mode(s)") $sModesList &= " ... and " & ($aModes[0][0] - 5) & " more mode(s)" & @CRLF EndIf If $bTestAll Then $sAllResults &= "Monitor #" & $iTestMonitor & " (" & $sDevice & "): " & $aModes[0][0] & " modes" & @CRLF & $sModesList Else $sAllResults = "Monitor #" & $iTestMonitor & " (" & $sDevice & "): " & $aModes[0][0] & " modes" & @CRLF & $sModesList EndIf EndIf Next Local $sMsg = "TEST 15: COMPLETE" & @CRLF & @CRLF If $bTestAll Then $sMsg &= "Total Modes Found: " & $iTotalModes & @CRLF & @CRLF EndIf $sMsg &= "Display Modes:" & @CRLF & $sAllResults If Not $g_bAutoMode Then MsgBox(64, "Example 15", $sMsg, 10) EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_15 Func FuncTest_16() _Log('+ TEST 16: Get monitor from rectangle ----------------\') ; Get monitor that overlaps with a rectangle _Monitor_GetList() Local $cnt = _Monitor_GetCount() If $cnt < 1 Then Local $sMsg = "TEST 16: SKIPPED" & @CRLF & "No monitors detected" _Log("---> Example 16: No monitors detected") If Not $g_bAutoMode Then MsgBox(64, "Example 16", $sMsg, 3) Else ; Create a test rectangle (center of primary monitor) Local $prim = _Monitor_GetPrimary() If $prim = 0 Then $prim = 1 Local $iLeft, $iTop, $iRight, $iBottom _Monitor_GetBounds($prim, $iLeft, $iTop, $iRight, $iBottom) Local $iCenterX = $iLeft + ($iRight - $iLeft) / 2 Local $iCenterY = $iTop + ($iBottom - $iTop) / 2 Local $iRectW = 200, $iRectH = 150 Local $iRectLeft = $iCenterX - $iRectW / 2 Local $iRectTop = $iCenterY - $iRectH / 2 Local $iRectRight = $iCenterX + $iRectW / 2 Local $iRectBottom = $iCenterY + $iRectH / 2 _Log("---> Example 16: Testing rectangle: L=" & $iRectLeft & ", T=" & $iRectTop & ", R=" & $iRectRight & ", B=" & $iRectBottom) Local $iMonitor = _Monitor_GetFromRect($iRectLeft, $iRectTop, $iRectRight, $iRectBottom) If @error Then Local $sMsg = "TEST 16: FAILED" & @CRLF & "ERROR getting monitor from rect" & @CRLF & "@error=" & @error _Log("---> Example 16: ERROR getting monitor from rect: @error=" & @error) If Not $g_bAutoMode Then MsgBox(48, "Example 16", $sMsg, 3) Else If $iMonitor > 0 Then Local $aInfo = _Monitor_GetInfo($iMonitor) Local $sDevice = @error ? "N/A" : $aInfo[10] Local $sPrimary = @error ? "" : ($aInfo[9] ? " [PRIMARY]" : "") Local $sMsg = "TEST 16: SUCCESS" & @CRLF & @CRLF & _ "Test Rectangle:" & @CRLF & _ " Left: " & $iRectLeft & ", Top: " & $iRectTop & @CRLF & _ " Right: " & $iRectRight & ", Bottom: " & $iRectBottom & @CRLF & @CRLF & _ "Found Monitor: #" & $iMonitor & $sPrimary & @CRLF & _ "Device: " & $sDevice _Log("---> Example 16: Rectangle overlaps with Monitor #" & $iMonitor & " (" & $sDevice & ")") If Not $g_bAutoMode Then MsgBox(64, "Example 16", $sMsg, 4) Else Local $sMsg = "TEST 16: NO MATCH" & @CRLF & @CRLF & "Rectangle does not overlap with any monitor" _Log("---> Example 16: Rectangle does not overlap with any monitor") If Not $g_bAutoMode Then MsgBox(48, "Example 16", $sMsg, 3) EndIf EndIf EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_16 Func FuncTest_17() _Log('+ TEST 17: Get monitor from window -------------------\') ; Get monitor containing a specific window _Monitor_GetList() ; Try to find Notepad or use current active window Local $hWnd = WinGetHandle("[CLASS:Notepad]") If @error Or Not $hWnd Then $hWnd = WinGetHandle("[ACTIVE]") If @error Or Not $hWnd Then _Log("---> Example 17: No suitable window found. Opening Notepad...") $pidNotepad = Run("notepad.exe") If WinWaitActive("[CLASS:Notepad]", "", 3) Then Sleep(500) $hWnd = WinGetHandle("[CLASS:Notepad]") Else _Log("---> Example 17: ERROR - Could not find or create test window") Return EndIf EndIf EndIf If $hWnd Then Local $sTitle = WinGetTitle($hWnd) _Log("---> Example 17: Testing window: " & ($sTitle = "" ? "[No Title]" : $sTitle) & " (Handle: " & $hWnd & ")") Local $iMonitor = _Monitor_GetFromWindow($hWnd) If @error Then _Log("---> Example 17: ERROR getting monitor from window: @error=" & @error) Else If $iMonitor > 0 Then Local $aInfo = _Monitor_GetInfo($iMonitor) Local $sDevice = @error ? "N/A" : $aInfo[10] Local $sPrimary = @error ? "" : ($aInfo[9] ? " [PRIMARY]" : "") _Log("---> Example 17: Window is on Monitor #" & $iMonitor & " (" & $sDevice & ")" & $sPrimary) ; Get window position for verification Local $aWinPos = WinGetPos($hWnd) If Not @error Then _Log(" Window position: X=" & $aWinPos[0] & ", Y=" & $aWinPos[1]) _Log(" Monitor bounds: L=" & $aInfo[1] & ", T=" & $aInfo[2] & ", R=" & $aInfo[3] & ", B=" & $aInfo[4]) EndIf Local $sMsg = "TEST 17: SUCCESS" & @CRLF & @CRLF & _ "Window: " & ($sTitle = "" ? "[No Title]" : $sTitle) & @CRLF & _ "Handle: " & $hWnd & @CRLF & @CRLF & _ "Monitor: #" & $iMonitor & $sPrimary & @CRLF & _ "Device: " & $sDevice & @CRLF & @CRLF & _ "Window Position:" & @CRLF & _ " X: " & $aWinPos[0] & ", Y: " & $aWinPos[1] If Not $g_bAutoMode Then MsgBox(64, "Example 17", $sMsg, 5) Else _Log("---> Example 17: Window is not on any monitor") EndIf EndIf EndIf _Log('- End ------------------------------------------------/') EndFunc ;==>FuncTest_17 ; ================================================================================================== ; Small helper to push item into dynamic array (simple) ; ================================================================================================== Func __ArrayAdd(ByRef $a, $v) Local $n = 0 If IsArray($a) Then $n = UBound($a) ReDim $a[$n + 1] $a[$n] = $v EndFunc ;==>__ArrayAdd
    2 points
  8. Thanks for getting to the bottom of this. I updated the functions from your post a couple posts up that you updated. The functions work which is great. But unfortunately the video just shows black and will not play. I'll have to do some more research into how to get this to work. The functions are good, but there must be some other requirements that I have to do.
    2 points
  9. No worries! This one probably needs a tidy up - but here's a rough snappy-snappy version. If this is useful, I can probably just keep chipping away at it over the weekend if you'd like? - Just proof of concept things like click-to-select, or multi-select with shift & ctrl etc.. Edit: You need to drag out rectangles to create buttons in this example! #include <guiConstants.au3> #include <winapi.au3> Global Const $MK_LBUTTON = 1 Global Const $iSnap = 15 Global $hCursor_Cross = _WinAPI_LoadCursor(0, $IDC_CROSS) Global $hGui = GUICreate("", 300, 200, 100, 100, BitOR($WS_SIZEBOX, $WS_MINIMIZEBOX)) Global $hBtnProc = DllCallbackRegister("btnProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") Global $pBtnProc = DllCallbackGetPtr($hBtnProc) Global $hWndProc = DllCallbackRegister("WndProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") Global $pWndProc = DllCallbackGetPtr($hWndProc) _WinAPI_SetWindowSubclass($hGui, $pWndProc, 1000) GUISetState() Local $iMsg While WinExists($hGui) $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _WinAPI_RemoveWindowSubclass($hGui, $pWndProc, 1000) Func WndProc($hWnd, $iMsg, $wParam, $lParam, $iIdSubclass, $dwRefData) Local $iRet Local Static $bDrawRect, $tRect = DllStructCreate($tagRect) Switch $iMsg Case $WM_SETCURSOR Local $iSrc = BitAND($lParam, 0xFFFF), $iEvent = BitShift($lParam, 16) If $iSrc = $HTCLIENT Then _WinAPI_SetCursor($hCursor_Cross) $iRet = 1 Else $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndIf Case $WM_LBUTTONDOWN $tRect.Left = BitAND($lParam, 0xFFFF) $tRect.Top = BitShift($lParam, 16) $tRect.Left -= Mod($tRect.Left, $iSnap) $tRect.Top -= Mod($tRect.Top, $iSnap) $bDrawRect = True $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) Case $WM_MOUSEMOVE ;~ Local $iX = BitAND($lParam, 0xFFFF), $iY = BitShift($lParam, 16) If BitAND($wParam, $MK_LBUTTON) = $MK_LBUTTON Then _WinAPI_InvalidateRect($hWnd, $tRect, True) $tRect.Right = BitAND($lParam, 0xFFFF) $tRect.Bottom = BitShift($lParam, 16) $tRect.Right -= Mod($tRect.Right, $iSnap) $tRect.Bottom -= Mod($tRect.Bottom, $iSnap) _WinAPI_InvalidateRect($hWnd, $tRect, True) $iRet = 0 Else $bDrawRect = False $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndIf Case $WM_PAINT If $bDrawRect Then Local $tPaintStruct = $tagPAINTSTRUCT Local $hDC = _WinAPI_BeginPaint($hWnd, $tPaintStruct) Local $hPen = _WinAPI_CreatePen($PS_DOT, 1, _WinAPI_RGB(0, 0, 0)) Local $hBrush = _WinAPI_GetStockObject($WHITE_BRUSH) _WinAPI_SelectObject($hDC, $hPen) _WinAPI_SelectObject($hDC, $hBrush) _WinAPI_Rectangle($hDC, $tRect) _WinAPI_DeleteObject($hPen) _WinAPI_DeleteObject($hBrush) _WinAPI_EndPaint($hWnd, $tPaintStruct) $iRet = 0 Else $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndIf Case $WM_LBUTTONUP $bDrawRect = False $tRect.Right = BitAND($lParam, 0xFFFF) $tRect.Bottom = BitShift($lParam, 16) $tRect.Right -= Mod($tRect.Right, $iSnap) $tRect.Bottom -= Mod($tRect.Bottom, $iSnap) _WinAPI_InvalidateRect($hWnd, $tRect, True) Local $idBtn = GUICtrlCreateButton("", _ ($tRect.Left < $tRect.Right) ? $tRect.Left : $tRect.Right, _ ($tRect.Top < $tRect.Bottom) ? $tRect.Top : $tRect.Bottom, _ Abs($tRect.Left - $tRect.Right), _ Abs($tRect.Top - $tRect.Bottom)) _WinAPI_SetWindowSubclass(GUICtrlGetHandle($idBtn), $pBtnProc, $idBtn) $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) Case $WM_SIZE ;This prevents autoit's docking logic from moving controls around on window restore. $iRet = _WinAPI_DefWindowProcW($hWnd, $iMsg, $wParam, $lParam) Case Else $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndSwitch Return $iRet EndFunc ;==>WndProc Func btnProc($hWnd, $iMsg, $wParam, $lParam, $iIdSubclass, $dwRefData) Local $iRet Local Static $iXOffset, $iYOffset Switch $iMsg Case $WM_NCHITTEST Local $aPoint[2] = [BitAND($lParam, 0xFFFF), BitShift($lParam, 16)] ;Mouse coords can be negative on edge cases! If BitAND($aPoint[0], 0x8000) Then $aPoint[0] = BitOR(0xFFFF0000, $aPoint[0]) If BitAND($aPoint[1], 0x8000) Then $aPoint[1] = BitOR(0xFFFF0000, $aPoint[1]) Local $aPos = WinGetPos($hWnd), $iMar = 10 $iRet = $HTCAPTION If $aPoint[0] - $aPos[0] < $iMar Then $iRet = $HTLEFT If $aPoint[0] - $aPos[0] > ($aPos[2] - $iMar) Then $iRet = $HTRIGHT If $aPoint[1] - $aPos[1] < $iMar Then Switch $iRet Case $HTLEFT $iRet = $HTTOPLEFT Case $HTRIGHT $iRet = $HTTOPRIGHT Case Else $iRet = $HTTOP EndSwitch ElseIf $aPoint[1] - $aPos[1] > ($aPos[3] - $iMar) Then Switch $iRet Case $HTLEFT $iRet = $HTBOTTOMLEFT Case $HTRIGHT $iRet = $HTBOTTOMRIGHT Case Else $iRet = $HTBOTTOM EndSwitch EndIf If $aPoint[0] < 0 Then $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) If $aPoint[1] < 0 Then $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) _WinAPI_RedrawWindow($hWnd) Case $WM_NCLBUTTONDBLCLK ;Prevent double-click maximizing in "caption" If $wParam <> $HTCAPTION Then $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) Case $WM_SIZING Local $tRect = DllStructCreate($tagRect, $lParam) Local $tRect2 = _WinAPI_GetWindowRect($hWnd) $tRect.Left += Mod($tRect2.Left - $tRect.Left, $iSnap) $tRect.Top += Mod($tRect2.Top - $tRect.Top, $iSnap) $tRect.Right += Mod($tRect2.Right - $tRect.Right, $iSnap) $tRect.Bottom += Mod($tRect2.Bottom - $tRect.Bottom, $iSnap) $iRet = True Case $WM_MOVING Local $tRect = DllStructCreate($tagRect, $lParam) Local $tRect2 = _WinAPI_GetWindowRect($hWnd) $iXOffset += $tRect.Left - $tRect2.Left $iYOffset += $tRect.Top - $tRect2.Top Local $iSnapH = Floor($iXOffset / $iSnap) * $iSnap Local $iSnapV = Floor($iYOffset / $iSnap) * $iSnap $iXOffset -= $iSnapH $iYOffset -= $iSnapV $tRect.Left = $tRect2.Left + $iSnapH $tRect.Right = $tRect2.Right + $iSnapH $tRect.Top = $tRect2.Top + $iSnapV $tRect.Bottom = $tRect2.Bottom + $iSnapV $iRet = 0 Case $WM_EXITSIZEMOVE $iXOffset = 0 $iYOffset = 0 $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) Case $WM_SETCURSOR Local $iSrc = BitAND($lParam, 0xFFFF), $iEvent = BitShift($lParam, 16) If $iSrc = $HTCAPTION And $iEvent = $WM_LBUTTONDOWN Then _WinAPI_SetCursor($hCursor_Cross) $iRet = 1 Else $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndIf Case Else $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndSwitch Return $iRet EndFunc ;==>btnProc
    2 points
  10. On that point I should confess that I haven't updated my everyday PC to the latest version and that have projects still in v3.3.14.2 on other PCs ( quite shamelessly too ). If I had to start a new project, it'd be advisable to use the latest. In this case, that is so involved with the OS, is more important than just a SQLite script ( for example ), were the GUI is just to have a working interface. So yes, I too am of the opinion that you should focus the project on the updated engine/stub and it's UDFs. And as you've discovered yourself, a portable instance of other versions are quite simple to have. ( suck on that python !. ppl had to invent "Docker" to solve your issues ! )
    2 points
  11. Just be aware that the function which actually uses $CP_UTF8 (_WinAPI_MultiByteToWideChar) has also changed since the update.... The old version of this doesn't work as the strings in the metadata files aren't null-terminated. Not that we're necessarily calling this func in this project - but just FYI!
    2 points
  12. Sorry, I meant oopsies in applying the DPI stuff
    1 point
  13. For some reason the parent resized the work area.
    1 point
  14. Hey! Would someone be willing to try this out please? https://github.com/matthewrg/Guiscape/archive/refs/heads/main.zip
    1 point
  15. Thank you. I'm making progress on understanding the problem. So ... 96 is divided into the DPI reported by Windows. That gives a factor by which to multiply all of the sizes of the controls, fonts, etc which will make them look as though they were being displayed on a 96 (100%?) monitor? ... Ahh, but then we have per monitor aware DPI ...
    1 point
  16. Did you search & update? 😉
    1 point
  17. ... Func _SQLite_Startup($sDll_Filename = "", $bUTF8ErrorMsg = False, $iForceLocal = 0, $hPrintCallback = $__g_hPrintCallback_SQLite, $bAutoItTypeConversion = False) ... If $sDll_Filename = "" Then $sDll_Filename = "sqlite3.dll" If @AutoItX64 And (StringInStr($sDll_Filename, "_x64") = 0) Then $sDll_Filename = StringReplace($sDll_Filename, ".dll", "_x64.dll") ... ..therefore, your x86 DLL stays as is named in the zip. The x64 version from the zip file needs to be renamed to sqlite3_x64.dll. Do that and you'll be running it without issues
    1 point
  18. @argumentum - thanks for the input. I'm not sure if this additional info helps. But I found it interesting... Windows 11 has now junked the old Windows 10 files - I can't go back and more importantly, Windows can no longer link to any old system files. So that's out of the way. I have been running happily on Autoit v3.3.18.0 and SciTE v4.2.0 (2019) since I last posted. Last night, just for fun, I installed SciTE 4.4.6 (2021) over the existing installation to see what happened. No delay. So I turned the backups back on. I had turned them off because SciTE 4.2.0 was backing up the .au3 files in the script folder, and not a 'backup' sub folder. I used to keep 30 (a bit extreme, but hey..). The delay was back. Thinking that 30 backups was a bit extreme, I set it to 1. Same delay. Set it to 0, no delay. The script folder is on my desktop, so I moved it to the root of data drive D:, a completely different physical drive, to side step any potential permissions problems. Exactly the same results. I've concluded that there's nothing wrong with AutoIT, or SciTE. I think it's something that's happened whilst using Microsoft's Upgrade In Place of Windows 10. Apart from not having my backups automatically saved, I am back, up and running, with the latest versions and will now (probably) walk away from the issue. (.. until I have to do a full Windows re-install, of course!) Oh, and the PC seems very happy with Windows 11 by the way, despite its age! Best wishes all, John
    1 point
  19. Ok that works, kinda, it doesnt trigger until I moved the mouse from the start button and into the window.
    1 point
  20. ;********************************** While Sleep(100) Local $hStart = CheckForTitle("Start", "Windows.UI.Core.CoreWindow") If $hStart Then MsgBox(0, " 👮 I caught you.", "The handle to the 'Start' window: " & $hStart) WEnd ;**********************************
    1 point
  21. @ioa747 Holy Guacamole! That is short and sweet. 🙏 I just tested your example and it does exactly what I need and it does it beautifully and with a small amount of code. I am definitely going to try to swap out my existing functionality and use yours instead because it's more accurate and should be way more efficient as well compared to what I was doing.
    1 point
  22. ; https://www.autoitscript.com/forum/topic/213297-how-to-detect-when-start-menu-opens-win10win11/#findComment-1547177 #include <WinAPISysWin.au3> HotKeySet("{ESC}", "GoToExit") ;********************************** While Sleep(100) Local $hStart = CheckForTitle("Start") If $hStart Then MsgBox(0, " 👮 I caught you.", "The handle to the 'Start' window: " & $hStart) WEnd ;********************************** Func CheckForTitle($sTitle, $sClass = "") Local Static $tStruct = DllStructCreate($tagPOINT) ; Create a structure that defines the point to be checked. DllStructSetData($tStruct, "x", MouseGetPos(0)) ; Update the X and Y elements with the X and Y co-ordinates of the mouse. DllStructSetData($tStruct, "y", MouseGetPos(1)) ; Update the X and Y elements with the X and Y co-ordinates of the mouse. Local $hWnd = _WinAPI_WindowFromPoint($tStruct) ; Retrieves the handle of the window that contains the specified point. Local $sActiveTitle = WinGetTitle($hWnd) ; Retrieves the full title from a window. If $sActiveTitle = $sTitle Then Local $sActiveClass = _WinAPI_GetClassName($hWnd) If $sClass = "" Then Return $hWnd Else If $sActiveClass = $sClass Then Return $hWnd EndIf EndIf Return 0 EndFunc ;==>CheckForTitle Func GoToExit() Exit EndFunc ;==>GoToExit
    1 point
  23. I just entered the club, of the windows11 😭 ; https://www.autoitscript.com/forum/topic/213285-autoitchm-with-windows-11/#findComment-1547194 ;---------------------------------------------------------------------------------------- ; Title...........: Active_Help.au3 ; Description.....: Inject a custom .CSS file into help (Dark theme) ; closes the annoying notification MsgBox ; opens MSDN links with right click (for quick Navigation) ; opens MSDN links with left click (In case you forget) ; AutoIt Version..: 3.3.18.0 Author: ioa747 Script Version: 0.2 ; Note............: Testet in Windows 11 Pro 24H2 Date:4/11/2025 ;---------------------------------------------------------------------------------------- ;~ #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #NoTrayIcon #include <IE.au3> #include <WindowsConstants.au3> #include <Misc.au3> Global $g_ObjErr = ObjEvent("AutoIt.Error", "__ObjAutoItErrorEvent") Global $oIE Global $sMyCSS = FileRead(@ScriptDir & "\default.css") ; Your custom CSS file While 1 InjectHelp() Sleep(300) WEnd ;--------------------------------------------------------------------------------------- Func _CheckForMSDN_RB() ; opens MSDN links with right click (for quick Navigation) If Not WinActive("AutoIt Help") Then Return If MouseGetCursor() = 0 Then ; 0=Hand ; 2=Arrow If _IsPressed("02") Then ; 02=Right mouse button Local $aMPos = MouseGetPos() Sleep(200) Send("{ESC}") Sleep(200) ; SHIFT & Click Send("{SHIFTDOWN}") MouseClick("left", $aMPos[0], $aMPos[1]) Sleep(200) Send("{SHIFTUP}") EndIf EndIf EndFunc ;==>_CheckForMSDN_RB ;--------------------------------------------------------------------------------------- Func _CheckForMSDN_LB($hWND) ; opens MSDN links with left click (In case you forget) Local $hMSDN = WinGetHandle("[TITLE:Script Error; CLASS:Internet Explorer_TridentDlgFrame]") If $hMSDN Then Local $aMPos = MouseGetPos() Local $aWPos = WinGetPos($hWND) Local $aCLPos = ControlGetPos($hWND, "", "Internet Explorer_Server1") Local $hGhostGUI = GhostGUI($hWND, $aCLPos[2], $aCLPos[3], $aWPos[0] + $aCLPos[0] + 6, $aWPos[1] + $aCLPos[1] + 46) WinActivate($hWND) Do ControlSend($hMSDN, "", "Internet Explorer_Server1", "n") Sleep(50) $hMSDN = WinGetHandle("[TITLE:Script Error; CLASS:Internet Explorer_TridentDlgFrame]") WinActivate($hWND) Until Not $hMSDN Sleep(50) Send("{ALTDOWN}") Send("{LEFT}") Send("{ALTUP}") Sleep(200) GUIDelete($hGhostGUI) ; SHIFT & Click Send("{SHIFTDOWN}") MouseClick("left", $aMPos[0], $aMPos[1]) Sleep(200) Send("{SHIFTUP}") EndIf EndFunc ;==>_CheckForMSDN_LB ;--------------------------------------------------------------------------------------- Func GhostGUI($hWND, $iWidth, $iHeight, $iLeft, $iTop, $BackColor = 0x000000, $Transparency = 200) Local $hGUI = GUICreate('GhostGUI', $iWidth, $iHeight, $iLeft, $iTop, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TRANSPARENT, $WS_EX_TOPMOST), $hWND) GUISetBkColor($BackColor) WinSetTrans($hGUI, '', $Transparency) GUISetState(@SW_SHOW, $hGUI) Return $hGUI EndFunc ;==>GhostGUI ;--------------------------------------------------------------------------------------- Func _CheckForMsgBox() ; closes the annoying notification MsgBox Local $hMsgBox = WinGetHandle("[TITLE:Help; CLASS:#32770]", "Some content of this document has been blocked for your safety.") If $hMsgBox Then ControlClick($hMsgBox, "", "Button1") EndFunc ;==>_CheckForMsgBox ;--------------------------------------------------------------------------------------- Func InjectHelp() ; Inject a custom .CSS file into help (Dark theme) ; by @Gianni ; https://www.autoitscript.com/forum/topic/211640-autoit-help-file-for-dark-environment/?do=findComment&comment=1531446 Local $hWND = WinGetHandle("AutoIt Help") ; handle of the AutoIt Help window If Not WinExists($hWND) Then Return ; MsgBox(0, 'Help not found', "no AutoIt Help running", 3) $oIE = _IEAttach($hWND, "embedded") ; get reference to the BrowserControl embedded in the Help If @error Then Return ; MsgBox(0, 'Browser Control error', "problems on attaching Browser Control", 3) ; Set your custom CSS settings _WebBrowser_CSS_Inject($oIE, $sMyCSS) ; get a reference to the browser's window (for event management purpose) Local $oWindow = $oIE.document.parentwindow ; setup an event management Local $Event = ObjEvent($oWindow, "IEEvent_", 'HTMLWindowEvents') If @error Then Return While WinExists($hWND) ; stay alive only while the help is running GUIGetMsg() ; just to delay the CPU load _CheckForMsgBox() _CheckForMSDN_LB($hWND) _CheckForMSDN_RB() WEnd Return ;MsgBox(0, '', "AutoIt Help closed", 3) EndFunc ;==>InjectHelp ;--------------------------------------------------------------------------------------- Volatile Func IEEvent_onload($oEvent) ; following function is fired each time the Help page changes ;ConsoleWrite("Debug: onload event" & @crlf) _WebBrowser_CSS_Inject($oIE, $sMyCSS) ; ; apply your custom CSS setting to the loaded page EndFunc ;==>IEEvent_onload ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WebBrowser_CSS_Inject ; Description ...: this function creates into the html document a CSS node element with embedded the passed CSS or a link to a CSS ; Syntax ........: _WebBrowser_CSS_Inject(Byref $oIE_Server, $sStylesheet[, $bIsUrl = False]) ; Parameters ....: $oIE_Server - a Webbrowser object reference. ; $sStylesheet - CSS source to be injected into the page (either, a CSS or an URL (a link to a CSS) ; $bIsUrl - [optional] True if above parameter is an URL (a link to a CSS source). Default is False. ; Return values .: A Node Object reference, representing the appended node ; Author ........: Gianni ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _WebBrowser_CSS_Inject(ByRef $oIE_Server, $sStylesheet, $bIsUrl = False) ; Inject css Local $oStyleNode Local $objDocument = $oIE_Server.document ; If $bIsUrl Then ; use the link to load a stylesheet $oStyleNode = $objDocument.createElement('link') ; // Creates <link /> $oStyleNode.type = "text/css" $oStyleNode.rel = 'stylesheet' $oStyleNode.href = $sStylesheet Else ; inject the stylesheet directly $oStyleNode = $objDocument.createElement('style') ; // Creates <style></style> $oStyleNode.type = 'text/css' $oStyleNode.styleSheet.cssText = $sStylesheet ; // Syntax for IE EndIf ; Local $oNode = $objDocument.getElementsByTagName('head').item(0).appendChild($oStyleNode) If $bIsUrl Then ; wait till css has been downloaded Do Sleep(250) ; ConsoleWrite('css: ' & $oNode.ReadyState & @CRLF) ; debug purpose Until $oNode.ReadyState = "loaded" Or $oNode.ReadyState = "complete" EndIf Return $oNode EndFunc ;==>_WebBrowser_CSS_Inject ;--------------------------------------------------------------------------------------- Func __ObjAutoItErrorEvent() ; reset Obj error If IsObj($g_ObjErr) Then ; Clear the properties of ObjEvent $g_ObjErr.Description = "" $g_ObjErr.Number = 0 EndIf EndFunc ;==>__ObjAutoItErrorEvent ;--------------------------------------------------------------------------------------- default.css
    1 point
  24. This GUI builder project is off to a great start. Before you all get too far into completing the GUI for it, I'm wondering, is there any plans to make Guiscape DPI aware? The reason why I ask is because it would be much easier to plan it into the project early on. The further you get into it, it could become much more complex to add DPI awareness later.
    1 point
  25. Yes but also working as a overview for navigation for example. Adding a description to each folder link. This is of-course not necessary, but may improve the user experience overall, despite the extra work.
    1 point
  26. Thanks for the input @genius257, I agree that the examples folder is a bit cluttered to find what you need in it. Moving them to their individual element type would help fix that, mLipok and I discussed this before, but it might need to be reconsidered. Making sub-folders for each type is an interesting idea, it would need a bit of planning as each example would need to be modified to fix the include path, but that wouldn't be too hard to automate I think. Yes, Documentation is definitely lacking currently, which is something a few have already brought up. Water actually suggested a wiki page with a few words on getting started with the UDF, which would help I believe. Do you mean that each ReadMe would give an overview of the purpose of each group of examples? i.e. "These examples help automate data input into cells etc..."? Mattyd and Water also suggested to try the Simple Help file generator, which would help with linking to related functions and also the examples. Not to mention guidance on usage. This would take some work to setup as the Headers aren't formatted 100% correct, and to also add more usage documentation, which is currently not filled in really. I've tried to avoid this, (one reason there's so many functions), but I agree. I've had thoughts also on _DocConnect, which has, in my opinion, too many options for finding an open document. And the example you mention. Yes, I was originally attempting to semi-mirror the Word UDF functions, though I found it not possible soon on due to the different functionality in some areas between the two Office suites. Now that the UDF is more fleshed out, the users themselves, if they cared to, can easily connect to an existing document, and see if it's fit to use. Thanks for the tip on CI Actions, I'll have to look into that at some point. I currently just have a script that runs each example and X's the MsgBoxes . Thanks for the food for thought. Best regards,
    1 point
  27. NO, It just moves the GUI to another screen one by one (Used for testing or resolution change or screen change functionality) The only way to “show on all screens at once” is: Create multiple GUIs (windows) — one GUI for each screen.
    1 point
  28. Here is yesterday's effort - single select button for now.. Double click sets the text, delete removes the control. ;~ #AutoIt3Wrapper_UseX64=N #include <WindowsSysColorConstants.au3> #include <guiConstants.au3> #include <winapi.au3> #include <guibutton.au3> #include <WinAPIvkeysConstants.au3> Global Const $tagMINMAXINFO = "long Reserved[2]; long MaxSize[2]; long MaxPosition[2]; long MinTrackSize[2]; long MaxTrackSize[2]" Global Const $MK_LBUTTON = 1 Global Const $iSnap = 15 Global $hCursor_Cross = _WinAPI_LoadCursor(0, $IDC_CROSS) Global $hGui = GUICreate("", 300, 200, 100, 100, BitOR($WS_SIZEBOX, $WS_MINIMIZEBOX)) GUISetState() Global $hBtnProc = DllCallbackRegister("btnProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") Global $pBtnProc = DllCallbackGetPtr($hBtnProc) Global $hWndProc = DllCallbackRegister("WndProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") Global $pWndProc = DllCallbackGetPtr($hWndProc) _WinAPI_SetWindowSubclass($hGui, $pWndProc, 1000) GUISetState() Local $iMsg While WinExists($hGui) $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _WinAPI_RemoveWindowSubclass($hGui, $pWndProc, 1000) Func WndProc($hWnd, $iMsg, $wParam, $lParam, $iIdSubclass, $dwRefData) Local $iRet Local Static $bDrawRect, $tPaintRect = DllStructCreate($tagRect) Switch $iMsg Case $WM_SETCURSOR Local $iSrc = _WinAPI_LoWord($lParam), $iEvent = _WinAPI_HiWord($lParam) If $iSrc = $HTCLIENT Then _WinAPI_SetCursor($hCursor_Cross) $iRet = 1 Else $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndIf Case $WM_LBUTTONDOWN Local $tPoint = _WinAPI_MakePoints($lParam) $tPaintRect.Left = $tPoint.X $tPaintRect.Top = $tPoint.Y $tPaintRect.Left -= Mod($tPaintRect.Left, $iSnap) $tPaintRect.Top -= Mod($tPaintRect.Top, $iSnap) $bDrawRect = True ;~ _WinAPI_TrackMouseEvent($hWnd, $TME_LEAVE) $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) Case $WM_MOUSEMOVE Local $tPoint = _WinAPI_MakePoints($lParam) If BitAND($wParam, $MK_LBUTTON) = $MK_LBUTTON Then _WinAPI_InvalidateRect($hWnd, $tPaintRect, True) $tPaintRect.Right = $tPoint.X $tPaintRect.Bottom = $tPoint.Y $tPaintRect.Right -= Mod($tPaintRect.Right, $iSnap) $tPaintRect.Bottom -= Mod($tPaintRect.Bottom, $iSnap) _WinAPI_InvalidateRect($hWnd, $tPaintRect, True) $iRet = 0 Else If $bDrawRect Then _WinAPI_InvalidateRect($hWnd, $tPaintRect, True) $bDrawRect = False $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndIf Case $WM_PAINT If $bDrawRect Then Local $tPaintStruct = $tagPAINTSTRUCT Local $hDC = _WinAPI_BeginPaint($hWnd, $tPaintStruct) Local $hPen = _WinAPI_CreatePen($PS_DOT, 1, _WinAPI_RGB(0, 0, 0)) Local $hBrush = _WinAPI_GetStockObject($WHITE_BRUSH) _WinAPI_SelectObject($hDC, $hPen) _WinAPI_SelectObject($hDC, $hBrush) _WinAPI_Rectangle($hDC, $tPaintRect) _WinAPI_DeleteObject($hPen) _WinAPI_DeleteObject($hBrush) _WinAPI_EndPaint($hWnd, $tPaintStruct) $iRet = 0 Else $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndIf Case $WM_LBUTTONUP Local $tPoint = _WinAPI_MakePoints($lParam) If $bDrawRect Then $bDrawRect = False $tPaintRect.Right = $tPoint.X $tPaintRect.Bottom = $tPoint.Y $tPaintRect.Right -= Mod($tPaintRect.Right, $iSnap) $tPaintRect.Bottom -= Mod($tPaintRect.Bottom, $iSnap) _WinAPI_InvalidateRect($hWnd, $tPaintRect, True) If Abs($tPaintRect.Left - $tPaintRect.Right) >= $iSnap _ ;MinWidth & Height. And Abs($tPaintRect.Top - $tPaintRect.Bottom) >= $iSnap Then ;Need border & clipsiblings to paint custom frame. using UDF for button to avoid any surprises in autoit's default btn proc Local $hBtn = _GUICtrlButton_Create($hWnd, "", _ ($tPaintRect.Left < $tPaintRect.Right) ? $tPaintRect.Left : $tPaintRect.Right, _ ($tPaintRect.Top < $tPaintRect.Bottom) ? $tPaintRect.Top : $tPaintRect.Bottom, _ Abs($tPaintRect.Left - $tPaintRect.Right), _ Abs($tPaintRect.Top - $tPaintRect.Bottom), _ BitOR($BS_PUSHLIKE, $WS_BORDER, $WS_CLIPSIBLINGS)) _WinAPI_SetWindowSubclass($hBtn, $pBtnProc, _WinAPI_GetDlgCtrlID($hBtn)) EndIf EndIf $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) Case $WM_SIZE ;This prevents autoit's docking logic from moving controls around on window restore. $iRet = _WinAPI_DefWindowProcW($hWnd, $iMsg, $wParam, $lParam) ;~ Case $WM_MOUSELEAVE ;~ Local $tPoint = _WinAPI_GetMousePos(True, $hWnd) ;~ If ($tPoint.X < 0) Or ($tPoint.X > _WinAPI_GetWindowWidth($hWnd)) Then ;~ ElseIf ($tPoint.Y < 0) Or ($tPoint.Y > _WinAPI_GetWindowHeight($hWnd)) Then ;~ EndIf Case Else $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndSwitch Return $iRet EndFunc ;==>WndProc Func btnProc($hWnd, $iMsg, $wParam, $lParam, $iIdSubclass, $dwRefData) Local $iRet Local Static $iXOffset, $iYOffset, $hHasFocus, $hLastFocus;, $tStartPos Local Static $hDrag Switch $iMsg Case $WM_NCHITTEST Local $tPoint = _WinAPI_MakePoints($lParam) Local $tRect = _WinAPI_GetWindowRect($hWnd) Local $iMar = 10 $iRet = $HTCLIENT ;only in caption bar if left button is down. (no kb input availabe in caption!) Local $iTestKey = _WinAPI_GetSystemMetrics($SM_SWAPBUTTON) ? $VK_RBUTTON : $VK_LBUTTON If BitAnd(0x8000, _WinAPI_GetAsyncKeyState($iTestKey)) Then $iRet = $HTCAPTION If $tPoint.X - $tRect.Left < $iMar Then $iRet = $HTLEFT If $tPoint.X > ($tRect.Right - $iMar) Then $iRet = $HTRIGHT If $tPoint.Y - $tRect.Top < $iMar Then Switch $iRet Case $HTLEFT $iRet = $HTTOPLEFT Case $HTRIGHT $iRet = $HTTOPRIGHT Case Else $iRet = $HTTOP EndSwitch ElseIf $tPoint.Y > ($tRect.Bottom - $iMar) Then Switch $iRet Case $HTLEFT $iRet = $HTBOTTOMLEFT Case $HTRIGHT $iRet = $HTBOTTOMRIGHT Case Else $iRet = $HTBOTTOM EndSwitch EndIf If $tPoint.X < 0 Then $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) If $tPoint.Y < 0 Then $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) _WinAPI_RedrawWindow($hWnd) Case $WM_NCLBUTTONDOWN $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) _WinaPI_SetFocus($hWnd) Case $WM_SETFOCUS $hHasFocus = $hWnd _SendMessage($wParam, $WM_KILLFOCUS, $hWnd) $hLastFocus = $hWnd _WinAPI_RedrawWindow($hWnd, 0, 0, BitOR($RDW_FRAME, $RDW_INVALIDATE)) $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) Case $WM_KILLFOCUS _WinAPI_RedrawWindow($hWnd, 0, 0, BitOR($RDW_FRAME, $RDW_INVALIDATE)) $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) Case $WM_NCLBUTTONDBLCLK ;Prevent double-click maximizing in "caption" - also now set caption. If $wParam = $HTCAPTION Then Local $iCaptionLen = _SendMessage($hWnd, $WM_GETTEXTLENGTH) Local $tCaption = DllStructCreate(StringFormat("wchar text[%d]", $iCaptionLen + 1)) _SendMessage($hWnd, $WM_GETTEXT, DllStructGetSize($tCaption), $tCaption, 0, "wparam", "struct*") Local $sCaption = InputBox("Edit Caption", " ", $tCaption.Text, "", 150, 60, BitAND($lParam, 0xFFFF), BitShift($lParam, 16)) If Not @error Then _SendMessage($hWnd, $WM_SETTEXT, 0, $sCaption, 0, "wparam", "wstr") Else $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndIf Case $WM_GETMINMAXINFO ;Min width jumps to ~150 with WS_BORDER - I guess it gets min window size: SM_CYMINTRACK Local $tMinMaxInfo = DllStructCreate($tagMINMAXINFO, $lParam) $tMinMaxInfo.MinTrackSize(1) = $iSnap + 1 $tMinMaxInfo.MinTrackSize(2) = $iSnap + 1 $iRet = 0 Case $WM_SIZING Local $tRect = DllStructCreate($tagRect, $lParam) Local $tRect2 = _WinAPI_GetWindowRect($hWnd) $tRect.Left += Mod($tRect2.Left - $tRect.Left, $iSnap) $tRect.Top += Mod($tRect2.Top - $tRect.Top, $iSnap) $tRect.Right += Mod($tRect2.Right - $tRect.Right, $iSnap) $tRect.Bottom += Mod($tRect2.Bottom - $tRect.Bottom, $iSnap) $iRet = True Case $WM_NCPAINT Local $hDC = _WinAPI_GetWindowDC($hWnd) Local $tRect = _WinAPI_GetClientRect($hWnd) $tRect.Right = _WinAPI_GetWindowWidth($hWnd) $tRect.Bottom = _WinAPI_GetWindowHeight($hWnd) Local $hPenCol = ($hHasFocus = $hWnd) ? _WinAPI_RGB(0, 0xAA, 0) : _WinAPI_GetSysColor($COLOR_3DFACE) Local $hPen = _WinAPI_CreatePen($PS_SOLID, 1, $hPenCol) _WinAPI_SelectObject($hDC, $hPen) _WinAPI_Rectangle($hDC, $tRect) _WinAPI_DeleteObject($hPen) _WinAPI_ReleaseDC($hWnd, $hDC) $iRet = 0 Case $WM_MOVING Local $tRect = DllStructCreate($tagRect, $lParam) Local $tRect2 = _WinAPI_GetWindowRect($hWnd) $iXOffset += $tRect.Left - $tRect2.Left $iYOffset += $tRect.Top - $tRect2.Top Local $iSnapH = Floor($iXOffset / $iSnap) * $iSnap Local $iSnapV = Floor($iYOffset / $iSnap) * $iSnap $iXOffset -= $iSnapH $iYOffset -= $iSnapV $tRect.Left = $tRect2.Left + $iSnapH $tRect.Right = $tRect2.Right + $iSnapH $tRect.Top = $tRect2.Top + $iSnapV $tRect.Bottom = $tRect2.Bottom + $iSnapV $iRet = 0 Case $WM_EXITSIZEMOVE $iXOffset = 0 $iYOffset = 0 $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) Case $WM_KEYDOWN If $wParam = $VK_DELETE Then ;~ _WinAPI_DestroyWindow($hWnd) _WinAPI_PostMessage($hWnd, $WM_DESTROY, 0, 0) Else $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndIf Case $WM_DESTROY _WinAPI_RemoveWindowSubclass($hWnd, $pBtnProc, $iIdSubclass) $iRet = _WinAPI_DefWindowProcW($hWnd, $iMsg, $wParam, $lParam) _GUICtrlButton_Destroy($hWnd) Case $WM_SETCURSOR Local $iSrc = BitAND($lParam, 0xFFFF), $iEvent = BitShift($lParam, 16) If $iSrc = $HTCAPTION And $iEvent = $WM_LBUTTONDOWN Then _WinAPI_SetCursor($hCursor_Cross) $iRet = 1 Else $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndIf Case Else $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndSwitch Return $iRet EndFunc ;==>btnProc Func _WinAPI_MakePoints($iValue) Local $tPoint = DllStructCreate($tagPoint) DllStructSetData($tPoint, 1, _WinAPI_WordToShort(_WinAPI_LoWord($iValue))) DllStructSetData($tPoint, 2, _WinAPI_WordToShort(_WinAPI_HiWord($iValue))) Return $tPoint EndFunc
    1 point
  29. And we welcome back GUI GURU jaberwacky to the GUI front. Oct 27 2025 - Guiscape -- A new GUI builder project! by jaberwacky Added to the first post. Good to see him at it again.
    1 point
  30. Here is the project page where I originally found the version with x64 support: https://github.com/AutoItMicro/AutoItObject
    1 point
  31. @WildByDesign post it in this thread just look on tuesday post I just again post your stuff updated for #include aand tidy used Guiscape.zip
    1 point
  32. I assume you must hook to the external program to change visuals.
    1 point
  33. I didn't realize that I had accumulated so many examples, projects and other testing files that I was playing around with while learning AutoIt. It wasn't until recently that I realized that I was having trouble finding specific examples, testing scripts and specific function testing. This SearchContent script is an absolute godsend. A real treasure and a "saver of time".
    1 point
  34. I'd say that's more to do with the UWP popup class - so its probably not relevant to our win32 apps. TBH I wouldn't hold my breath given that full screen is explicitly not supported in xaml islands. But happy to be proven wrong though!
    1 point
  35. Ah apologies... so we've all stuffed up well here! - I haven't re-tested, but from looking at things... In the first one, we are: IMediaPlayerElement_GetIsFullWindow($pPlayer) But. $pPlayer is the mediaplayer object. not the mediaplayerelement object! So we think we're calling function #19 in the IMediaPlayerElement vtable. but we're actually calling function #19 in IMediaPlayer. which is IMediaPlayer::GetIsMuted My last demo I'm also using the wrong obj in both the getter and setter. Func _MediaPlayer_SetIsFullWindow($iMPIdx, $bState) If $iMPIdx < 1 Or $iMPIdx >= UBound($__g_apPlayers) Then Return False _WinRT_SwitchInterface($__g_apMPElements[$iMPIdx], $sIID_IMediaPlayerElement) If Not @error Then IMediaPlayerElement_SetIsFullWindow($__g_apPlayers[$iMPIdx], $bState) Return @error = $S_OK EndFunc $__g_apPlayers[$iMPIdx] should be $__g_apMPElements[$iMPIdx].
    1 point
  36. 1 point
  37. Ah ok, In the second example, and $hPlayer isn't an object pointer - its a psuedo handle. Basically I've dumped the associated objects of a "player" into an arrays, and hplayer is simply an index. ;from _MediaPlayer_Create, $hPlayer is $iMPIdx! Local $iMPIdx = UBound($__g_apXamlSources) ReDim $__g_apXamlSources[$iMPIdx + 1] ReDim $__g_apMPElements[$iMPIdx + 1] ReDim $__g_apPlayers[$iMPIdx + 1] Try these ones! - Edit 31/10: Corrected error as discussed below. Func _MediaPlayer_SetIsFullWindow($iMPIdx, $bState) If $iMPIdx < 1 Or $iMPIdx >= UBound($__g_apPlayers) Then Return False _WinRT_SwitchInterface($__g_apMPElements[$iMPIdx], $sIID_IMediaPlayerElement) If Not @error Then IMediaPlayerElement_SetIsFullWindow($__g_apMPElements[$iMPIdx], $bState) Return @error = $S_OK EndFunc Func _MediaPlayer_GetIsFullWindow($iMPIdx) If $iMPIdx < 1 Or $iMPIdx >= UBound($__g_apPlayers) Then Return False _WinRT_SwitchInterface($__g_apMPElements[$iMPIdx], $sIID_IMediaPlayerElement) If Not @error Then $bState = IMediaPlayerElement_GetIsFullWindow($__g_apMPElements[$iMPIdx]) Return SetError(@error, @extended, $bState) EndFunc Then for the transport button - not that it achieves anything!. Func _MediaPlayer_SetIsFullScreenVisible($iMPIdx, $bState) Local $iErr If $iMPIdx < 1 Or $iMPIdx >= UBound($__g_apPlayers) Then Return False Local $pTransport = __MediaPlayer_GetTransport($iMPIdx) If @error Then Return SetError(@error, @extended, False) IMediaTransportControls_SetIsFullWindowButtonVisible($pTransport, $bState) $iErr = @error IUnknown_Release($pTransport) Return $iErr = $S_OK EndFunc Func _MediaPlayer_SetIsFullScreenEnabled($iMPIdx, $bState) Local $iErr If $iMPIdx < 1 Or $iMPIdx >= UBound($__g_apPlayers) Then Return False Local $pTransport = __MediaPlayer_GetTransport($iMPIdx) If @error Then Return SetError(@error, @extended, False) IMediaTransportControls_SetIsFullWindowEnabled($pTransport, $bState) $iErr = @error IUnknown_Release($pTransport) Return $iErr = $S_OK EndFunc Func _MediaPlayer_GetIsFullScreenVisible($iMPIdx) Local $iErr, $iExt, $bState = False If $iMPIdx < 1 Or $iMPIdx >= UBound($__g_apPlayers) Then Return False Local $pTransport = __MediaPlayer_GetTransport($iMPIdx) If @error Then Return SetError(@error, @extended, False) $bState = IMediaTransportControls_GetIsFullWindowButtonVisible($pTransport) $iErr = @error $iExt = @extended IUnknown_Release($pTransport) Return $iErr = $S_OK EndFunc Func _MediaPlayer_GetIsFullScreenEnabled($iMPIdx) Local $iErr, $iExt, $bState = False If $iMPIdx < 1 Or $iMPIdx >= UBound($__g_apPlayers) Then Return False Local $pTransport = __MediaPlayer_GetTransport($iMPIdx) If @error Then Return SetError(@error, @extended, False) $bState = IMediaTransportControls_GetIsFullWindowEnabled($pTransport) $iErr = @error $iExt = @extended IUnknown_Release($pTransport) Return SetError($iErr, $iExt, $bState) EndFunc
    1 point
  38. @SOLVE-SMART I updated the script in the first post to support 3.3.16.1. Thanks for letting me know about that. Now I've got a portable setup of 3.3.16.1 so that I can test any of my scripts on as well.
    1 point
  39. Local Const $CP_UTF8 = 65001 should solve that. For _IsPressed(), people can press F1 to find out what UDF is that in. Easy peasy lemon squeezy
    1 point
  40. wakillon

    enumicons.au3

    New Version 2.1.0.4 Display modified Left click on an icon for save it with the size you want, regardless of the mode (Ordinal/Name) used The file path is indicated as ioa747 wished enumicons.au3
    1 point
  41. wakillon

    AutoIt Snippets

    Trick for display your favorite directories in FileSaveDialog and FileOpenDialog with Win 11 The favorite directories are set in registry to : HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\comdlg32\Placesbar Example of Placesbar Reg File Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\comdlg32\Placesbar] "Place1"="C:\\" "Place2"="C:\\Program Files (x86)\\AutoIt3\\Include" "Place4"="D:\\" "Place0"=dword:00000011 "Place3"=dword:00000010 11 is "My Computer" and 10 the Desktop #Region ;************ Includes ************ #Include <WinAPITheme.au3> #EndRegion ;************ Includes ************ $hGui = GUICreate('', 500, 500) GUISetState() ; Default display FileSaveDialog('Save file', @WorkingDir, 'Scripts (*.au3)', $FD_PATHMUSTEXIST, '', $hGui) ; ; Display with PlacesBar _WinAPI_SetThemeAppProperties($STAP_ALLOW_NONCLIENT) FileSaveDialog('Save file', @WorkingDir, 'Scripts (*.au3)', $FD_PATHMUSTEXIST, '', $hGui) FileOpenDialog('Select a file', @WorkingDir & '\', 'Images (*.jpg;*.bmp)', $FD_FILEMUSTEXIST, '', $hGui) ; ; Reset default display _WinAPI_SetThemeAppProperties(-1) FileSaveDialog('Save file', @WorkingDir, 'Scripts (*.au3)', $FD_PATHMUSTEXIST, '', $hGui) GUIDelete($hGui) Exit
    1 point
  42. Sorry I'm newbie In the forum So. .cursorrules it's specific file format Cursor uses as Main/system prompt it should be placed into project root You can define the AI model howto response. This is mine but you can edit it. Role You are an AutoIt Script Engineer (Windows automation, GUI apps, COM, WinAPI, file/window control, reliable tool-building). Action Understand the task and proactively clarify any gaps. Write AutoIt v3-compatible, robust, well-commented code (with UDFs where helpful). Build an event-driven GUI with status indicators and logging. Implement solid error handling (@error/@extended), return codes, and graceful cleanup. When needed: COM automation (Excel/Word), WinAPI calls, image-based detection (PixelSearch/ImageSearch UDF), window/process control. Provide self-tests per major function and basic timing/metrics. Include build/run instructions and config tips. Steps Requirements summary → inputs/outputs, target OS (Win10/11), permissions. Design → modules, UDFs (#include), GUI flow, logging strategy. Implementation → clear #Region/#EndRegion blocks, consistent naming ($g_s, $a, Func PascalCase). Error handling → guards, fallbacks, resource disposal. Tests → function self-tests, synthetic data, edge cases. Performance → tuned sleeps, correct WinWait/Control* usage. Documentation → README (run, params, known limits), changelog. Release → Aut2Exe build options, versioning, code-sign/AV false positive tips. Context Typical use-cases: desktop automation (form fill, buttons), stable GUI bots, Excel report generation, screen-based detection (icons, buttons, coordinates). Environment: Windows 10/11 x64, AutoIt v3 + SciTE; optional external UDFs (e.g., ImageSearch.au3; if unavailable, provide PixelSearch+tolerance alternative). Non-goal: brittle fixed-delay scripts; prefer state-driven and window-control-based logic. Examples GUI launcher: Start/Stop, log panel, tray icon; workflow: find window → control interaction → verify → log. Excel COM: open workbook, read ranges, export CSV, robust error handling and proper Quit(). Image locate & click: load templates from folder → tolerant search → click coordinates → verification step. WinAPI targeting: focusless ControlSend/ControlClick, class-based selection, DPI-aware settings. Format First: short Summary (goal, inputs/outputs). Then: a single .au3 code file, runnable, richly commented; sections: Config, Utils, GUI, Core, Tests, Main. Finally: README (install, run, troubleshooting, known limitations). Code display: canmore.create_doc (single file, copyable). Output language: English; variable/function names in English; logs may be mixed EN/HU if needed. Next step you should add the Autoit documentation for more robust code and less hallucination into settings Any time if you had any mistake and needs correction, just call in chat.
    1 point
  43. Jon

    AutoIt v3.3.18.0 Released

    AutoIt v3.3.18.0 has been released - mainly a UDF release. Thanks to @jpm and the MVPs who were responsible for the majority of code in this version. Download it here. Complete list of changes: History
    1 point
  44. I know it's an ancient topic, but with many people working with multiple monitors a full answer was still sorely missing - every single answer here was manual. Here's my fully automated UDF I came up with, which allows simply giving a monitor number and utilizing it via Windows API. You can also use it for your default monitor but with a quick way to maximize or center it. GUICreateMonitor.au3 #include-once #include <GUIConstantsEx.au3> ; for $GUI_EVENT_CLOSE #include <WinAPIGdi.au3> ; #FUNCTION# ==================================================================================================================== ; Description ...: Create a GUI on a specific monitor ; Parameters ....: $iMonitorNumber - Monitor number (1-based index) or 0 for Primary or empty for Windows to decide ; $iCreate - Actually create the GUI, otherwise just return an array of its potential values ; $sTitle - Title to use for GUI ; $iWidth - Width to use for GUI - can be number or "max" ; $iHeight - Height to use for GUI - can be number or "max" ; $oLeft - Left side to use for GUI - can be number or "center" or "max" ; $oTop - Top side to use for GUI - can be number or "center" or "max" ; $iStyle - Style to use for GUI ; $iExStyle - Extended style to use for GUI ; $iParent - Parent to use for GUI ; Return values .: See GUICreate ; Author ........: LWC <https://lior.weissbrod.com> ; Modified ......: ; ================================================================================================================== Func GUICreateOnMonitor($iMonitorNumber, $iCreate, $sTitle, $iWidth = 0, $iHeight = 0, $oLeft = 0, $oTop = 0, $iStyle = "", $iExStyle = "", $iParent = "") if IsNumber($iMonitorNumber) then ; Get monitor information Local $aMonitorData = GetMonitorInfo() Local $aMonitors = $aMonitorData[0] Local $iPrimaryMonitorIndex = $aMonitorData[1] Local $iMonitorCount = UBound($aMonitors) EndIf ; Fallback for an non exising monitor If IsNumber($iMonitorNumber) and ($iMonitorNumber < 1 Or $iMonitorNumber > $iMonitorCount) Then If $iPrimaryMonitorIndex >= 0 Then $iMonitorNumber = $iPrimaryMonitorIndex + 1 ; Convert to 1-based index Else $iMonitorNumber = 1 EndIf EndIf ; Get monitor position Local $iMonitorIndex = IsNumber($iMonitorNumber) ? $iMonitorNumber - 1 : "" ; (1-based index to 0-based array) Local $iMonitorWidth = IsNumber($iMonitorNumber) ? $aMonitors[$iMonitorIndex][3] : @DesktopWidth Local $iMonitorHeight = IsNumber($iMonitorNumber) ? $aMonitors[$iMonitorIndex][4] : @DesktopHeight Local $iLeft = IsNumber($iMonitorNumber) ? $aMonitors[$iMonitorIndex][1] : 0 Local $iTop = IsNumber($iMonitorNumber) ? $aMonitors[$iMonitorIndex][2] : 0 ; Position window on monitor If $iWidth == "max" Then $iWidth = $iMonitorWidth If $iHeight == "max" Then $iHeight = $iMonitorHeight Local $iWindowLeft = $iLeft + (($oLeft == "max") ? $iMonitorWidth : (($oLeft == "center") ? ($iMonitorWidth - $iWidth) / 2 : $oLeft)) Local $iWindowTop = $iTop + (($oTop == "max") ? $iMonitorHeight : (($oTop == "center") ? ($iMonitorHeight - $iHeight) / 2 : $oTop)) Local $iSimulate = False If $iSimulate Then MsgBox($MB_ICONINFORMATION, "Simulation", "GUICreate(" & Chr(34) & $sTitle & Chr(34) & ", " & (($iWidth == "") ? "Default" : $iWidth) & ", " & (($iHeight == "") ? "Default" : $iHeight) & ", " & $iWindowLeft & ", " & $iWindowTop & " ," & (($iStyle == "") ? "Default" : $iStyle) & ", " & (($iExStyle == "") ? "Default" : $iExStyle) & ", " & (($iParent == "") ? "Default" : $iParent) & ")") EndIf Local $return = [IsNumber($iMonitorNumber) ? $iMonitorNumber : "", $iMonitorWidth, $iMonitorHeight, $iWindowLeft, $iWindowTop] Return $iCreate ? ($iSimulate ? 0 : GUICreate($sTitle, ($iWidth == "") ? Default : $iWidth, ($iHeight == "") ? Default : $iHeight, $iWindowLeft, $iWindowTop, ($iStyle == "") ? Default : $iStyle, ($iExStyle == "") ? Default : $iExStyle, ($iParent == "") ? Default : $iParent)) : $return EndFunc ; #FUNCTION# ==================================================================================================================== ; Description ...: Get monitor information (filtered for physical monitors) ; Parameters ....: None ; Return values .: Array (empty if no info) ; Author ........: LWC <https://lior.weissbrod.com> ; Modified ......: ; ================================================================================================================== Func GetMonitorInfo() Local $aMonitors[0][5] ; [index][0=handle, 1=left, 2=top, 3=width, 4=height] Local $iMonitorCount = 0 Local $aResult = _WinAPI_EnumDisplayMonitors() If @error Or Not IsArray($aResult) Then Return $aMonitors EndIf $iMonitorCount = UBound($aResult) ; Filter out virtual monitors (those with very small dimensions or zero dimensions) Local $aFilteredMonitors[0][5] Local $iFilteredCount = 0 Local $iPrimaryMonitorIndex = -1 ; Track which monitor is primary For $i = 0 To $iMonitorCount - 1 ; Get monitor handle from the enumeration result Local $hMonitor = $aResult[$i][0] ; Skip null/invalid handles If $hMonitor = 0 Then ContinueLoop EndIf Local $aMonitorInfo = _WinAPI_GetMonitorInfo($hMonitor) If @error Then ContinueLoop EndIf ; Extract rectangle data from the monitor info ; $aMonitorInfo[0] = $tagRECT structure for monitor rectangle Local $tRect = $aMonitorInfo[0] Local $iLeft = DllStructGetData($tRect, 1) Local $iTop = DllStructGetData($tRect, 2) Local $iRight = DllStructGetData($tRect, 3) Local $iBottom = DllStructGetData($tRect, 4) Local $iWidth = $iRight - $iLeft Local $iHeight = $iBottom - $iTop ; Filter out monitors with dimensions less than 100x100 (likely virtual) If $iWidth >= 100 And $iHeight >= 100 Then ReDim $aFilteredMonitors[$iFilteredCount + 1][5] $aFilteredMonitors[$iFilteredCount][0] = $hMonitor ; handle $aFilteredMonitors[$iFilteredCount][1] = $iLeft ; left $aFilteredMonitors[$iFilteredCount][2] = $iTop ; top $aFilteredMonitors[$iFilteredCount][3] = $iWidth ; width $aFilteredMonitors[$iFilteredCount][4] = $iHeight ; height ; Check if this is the primary monitor If $aMonitorInfo[2] = 1 Then ; Primary flag $iPrimaryMonitorIndex = $iFilteredCount EndIf $iFilteredCount += 1 EndIf Next ; Store primary monitor index in the first element for easy access Local $aResult[2] $aResult[0] = $aFilteredMonitors $aResult[1] = $iPrimaryMonitorIndex Return $aResult EndFunc ; #FUNCTION# ==================================================================================================================== ; Description ...: Create a sample GUI on a specific monitor ; Parameters ....: See CreateGUIOnMonitor ; Return values .: None ; Author ........: LWC <https://lior.weissbrod.com> ; Modified ......: ; ================================================================================================================== Func sampleGUICreateOnMonitor($iMonitorNumber, $iCreate, $sTitle, $iWidth = 0, $iHeight = 0, $oLeft = 0, $oTop = 0, $iStyle = "", $iExStyle = "", $iParent = "") Local $hGUI = GUICreateOnMonitor($iMonitorNumber, $iCreate, $sTitle, $iWidth, $iHeight, $oLeft, $oTop, $iStyle, $iExStyle, $iParent) if $hGUI <> 0 then GUISetState(@SW_SHOW, $hGUI) While 1 Local $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE GUIDelete($hGUI) ExitLoop EndSwitch WEnd EndIf EndFunc ; sampleGUICreateOnMonitor(1, True, "Sample GUI", 400, 300, "center", "center") ; sampleGUICreateOnMonitor(1, True, "Sample GUI", "max", "max")
    1 point
  45. jugador

    AutoIt Snippets

    reduce the use of global variables __ExampleA() Func __ExampleA() __Get_Global() __Get_Global('add', 'Msg', 'Is it working?') __Print() __Get_Global('CLose') EndFunc Func __Print() ConsoleWrite('!: ' & __Get_Global('get', 'Msg') & @crlf) EndFunc ; #FUNCTION# ============================================================================= ; Name ..........: __Get_Global ; ======================================================================================== Func __Get_Global($method = -1, $sKey = '', $sValue = '') Local Static $o_SDist If Not IsObj($o_SDist) Then $o_SDist = ObjCreate( "Scripting.Dictionary" ) If Not IsObj($o_SDist) Then Return SetError(1) Endif IF (($method = 'add') AND ($sKey <> '')) Then If $o_SDist.Exists($sKey) Then Return $o_SDist.Add($sKey, $sValue) EndIf IF (($method = 'get') AND ($sKey <> '')) Then Return $o_SDist.Item($sKey) IF $method = 'CLose' Then $o_SDist = 0 EndFunc
    1 point
  46. Nine

    AutoIt Snippets

    Here another approach to display large MsgBox (based only on mouse). I had this code for WMI when lots of properties need to be shown : #include <Constants.au3> #include <WinAPIProc.au3> #include <WinAPISys.au3> #include <WindowsConstants.au3> #include <WinAPIConstants.au3> Opt("MustDeclareVars", True) Global Const $tagMOUSEHOOKSTRUCT = $tagPOINT & ";hwnd hwnd;uint wHitTestCode;ulong_ptr dwExtraInfo;dword mouseData;" Global $hHook Example() Func Example() Local $hStub = DllCallbackRegister(WH_MOUSE, "LRESULT", "int;wparam;lparam") $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE, DllCallbackGetPtr($hStub), 0, _WinAPI_GetCurrentThreadId()) Local $sList = "First line here" & @CR For $i = 2 To 200 $sList &= "Line " & $i & @CR Next $sList &= "Last line here" Local $iRep = MsgBox($MB_OKCANCEL, "Example", $sList) _WinAPI_UnhookWindowsHookEx($hHook) DllCallbackFree($hStub) EndFunc ;==>Example Func WH_MOUSE($iMsg, $wParam, $lParam) If $iMsg Then Return _WinAPI_CallNextHookEx($hHook, $iMsg, $wParam, $lParam) Local $tMouse = DllStructCreate($tagMOUSEHOOKSTRUCT, $lParam) Local $hWnd = _WinAPI_GetAncestor($tMouse.hwnd, $GA_ROOT) If $wParam = $WM_MOUSEWHEEL Then Local $iDir = _WinAPI_HiWord($tMouse.mouseData) WinMove($hWnd, "", WinGetPos($hWnd)[0], WinGetPos($hWnd)[1] + ($iDir / 3)) ElseIf $wParam = $WM_LBUTTONDOWN Then If $tMouse.hwnd = $hWnd Then WinMove($hWnd, "", WinGetPos($hWnd)[0], 0) ElseIf $wParam = $WM_RBUTTONDOWN Then WinMove($hWnd, "", WinGetPos($hWnd)[0], @DesktopHeight - WinGetPos($hWnd)[3] - 50) EndIf Return _WinAPI_CallNextHookEx($hHook, $iMsg, $wParam, $lParam) EndFunc ;==>WH_MOUSE Left click will bring you to top Right click will bring you to bottom Mouse wheel to scroll the MsgBox Enjoy !
    1 point
  47. This UDF brings the power and flexibility of jq to AutoIt scripts. jq is an open-source, powerful, and flexible command-line based JSON processor. As it says on their website, jq is like 'sed' for JSON. jq can be used for the simplest of tasks like retrieving JSON objects and values (parsing), to very advanced JSON processing using its numerous built-in functions and conditional processing. Its built-in functions can handle math, selection, conditional processing, mapping, object and array manipulation, flattening, reduction, grouping, and much more. You can even create your own jq functions. You can learn more about jq and even play with it in real-time, using jq's online jq playground, all on their website. Here and some helpful links to get you more familiar with jq, what can be done with it, its built-in functions, and its syntax. jq Website: https://jqlang.github.io/jq/ jq Manual: https://jqlang.github.io/jq/manual/ jqWiki (FAQ, Cookbook, Advanced Topics) https://github.com/jqlang/jq/wiki jq is a single 32 or 64 bit executable that has no other dependencies. Just like using the SQLite UDF, the only requirement to use this UDF is that the jq executable reside in a location in which the UDF can execute it. The latest win32 & win64 versions have been included in the UDF download. You can always get newer versions from the jq website. jq at a high level Like 'sed', jq reads JSON in, either through STDIN or one or more files, processes it thru one or more "filters", and outputs the results. You can, optionally, supply "options" that affect how it reads the input, where it gets its "filters", and how it writes its output. It looks a little like this: JSON ---> jq processor (using supplied filters and options) ---> Output So in jq lingo, you basically use "Filters" to tell jq what you want it to do. So in the UDF file, that is why the main functions ( _jqExec() and _jqExecFile() ) refer to filters and options. Please make note that jq works with relatively strict JSON. This means that all JSON read must be conform to the standard. Luckily, jq is pretty good at identifying where a format error exists in non standard JSON. The jq UDF There are 2 main funtions in the UDF file, _jqExec and jqExecFile. With these 2 functions, you can pretty much do anything that jq can do. The only difference between to two functions is whether the JSON is supplied by a string or a file. The 2 primary functions simply call the jq executable with the supplied information, after properly formatting the parameters. There are additional functions in the UDF to easily pretty-print your json, compact-print your json, dump the json data with its associated paths, and see if specific JSON keys exist, but they all just execute the _jqExec or _jqExecFile function with the proper filter. There are also a couple of extra functions to display what version of the UDF and jq executable you are currently using. There are also a couple of functions to enable and disable logging of jq information for debugging purposes. Most of the jq UDF file functions return an @error if unsuccessful. Some also include @extended info. Please see the actual function headers for more information on their usage and return values. The 2 primary functions below just format your jq request and pass it on the jq executable. The functions will also properly escape double quotes (") that are used in the filter. For most simple tasks, you just need to supply the JSON source and a filter. _jqExec($sJson, $sFilter, $sOptions = Default, $sWorkingDir = Default) Or _jqExecFile($sJsonFile, $sFilter, $sOptions = Default, $sWorkingDir = Default) Using jq in your script As stated earlier, the jq executable must reside somewhere where the script can locate and execute it. The _jqInit() function always has to be executed before any jq processing occurs. _jqInit() merely locates the executable or uses the supplied path. It also clears any previous debug log. The jq UDF folder contains a jq example script that has several examples to how to do some of the most common JSON processing tasks. Here are a few examples to get you started: How to pretty-print some JSON #include "jq.au3" ;_jqInit is only needed if the jq executale is not in the PATH or @ScriptDir _jqInit() If @error Then Exit ConsoleWrite("ERROR: Unable to initialize jq - @error = " & @error & @CRLF) $sJson = '{"fruits":[{"Apple":{"color":"Red","season":"Fall"}}, {"Banana":{"color":"Yellow","season":"Summer"}}]}' $sCmdOutput = _jqPrettyPrintJson($sJson) ConsoleWrite(@CRLF & "Pretty-Print JSON" & @CRLF & $sCmdOutput & @CRLF) How to compact-print some JSON #include "jq.au3" ;Initialize jq environment _jqInit() If @error Then Exit ConsoleWrite("ERROR: Unable to initialize jq - @error = " & @error & @CRLF) $sJson = '{ "fruits" : [{"Apple" : {"color":"Red","season":"Fall"}}, {"Banana":{"color":"Yellow","season":"Summer"}}]}' $sCmdOutput = _jqCompactPrintJson($sJson) ConsoleWrite(@CRLF & "Compact-Print JSON" & @CRLF & $sCmdOutput & @CRLF) Dump JSON data (paths and values) #include "jq.au3" ;Initialize jq environment _jqInit() If @error Then Exit ConsoleWrite("ERROR: Unable to initialize jq - @error = " & @error & @CRLF) $sJson = '{ "fruits" : [{"Apple" : {"color":"Red","season":"Fall"}}, {"Banana":{"color":"Yellow","season":"Summer"}}]}' $sCmdOutput = _jqDump($sJson) ConsoleWrite(@CRLF & "Dump JSON paths and values" & @CRLF & $sCmdOutput & @CRLF) How to GET JSON values #include "jq.au3" ;Initialize jq environment _jqInit() If @error Then Exit ConsoleWrite("ERROR: Unable to initialize jq - @error = " & @error & @CRLF) $sJson = '{"Apple" : {"color":"Red","season":"Fall"}, "Banana":{"color":"Yellow","season":"Summer"}}' $sFilter = '.Banana.color' $sCmdOutput = _jqExec($sJson, $sFilter) ConsoleWrite("Get color of banana" & @CRLF) ConsoleWrite("Input: : " & _jqCompactPrintJson($sJson) & @CRLF) ConsoleWrite("Filter : " & $sFilter & @CRLF) ConsoleWrite("Output : " & $sCmdOutput & @CRLF) or #include "jq.au3" ;Initialize jq environment _jqInit() If @error Then Exit ConsoleWrite("ERROR: Unable to initialize jq - @error = " & @error & @CRLF) $sJson = '{"Apple" : {"color":"Red","season":"Fall"}, "Banana":{"color":"Yellow","season":"Summer"}}' $sFilter = 'getpath(["Banana", "color"])' $sCmdOutput = _jqExec($sJson, $sFilter) ConsoleWrite("Get color of banana" & @CRLF) ConsoleWrite("Input: : " & _jqCompactPrintJson($sJson) & @CRLF) ConsoleWrite("Filter : " & $sFilter & @CRLF) ConsoleWrite("Output : " & $sCmdOutput & @CRLF) Check for the existence of a key #include "jq.au3" ;Initialize jq environment _jqInit() If @error Then Exit ConsoleWrite("ERROR: Unable to initialize jq - @error = " & @error & @CRLF) $sJson = '{"Apple":{"color":"Red","season":"Fall"}, "Banana":{"color":"Yellow","season":"Summer"}}' $sFilter = '.Banana | has("color")' $sCmdOutput = _jqExec($sJson, $sFilter) ConsoleWrite("Check for existence of color key within Banana object" & @CRLF) ConsoleWrite("Input: : " & _jqCompactPrintJson($sJson) & @CRLF) ConsoleWrite("Filter : " & $sFilter & @CRLF) ConsoleWrite("Output : " & $sCmdOutput & @CRLF) Count of how many Items in an object #include "jq.au3" ;Initialize jq environment _jqInit() If @error Then Exit ConsoleWrite("ERROR: Unable to initialize jq - @error = " & @error & @CRLF) $sJson = '{"Apple":{"color":"Red"}, "Banana":{"color":"Yellow","season":"Summer"}}' $sFilter = '.Banana | length' $sCmdOutput = _jqExec($sJson, $sFilter) ConsoleWrite("How many items in the Banana object" & @CRLF) ConsoleWrite("Input: : " & _jqCompactPrintJson($sJson) & @CRLF) ConsoleWrite("Filter : " & $sFilter & @CRLF) ConsoleWrite("Output : " & $sCmdOutput & @CRLF) How to PUT/Create/Modify JSON #include "jq.au3" ;Initialize jq environment _jqInit() If @error Then Exit ConsoleWrite("ERROR: Unable to initialize jq - @error = " & @error & @CRLF) $sInput = "" $sFilter = 'setpath(["Apple","color"];"Red") | setpath(["Banana","color"];"Yellow") | setpath(["Banana","season"];"Summer")' $sOptions = '-n' ;required if no input supplied $sCmdOutput = _jqExec($sInput, $sFilter, $sOptions) ConsoleWrite("Update/Create JSON" & @CRLF) ConsoleWrite("Filter : " & $sFilter & @CRLF) ConsoleWrite("Output : " & @CRLF & $sCmdOutput & @CRLF) List all of the fruits (top-level keys) #include "jq.au3" ;Initialize jq environment _jqInit() If @error Then Exit ConsoleWrite("ERROR: Unable to initialize jq - @error = " & @error & @CRLF) $sJson = '{"Apple":{"color":"Red"}, "Banana":{"color":"Yellow","season":"Summer"}}' $sFilter = 'keys | .[]' $sCmdOutput = _jqExec($sJson, $sFilter) ConsoleWrite("List all top-level keys (fruits)" & @CRLF) ConsoleWrite("Input : " & $sJson & @CRLF) ConsoleWrite("Filter : " & $sFilter & @CRLF) ConsoleWrite("Output : " & @CRLF & $sCmdOutput & @CRLF) Calculate the sum of all of the objects' price * qty #include "jq.au3" ;Initialize jq environment _jqInit() If @error Then Exit ConsoleWrite("ERROR: Unable to initialize jq - @error = " & @error & @CRLF) $sJson = '[{"id":1,"price":20.00,"qty":10},{"id":2,"price":15.00,"qty":20.25},{"id":3,"price":10.50,"qty":30}]' $sFilter = 'map(.price * .qty) | add' $sCmdOutput = _jqExec($sJson, $sFilter) ConsoleWrite("Calculate the sum of all of the objects' price * qty" & @CRLF) ConsoleWrite("Input : " & $sJson & @CRLF) ConsoleWrite("Filter : " & $sFilter & @CRLF) ConsoleWrite("Output : " & $sCmdOutput & @CRLF) The examples above, and the ones in the example files, merely scratch the surface of what jq can do. It may look intimidating at first but it really isn't that bad once you start playing with it. You can find several more examples and play around with them or create your own using jqPlayground. jqPlayground is a separate, stand alone, interactive tool for creating, testing and learning JSON processing using jq. If you have any questions regarding the UDF, or how to perform a certain task using jq, I'll try my best to answer them. Since jq has been around for a while now, there's also several jq-related questions and answers on StackOverflow. >>> Download the UDF in the Files Section <<<
    1 point
  48. UEZ

    Tester needed ^^

    @argumentum I hope you don't mind me doing something similar in parallel. I would like to test the code on different OS, need your support. It would make sense to have 2+ monitors, if possible with > 96 DPI. I don't know from which os it is possible to set different DPIs per monitor (WIn10+?). I tested it on Win11 22H2 and worked properly on 3 monitors with 3 different DPIs (left 100%, middle 125 % (main), right 150%). Just run the code and move the GUI over all your monitors. Theoretically the GUI should be adjusted accordingly. _WinAPI_DPI.au3: ;Coded by UEZ build 2023-08-15 beta #include-once #include <GDIPlus.au3> #include <Misc.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 Global Const $DPI_AWARENESS_CONTEXT_UNAWARE = $DPI_AWARENESS_UNAWARE - 1 Global Const $DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = $DPI_AWARENESS_UNAWARE - 2 Global Const $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = $DPI_AWARENESS_UNAWARE - 3 Global Const $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = $DPI_AWARENESS_UNAWARE - 4 Global Const $DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = $DPI_AWARENESS_UNAWARE - 5 ; 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 #EndRegion DPI Constants #Region WinAPI DPI ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-adjustwindowrectexfordpi Func _WinAPI_AdjustWindowRectExForDpi($dpi, $dwStyle, $dwExStyle, $bMenu = False) Local $tRECT = DllStructCreate($tagRECT) Local $aResult = DllCall("user32.dll", "bool", "AdjustWindowRectExForDpi", "struct*", $tRECT, "dword", $dwStyle, "bool", $bMenu, "dword", $dwExStyle, "int", $dpi) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If $aResult[0] Then Return SetError(2, @extended, 0) Return $tRECT EndFunc ;==>_WinAPI_AdjustWindowRectExForDpi ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfofordpi Func _WinAPI_SystemParametersInfoForDpi($uiAction, $uiParam, $pvParam, $fWinIni, $dpi) Local $aResult = DllCall("user32.dll", "bool", "SystemParametersInfoForDpi", "uint", $uiAction, "uint", $uiParam, "struct*", $pvParam, "uint", $fWinIni, "uint", $dpi) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] 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) ;requires Win10 v1803+ / Windows Server 2016+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_InheritWindowMonitor ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-isvaliddpiawarenesscontext Func _WinAPI_IsValidDpiAwarenessContext($DPI_AWARENESS_CONTEXT_value) Local $aResult = DllCall("user32.dll", "bool", "IsValidDpiAwarenessContext", @AutoItX64 ? "int64" : "int", $DPI_AWARENESS_CONTEXT_value) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_IsValidDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-logicaltophysicalpointforpermonitordpi Func _WinAPI_LogicalToPhysicalPointForPerMonitorDPI($hWnd) Local $tPOINT = DllStructCreate($tagPOINT) Local $aResult = DllCall("user32.dll", "bool", "LogicalToPhysicalPointForPerMonitorDPI", "hwnd", $hWnd, "struct*", $tPOINT) ;requires Win 8.1+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $tPOINT EndFunc ;==>_WinAPI_LogicalToPhysicalPointForPerMonitorDPI ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-physicaltologicalpointforpermonitordpi Func _WinAPI_PhysicalToLogicalPointForPerMonitorDPI($hWnd) Local $tPOINT = DllStructCreate($tagPOINT) Local $aResult = DllCall("user32.dll", "bool", "PhysicalToLogicalPointForPerMonitorDPI", "hwnd", $hWnd, "struct*", $tPOINT) ;requires Win 8.1+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $tPOINT EndFunc ;==>_WinAPI_PhysicalToLogicalPointForPerMonitorDPI Func _GDIPlus_GetDPI($hGUI = 0) _GDIPlus_Startup() Local $hGfx = _GDIPlus_GraphicsCreateFromHWND($hGUI) If @error Then Return SetError(1, @extended, 0) Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0) If @error Then Return SetError(2, @extended, 0) _GDIPlus_GraphicsDispose($hGfx) _GDIPlus_Shutdown() Return $aResult[2] EndFunc ;==>_GDIPlus_GetDPI Func _WinAPI_GetDPI($hWnd = 0) $hWnd = Not $hWnd ? _WinAPI_GetDesktopWindow() : $hWnd Local Const $hDC = _WinAPI_GetDC($hWnd) If @error Then Return SetError(1, 0, 0) Local Const $iDPI = _WinAPI_GetDeviceCaps($hDC, $LOGPIXELSX) If @error Or Not $iDPI Then _WinAPI_ReleaseDC($hWnd, $hDC) Return SetError(2, 0, 0) EndIf _WinAPI_ReleaseDC($hWnd, $hDC) Return $iDPI EndFunc ;==>_WinAPI_GetDPI ;https://learn.microsoft.com/en-us/windows/win32/api/shellscalingapi/nf-shellscalingapi-getdpiformonitor Func _WinAPI_GetDpiForPrimaryMonitor($hMOnitor = 0, $dpiType = $MDT_DEFAULT) If $hMOnitor = 0 Then Local $aMonitors = _WinAPI_EnumDisplayMonitors() If @error Or Not IsArray($aMonitors) Then Return SetError(1, 0, 0) Local $i For $i = 1 To $aMonitors[0][0] If _WinAPI_GetMonitorInfo($aMonitors[$i][0])[2] = 1 Then $hMOnitor = $aMonitors[$i][0] ExitLoop EndIf Next EndIf Local $tx = DllStructCreate("int dpiX"), $tY = DllStructCreate("int dpiY") Local $aResult = DllCall("Shcore.dll", "long", "GetDpiForMonitor", "handle", $hMOnitor, "long", $dpiType, "struct*", $tx, "struct*", $tY) If @error Or Not IsArray($aResult) Then Return SetError(2, 0, 0) Return $tx.dpiX EndFunc ;==>_WinAPI_GetDpiForPrimaryMonitor ;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) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) 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") ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDpiForSystem ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getthreaddpiawarenesscontext Func _WinAPI_GetThreadDpiAwarenessContext() Local $aResult = DllCall("user32.dll", "uint", "GetThreadDpiAwarenessContext") ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetThreadDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpifromdpiawarenesscontext Func _WinAPI_GetDpiFromDpiAwarenessContext($DPI_AWARENESS_CONTEXT_value) Local $aResult = DllCall("user32.dll", "uint", "GetDpiFromDpiAwarenessContext", @AutoItX64 ? "int64" : "int", $DPI_AWARENESS_CONTEXT_value) ;requires Win10 v1803+ / Windows Server 2016+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDpiFromDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getawarenessfromdpiawarenesscontext Func _WinAPI_GetAwarenessFromDpiAwarenessContext($DPI_AWARENESS_CONTEXT_value) Local $aResult = DllCall("user32.dll", "uint", "GetAwarenessFromDpiAwarenessContext", @AutoItX64 ? "int64" : "int", $DPI_AWARENESS_CONTEXT_value) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetAwarenessFromDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpiawarenesscontextforprocess Func _WinAPI_GetDpiAwarenessContextForProcess($hProcess) Local $aResult = DllCall("user32.dll", "uint", "GetDpiAwarenessContextForProcess", "handle", $hProcess) ;requires Win10 v1803+ / Windows Server 2016+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDpiAwarenessContextForProcess ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemdpiforprocess Func _WinAPI_GetSystemDpiForProcess($hProcess) Local $aResult = DllCall("user32.dll", "uint", "GetSystemDpiForProcess", "handle", $hProcess) ;requires Win10 v1803+ / Windows Server 2016+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 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", "uint", "GetWindowDpiAwarenessContext", "hwnd", $hWnd) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetWindowDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setprocessdpiawarenesscontext Func _WinAPI_SetProcessDpiAwarenessContext($DPI_AWARENESS_CONTEXT_value) Local $aResult = DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", $DPI_AWARENESS_CONTEXT_value) ;requires Win10 v1703+ / Windows Server 2016+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setthreaddpiawarenesscontext Func _WinAPI_SetThreadDpiAwarenessContext($DPI_AWARENESS_CONTEXT_value) Local $aResult = DllCall("user32.dll", "uint", "SetThreadDpiAwarenessContext", @AutoItX64 ? "int64" : "int", $DPI_AWARENESS_CONTEXT_value) ;requires Win10 v1703+ / Windows Server 2016+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_SetThreadDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness Func _WinAPI_SetProcessDpiAwareness($PROCESS_DPI_AWARENESS = $DPI_AWARENESS_PER_MONITOR_AWARE) Local $aResult = DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $PROCESS_DPI_AWARENESS) ;requires Win 8.1+ / Server 2012 R2+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If $aResult[0] Then Return SetError(2, $aResult[0], 0) Return $aResult[0] ;0 is S_OK EndFunc ;==>_WinAPI_SetProcessDpiAwareness Func _WinAPI_SetDPIAwareness($DPIAwareContext = $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE, $iMode = 1) Switch @OSBuild Case 6000 To 9199 Local $aResult = DllCall("user32.dll", "bool", "SetProcessDPIAware") ;requires Vista+ / Server 2008+ If Not $aResult[0] Then Return SetError(1, 0, 0) Case 9200 To 13999 $DPIAwareContext = ($DPIAwareContext < 0) ? 0 : ($DPIAwareContext > 2) ? 2 : $DPIAwareContext _WinAPI_SetProcessDpiAwareness($DPIAwareContext) If @error Then Return SetError(2, @error, 0) Case @OSBuild > 13999 $DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext $iMode = ($iMode < 1) ? 1 : ($iMode > 2) ? 2 : $iMode Local $iResult Switch $iMode Case 1 $iResult = _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext) If Not $iResult Or @error Then Return SetError(3, 0, 0) Case 2 #cs Return DPI_AWARENESS_CONTEXT values $DPI_AWARENESS_CONTEXT_UNAWARE = 0x6010 / 24592 $DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = 0x9011 / 36881 $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = 0x12 / 18 $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = 0x22 / 34 $DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = 0x40006010 / 1073766416 #ce $iResult = _WinAPI_SetThreadDpiAwarenessContext($DPIAwareContext) If Not $iResult Or @error Then Return SetError(4, 0, 0) EndSwitch EndSwitch Local $iDPI If @OSBuild < 9200 Then $iDPI = _WinAPI_GetDPI() If @error Or Not $iDPI Then Return SetError(5, 0, 0) Else $iDPI = _WinAPI_GetDpiForPrimaryMonitor() If @error Or Not $iDPI Then Return SetError(6, 0, 0) EndIf Return $iDPI EndFunc ;==>_WinAPI_SetDPIAwareness #EndRegion WinAPI DPI Example.au3: ; AutoIt GUI Example ; Created: 17/01/2005 - CyberSlug ; Modifed: 05/12/2011 - guinness ; Modifed: 09/06/2014 - mLipok ; Modifed: 15/10/2018 - mLipok ; Modifed: 14/08/2023 - UEZ #AutoIt3Wrapper_Change2CUI=n #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/so #AutoIt3Wrapper_Res_HiDpi=n ;must be n otherwise _WinAPI_SetDPIAwareness() function will fail! #AutoIt3Wrapper_UseX64=n #Region INCLUDE #include <AVIConstants.au3> #include <GuiConstantsEx.au3> #include <TreeViewConstants.au3> #include <Array.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WinAPIGdiDC.au3> #include <WindowsConstants.au3> #include "_WinAPI_DPI.au3" #EndRegion INCLUDE #Region INITIALIZATION and EXIT Global $aCtrl[43][6], $ahWnd[2][10], $g_iDPI_ratio1, $g_iDPI_ratio2, $iw = 400, $ih = 200 _Example() ; Finished! #EndRegion INITIALIZATION and EXIT Func _Example() Local $AWARENESS Switch @OSBuild Case 9200 To 13999 $AWARENESS = $DPI_AWARENESS_PER_MONITOR_AWARE Case @OSBuild > 13999 $AWARENESS = $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 EndSwitch Local $iDPI = _WinAPI_SetDPIAwareness($AWARENESS, 2), $iDPI_def = 96 If $iDPI = 0 Then Exit MsgBox($MB_ICONERROR, "ERROR", "Unable to set DPI awareness!!!", 10) $g_iDPI_ratio1 = $iDPI / $iDPI_def $g_iDPI_ratio2 = $iDPI_def / $iDPI #Region GUI Local $sPath = RegRead("HKLM\SOFTWARE\" & (@AutoItX64 ? "WOW6432Node\" : "") & "AutoIt v3\AutoIt", "InstallDir") $sPath = ($sPath = "" ? @ProgramFilesDir & "\AutoIt3\" : $sPath & "\") ;assume default path $ahWnd[0][1] = 8.5 * $g_iDPI_ratio1 $ahWnd[0][0] = GUICreate("DPI Sample GUI", 400 * $g_iDPI_ratio1, 400 * $g_iDPI_ratio1) GUISetIcon(@SystemDir & "\mspaint.exe", 0) GUISetFont($ahWnd[0][1], 400, 0, "Arial", $ahWnd[0][0], $CLEARTYPE_QUALITY) #EndRegion GUI #Region MENU $aCtrl[1][0] = GUICtrlCreateMenu("Menu &One") $aCtrl[2][0] = GUICtrlCreateMenu("Menu &Two") $aCtrl[3][0] = GUICtrlCreateMenu("Menu Th&ree") $aCtrl[4][0] = GUICtrlCreateMenu("Menu &Four") GUICtrlCreateMenuItem('SubMenu One &A', $aCtrl[1][0]) GUICtrlCreateMenuItem('SubMenu One &B', $aCtrl[1][0]) #EndRegion MENU #Region CONTEXT MENU $aCtrl[5][0] = GUICtrlCreateContextMenu() GUICtrlCreateMenuItem("Context Menu", $aCtrl[5][0]) GUICtrlCreateMenuItem("", $aCtrl[5][0]) ; Separator GUICtrlCreateMenuItem("&Properties", $aCtrl[5][0]) #EndRegion CONTEXT MENU #Region PIC $aCtrl[6][2] = 0 ;x $aCtrl[6][3] = 0 ;y $aCtrl[6][4] = 169 ;w $aCtrl[6][5] = 68 ;h $aCtrl[6][0] = GUICtrlCreatePic($sPath & "Examples\GUI\logo4.gif", $aCtrl[6][2] * $g_iDPI_ratio1, $aCtrl[6][3] * $g_iDPI_ratio1, $aCtrl[6][4] * $g_iDPI_ratio1, $aCtrl[6][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region PIC') $aCtrl[7][2] = 75 $aCtrl[7][3] = 1 $aCtrl[7][4] = 80 $aCtrl[7][5] = 16 $aCtrl[7][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[7][0] = GUICtrlCreateLabel("Sample Pic", $aCtrl[7][2] * $g_iDPI_ratio1, $aCtrl[7][3] * $g_iDPI_ratio1, $aCtrl[7][4] * $g_iDPI_ratio1, $aCtrl[7][5] * $g_iDPI_ratio1) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) GUICtrlSetColor(-1, 0xFFFFFF) GUICtrlSetFont(-1, $aCtrl[7][1] * $g_iDPI_ratio1) #EndRegion PIC #Region AVI $aCtrl[8][2] = 180 $aCtrl[8][3] = 10 $aCtrl[8][4] = 32 $aCtrl[8][5] = 32 $aCtrl[8][0] = GUICtrlCreateAvi($sPath & "Examples\GUI\SampleAVI.avi", 0, $aCtrl[8][2] * $g_iDPI_ratio1, $aCtrl[8][3] * $g_iDPI_ratio1, $aCtrl[8][4] * $g_iDPI_ratio1, $aCtrl[8][5] * $g_iDPI_ratio1, $ACS_AUTOPLAY) GUICtrlSetTip(-1, '#Region AVI') ; TODO $aCtrl[9][2] = 175 $aCtrl[9][3] = 50 $aCtrl[9][4] = 50 $aCtrl[9][5] = 12 $aCtrl[9][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[9][0] = GUICtrlCreateLabel("Sample avi", $aCtrl[9][2] * $g_iDPI_ratio1, $aCtrl[9][3] * $g_iDPI_ratio1, $aCtrl[9][4] * $g_iDPI_ratio1, $aCtrl[9][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region AVI - Label') GUICtrlSetFont(-1, $aCtrl[9][1] * $g_iDPI_ratio1) #EndRegion AVI #Region TAB $aCtrl[10][2] = 240 $aCtrl[10][3] = 0 $aCtrl[10][4] = 150 $aCtrl[10][5] = 70 $aCtrl[10][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[10][0] = GUICtrlCreateTab($aCtrl[10][2] * $g_iDPI_ratio1, $aCtrl[10][3] * $g_iDPI_ratio1, $aCtrl[10][4] * $g_iDPI_ratio1, $aCtrl[10][5] * $g_iDPI_ratio1) GUICtrlSetFont(-1, $aCtrl[10][1] * $g_iDPI_ratio1) $aCtrl[11][0] = GUICtrlCreateTabItem("One") GUICtrlSetTip(-1, '#Region TAB1') $aCtrl[12][2] = 244 $aCtrl[12][3] = 35 $aCtrl[12][4] = 140 $aCtrl[12][5] = 24 $aCtrl[12][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[12][0] = GUICtrlCreateLabel("Sample Tab with TabItems", $aCtrl[12][2] * $g_iDPI_ratio1, $aCtrl[12][3] * $g_iDPI_ratio1, $aCtrl[12][4] * $g_iDPI_ratio1, $aCtrl[12][5] * $g_iDPI_ratio1) GUICtrlSetFont(-1, $aCtrl[12][1] * $g_iDPI_ratio1) $aCtrl[13][0] = GUICtrlCreateTabItem("Two") GUICtrlSetTip(-1, '#Region TAB2') $aCtrl[14][0] = GUICtrlCreateTabItem("Three") GUICtrlSetTip(-1, '#Region TAB3') GUICtrlCreateTabItem("") #EndRegion TAB #Region COMBO $aCtrl[15][2] = 250 $aCtrl[15][3] = 80 $aCtrl[15][4] = 120 $aCtrl[15][5] = 100 $aCtrl[15][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[15][0] = GUICtrlCreateCombo("Sample Combo", $aCtrl[15][2] * $g_iDPI_ratio1, $aCtrl[15][3] * $g_iDPI_ratio1, $aCtrl[15][4] * $g_iDPI_ratio1, $aCtrl[15][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region COMBO') GUICtrlSetFont(-1, $aCtrl[15][1] * $g_iDPI_ratio1) #EndRegion COMBO #Region PROGRESS $aCtrl[16][2] = 60 $aCtrl[16][3] = 80 $aCtrl[16][4] = 150 $aCtrl[16][5] = 20 $aCtrl[16][0] = GUICtrlCreateProgress($aCtrl[16][2] * $g_iDPI_ratio1, $aCtrl[16][3] * $g_iDPI_ratio1, $aCtrl[16][4] * $g_iDPI_ratio1, $aCtrl[16][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region PROGRES') GUICtrlSetData(-1, 60) $aCtrl[17][2] = 5 $aCtrl[17][3] = 82 $aCtrl[17][4] = 50 $aCtrl[17][5] = 18 $aCtrl[17][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[17][0] = GUICtrlCreateLabel("Progress:", $aCtrl[17][2] * $g_iDPI_ratio1, $aCtrl[17][3] * $g_iDPI_ratio1, $aCtrl[17][4] * $g_iDPI_ratio1, $aCtrl[17][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region PROGRES - Label') GUICtrlSetFont(-1, $aCtrl[17][1] * $g_iDPI_ratio1) #EndRegion PROGRESS #Region EDIT $aCtrl[18][2] = 10 $aCtrl[18][3] = 110 $aCtrl[18][4] = 150 $aCtrl[18][5] = 70 $aCtrl[18][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[18][0] = GUICtrlCreateEdit(@CRLF & " Sample Edit Control", $aCtrl[18][2] * $g_iDPI_ratio1, $aCtrl[18][3] * $g_iDPI_ratio1, $aCtrl[18][4] * $g_iDPI_ratio1, $aCtrl[18][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region EDIT') GUICtrlSetFont(-1, $aCtrl[18][1] * $g_iDPI_ratio1) #EndRegion EDIT #Region LIST $aCtrl[19][2] = 5 $aCtrl[19][3] = 190 $aCtrl[19][4] = 100 $aCtrl[19][5] = 90 $aCtrl[19][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[19][0] = GUICtrlCreateList("", $aCtrl[19][2] * $g_iDPI_ratio1, $aCtrl[19][3] * $g_iDPI_ratio1, $aCtrl[19][4] * $g_iDPI_ratio1, $aCtrl[19][5] * $g_iDPI_ratio1) GUICtrlSetFont(-1, $aCtrl[19][1] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region LIST') GUICtrlSetData(-1, "A.Sample|B.List|C.Control|D.Here", "B.List") #EndRegion LIST #Region ICON $aCtrl[20][2] = 175 $aCtrl[20][3] = 120 $aCtrl[20][4] = 32 $aCtrl[20][5] = 32 $aCtrl[20][0] = GUICtrlCreateIcon("explorer.exe", 0, $aCtrl[20][2] * $g_iDPI_ratio1, $aCtrl[20][3] * $g_iDPI_ratio1, $aCtrl[20][4] * $g_iDPI_ratio1, $aCtrl[20][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region ICON') $aCtrl[21][2] = 180 $aCtrl[21][3] = 160 $aCtrl[21][4] = 50 $aCtrl[21][5] = 20 $aCtrl[21][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[21][0] = GUICtrlCreateLabel("Icon", $aCtrl[21][2] * $g_iDPI_ratio1, $aCtrl[21][3] * $g_iDPI_ratio1, $aCtrl[21][4] * $g_iDPI_ratio1, $aCtrl[21][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region ICON - Label') GUICtrlSetFont(-1, $aCtrl[21][1] * $g_iDPI_ratio1) #EndRegion ICON #Region LIST VIEW $aCtrl[22][2] = 110 $aCtrl[22][3] = 190 $aCtrl[22][4] = 110 $aCtrl[22][5] = 80 $aCtrl[22][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[22][0] = GUICtrlCreateListView("Sample|ListView|", $aCtrl[22][2] * $g_iDPI_ratio1, $aCtrl[22][3] * $g_iDPI_ratio1, $aCtrl[22][4] * $g_iDPI_ratio1, $aCtrl[22][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region LIST VIEW') GUICtrlSetFont(-1, $aCtrl[22][1] * $g_iDPI_ratio1) GUICtrlCreateListViewItem("A|One", $aCtrl[22][0]) GUICtrlCreateListViewItem("B|Two", $aCtrl[22][0]) GUICtrlCreateListViewItem("C|Three", $aCtrl[22][0]) #EndRegion LIST VIEW #Region GROUP WITH RADIO BUTTONS $aCtrl[23][2] = 230 $aCtrl[23][3] = 120 $aCtrl[23][4] = 110 $aCtrl[23][5] = 80 $aCtrl[23][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[23][0] = GUICtrlCreateGroup("Sample Group", $aCtrl[23][2] * $g_iDPI_ratio1, $aCtrl[23][3] * $g_iDPI_ratio1, $aCtrl[23][4] * $g_iDPI_ratio1, $aCtrl[23][5] * $g_iDPI_ratio1) GUICtrlSetFont(-1, $aCtrl[22][1] * $g_iDPI_ratio1) $aCtrl[24][2] = 250 $aCtrl[24][3] = 140 $aCtrl[24][4] = 80 $aCtrl[24][5] = 32 $aCtrl[24][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[24][0] = GUICtrlCreateRadio("Radio One", $aCtrl[24][2] * $g_iDPI_ratio1, $aCtrl[24][3] * $g_iDPI_ratio1, $aCtrl[24][4] * $g_iDPI_ratio1, $aCtrl[24][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region GROUP WITH RADIO BUTTONS- RADIO1') GUICtrlSetFont(-1, $aCtrl[24][1] * $g_iDPI_ratio1) GUICtrlSetState(-1, $GUI_CHECKED) $aCtrl[25][2] = 250 $aCtrl[25][3] = 165 $aCtrl[25][4] = 80 $aCtrl[25][5] = 32 $aCtrl[25][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[25][0] = GUICtrlCreateRadio("Radio Two", $aCtrl[25][2] * $g_iDPI_ratio1, $aCtrl[25][3] * $g_iDPI_ratio1, $aCtrl[25][4] * $g_iDPI_ratio1, $aCtrl[25][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region GROUP WITH RADIO BUTTONS- RADIO2') GUICtrlSetFont(-1, $aCtrl[25][1] * $g_iDPI_ratio1) GUICtrlCreateGroup("", -99, -99, 1, 1) ;close group #EndRegion GROUP WITH RADIO BUTTONS #Region UPDOWN $aCtrl[26][2] = 350 $aCtrl[26][3] = 113 $aCtrl[26][4] = 40 $aCtrl[26][5] = 12 $aCtrl[26][1] = 8 * $g_iDPI_ratio2 $aCtrl[26][0] = GUICtrlCreateLabel("UpDown", $aCtrl[26][2] * $g_iDPI_ratio1, $aCtrl[26][3] * $g_iDPI_ratio1, $aCtrl[26][4] * $g_iDPI_ratio1, $aCtrl[26][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region UPDOWN - Label') GUICtrlSetFont(-1, $aCtrl[26][1] * $g_iDPI_ratio1) $aCtrl[27][2] = 350 $aCtrl[27][3] = 130 $aCtrl[27][4] = 40 $aCtrl[27][5] = 20 $aCtrl[27][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[27][0] = GUICtrlCreateInput("42", $aCtrl[27][2] * $g_iDPI_ratio1, $aCtrl[27][3] * $g_iDPI_ratio1, $aCtrl[27][4] * $g_iDPI_ratio1, $aCtrl[27][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region UPDOWN - Input') GUICtrlSetFont(-1, $aCtrl[27][1] * $g_iDPI_ratio1) $aCtrl[28][0] = GUICtrlCreateUpdown(-1) GUICtrlSetTip(-1, '#Region UPDOWN - Updown') #EndRegion UPDOWN #Region LABEL $aCtrl[29][2] = 350 $aCtrl[29][3] = 165 $aCtrl[29][4] = 40 $aCtrl[29][5] = 40 $aCtrl[29][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[29][0] = GUICtrlCreateLabel("Green" & @CRLF & "Label", $aCtrl[29][2] * $g_iDPI_ratio1, $aCtrl[29][3] * $g_iDPI_ratio1, $aCtrl[29][4] * $g_iDPI_ratio1, $aCtrl[29][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region LABEL') GUICtrlSetBkColor(-1, 0x00FF00) GUICtrlSetFont(-1, $aCtrl[29][1] * $g_iDPI_ratio1) #EndRegion LABEL #Region SLIDER $aCtrl[30][2] = 235 $aCtrl[30][3] = 215 $aCtrl[30][4] = 40 $aCtrl[30][5] = 16 $aCtrl[30][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[30][0] = GUICtrlCreateLabel("Slider:", $aCtrl[30][2] * $g_iDPI_ratio1, $aCtrl[30][3] * $g_iDPI_ratio1, $aCtrl[30][4] * $g_iDPI_ratio1, $aCtrl[30][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region SLIDER - Label') GUICtrlSetFont(-1, $aCtrl[30][1] * $g_iDPI_ratio1) $aCtrl[31][2] = 270 $aCtrl[31][3] = 210 $aCtrl[31][4] = 120 $aCtrl[31][5] = 30 $aCtrl[31][0] = GUICtrlCreateSlider($aCtrl[31][2] * $g_iDPI_ratio1, $aCtrl[31][3] * $g_iDPI_ratio1, $aCtrl[31][4] * $g_iDPI_ratio1, $aCtrl[31][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region SLIDER') GUICtrlSetData(-1, 30) #EndRegion SLIDER #Region INPUT $aCtrl[32][2] = 235 $aCtrl[32][3] = 255 $aCtrl[32][4] = 130 $aCtrl[32][5] = 20 $aCtrl[32][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[32][0] = GUICtrlCreateInput("Sample Input Box", $aCtrl[32][2] * $g_iDPI_ratio1, $aCtrl[32][3] * $g_iDPI_ratio1, $aCtrl[32][4] * $g_iDPI_ratio1, $aCtrl[32][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region INPUT') GUICtrlSetFont(-1, $aCtrl[32][1] * $g_iDPI_ratio1) #EndRegion INPUT #Region DATE $aCtrl[33][2] = 5 $aCtrl[33][3] = 280 $aCtrl[33][4] = 200 $aCtrl[33][5] = 20 $aCtrl[33][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[33][0] = GUICtrlCreateDate("", $aCtrl[33][2] * $g_iDPI_ratio1, $aCtrl[33][3] * $g_iDPI_ratio1, $aCtrl[33][4] * $g_iDPI_ratio1, $aCtrl[33][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region DATE') GUICtrlSetFont(-1, $aCtrl[33][1] * $g_iDPI_ratio1) $aCtrl[34][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[34][2] = 10 $aCtrl[34][3] = 305 $aCtrl[34][4] = 200 $aCtrl[34][5] = 20 $aCtrl[34][0] = GUICtrlCreateLabel("(Date control expands into a calendar)", $aCtrl[34][2] * $g_iDPI_ratio1, $aCtrl[34][3] * $g_iDPI_ratio1, $aCtrl[34][4] * $g_iDPI_ratio1, $aCtrl[34][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region DATE - Label') GUICtrlSetFont(-1, $aCtrl[34][1] * $g_iDPI_ratio1) #EndRegion DATE #Region BUTTON $aCtrl[35][2] = 10 $aCtrl[35][3] = 330 $aCtrl[35][4] = 100 $aCtrl[35][5] = 30 $aCtrl[35][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[35][0] = GUICtrlCreateButton("Click me :-)", $aCtrl[35][2] * $g_iDPI_ratio1, $aCtrl[35][3] * $g_iDPI_ratio1, $aCtrl[35][4] * $g_iDPI_ratio1, $aCtrl[35][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region BUTTON') GUICtrlSetFont(-1, $aCtrl[35][1] * $g_iDPI_ratio1) #EndRegion BUTTON #Region CHECKBOX $aCtrl[36][2] = 130 $aCtrl[36][3] = 335 $aCtrl[36][4] = 80 $aCtrl[36][5] = 20 $aCtrl[36][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[36][0] = GUICtrlCreateCheckbox("Checkbox", $aCtrl[36][2] * $g_iDPI_ratio1, $aCtrl[36][3] * $g_iDPI_ratio1, $aCtrl[36][4] * $g_iDPI_ratio1, $aCtrl[36][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region CHECKBOX') GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlSetFont(-1, $aCtrl[36][1] * $g_iDPI_ratio1) #EndRegion CHECKBOX #Region TREEVIEW ONE $aCtrl[37][2] = 210 $aCtrl[37][3] = 290 $aCtrl[37][4] = 80 $aCtrl[37][5] = 80 $aCtrl[37][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[37][0] = GUICtrlCreateTreeView($aCtrl[37][2] * $g_iDPI_ratio1, $aCtrl[37][3] * $g_iDPI_ratio1, $aCtrl[37][4] * $g_iDPI_ratio1, $aCtrl[37][5] * $g_iDPI_ratio1) GUICtrlSetTip(-1, '#Region TREEVIEW ONE') GUICtrlSetFont(-1, $aCtrl[37][1] * $g_iDPI_ratio1) $aCtrl[38][0] = GUICtrlCreateTreeViewItem("TreeView", $aCtrl[37][0]) GUICtrlCreateTreeViewItem("Item1", $aCtrl[38][0]) GUICtrlCreateTreeViewItem("Item2", $aCtrl[38][0]) GUICtrlCreateTreeViewItem("Foo", -1) GUICtrlSetState($aCtrl[38][0], $GUI_EXPAND) #EndRegion TREEVIEW ONE #Region TREEVIEW TWO $aCtrl[39][2] = 295 $aCtrl[39][3] = 290 $aCtrl[39][4] = 103 $aCtrl[39][5] = 80 $aCtrl[39][1] = 8.5 * $g_iDPI_ratio2 $aCtrl[39][0] = GUICtrlCreateTreeView($aCtrl[39][2] * $g_iDPI_ratio1, $aCtrl[39][3] * $g_iDPI_ratio1, $aCtrl[39][4] * $g_iDPI_ratio1, $aCtrl[39][5] * $g_iDPI_ratio1, $TVS_CHECKBOXES) GUICtrlSetTip(-1, '#Region TREEVIEW TWO') GUICtrlSetFont(-1, $aCtrl[39][1] * $g_iDPI_ratio1) GUICtrlCreateTreeViewItem("TreeView", $aCtrl[39][0]) GUICtrlCreateTreeViewItem("With", $aCtrl[39][0]) GUICtrlCreateTreeViewItem("$TVS_CHECKBOXES", $aCtrl[39][0]) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlCreateTreeViewItem("Style", $aCtrl[39][0]) #EndRegion TREEVIEW TWO #Region GUI MESSAGE LOOP GUISetState(@SW_SHOW) If @OSBuild > 9599 Then GUIRegisterMsg($WM_DPICHANGED, "WM_DPICHANGED") ;requires Win 8.1+ / Server 2012 R2+ GUIRegisterMsg($WM_GETMINMAXINFO, "WM_GETMINMAXINFO") GUIRegisterMsg($WM_SIZE, "WM_SIZE") Local $hGUI_child, $hImage, $hGDIBitmap, $hGfx, $hPath, $hFamily, $hFormat, $tLayout, $hPen, $hBrush, $hB, $aGUIGetMsg _GDIPlus_Startup() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _GDIPlus_PathDispose($hPath) _GDIPlus_PenDispose($hPen) _GDIPlus_BrushDispose($hBrush) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_ImageDispose ($hImage) _GDIPlus_GraphicsDispose($hGfx) _GDIPlus_Shutdown() GUIRegisterMsg($WM_DPICHANGED, "") GUIRegisterMsg(WM_GETMINMAXINFO, "") GUIRegisterMsg(WM_SIZE, "") GUIDelete() Exit Case $aCtrl[35][0] If $hImage Then $hImage = _GDIPlus_ImageDispose($hImage) $hImage = _GDIPlus_BitmapCreateFromScan0($iw * $g_iDPI_ratio1, $ih * $g_iDPI_ratio1) If $hGfx Then _GDIPlus_GraphicsDispose($hGfx) $hGfx = _GDIPlus_ImageGetGraphicsContext($hImage) _GDIPlus_GraphicsSetTextRenderingHint($hGfx, $GDIP_TEXTRENDERINGHINTANTIALIAS) _GDIPlus_GraphicsSetSmoothingMode($hGfx, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hGfx, 0xFFF0F0F0) If $hPath Then _GDIPlus_PathDispose($hPath) $hPath = _GDIPlus_PathCreate() If $hFamily Then _GDIPlus_FontFamilyDispose($hFamily) $hFamily = _GDIPlus_FontFamilyCreate("Arial") If $hFormat Then _GDIPlus_StringFormatDispose($hFormat) $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) _GDIPlus_StringFormatSetLineAlign($hFormat, 1) $tLayout = _GDIPlus_RectFCreate(0, 0, $iw * $g_iDPI_ratio1, $ih * $g_iDPI_ratio1) _GDIPlus_PathAddString($hPath, "Hello World!", $tLayout, $hFamily, 0, 50 * $g_iDPI_ratio1, $hFormat) If $hPen Then _GDIPlus_PenDispose($hPen) $hPen = _GDIPlus_PenCreate(0xFF000000, 8) _GDIPlus_PenSetLineJoin($hPen, 2) _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen) If $hBrush Then _GDIPlus_BrushDispose($hBrush) $hBrush = _GDIPlus_BrushCreateSolid(0xFF00FF00) _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush) If $hGDIBitmap Then _WinAPI_DeleteObject($hGDIBitmap) $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) Local $aGUI_Pos = WinGetPos($ahWnd[0][0]) $ahWnd[1][0] = GUICreate("GDI+ Child Window", $iw * $g_iDPI_ratio1, $ih * $g_iDPI_ratio1, $aGUI_Pos[0] - ($aGUI_Pos[2] - $iw * $g_iDPI_ratio1) / 2, $aGUI_Pos[1] + $ih * $g_iDPI_ratio1 / 2, $WS_SIZEBOX, -1, $ahWnd[0][0]) $aCtrl[40][2] = 0 $aCtrl[40][3] = 0 $aCtrl[40][4] = $iw $aCtrl[40][5] = $ih $aCtrl[40][0] = GUICtrlCreatePic("", $aCtrl[40][2], $aCtrl[40][3], $aCtrl[40][4] * $g_iDPI_ratio1, $aCtrl[40][5] * $g_iDPI_ratio1) _WinAPI_DeleteObject(GUICtrlSendMsg($aCtrl[40][0], $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap)) GUISetState(@SW_SHOW, $ahWnd[1][0]) While 1 $aGUIGetMsg = GUIGetMsg(1) Switch $aGUIGetMsg[1] Case $ahWnd[1][0] Switch $aGUIGetMsg[0] Case $GUI_EVENT_CLOSE GUIDelete($ahWnd[1][0]) ExitLoop EndSwitch EndSwitch WEnd EndSwitch WEnd #EndRegion GUI MESSAGE LOOP EndFunc ;==>_Example Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg, $wParam, $lParam Switch $hWnd Case $ahWnd[1][0] Local $aSize = ControlGetPos($ahWnd[1][0], "", $aCtrl[40][0]) $aCtrl[40][2] = $aSize[0] $aCtrl[40][3] = $aSize[1] $aCtrl[40][4] = _WinAPI_LoWord($lParam) $aCtrl[40][5] = _WinAPI_HiWord($lParam) GUICtrlSetPos($aCtrl[40][0], $aCtrl[40][2], $aCtrl[40][3], $aCtrl[40][4], $aCtrl[40][5]) EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_SIZE Func WM_GETMINMAXINFO($hWnd, $Msg, $wParam, $lParam) If $hWnd = $ahWnd[1][0] Then Local $minmaxinfo = DllStructCreate("long ptReservedX;long ptReservedY;long ptMaxSizeX; long ptMaxSizeY;long ptMaxPositionX;long ptMaxPositionY;long ptMinTrackSizeX;long ptMinTrackSizeY;long ptMaxTrackSizeX;long ptMaxTrackSizeY ", $lParam) $minmaxinfo.ptMinTrackSizeX = $iw / 2 $minmaxinfo.ptMinTrackSizeY = $ih / 2 $minmaxinfo.ptMaxTrackSizeX = $iw * 3 $minmaxinfo.ptMaxTrackSizeY = $ih * 3 EndIf Return "GUI_RUNDEFMSG" EndFunc ;==>WM_GETMINMAXINFO Func WM_DPICHANGED($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg Local $iDPI = _WinAPI_LoWord($wParam) ConsoleWrite("DPI change triggered! DPI: " & $iDPI & @CRLF) $g_iDPI_ratio1 = $iDPI / 96 $g_iDPI_ratio2 = $g_iDPI_ratio1 ^ -1 Local $tRECT = DllStructCreate($tagRECT, $lParam) Local $iX = $tRECT.left, $iY = $tRECT.top, $iW = $tRECT.right - $iX, $iH = $tRECT.bottom - $iY, $i Switch $hWnd Case $ahWnd[0][0] _WinAPI_SetWindowPos($ahWnd[0][0], 0, $iX, $iY, $iW, $iH, BitOR($SWP_NOZORDER, $SWP_NOACTIVATE)) For $i = 0 To 39 If $aCtrl[$i][1] Then GUICtrlSetFont($aCtrl[$i][0], $aCtrl[$i][1] * $g_iDPI_ratio1) If $aCtrl[$i][4] Then GUICtrlSetPos($aCtrl[$i][0], $aCtrl[$i][2] * $g_iDPI_ratio1, $aCtrl[$i][3] * $g_iDPI_ratio1, $aCtrl[$i][4] * $g_iDPI_ratio1, $aCtrl[$i][5] * $g_iDPI_ratio1) Next _WinAPI_UpdateWindow($ahWnd[0][0]) Case $ahWnd[1][0] $i = 40 _WinAPI_SetWindowPos($ahWnd[1][0], 0, $iX, $iY, $iW, $iH, BitOR($SWP_NOZORDER, $SWP_NOACTIVATE)) GUICtrlSetPos($aCtrl[$i][0], $aCtrl[$i][2], $aCtrl[$i][3], $aCtrl[$i][4], $aCtrl[$i][5]) _WinAPI_UpdateWindow($ahWnd[1][0]) EndSwitch Return 1 EndFunc ;==>WM_DPICHANGED THX.
    1 point
  49. ValeryVal

    Barcode - UDF

    This isn't laborious work. There is the Ocvita Barcode ActiveX Control based on zint engine. It has more than 50 1D (EAN, ISBN, Code 128 and so on) and 2D (QR Code, Datamatrix, Aztec) symbologies. You can download from here http://ocvita.ru/content/view/90/35/ Register OcvitaBarcode.ocx by command regsvr32 OcvitaBarcode.ocx BCode.au3 is my simple example how to use Ocvita Barcode ActiveX by AutoIt3 $GUI = GUICreate("OCVITA_BARCODE by AutoIt3, Valery Ivanov, 19 September, 2013", 400, 400, -1, -1) $oBCode = ObjCreate("Ocvita.Barcode") $oBCodeGUI = GUICtrlCreateObj($oBCode, 10, 110, 380, 280) $oBCode.barcode = "Valery" $oBCode.hrtext = "Valery" GUISetState() While 1 $nMsg = GUIGetMsg() Select Case $nMsg = -3 Exit EndSelect WEnd Enjoy!
    1 point
×
×
  • Create New...