timmy2 Posted June 7, 2013 Share Posted June 7, 2013 I found >this thread started by chuber while searching for a way to get the useable desktop area (size of primary monitor desktop minus taskbar). My first bit of bafflement was why the code written by chuber does not match the quote of his code in the reply that follows his post. Since I didn't want to tackle figuring out Sysinternal's debug viewer I went with the version of his code that omits all the lines starting with "If $DEBUG_001...". (more is omitted than that but I think it's missing only comments) I'll paste this version below. It compiles fine. What chuber posted is a function. So my first goal is to write a simple MsgBox that will show me the results of his function. When I insert a simple MsgBox to see the results of his function... MsgBox(0,"test",$aDesktop_Pos[0]) ...I get an error saying "Subscript used with non-Array variable.", yet he used $aDesktop_Pos as an array variable throughout his function and it's a global variable. What part of this do I not understand and how can I extract the info I'm seeking? Here's the code from the original thread. expandcollapse popup; #cs Script: Desktop client size and Taskbar position (code snippet) Author: Bruce Huber (cbruce) AutoIt: v3.2.12.1 Date: 2008.08.13 - Original release Purpose: Determine whether the Taskbar is visible or hidden and where it is docked on the Desktop. Also calculate the available Desktop client region, accounting for any Taskbar space. #ce ; Desktop and Taskbar position information - GetDesktopAndTaskbarPos(). Global Enum $DTP_X, $DTP_Y, $DTP_W, $DTP_H Global $aDesktop_Pos, $aTaskbar_Pos Global Enum $TBDL_UNKNOWN, $TBDL_LEFT, $TBDL_RIGHT, $TBDL_TOP, $TBDL_BOTTOM Global $Taskbar_Dock_Location = $TBDL_UNKNOWN Global $Taskbar_Visible Func GetDesktopAndTaskbarPos() ; Get the Desktop size - which includes the Taskbar space, if the Taskbar is visible. $aDesktop_Pos = WinGetPos( "Program Manager") ; Get the Taskbar size. $aTaskbar_Pos = WinGetPos( "[Class:Shell_TrayWnd]") ; Determine if Taskbar is taking up space on the Desktop. If ( $aTaskbar_Pos[$DTP_X] > -3) And ( $aTaskbar_Pos[$DTP_Y] > -3) And ( $aTaskbar_Pos[$DTP_X] < ( $aDesktop_Pos[$DTP_W] - 5)) And ( $aTaskbar_Pos[$DTP_Y] < ( $aDesktop_Pos[$DTP_H] - 5)) Then ; Taskbar is Visible. $Taskbar_Visible = True ; Calculate the parameters of the AVAILABLE Desktop client region. If ( $aTaskbar_Pos[$DTP_X] < 1) and ( $aTaskbar_Pos[$DTP_Y] > 0) and ( $aTaskbar_Pos[$DTP_W] > $aTaskbar_Pos[$DTP_H]) Then ; Taskbar is on the BOTTOM. $Taskbar_Dock_Location = $TBDL_BOTTOM ; We need to adjust the Desktop Height. $aDesktop_Pos[$DTP_H] = $aTaskbar_Pos[$DTP_Y] - 1 ElseIf ( $aTaskbar_Pos[$DTP_X] < 1) and ( $aTaskbar_Pos[$DTP_Y] < 1) and ( $aTaskbar_Pos[$DTP_W] < $aTaskbar_Pos[$DTP_H]) Then ; Taskbar is on the LEFT. $Taskbar_Dock_Location = $TBDL_LEFT ; We need to adjust the Desktop X and Width. $aDesktop_Pos[$DTP_X] = $aTaskbar_Pos[$DTP_X] + $aTaskbar_Pos[$DTP_W] + 1 $aDesktop_Pos[$DTP_W] = $aTaskbar_Pos[$DTP_X] - 1 ElseIf ( $aTaskbar_Pos[$DTP_X] > 0) and ( $aTaskbar_Pos[$DTP_Y] < 1) and ( $aTaskbar_Pos[$DTP_W] < $aTaskbar_Pos[$DTP_H]) Then ; Taskbar is on the RIGHT. $Taskbar_Dock_Location = $TBDL_RIGHT ; We need to adjust the Desktop Width. $aDesktop_Pos[$DTP_W] = $aTaskbar_Pos[$DTP_X] - 1 ElseIf ( $aTaskbar_Pos[$DTP_X] < 1) and ( $aTaskbar_Pos[$DTP_Y] < 1) and ( $aTaskbar_Pos[$DTP_W] > $aTaskbar_Pos[$DTP_H]) Then ; Taskbar is on the TOP. $Taskbar_Dock_Location = $TBDL_TOP ; We need to adjust the Desktop Y and Height. $aDesktop_Pos[$DTP_Y] = $aTaskbar_Pos[$DTP_Y] + $aTaskbar_Pos[$DTP_H] + 1 $aDesktop_Pos[$DTP_H] = $aTaskbar_Pos[$DTP_Y] - 1 Else ; Where the heck has the Taskbar gone? $Taskbar_Dock_Location = $TBDL_UNKNOWN EndIf Else ; Taskbar is Hidden. $Taskbar_Visible = False EndIf #cs $aDesktop_Pos now contains parameters that only define the AVAILABLE Desktop client region. This will be the entire Desktop if the Taskbar is hidden. Otherwise, the region will be the Desktop area minus the Taskbar area. $Taskbar_Dock_Location now specifies WHERE, on the Desktop, that the Taskbar is docked. #ce EndFunc ; GetDesktopAndTaskbarPos() ; I realize there's> a post in another thread that uses a different approach to finding the data I seek but all I need are "x,y,h,w" and I can't figure out how to extact that info from the script provided in that code (copy pasted below). This is humbling. expandcollapse popupGlobal Const $MONITOR_DEFAULTTONULL = 0x00000000 Global Const $MONITOR_DEFAULTTOPRIMARY = 0x00000001 Global Const $MONITOR_DEFAULTTONEAREST = 0x00000002 Global Const $CCHDEVICENAME = 32 Global Const $MONITORINFOF_PRIMARY = 0x00000001 $hMonitor = GetMonitorFromPoint(0, 0) ;$hMonitor = GetMonitorFromPoint(-2, 0) ;$hMonitor = GetMonitorFromPoint(@DesktopWidth, 0) If $hMonitor <> 0 Then Dim $arMonitorInfos[4] If GetMonitorInfos($hMonitor, $arMonitorInfos) Then _ Msgbox(0, "Monitor-Infos", "Rect-Monitor" & @Tab & ": " & $arMonitorInfos[0] & @LF & _ "Rect-Workarea" & @Tab & ": " & $arMonitorInfos[1] & @LF & _ "PrimaryMonitor?" & @Tab & ": " & $arMonitorInfos[2] & @LF & _ "Devicename" & @Tab & ": " & $arMonitorInfos[3]) EndIf Exit Func GetMonitorFromPoint($x, $y) $hMonitor = DllCall("user32.dll", "hwnd", "MonitorFromPoint", _ "int", $x, _ "int", $y, _ "int", $MONITOR_DEFAULTTONULL) Return $hMonitor[0] EndFunc Func GetMonitorInfos($hMonitor, ByRef $arMonitorInfos) Local $stMONITORINFOEX = DllStructCreate("dword;int[4];int[4];dword;char[" & $CCHDEVICENAME & "]") DllStructSetData($stMONITORINFOEX, 1, DllStructGetSize($stMONITORINFOEX)) $nResult = DllCall("user32.dll", "int", "GetMonitorInfo", _ "hwnd", $hMonitor, _ "ptr", DllStructGetPtr($stMONITORINFOEX)) If $nResult[0] = 1 Then $arMonitorInfos[0] = DllStructGetData($stMONITORINFOEX, 2, 1) & ";" & _ DllStructGetData($stMONITORINFOEX, 2, 2) & ";" & _ DllStructGetData($stMONITORINFOEX, 2, 3) & ";" & _ DllStructGetData($stMONITORINFOEX, 2, 4) $arMonitorInfos[1] = DllStructGetData($stMONITORINFOEX, 3, 1) & ";" & _ DllStructGetData($stMONITORINFOEX, 3, 2) & ";" & _ DllStructGetData($stMONITORINFOEX, 3, 3) & ";" & _ DllStructGetData($stMONITORINFOEX, 3, 4) $arMonitorInfos[2] = DllStructGetData($stMONITORINFOEX, 4) $arMonitorInfos[3] = DllStructGetData($stMONITORINFOEX, 5) EndIf Return $nResult[0] EndFunc Link to comment Share on other sites More sharing options...
BugFix Posted June 7, 2013 Share Posted June 7, 2013 I've made sometimes the following function for this: expandcollapse popup;=============================================================================== ; Function Name: _GetTaskBarProps($hProperty="") ; Description:: Gets the Taskbar properties ; Parameter(s): $_hProperty propertiy, you want to get ; "" (default) returns rectangle of taskbar as array [left,top,right,bottom] ; "top" - X1 left position ; "left" - Y1 top position ; "height" - Y2-Y1 height of taskbar ; "width" - X2-X1 width of taskbar ; "align" - Alignment (Clockwise): 1=right, 2=bottom, 3=left, 4=top ; $_fAlignAsStr TRUE returns alignment as string (left, top, right, bottom), FALSE (default) as number ; Return Value(s): see $_hProperty ; Author(s): BugFix (bugfix@autoit.de) ;=============================================================================== Func _GetTaskBarProps($_hProperty="", $_fAlignAsStr=False) Local $tRect = DllStructCreate("long;long;long;long"), $hWnd, $ret, $vRet, $aAlign[5] = ['', 'right', 'bottom', 'left', 'top'] $_hProperty = StringStripWS($_hProperty, 3) $ret = DllCall("user32.dll", 'long', "FindWindowA", 'str', "Shell_traywnd", 'str', "") $hWnd = $ret[0] DllCall("User32.dll", "int", "GetWindowRect", "hwnd", $hWnd, "ptr", DllStructGetPtr($tRect)) Local $left = DllStructGetData($tRect, 1) Local $top = DllStructGetData($tRect, 2) Local $right = DllStructGetData($tRect, 3) Local $bottom = DllStructGetData($tRect, 4) If $_hProperty = "" Then Local $aOut[4] = [$left, $top, $right, $bottom] Return $aOut EndIf Switch $_hProperty Case "top" Return $top Case "left" Return $left Case "height" Return $bottom - $top Case "width" Return $right - $left Case "align" If $top < 1 And $left < 1 Then If $bottom > $right Then $vRet = 3 If $right > $bottom Then $vRet = 4 ElseIf $top < 1 And $left > 0 Then $vRet = 1 Else $vRet = 2 EndIf EndSwitch If $_fAlignAsStr Then Return $aAlign[$vRet] Return $vRet EndFunc ;==>_GetTaskBarProps Best Regards BugFix Link to comment Share on other sites More sharing options...
BrewManNH Posted June 7, 2013 Share Posted June 7, 2013 (edited) This script doesn't get the primary monitor's dimensions, it gets the total desktop width (dual monitors on my setup), then subtracts the taskbar height from the desktop height but doesn't take into account you might have more than one monitor. Not to mention, it's poorly written. EDIT: Just wanted to make a note here that this reply was to the OP, and not to BugFix's post. Edited June 7, 2013 by BrewManNH If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted June 7, 2013 Moderators Share Posted June 7, 2013 timmy2,Rather than use those old functions, why not use something much simpler to get the useable desktop area? expandcollapse popup#include <Array.au3> ; Just for display $aDeskTopData = _DeskTopData() $iError = @error If IsArray($aDeskTopData) Then _ArrayDisplay($aDeskTopData) Else MsgBox(0, "Error", $iError) EndIf Func _DeskTopData() Local $tWorkArea ; Determine which struct syntax to use to use If @AutoItVersion < "3.3.8.0" Then $tWorkArea = DllStructCreate("long Left;long Top;long Right;long Bottom") Else $tWorkArea = DllStructCreate("struct;long Left;long Top;long Right;long Bottom;endstruct") EndIf ; Determine available work area ; $SPI_GETWORKAREA = 48 DllCall("user32.dll", "bool", "SystemParametersInfoW", "uint", 48, "uint", 0, "ptr", DllStructGetPtr($tWorkArea), "uint", 0) If @error Then Return SetError(2, 0, "") EndIf Local $aDeskTopData[5] = [DllStructGetData($tWorkArea, "Left"), DllStructGetData($tWorkArea, "Top"), _ DllStructGetData($tWorkArea, "Right"), DllStructGetData($tWorkArea, "Bottom"), 1] ; Assume taskbar visible ; Check if Taskbar is hidden Local $aRet = DllCall("shell32.dll", "uint", "SHAppBarMessage", "dword", 0x00000004, "ptr*", 0) ; $ABM_GETSTATE If @error Then Return SetError(1, 0, "") EndIf If BitAND($aRet[0], 0x01) Then $aDeskTopData[4] = 0 ; Set to hidden EndIf Return $aDeskTopData EndFunc ;==>_DeskTopDataI leave you to do the maths to find out the width and height. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
kaotkbliss Posted June 7, 2013 Share Posted June 7, 2013 I haven't looked at the code, but it also probably doesn't take into account where the taskbar is. rarely I've seen the taskbar along the side of the screen. I've also noticed that taskbar functions I've found here will sometimes not return the correct properties causing unexpected behavior in scripts (I've only used getting taskbar properties in a loop to catch changes that might be made) so I use this to get the taskbar properties. $tray = WinGetPos("[CLASS:Shell_TrayWnd]") With that and these functions, I'm able to calculate the usable screen area expandcollapse popupGlobal $__MonitorList[1][5] $__MonitorList[0][0] = 0 #Region thanks to xrxca for these functions Func _GetMonitorFromPoint($XorPoint = 0, $y = 0) Local $MousePos, $myX, $myY If @NumParams = 0 Then $MousePos = MouseGetPos() $myX = $MousePos[0] $myY = $MousePos[1] ElseIf (@NumParams = 1) And IsArray($XorPoint) Then $myX = $XorPoint[0] $myY = $XorPoint[1] Else $myX = $XorPoint $myY = $y EndIf If $__MonitorList[0][0] == 0 Then _GetMonitors() EndIf Local $i = 0 Local $Monitor = 0 For $i = 1 To $__MonitorList[0][0] If ($myX >= $__MonitorList[$i][1]) _ And ($myX < $__MonitorList[$i][3]) _ And ($myY >= $__MonitorList[$i][2]) _ And ($myY < $__MonitorList[$i][4]) Then $Monitor = $i Next Return $Monitor EndFunc ;==>_GetMonitorFromPoint Func _GetMonitors() $__MonitorList[0][0] = 0 ; Added so that the global array is reset if this is called multiple times Local $handle = DllCallbackRegister("_MonitorEnumProc", "int", "hwnd;hwnd;ptr;lparam") DllCall("user32.dll", "int", "EnumDisplayMonitors", "hwnd", 0, "ptr", 0, "ptr", DllCallbackGetPtr($handle), "lparam", 0) DllCallbackFree($handle) Local $i = 0 For $i = 1 To $__MonitorList[0][0] If $__MonitorList[$i][1] < $__MonitorList[0][1] Then $__MonitorList[0][1] = $__MonitorList[$i][1] If $__MonitorList[$i][2] < $__MonitorList[0][2] Then $__MonitorList[0][2] = $__MonitorList[$i][2] If $__MonitorList[$i][3] > $__MonitorList[0][3] Then $__MonitorList[0][3] = $__MonitorList[$i][3] If $__MonitorList[$i][4] > $__MonitorList[0][4] Then $__MonitorList[0][4] = $__MonitorList[$i][4] Next Return $__MonitorList EndFunc ;==>_GetMonitors Func _MonitorEnumProc($hMonitor, $hDC, $lRect, $lParam) Local $Rect = DllStructCreate("int left;int top;int right;int bottom", $lRect) $__MonitorList[0][0] += 1 ReDim $__MonitorList[$__MonitorList[0][0] + 1][5] If $hDC = $hDC Then EndIf If $lParam = $lParam Then EndIf $__MonitorList[$__MonitorList[0][0]][0] = $hMonitor $__MonitorList[$__MonitorList[0][0]][1] = DllStructGetData($Rect, "left") $__MonitorList[$__MonitorList[0][0]][2] = DllStructGetData($Rect, "top") $__MonitorList[$__MonitorList[0][0]][3] = DllStructGetData($Rect, "right") $__MonitorList[$__MonitorList[0][0]][4] = DllStructGetData($Rect, "bottom") Return 1 ; Return 1 to continue enumeration EndFunc ;==>_MonitorEnumProc #EndRegion thanks to xrxca for these functions 010101000110100001101001011100110010000001101001011100110010000 001101101011110010010000001110011011010010110011100100001 My Android cat and mouse gamehttps://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek We're gonna need another Timmy! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now