Sign in to follow this  
Followers 0
ces1a

Wrong Screen Resolution Displayed by Autoit Macros

7 posts in this topic

I recently upgraded my laptop to one with Windows 10 and higher screen resolution.  In the process I found that some of my scripts did not work right when using Autoit's @DesktopWidth and @DesktopHeight macros.  Insteat of 1920 x 1080 resolution Autoit detects 1536 x 864.  Thus, GUIs designed to appear near the right edge of the screen  displayed closer to the horizontal middle of the screen.  I assume others may have the same problem.

A search on this forum and Microsoft Script Center helped me to write the following script that gets the true screen width and height from WMI.

MsgBox(0, '', _GetMonitorInfo())

Func _GetMonitorInfo()
    Local $oWMI, $Listing, $sWidth = 0, $sHeight = 0
    $oWMI = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
    If IsObj($oWMI) Then
        $Listing = $oWMI.ExecQuery("SELECT * FROM Win32_DesktopMonitor")
        If IsObj($Listing) Then
            For $oItem In $Listing
                $sHeight = $oItem.ScreenHeight
                $sWidth = $oItem.ScreenWidth
            Next
        EndIf
    EndIf
    Return "Width: " & $sWidth & @CRLF & "Height: " & $sHeight
EndFunc ;_GetMonitorInfo


Hopefully it will benefit others.  I for sure am very happy with all the samples I been able to find here in the past.

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Have you tried adding:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Res_HiDpi=Y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Then when you compile the code this works on W7 and 8 at least Could you try it on your win 10 install 

Edited by Bilgus

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

This can happen when Win10 auto-rescales (see under display settings, I think 125% is default for 1920x1080) to make them easier to read (as hi-res screens make everything that used to look about the right size look tiny now). To make your original script work in full resolution (with macros returning the correct (full) dimensions), while maintaining rescaling for regular programmes, add:

DllCall("User32.dll","bool","SetProcessDPIAware")

This causes the script to take advantage of the full current resolution, but at the cost of its text and graphics appearing smaller than if running rescaled.

Edited by RTFC

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

3 hours ago, RTFC said:

This can happen when Win10 auto-rescales (see under display settings, I think 125% is default for 1920x1080) to make them easier to read (as hi-res screens make everything that used to look about the right size look tiny now). To make your original script work in full resolution (with macros returning the correct (full) dimensions), while maintaining rescaling for regular programmes, add:

DllCall("User32.dll","bool","SetProcessDPIAware")

This causes the script to take advantage of the full current resolution, but at the cost of its text and graphics appearing smaller than if running rescaled.

Hey, Thanks.

Noted This: https://msdn.microsoft.com/en-us/library/windows/desktop/ms633543(v=vs.85).aspx

Note  SetProcessDPIAware is subject to a possible race condition if a DLL caches dpi settings during initialization. For this reason, it is recommended that dpi-aware be set through the application (.exe) manifest rather than by calling SetProcessDPIAware.

 

So it sounds like something like this is in order.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Res_HiDpi=Y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

If Not (@Compiled ) Then DllCall("User32.dll","bool","SetProcessDPIAware")

 

 

Edited by Bilgus

Share this post


Link to post
Share on other sites

Thanks a lot to everyone.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Res_HiDpi=Y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

The above lines seem to make my executable unable to run.  I have not figured out why yet.

DllCall("User32.dll","bool","SetProcessDPIAware")

Lets my script run but causes distortion to my labels,

However, looks like this is the right direction to go.

Thanks a million...

 

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

I know turning scaling off would change your labels not sure about the app not running with the manifest entry added though.

I wonder if maybe it has something to do with this: 'SetProcessDPIAware is available for use in the operating systems specified in the Requirements section. It may be altered or unavailable in subsequent versions. Instead, use SetProcessDpiAwareness'

SetProcessDpiAwareness: https://msdn.microsoft.com/en-us/library/windows/desktop/dn302122(v=vs.85).aspx

It seems to have the same caveats as SetProcessDPIAware as in placing in manifest rather than calling the function directly,

it also isn't available till win 8 and later.

Perhaps W10 won't work with the older function in the manifest which I find odd. If so,  I think additions to the manifest or logic would be something that would have to be updated in the Autoit  Res_HiDpi Pragma

Maybe someone more knowledgeable with aut2Exe  would be able to inform us on that.

For the time being maybe you should use either your current function or maybe do something like this:

If @OsType="WIN_10" Then
    DllCall("Shcore.dll","long","PROCESS_DPI_AWARENESS",1) 
Else
    DllCall("User32.dll","bool","SetProcessDPIAware") 
EndIf
;hResult is 32bit

;PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE  = 2

Not sure if I got that dll call right I'm not near a PC to test atm.

Also, Not necessarily directed at you:
I'm unsure how likely it is that a Dll would cache the dpi data.

Would the Dll be something called by Autoit or the OS. 

What exact situation would result in this Race Condition and what are the consequences?

Be something to look into as the MSDN page is kind of vague.

Edited by Bilgus
changed return type on Shcore.dll to long

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
Sign in to follow this  
Followers 0

  • Similar Content

    • mdwerne
      By mdwerne
      Hello,
      I'm working on a script that writes detailed application event logs, and I'd like to know if there is a way with Autoit to write multiple lines of XML EventData (see example below):
      <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> <System> <Provider Name="Application" /> <EventID Qualifiers="0">1001</EventID> <Level>4</Level> <Task>0</Task> <Keywords>0x80000000000000</Keywords> <TimeCreated SystemTime="2015-07-12T21:26:07.000000000Z" /> <EventRecordID>86554</EventRecordID> <Channel>Application</Channel> <Computer>YOUR_COMPUTER</Computer> <Security /> </System> <EventData> <Data>DeskTop Agent: Mike</Data> <Data>Observer Username: Miguel</Data> etc... </EventData> </Event> So far, using EventCreate, everything I send end's up in a single <data> entry (see below):
      <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> <System> <Provider Name="Application" /> <EventID Qualifiers="0">1001</EventID> <Level>4</Level> <Task>0</Task> <Keywords>0x80000000000000</Keywords> <TimeCreated SystemTime="2015-07-12T21:26:07.000000000Z" /> <EventRecordID>86554</EventRecordID> <Channel>Application</Channel> <Computer>YOUR_COMPUTER</Computer> <Security /> </System> <EventData> <Data>DeskTop Agent: Mike Observer Username: Miguel</Data> </EventData> </Event> Here is the code I'm using thus far (which does not work the way I'd like):
      $LogData = @CRLF & "DeskTop Agent: " & @UserName & @CRLF & "Observer Username: " & $DTObserver & @CRLF & "File name/s with extension: " & $FilenameWextension & @CRLF & "Action Performed: " & $ActionPerformed & @CRLF & "Explanation: " & $Explanation & @CRLF & "Machine Name: " & @ComputerName & @CRLF & "IP Address: " & @IPAddress1 & @CRLF & "App1Installed: " & $App1 & @CRLF & "App2Installed: " & $App2 Run("eventcreate /T Information /ID 100 /L Application /SO DTALog /D " & Chr(34) & "DTALog Details: " & $LogData & Chr(34), "", @SW_HIDE, 2) I found a Stackoverflow post that talks about doing it in C# (https://stackoverflow.com/questions/7694276/how-to-add-multiple-lines-of-eventdata-to-an-eventlog-in-windows)
      but I'd like to determine if it can be accomplished with AutoIt!.
      Thanks for your time,
      -Mike
    • Shirdish_chakravarthi
      By Shirdish_chakravarthi
      i am working on a application where if the flashing is success i get a window saying "SUCCESS" and if the flashing failed a window saying "FAILED" and i have to automatically identify pass or fail.the problem is both the windows are having the same control ID. how can i differentiate between both windows? so that i can make use of that in script for automation///
       
       
      Thanks
    • comtech80
      By comtech80
      Folks,
      I have an issue I've been trying to solve for a while, I'm trying to add static routes in DHCP via a 121 route rule in Windows 2012 R2 is a brutal manual process and wanted to automate this via AutoIT.
       
      When I use the "ControlGetText" everything displays properly in the MSG box but when I try and use "ControlSetText" or "ControlSend" the values won't display in the input box but the action comes back as successful?
      Anyone able to help me with this? I'm thinking this might be an active window issue but i'm not sure.
      Here is a part of my code.
       
      $hWnd = WinWait("[TITLE:Add a Static Route]","", 10)
      WinActivate($hWnd)
      $Status = ControlSend($hWnd, "", "[CLASS:Edit; INSTANCE:4]", "192"); Does not add 192 to the text box.
      Local $sTextEdit1 = ControlGetText($hWnd, "", "[CLASS:Edit; INSTANCE:1]")
      ConsoleWrite ( "ControlSend Status: " &  $Status & @CRLF); Returns a Value of 1
      ConsoleWrite ( "ControlGetText Value Edit1: " &  $sTextEdit1 & @CRLF);
       
      Please see attachment for more info.

    • lganta
      By lganta
      Hello!
      I created some scripts for a simple farming bot a few years ago and they rely on ControlSend.
      A year ago I quit that game and then installed Windows 10 (was using windows 7).
      Recently I installed that game and tried running them again and they seem to work (I have some messages displayed on the screen with the state of the bot ), except for the ControlSend part (which obviously is crucial).
      I started debugging the scripts so I created a basic script that makes use of Send. I tested this with Notepad in focus and works just fine and then with my game window in focus and it didn't work (it's supposed to write that text in an input box from the game).
      #include <MsgBoxConstants.au3> Sleep(3000); Send("some text"); MsgBox($MB_OK, "Notification", "Control was sent!");  
      Is there a way for the creators of the game to create some kind of security system against this? Or something happens because I updated to Windows 10?
      Is there something I'm missing?
      Thank you!
    • nacerbaaziz
      By nacerbaaziz
      Hi dear
      I have a question
      about the display language of the system
      How can I get the current display language and how can I change it by autoit
      Of course, if this is possible
      Greetings to all and hope you help me