Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.
Keywords: Screen Window Pixel Coordinate Absolute Relative Virtual 1000 Dialog Unit Upper Lower Bottom Top Left Right Corner X Y Point
WinBatch has functions that deal with three basic types of screen coordinates:
[x,y] [*]--------------------------- | | | | | | | | | | | | ----------------------------[*] [x,y]A window coordinate, in WinBatch, is a string variable (actually a list) containing four numbers separated by commas or spaces. These four numbers define two points on the screen. The first number is the "X" coordinate of the first point, the second number is the "Y" coordinate of the first point, the third number is the "X" coordinate of the second point, and finally the fourth number is the "Y" coordinate of the second point.
The "0,0" point is in the upper left of the screen, and the "999,999" point is at the lower right.
With just these two points, WinBatch can size and place a number of items.
Coordinates are based on a virtual 1000 x 1000 screen. "x-upper left corner", "y-upper left corner", "x-bottom right corner", and "y-bottom right corner" are based on a logical screen that is 1000 points wide by 1000 points high.
The benefit of the 1000x1000 screen is that it helps users easily calculate relative screen positions regardless of screen resolution. The drawback is possible loss of precision, caused by screens with with resolutions greater than 1000 pixels to be scaled down to 1000. One way to avoid this is to grab and save the coordinates from the beginning of the script and do all calculations from that initial point. You avoid 'coordinate creep' that way.
On multi-monitor systems the 1000 x 1000 virtual screen units may have some counter-intuitive behavior when you have multiple monitors that operate at different resolutions.
For Example:
If you have 3 monitors with the resolution 1600 x 1200, here are the screen coordinates for each monitor:
Zoomed windows can return values greater than 1000 or less than 0 (negative values). For example, the "x-upper left corner" and "y-upper left corner" coordinate is returned as -3. This is simply how Windows works. The Windows OS intentionally sets the size of a maximized window to be outside the boundaries of it's work area by default (i.e. WinZoom). This has to do with how a maximized window's border invisibility is handled. WinZoom simply maximizes a window so the results reported by WinPosition are accurately reflecting the maximized window's size and position. If you were to call the underlying Win32 APIs directly, you would see the same effect in pixels.
You might be better off using WinPlaceGet rather than WinPosition.
You should check the state of the window using WinState before calling any function that returns virtual 1000 x 1000 screen coordinates. Then use WinPlaceGet to deal with zoomed or iconized windows because it returns different values based on the state of the window. The returned value is a string of either 2 or 4 numbers, as follows:
Iconic windows "x y" (upper left corner of the icon) Normal windows "upper-x upper-y lower-x lower-y" Zoomed windows "x y" (upper left corner of the window)Here is a code sample showing the different values returned by WinPosition and WinPlaceGet.
Run('Notepad.exe','') ;ICONIZE WINDOW ISSUE title = "~Notepad" WinIconize( "~Notepad" ) place = WinPlaceGet(WinState( title ), "~Notepad") pos = WinPosition("~Notepad") Pause('Notepad results -@ICONIZE','WinPlaceGet = ':place:@LF:'WinPosition = ':pos) ;ZOOM WINDOW ISSUE title = "~Notepad" WinZoom( title ) place = WinPlaceGet(WinState( title ), title ) pos = WinPosition(title) Pause('Notepad results - @ZOOMED','WinPlaceGet = ':place:@LF:'WinPosition = ':pos) WinClose('~Notepad') Exit
Functions: BoxBitmap, BoxButtonDraw, BoxDrawCircle, BoxDrawLine, BoxDrawRect, BoxDrawText, BoxesUp, BoxmapMode, BoxNew,
IntControl 63, MouseCoords, MouseInfo, MouseMove, WinPlace, WinPlaceChild, WinPlaceGet, WinPlaceSet, WinPosition,
WinPositionChild
Dialog Units:
Dialog Units are used primarily by the Dialog function. Dialog units are based on the system font, DPI, and screen resolution. System font is defined as the default font defined by Windows. Dialog Units basically speaking: 1 width unit = 1/4 width of system font and 1 height unit = 1/8 height of system font.
Functions: Dialog, IntControl 75, Dialog {UserDefinedCallback}, WinMetrics.
The WinMetrics function in the Windows Interface Language help file can help you figure out what current Dialog unit size is.
pixperunit_horz = WinMetrics(-5) pixperunit_vert = WinMetrics(-6)Use WinMetrics to translate dialog units to pixels:
ScreenWidth = WinMetrics(0)/WinMetrics(-6) ;Determine screen width in dialog units ScreenHeight = WinMetrics(1)/WinMetrics(-5) ;Determine screen height in dialog units Message (ScreenWidth,ScreenHeight)This information can be used for calculations as follows:
DlgWidth = ScreenWidth*0.663 ;Make a dialog 2/3 width of screen DlgHeight= ScreenHeight*0.5 ;Make a dialog 1/2 height of screen DlgX=(ScreenWidth-DlgWidth) /2 ;Determine X co-ordinate for a dialog to be centered DlgY=(ScreenHeight-DlgHeight)/2;Determine Y co-ordinate for a dialog to be centered
Coordinates expressed in Windows virtual screen pixel coordinates, in the format: "left,top,right,bottom". A few functions (see below) can return virtual screen pixel coordinates, but only one known function accepts these coordinates as a parameter. That is SysParamInfo 47 SetWorkArea.
How do I get the size of the active windows in pixels?
winpos = WinPosition(WinGetactive()) xulc = ItemExtract(1, winpos, ",") yulc = ItemExtract(2, winpos, ",") xbrc = ItemExtract(3, winpos, ",") ybrc = ItemExtract(4, winpos, ",") width = (xbrc - xulc) * WinMetrics(0) / 1000 height = (ybrc - yulc) * WinMetrics(1) / 1000 Message(width, height)
Functions: MouseInfo, SysParaminfo, WinMetrics and {DllCalls to Windows API Functions}
; Converts horizontal dialog units to pixels. (x axis) #DefineFunction ToPixelsHorizontal(du) Return Int(du*WinMetrics(-6)) #EndFunction ; Converts vertical dialog units to pixels. ( y axis) #DefineFunction ToPixelsVertical(du) Return Int(du*WinMetrics(-5)) #EndFunction ; Test data. nDuX = 40 ; Horizontal dimension in du. nDuY = 11 ; Vertical dimension in du. ; Test. nPixelsX = ToPixelsHorizontal( nDuX ) nPixelsY = ToPixelsVertical( nDuY ) ; Result. Message("Dialog Units x = %nDuX%, y = %nDuy%", "Pixels x = %nPixelsX%, y = %nPixelsY%")
sWorkArea = SysParamInfo(48, "", 0) iLeft = ItemExtract(1, sWorkArea, ",") iTop = ItemExtract(2, sWorkArea, ",") iRight = ItemExtract(3, sWorkArea, ",") iBottom = ItemExtract(4, sWorkArea, ",") ; Calculation : WorkArea multiplied by 1000 then divided by actual screen height. ; xulc = iLeft*1000/WinMetrics(0) ; yulc = iTop*1000/WinMetrics(1) ; xbrc = iRight*1000/WinMetrics(0) ; ybrc = iBottom*1000/WinMetrics(1) ; More Precise MulDiv Calculation xulc = DllCall(DirWindows(1):"kernel32.dll",long:"MulDiv",long:iLeft,long:1000,long:WinMetrics(0)) yulc = DllCall(DirWindows(1):"kernel32.dll",long:"MulDiv",long:iTop,long:1000,long:WinMetrics(1)) xbrc = DllCall(DirWindows(1):"kernel32.dll",long:"MulDiv",long:iRight,long:1000,long:WinMetrics(0)) ybrc = DllCall(DirWindows(1):"kernel32.dll",long:"MulDiv",long:iBottom,long:1000,long:WinMetrics(1)) Pause('GetWorkArea Window Resize Results',xulc:',':yulc:',':xbrc:',':ybrc) title = '' ; Blank string refers to the Main WIL window WinPlace( xulc, yulc, xbrc, ybrc, title ) TimeDelay(5) Exit
winpos = WinPosition(WinGetactive()) xulc = ItemExtract(1, winpos, ",") yulc = ItemExtract(2, winpos, ",") xbrc = ItemExtract(3, winpos, ",") ybrc = ItemExtract(4, winpos, ",") width = (xbrc - xulc) * WinMetrics(0) / 1000 height = (ybrc - yulc) * WinMetrics(1) / 1000 Message(width, height)
Article ID: W17511
Filename: Screen Coordinates Explained.txt
File Created: 2011:11:29:08:36:46
Last Updated: 2011:11:29:08:36:46