Jump to content

Get top-left pixel of window- VDI


MPoud
 Share

Recommended Posts

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.

 

Link to comment
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

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

GPO Tool - Export/Import Group policy settings.

MirrorDir - Synchronize/Backup/Mirror Folders

BeatsPlayer - Music player.

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

String Trigger - Triggers pasting text or applications or internet links on specific strings.

Inconspicuous - Hide files in plain sight, not fully encrypted.

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.

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

Au3Record.exe

Link to comment
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.

Link to comment
Share on other sites

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

Edited by careca
Spoiler

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

GPO Tool - Export/Import Group policy settings.

MirrorDir - Synchronize/Backup/Mirror Folders

BeatsPlayer - Music player.

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

String Trigger - Triggers pasting text or applications or internet links on specific strings.

Inconspicuous - Hide files in plain sight, not fully encrypted.

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.

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

Au3Record.exe

Link to comment
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?

Link to comment
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.

 

 

 

Link to comment
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

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

GPO Tool - Export/Import Group policy settings.

MirrorDir - Synchronize/Backup/Mirror Folders

BeatsPlayer - Music player.

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

String Trigger - Triggers pasting text or applications or internet links on specific strings.

Inconspicuous - Hide files in plain sight, not fully encrypted.

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.

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

Au3Record.exe

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

  • 2 weeks later...
  • 1 month later...

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')

 

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...