MPoud

Get top-left pixel of window- VDI

13 posts in this topic

Hi everyone,

In our company we use 3 monitors connected to a Thin Client that opens a Virtual Desktop (VMware View).

On the Virtual desktop (windows 10) an AutoIt script is launched which opens three webpages in different Internet Explorer windows. After opening the Internet Explorer window, I move it to the right screen with the WinMove function of AutoIt. This function expects a X-Y coordinate for the window.

In a normal situation, the first screen wil be main, second and third wil be on the right of each other.
So the upperleft pixel in every screen (with a resolution of 1920,1080) will be:
Screen 1 (master): 0,0
Screen 2 (right of the master): 1920,0
Screen 3 (right of screen 2): 3840,0

So to place the Internet Explorer windows on the correct screen, I use the X,Y coordinates above. These are hardcoded in my script.

Unfortunately, when using Thin clients and VDI the election of who is main can be different on every boot. (Can't force or change this).
This way the coordinates change and my script fails. Because when the third screen becomes master, then the coordinates will be:
Screen 1 (left of screen 2): -3840,0
Screen 2 (left of master): -1920,0
Screen 3 (master): 0,0

Or when the middle becomes master:
Screen 1 (left of master): -1920,0
Screen 2 (master): 0,0
Screen 3 (right of master): 1920,0

There is no way I can force a screen to be the master, or I just don't know how.

I Think the only way to fix this problem, is to stop using Hard coded coordinates and start the script with finding the right coordinates to use.

Is there any way to identify the screens and request the upperleft pixel of the whole desktop (Not of one display).
This way I know what the coordinate is of the most left window and start counting from that value.

Or maybe there is a better way?

Hope somebody can help me with this. I am kind of a newbie of AutoIt and not kind of a programmer myself.

 

Share this post


Link to post
Share on other sites



I think i would check the desktop coordinates this way:

if @desktopwidth = 0 then master is 3

if @desktopwidth < 1920 then master is 2

if @desktopwidth < 3840 then master is 1

and act accordingly.

Or maybe im thinking wrong.

 


Spoiler

Paster - Main function is to paste text, but has more functions.

OpenW - Open With... alternative, Open any file with any application, set it's icon, set application as default.

Renamer - Rename files and folders, remove portions of text from the filename etc.

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Firefox Profile Backup - Backup/restore previously saved profile.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

IUIAutomation - Topic with framework and examples

Share this post


Link to post
Share on other sites

Mm I get what you mean. Do you know which functon I have to use to determine desktopwidth? And if i determine this desktopwidth. Will I receive a smaller number when another screen is master? I think I will receive 5760px (3 x 1920px), because the width of the desktop doesnt change, only the way its plotted.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

It's a macro @DesktopWidth I don't have multiple monitors so i can't test the theory.

Edited by careca

Spoiler

Paster - Main function is to paste text, but has more functions.

OpenW - Open With... alternative, Open any file with any application, set it's icon, set application as default.

Renamer - Rename files and folders, remove portions of text from the filename etc.

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Firefox Profile Backup - Backup/restore previously saved profile.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

IUIAutomation - Topic with framework and examples

Share this post


Link to post
Share on other sites

Unfortunately @DesktopWidth gives me the width of the primary screen. Not the location of the screen :(.

Share this post


Link to post
Share on other sites

With this code:

#include <WinAPIGdi.au3>
#include <WinAPISys.au3>

Local $tPos = _WinAPI_GetMousePos()
Local $hMonitor = _WinAPI_MonitorFromPoint($tPos)
Local $aData = _WinAPI_GetMonitorInfo($hMonitor)

If IsArray($aData) Then

MsgBox($MB_SYSTEMMODAL, '', 'Example of _DesktopDimensions:' & @CRLF & _
        'Handle = ' & $hMonitor & @CRLF & _
        'Rectangle = ' & DllStructGetData($aData[0], 1) & ', ' & DllStructGetData($aData[0], 2) & ', ' & DllStructGetData($aData[0], 3) & ', ' & DllStructGetData($aData[0], 4) & @CRLF & _
        'Work area = ' & DllStructGetData($aData[1], 1) & ', ' & DllStructGetData($aData[1], 2) & ', ' & DllStructGetData($aData[1], 3) & ', ' & DllStructGetData($aData[1], 4) & @CRLF & _
        'Primary = ' & $aData[2] & @CRLF & _
        'Device name = ' & $aData[3] & @CRLF)

EndIf

I receive the information I need, but only from one Display. So if I run this code on monitor 2 (currently the master and therefor \\,\DISPLAY1): I receive a rectangle of 0,0

If I run the code on Monitor 1 (left of the current master and for Windows Device Name \\,\DISPLAY2): I receive a rectangle of -1920,0.

Exactly what I need to know. But I have to run this tool on every screen seperately. Is there a piece of code, to select a monitor by Device Name (\\,\DISPLAY1 - \\,\DISPLAY2 - \\,\DISPLAY3)?

That way I can:
- Select \\.\Display1, measure it and save it to variable $rectangleDisplay1
- Select \\,\DISPLAY2, measure it and save it to variable $rectangleDisplay2
- Select \\,\DISPLAY3. measure it and save it to variable $rectangleDisplay3

And then check which variable has the lowest value.

Does anyone know the function to select a display?

Share this post


Link to post
Share on other sites

maybe here
https://msdn.microsoft.com/en-us/library/dd145071(v=vs.85).aspx

monitorfrompoint functions should get you at least the info you are searching for.

 

Selecting a display thru API like displayswitch.exe does from commandline I do not know.

 

 

 

Share this post


Link to post
Share on other sites
2 hours ago, MPoud said:

Unfortunately @DesktopWidth gives me the width of the primary screen. Not the location of the screen :(.

So it gives you always the same value...right? Ok, what about this, move a window to right and left of the primary screen, and check iswindowvisible.

Not pretty to have a window floating around, but hey, if it works.. and there's no better idea.


Spoiler

Paster - Main function is to paste text, but has more functions.

OpenW - Open With... alternative, Open any file with any application, set it's icon, set application as default.

Renamer - Rename files and folders, remove portions of text from the filename etc.

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Firefox Profile Backup - Backup/restore previously saved profile.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

IUIAutomation - Topic with framework and examples

Share this post


Link to post
Share on other sites

@careca Mm... good thinking! If I cant find another trick, I can always try that one. Thx!

Share this post


Link to post
Share on other sites

#10 ·  Posted

see help file on _WinAPI_MonitorFromPoint

You should be able to do exactly what you want to detect the information

#include <WinAPIGdi.au3>
#include <WinAPISys.au3>

Local $tPos = _WinAPI_GetMousePos()
;~ DllStructSetData($tPos, 1, 12000)
Local $hMonitor = _WinAPI_MonitorFromPoint($tPos, 0)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hMonitor = ' & $hMonitor & @CRLF & '>Error code: ' & @error & '    Extended code: 0x' & Hex(@extended) & @CRLF) ;### Debug Console

Local $aData = _WinAPI_GetMonitorInfo($hMonitor)
If IsArray($aData) Then
    ConsoleWrite('Handle:      ' & $hMonitor & @CRLF)
    ConsoleWrite('Rectangle:   ' & DllStructGetData($aData[0], 1) & ', ' & DllStructGetData($aData[0], 2) & ', ' & DllStructGetData($aData[0], 3) & ', ' & DllStructGetData($aData[0], 4) & @CRLF)
    ConsoleWrite('Work area:   ' & DllStructGetData($aData[1], 1) & ', ' & DllStructGetData($aData[1], 2) & ', ' & DllStructGetData($aData[1], 3) & ', ' & DllStructGetData($aData[1], 4) & @CRLF)
    ConsoleWrite('Primary:     ' & $aData[2] & @CRLF)
    ConsoleWrite('Device name: ' & $aData[3] & @CRLF)
EndIf

 

Share this post


Link to post
Share on other sites

#11 ·  Posted

ok rereading your post please check the examples on

_WinAPI_EnumDisplayMonitors

_WinAPI_EnumDisplayDevices

After you get a DisplayDevice.DeviceName like //./DisplayX from EnumDisplayDevices, you are supposed to call 'EnumDisplayDevices' a second time, this time providing the 'DisplayDevice.DeviceName' that you got from the previous call as lpDevice, and '0' as iDevNum. Then you'll have the monitor name in DisplayDevice.DeviceString.

Share this post


Link to post
Share on other sites

#12 ·  Posted

Thanks for all the help. I will try to write a new script. When finished I will post the script here

Share this post


Link to post
Share on other sites

#13 ·  Posted

Long time has passed, but finally I found some time to work on the code.

The info of Junkew just pointed me in the right direction. There is an example on the page of WinApi_EnumDisplayMonitors with exact the code I needed

; Declare Variables
   Local $aPos, $aData = _WinAPI_EnumDisplayMonitors()

   ; Walk through every display and save positions
   If IsArray($aData) Then
       ReDim $aData[$aData[0][0] + 1][5]
       For $i = 1 To $aData[0][0]
           $aPos = _WinAPI_GetPosFromRect($aData[$i][1])
           For $j = 0 To 3
               $aData[$i][$j + 1] = $aPos[$j]
           Next
       Next
   EndIf

   ; DEBUG - Show Array Info
   _ArrayDisplay($aData, 'Display Info')

 

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now