Jump to content

Keep GUICreate within visible desktop area with multiple screens


McLEMUR
 Share

Go to solution Solved by McLEMUR,

Recommended Posts

Hi!

I need a function or some other setting that would keep my GUICreate within visible desktop area, when there two or three displays.

Untitled_1.jpg

I can find RED values with the DllCall, however I cannot find underlined values.

Point on the program is to show current background images from all desktops, so that user would be able to move liked background to favorites. (In my case I have 150000+ images in slideshow every minute, and this program help to sort though these images)

Program creates GUI/s around the mouse (GUI size varies with the size of background/s) and problem occurs as shown in the picture (blue rectangles)

How can I guard against cases like shown in the image?

I calculate me positions in: getWinPos($fPosCount) Line: 212

 

Here is Wallpaper Fav. script:

#include <String.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <FileConstants.au3>
#include <GDIPlus.au3>
#include <ButtonConstants.au3>
#include <GUIConstants.au3>
#include <Misc.au3>
;~ #include <WinAPI.au3>
Global $ScaleWidth = 600
Global $favpath = "E:\Wallpaper\Favorite_Wallpaper\"
Global $opnexp[3]=      [99999,99999,99999]
Global $rem[3]=         [99999,99999,99999]
Global $MsboxInfo[3]=   [99999,99999,99999]
Global $close,$monNum,$Switch=0,$pic,$begin=0,$Gui[3],$mpos[2],$CurrPath[3],$dImage[3][2];[id][width,height]


; careful about regestry way on x64 systems
; WinWaitActive("[CLASS:WorkerW]") may change based on different systems

;~ Global $NumofMon = 1
Global $NumofMon = _GetSystemMetricsDll($SM_CMONITORS)
If $NumofMon > 3 Then MsgBox(16, "CRITICAL ERROR", "More moniors then supported!")


_GDIPlus_Startup()

While 1
;~    If _IsPressed('20') Then HotKey()
   If _IsPressed('05') and _IsPressed('06')  Then HotKey()
   If $Switch=1 Then
      Switch GUIGetMsg()
         Case 99999
            MsgBox(16, "CRITICAL ERROR", "L:77. Impossible GUIGetMsg() = 99999")

         Case $MsboxInfo[0]
            MsgBox(262144,"Info0",_getpath(0))
         Case $MsboxInfo[1]
            MsgBox(262144,"Info1",_getpath(1))
         Case $MsboxInfo[2]
            MsgBox(262144,"Info2",_getpath(2))

         Case $opnexp[0]
            Run("explorer.exe /n,/e,/select,"&_getpath(0))
            HotKey()
         Case $opnexp[1]
            Run("explorer.exe /n,/e,/select,"&_getpath(1))
            HotKey()
         Case $opnexp[2]
            Run("explorer.exe /n,/e,/select,"&_getpath(2))
            HotKey()

         Case $rem[0]
            FileRecycle(_getpath(0))
            HotKey()
         Case $rem[1]
            FileRecycle(_getpath(1))
            HotKey()
         Case $rem[2]
            FileRecycle(_getpath(2))
            HotKey()

         Case $GUI_EVENT_PRIMARYDOWN
            $close = $close + 1
            $begin = TimerInit()
            If $close = 2 Then
               $close = 0
               ToolTip("Favored")
               FileCopy(_getpath(WinGetTitle('')),$favpath,$FC_OVERWRITE + $FC_CREATEPATH)
               HotKey()
            EndIf

         Case $GUI_EVENT_CLOSE
            _GDIPlus_Shutdown()
            Exit
      EndSwitch

      If $NumofMon = 1 Then
         update_check(0)
      ElseIf $NumofMon = 2 Then
         update_check(0)
         update_check(1)
      ElseIf $NumofMon = 3 Then
         update_check(0)
         update_check(1)
         update_check(2)
      EndIf

   EndIf

   If TimerDiff($begin) > 200 Then $close = 0
   If TimerDiff($begin) > 1000 Then ToolTip("")
   Sleep(5)
WEnd
 _GDIPlus_Shutdown()

Func update_check($checkid)
   If $CurrPath[$checkid] <> _getpath($checkid) Then
      $CurrPath[$checkid] = _getpath($checkid)
      DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[$checkid], "int", 200, "long", 0x00090000) ; fade-out
      GUIDelete($Gui[$checkid])
      show($checkid)
      DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[$checkid], "int", 200, "long", 0x00080000) ; fade-in
      GUISetState(@SW_SHOW, $Gui[$checkid])
   EndIf
EndFunc


Func HotKey()
   If $Switch=0 and WinWaitActive("[CLASS:WorkerW]")<>0 Then
      Global $mpos = MouseGetPos()

      If $NumofMon = 1 Then
         show(0)
         DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[0], "int", 200, "long", 0x00080000) ; fade-in
         GUISetState(@SW_SHOW, $Gui[0])
      ElseIf $NumofMon = 2 Then
         show(0)
         show(1)
         DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[0], "int", 200, "long", 0x00080000) ; fade-in
         DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[1], "int", 200, "long", 0x00080000) ; fade-in
         GUISetState(@SW_SHOW, $Gui[0])
         GUISetState(@SW_SHOW, $Gui[1])
      ElseIf $NumofMon = 3 Then
         show(0)
         show(1)
         show(2)
         DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[0], "int", 200, "long", 0x00080000) ; fade-in
         DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[1], "int", 200, "long", 0x00080000) ; fade-in
         DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[2], "int", 200, "long", 0x00080000) ; fade-in
         GUISetState(@SW_SHOW, $Gui[0])
         GUISetState(@SW_SHOW, $Gui[1])
         GUISetState(@SW_SHOW, $Gui[2])
      Else
         MsgBox(16,"ERROR","L:135. Failed to initialize graphical interface.")
      EndIf
   $Switch=1
   Else
      If $NumofMon = 1 Then
         DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[0], "int", 200, "long", 0x00090000) ; fade-out
         GUIDelete($Gui[0])
      ElseIf $NumofMon = 2 Then
         DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[0], "int", 200, "long", 0x00090000) ; fade-out
         GUIDelete($Gui[0])
         DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[1], "int", 200, "long", 0x00090000) ; fade-out
         GUIDelete($Gui[1])
      ElseIf $NumofMon = 3 Then
         DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[0], "int", 200, "long", 0x00090000) ; fade-out
         GUIDelete($Gui[0])
         DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[1], "int", 200, "long", 0x00090000) ; fade-out
         GUIDelete($Gui[1])
         DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Gui[2], "int", 200, "long", 0x00090000) ; fade-out
         GUIDelete($Gui[2])
      EndIf
   $Switch=0
   EndIf
EndFunc


Func show($monNum)
   Local $path = _getpath($monNum)
   $CurrPath[$monNum] = $path
   Local $hImage = _GDIPlus_ImageLoadFromFile($path)
   Local $ImageWidth = _GDIPlus_ImageGetWidth($hImage)
   $dImage[$monNum][1] = _GDIPlus_ImageGetHeight($hImage)
   $dImage[$monNum][1] = $dImage[$monNum][1]/($ImageWidth/$ScaleWidth)
   $dImage[$monNum][0] = $ScaleWidth
   If StringUpper ( StringRight($path, 3 )) = 'PNG' Then
      $sCLSID = _GDIPlus_EncodersGetCLSID("JPG")
      _GDIPlus_ImageSaveToFileEx($hImage, @TempDir & "\"&$monNum&".JPG", $sCLSID)
      $path = @TempDir & "\"&$monNum&".JPG"
   EndIf

   _GDIPlus_ImageDispose($hImage)
   Local $WinPos = getWinPos($monNum)

   $Gui[$monNum] = GUICreate($monNum, $ScaleWidth, $dImage[$monNum][1], $WinPos[0], $WinPos[1], $WS_POPUP,BitOR($WS_EX_TOOLWINDOW,$WS_EX_TOPMOST))
   $Pic = GUICtrlCreatePic($path, 0, 0, $ScaleWidth, Round($dImage[$monNum][1]))
   $contm = GUICtrlCreateContextMenu($Pic)
   $opnexp[$monNum] = GUICtrlCreateMenuItem("Open folder", $contm)
   $MsboxInfo[$monNum] = GUICtrlCreateMenuItem("Info", $contm)
   $rem[$monNum] = GUICtrlCreateMenuItem("Remove", $contm)
EndFunc

Func _getpath($x)
   If $NumofMon = 1 Then
      Local $finput = RegRead("HKEY_CURRENT_USER\Control Panel\Desktop","TranscodedImageCache")
   Else
      Local $finput = RegRead("HKEY_CURRENT_USER\Control Panel\Desktop","TranscodedImageCache_00"&$x)
   EndIf

   If @error <> 0 Then MsgBox(16,"ERROR","Could not read regestry entery")
   Local $foutput = ''
   Local $stop = 0
   Local $start = 0

   While $finput <> ''
   If StringLeft( $finput, 2) > 0 Then $foutput &= _HexToString( StringLeft( $finput, 2))
   $finput = StringTrimLeft( $finput, 2)
   WEnd
   $start = StringInStr ( $foutput, ":\")-1
   $stop = StringInStr ( $foutput, "\\?\DISPLAY")
   $foutput = StringMid( $foutput, $start, $stop-$start)
;~   MsgBox(0,204,$foutput)
   If FileExists($foutput) = 0 Then
      MsgBox(16,"ERROR","Func:_getpath; file dosenot exist")
      $foutput = @ScriptDir & "\error.jpg"
   EndIf
   Return $foutput
EndFunc

Func getWinPos($fPosCount)
   Local $aRetturn[2]
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   If $NumofMon = 1 Then
      $aRetturn[0]=$mpos[0]-($dImage[$fPosCount][0]/2)
      $aRetturn[1]=$mpos[1]-($dImage[$fPosCount][1]/2)
      If $mpos[1] - ($dImage[$fPosCount][1]/2) < 0 Then $aRetturn[1] = 0 ;Top guard
      If $mpos[1] + ($dImage[$fPosCount][1]/2) > @DesktopHeight Then $aRetturn[1] = @DesktopHeight - $dImage[$fPosCount][1] ;Bottom guard
      If $mpos[0] - ($dImage[$fPosCount][0]/2) < 0 Then $aRetturn[0] = 0 ;Left guard
      If $mpos[0] + ($dImage[$fPosCount][0]/2) > @DesktopWidth Then $aRetturn[0] = @DesktopWidth - $dImage[$fPosCount][0] ;Right guard
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   ElseIf $NumofMon = 2 Then
      Local $VirtY = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 79)
      Local $VirtX = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 78)
      Local $LSVS = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 76)
      If $fPosCount = 0 Then
         If $mpos[1] - ($dImage[$fPosCount][1]/2) < 0 Then $mpos[1] = ($dImage[$fPosCount][1]/2) ;Top guard
         If $mpos[1] + ($dImage[$fPosCount][1]/2) > $VirtY[0] Then $mpos[1] = $VirtY[0] - ($dImage[$fPosCount][1]/2) ;Bottom guard
         If $mpos[0] - $dImage[$fPosCount][0] < $LSVS[0] Then $mpos[0] = $LSVS[0] + $dImage[$fPosCount][0];Left guard
         $aRetturn[0]=$mpos[0]-$dImage[$fPosCount][0]
         $aRetturn[1]=$mpos[1]-($dImage[$fPosCount][1]/2)
      EndIf
      If $fPosCount = 1 Then
         If $mpos[1] - ($dImage[$fPosCount][1]/2) < 0 Then                          ;Top guard
            $mpos[1] =  ($dImage[$fPosCount][1]/2)
            WinMove($Gui[0],"",$mpos[0] - $dImage[0][0],$mpos[1] - ($dImage[0][1]/2))
         EndIf                                                                      ;Top guard
         If $mpos[1] + ($dImage[$fPosCount][1]/2) > $VirtY[0] Then                  ;Bottom guard
            $mpos[1] = $VirtY[0] - ($dImage[$fPosCount][1]/2)
            WinMove($Gui[0],"",$mpos[0] - $dImage[0][0],$mpos[1] - ($dImage[0][1]/2))
         EndIf                                                                      ;Bottom guard
         If $mpos[0] + $dImage[$fPosCount][0] > $VirtX[0] - Abs($LSVS[0]) Then      ;Right guard
            $mpos[0] = $VirtX[0] - Abs($LSVS[0]) - $dImage[$fPosCount][0]
            WinMove($Gui[0],"",$mpos[0] - $dImage[0][0],$mpos[1]-($dImage[0][1]/2))
         EndIf                                                                      ;Right guard
         $aRetturn[0]=$mpos[0]+10
         $aRetturn[1]=$mpos[1]-($dImage[$fPosCount][1]/2)
      EndIf
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   ElseIf $NumofMon = 3 Then
      Local $VirtY = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 79)
      Local $LSVS = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 76)
      Local $VirtX = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 78)
      If $fPosCount = 0 Then
         If $mpos[1] - $dImage[$fPosCount][1] < 0 Then $mpos[1] =  $dImage[$fPosCount][1] ;Top guard
         If $mpos[0] - $dImage[$fPosCount][0] < $LSVS[0] Then $mpos[0] = $LSVS[0] + $dImage[$fPosCount][0];Left guard
         $aRetturn[0]=$mpos[0]-$dImage[$fPosCount][0]
         $aRetturn[1]=$mpos[1]-$dImage[$fPosCount][1]
      EndIf
      If $fPosCount = 1 Then
         If $mpos[1] - $dImage[$fPosCount][1] < 0 Then                              ;Top guard
            $mpos[1] = $dImage[$fPosCount][1]
            WinMove($Gui[0],"",$mpos[0] - $dImage[0][0],$mpos[1] - $dImage[0][1])
         EndIf                                                                      ;Top guard
         If $mpos[0] + $dImage[$fPosCount][0] > $VirtX[0] - Abs($LSVS[0]) Then      ;Right guard
            $mpos[0] = $VirtX[0] - Abs($LSVS[0]) - $dImage[$fPosCount][0]
            WinMove($Gui[0],"",$mpos[0] - $dImage[0][0],$mpos[1]-$dImage[0][1])
         EndIf                                                                      ;Right guard
         $aRetturn[0]=$mpos[0]+10
         $aRetturn[1]=$mpos[1]-$dImage[$fPosCount][1] ; error not true monitor top if 0 = actual 28
      EndIf
      If $fPosCount = 2 Then                                                        ;Bottom guard
         If $mpos[1] + $dImage[$fPosCount][1] + 10 > $VirtY[0] Then
            $mpos[1] = $VirtY[0] - $dImage[$fPosCount][1] - 10
            WinMove($Gui[0],"",$mpos[0] - 10 - $dImage[0][0],$mpos[1] - $dImage[0][1])
            WinMove($Gui[1],"",$mpos[0],$mpos[1]-$dImage[1][1])
         EndIf
         $aRetturn[0]=$mpos[0]-$dImage[$fPosCount][0]+($dImage[$fPosCount][0]/2)
         $aRetturn[1]=$mpos[1]+10
      EndIf                                                                         ;Bottom guard
   EndIf
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Return $aRetturn
EndFunc

Func _GetSystemMetricsDll($iIndex)
   Local $aResult = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $iIndex)
   If @error Then Return SetError(@error, @extended, 0)
   Return $aResult[0]
EndFunc   ;==>_WinAPI_GetSystemMetrics

And here is how I get my screen values:

;~    MsgBox(0,@DesktopHeight,@DesktopWidth)
; use this to debug in console window <--- LOOK
;#AutoIt3Wrapper_run_debug_mode=Y

;author: ahha
;filename: determine screen sizes v1b.au3

;<a href='http://msdn.microsoft.com/en-us/library/ms724385%28VS.85%29.aspx' class='bbc_url' title='External link' rel='nofollow external'>http://msdn.microsoft.com/en-us/library/ms724385%28VS.85%29.aspx</a>

$VirtX = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 78)    ;SM_CXVIRTUALSCREEN 78
;The width of the virtual screen, in pixels. The virtual screen is the bounding rectangle of all display monitors.
;The SM_XVIRTUALSCREEN metric is the coordinates for the left side of the virtual screen.

$VirtY = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 79)    ;SM_CYVIRTUALSCREEN 79
;The height of the virtual screen, in pixels. The virtual screen is the bounding rectangle of all display monitors.
;The SM_YVIRTUALSCREEN metric is the coordinates for the top of the virtual screen.

$Mons = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 80) ;SM_CMONITORS 80
;The number of display monitors on a desktop. For more information, see the Remarks section in this topic.

;Remarks
;System metrics can vary from display to display.
;GetSystemMetrics(SM_CMONITORS) counts only visible display monitors. This is different from EnumDisplayMonitors, which enumerates both visible display monitors and invisible pseudo-monitors that are associated with mirroring drivers. An invisible pseudo-monitor is associated with a pseudo-device used to mirror application drawing for remoting or other purposes.


$LSVS = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 76)     ;SM_XVIRTUALSCREEN 76
;The coordinates for the left side of the virtual screen. The virtual screen is the bounding rectangle of all display monitors.
;The SM_CXVIRTUALSCREEN metric is the width of the virtual screen.

$TSVS = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 77)     ;SM_YVIRTUALSCREEN 77
;The coordinates for the top of the virtual screen. The virtual screen is the bounding rectangle of all display monitors.
;The SM_CYVIRTUALSCREEN metric is the height of the virtual screen.

$PriDispX = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 0)  ;SM_CXSCREEN 0
;The width of the screen of the primary display monitor, in pixels.
;This is the same value obtained by calling GetDeviceCaps as follows: GetDeviceCaps( hdcPrimaryMonitor, HORZRES).

$PriDispY = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 1)  ;SM_CYSCREEN 1
;The height of the screen of the primary display monitor, in pixels.
;This is the same value obtained by calling GetDeviceCaps as follows: GetDeviceCaps( hdcPrimaryMonitor, VERTRES).


$mz = "SM_CXSCREEN = "&$PriDispX[0] &"   SM_CYSCREEN = "&$PriDispY[0]
$m0 = "@DesktopWidth = "&@DesktopWidth &"   @DesktopHeight = "&@DesktopHeight
$m1 = "Number of visible screen monitors: " & $Mons[0]
$m2 = "Maximum size of 'virtual screen' : " & $VirtX[0] &"x"& $VirtY[0]
$m3 = "Full 'virtual screen' coordinates: " & $LSVS[0] &"," & $TSVS[0] &" to "& $VirtX[0] &","& $VirtY[0]
MsgBox(0+262144, "Status of determine screen sizes", $mz &@CRLF& $m0 &@CRLF& $m1 &@CRLF& $m2 &@CRLF& $m3)
Edited by McLEMUR

The loneliness is when even SPAM does not come...

Link to comment
Share on other sites

why

$PriDispY = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 1)

and not

see microsoft link at help file for numbers to use

#include <WinAPI.au3>

$PriDispY = _WinAPI_GetSystemMetrics(1)

i now this don't awnser your question

Edited by Spider001
Link to comment
Share on other sites

why

$PriDispY = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 1)

and not

see microsoft link at help file for numbers to use

 

#include <WinAPI.au3>

$PriDispY = _WinAPI_GetSystemMetrics(1)

i now this don't awnser your question

 

If you look at #include <WinAPI.au3> you'll see that these two cases are exactly the same:

Func _WinAPI_GetSystemMetrics($iIndex)
    Local $aResult = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $iIndex)
    If @error Then Return SetError(@error, @extended, 0)

    Return $aResult[0]
EndFunc   ;==>_WinAPI_GetSystemMetrics

And my script:

$VirtY = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 79)

The loneliness is when even SPAM does not come...

Link to comment
Share on other sites

I'm still working out calculations, but I created 3 IF based on 3 different monitor setups(main/monitor/monitor; monitor/main/monitor; monitor/monitor/main), then within each IF created 3 other IF statements, which split MouseGetPos() into 3 cases based on x coordinate. So it came out to 12 nested IF statements. I've yet to finish calculations and testing but I'm still open to any other suggestions. In particular I have trouble calculating width of middle desktop in the case of main display is to the far most right to far most left - hence:

  • Is there a way to find out resolution of the monitor in which the mouse is in?
  • Is there a way to read information out of "Screen Resolution" when right clicking on the desktop? (that tooltip appears only when screen in question is grabbed and dragged around)

Untitled.jpg

ps. I know its a really specialized question since not many people had to deal with this problem, but please any idea will help.

The loneliness is when even SPAM does not come...

Link to comment
Share on other sites

The screen resolution of your video card registry

; Проверяем харды на наличие OS, и при упехе вытаскиваем установки разрешения экрана из реестра
$GUID = ''
$XResolution = ''
$YResolution = ''
$VRefresh = ''
For $i = 1 To $DrivesArr[0]
    $DrTp = DriveGetType($DrivesArr[$i] & '\')
    If $DrTp = 'Removable' Then $DrTp = 'Rem'
    If $DrivesArr[$i] <> 'A:' And $DrTp <> 'CDROM' And $DrTp <> 'Removable' And FileExists($DrivesArr[$i] & '\' & $Bootini & '\system32\config\system') Then
        Run(@ComSpec & ' /C REG LOAD HKLM\XP_SYSTEM ' & $DrivesArr[$i] & '\' & $Bootini & '\system32\config\system', '', @SW_HIDE)
        Sleep(100)
        $GUID = RegEnumKey("HKLM\XP_SYSTEM\ControlSet001\Hardware Profiles\0001\System\CurrentControlSet\Control\VIDEO", 2)
        ;$GUID = StringRegExpReplace($GUID, '(^.*)(\{.*\})(.*)$', '\2')
        $XResolution = RegRead('HKLM\XP_SYSTEM\ControlSet001\Hardware Profiles\0001\System\CurrentControlSet\Control\VIDEO\' & $GUID & '\0000', 'DefaultSettings.XResolution')
        $YResolution = RegRead('HKLM\XP_SYSTEM\ControlSet001\Hardware Profiles\0001\System\CurrentControlSet\Control\VIDEO\' & $GUID & '\0000', 'DefaultSettings.YResolution')
        $VRefresh = RegRead('HKLM\XP_SYSTEM\ControlSet001\Hardware Profiles\0001\System\CurrentControlSet\Control\VIDEO\' & $GUID & '\0000', 'DefaultSettings.VRefresh')
        RunWait(@ComSpec & ' /C REG UNLOAD HKLM\XP_SYSTEM', '', @SW_HIDE)
        If $L = 1 Then FileWrite($filelog, 'получены параметры из реестра X=' & $XResolution & ', Y=' & $YResolution & ', F=' & $VRefresh & 'Гц' & @CRLF)
        ExitLoop
    EndIf
Next

; Вытаскиваем разрешение экрана из потока данных
$rnim = Run(@TempDir & '\DumpEDID.exe', @TempDir, @SW_HIDE, 2)
$param = ''
While 1
    $param &= StdoutRead($rnim)
    If @error Then ExitLoop
WEnd
FileDelete(@TempDir & '\DumpEDID.exe') ; если нужен файл DumpEDID.exe, то закомментировать эту строку
$resize = StringRegExpReplace($param, '(?s)(.*Maximum Resolution.*?)(\d{3,}) X (\d{3,}).*', '\2|\3')
If $resize = '' Or @extended = 0 Or StringInStr($resize, @CRLF) Then
    $resize = StringRegExpReplace($param, '(?s)(.*\r\nImage Size.*?)(\d{2,}\S* X \d{2,}\S*).*', '\2')
    If $resize = '' Or @extended = 0 Or StringInStr($resize, @CRLF) Then $resize = '0|0' ; выход из скрипта если данные не получены
    Switch $resize
        Case '22.3 X 12.5'
            $resize = '1024|600'
            If $L = 1 Then FileWrite($filelog, 'детект образца 22.3 X 12.5: ' & $resize & @CRLF)
            ;Case '25.4 X 13.7'    ; липовый пример как добавить дополнительную интерпретацию, скопировав две строки и указав данные. Добавлять можно сколько угодно.
            ;   $resize='1280|800'
            ; Case Else
            ; Exit
    EndSwitch
EndIf
If $L = 1 Then FileWrite($filelog, 'DumpEDID выдал параметры: ' & $resize & @CRLF)

Here's another calculation function: - >_SetCoor

Link to comment
Share on other sites

  • Solution

The screen resolution of your video card registry

; Проверяем харды на наличие OS, и при упехе вытаскиваем установки разрешения экрана из реестра
$GUID = ''
$XResolution = ''
$YResolution = ''
$VRefresh = ''
For $i = 1 To $DrivesArr[0]
    $DrTp = DriveGetType($DrivesArr[$i] & '\')
    If $DrTp = 'Removable' Then $DrTp = 'Rem'
    If $DrivesArr[$i] <> 'A:' And $DrTp <> 'CDROM' And $DrTp <> 'Removable' And FileExists($DrivesArr[$i] & '\' & $Bootini & '\system32\config\system') Then
        Run(@ComSpec & ' /C REG LOAD HKLM\XP_SYSTEM ' & $DrivesArr[$i] & '\' & $Bootini & '\system32\config\system', '', @SW_HIDE)
        Sleep(100)
        $GUID = RegEnumKey("HKLM\XP_SYSTEM\ControlSet001\Hardware Profiles\0001\System\CurrentControlSet\Control\VIDEO", 2)
        ;$GUID = StringRegExpReplace($GUID, '(^.*)(\{.*\})(.*)$', '\2')
        $XResolution = RegRead('HKLM\XP_SYSTEM\ControlSet001\Hardware Profiles\0001\System\CurrentControlSet\Control\VIDEO\' & $GUID & '\0000', 'DefaultSettings.XResolution')
        $YResolution = RegRead('HKLM\XP_SYSTEM\ControlSet001\Hardware Profiles\0001\System\CurrentControlSet\Control\VIDEO\' & $GUID & '\0000', 'DefaultSettings.YResolution')
        $VRefresh = RegRead('HKLM\XP_SYSTEM\ControlSet001\Hardware Profiles\0001\System\CurrentControlSet\Control\VIDEO\' & $GUID & '\0000', 'DefaultSettings.VRefresh')
        RunWait(@ComSpec & ' /C REG UNLOAD HKLM\XP_SYSTEM', '', @SW_HIDE)
        If $L = 1 Then FileWrite($filelog, 'получены параметры из реестра X=' & $XResolution & ', Y=' & $YResolution & ', F=' & $VRefresh & 'Гц' & @CRLF)
        ExitLoop
    EndIf
Next

; Вытаскиваем разрешение экрана из потока данных
$rnim = Run(@TempDir & '\DumpEDID.exe', @TempDir, @SW_HIDE, 2)
$param = ''
While 1
    $param &= StdoutRead($rnim)
    If @error Then ExitLoop
WEnd
FileDelete(@TempDir & '\DumpEDID.exe') ; если нужен файл DumpEDID.exe, то закомментировать эту строку
$resize = StringRegExpReplace($param, '(?s)(.*Maximum Resolution.*?)(\d{3,}) X (\d{3,}).*', '\2|\3')
If $resize = '' Or @extended = 0 Or StringInStr($resize, @CRLF) Then
    $resize = StringRegExpReplace($param, '(?s)(.*\r\nImage Size.*?)(\d{2,}\S* X \d{2,}\S*).*', '\2')
    If $resize = '' Or @extended = 0 Or StringInStr($resize, @CRLF) Then $resize = '0|0' ; выход из скрипта если данные не получены
    Switch $resize
        Case '22.3 X 12.5'
            $resize = '1024|600'
            If $L = 1 Then FileWrite($filelog, 'детект образца 22.3 X 12.5: ' & $resize & @CRLF)
            ;Case '25.4 X 13.7'    ; липовый пример как добавить дополнительную интерпретацию, скопировав две строки и указав данные. Добавлять можно сколько угодно.
            ;   $resize='1280|800'
            ; Case Else
            ; Exit
    EndSwitch
EndIf
If $L = 1 Then FileWrite($filelog, 'DumpEDID выдал параметры: ' & $resize & @CRLF)
Here's another calculation function: - >_SetCoor

 

 

 

 

Yes! This is it.

I have rewritten your version here to work for all people who struggle with several displays and their relative positions to one another(Win 8): 

#include <WinAPI.au3>

getMonParam()

Func getMonParam()
   Local $aDevice, $i = 0, $sText
   While 1
      $aDevice = _WinAPI_EnumDisplayDevices("", $i)
      If @error Or Not $aDevice[0] Then Exit ;_WinAPI fail
      If BitAND($aDevice[3], 1) Then
         $regMonIDnum = StringTrimLeft(RegRead("HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\VIDEO", "\Device\Video"&StringTrimLeft($aDevice[1],11)),17)
         $regPathTrue = "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\UnitedVideo\CONTROL\VIDEO\"&StringTrimLeft($regMonIDnum,StringInStr($regMonIDnum,"\{"))
         $rOffSetX=Dec(Hex(RegRead($regPathTrue,"Attach.RelativeX"),8)) ;Left most cordinate
         $rOffSetY=Dec(Hex(RegRead($regPathTrue,"Attach.RelativeY"),8)) ;Top most cordinate
         $rScrRezX=RegRead($regPathTrue,"DefaultSettings.XResolution")  ;Right most cordinate
         $rScrRezY=RegRead($regPathTrue,"DefaultSettings.YResolution")  ;Bottom most cordinate
         If $rScrRezX="" And $rScrRezY="" Then ;Means that this is primary display
            $rScrRezX=@DesktopWidth
            $rScrRezY=@DesktopHeight
         EndIf
         MsgBox(0, StringTrimLeft($aDevice[1],11),$regPathTrue&@CRLF&@CRLF&"Left most cordinate: "&$rOffSetX&@CRLF&"Top most cordinate: "&$rOffSetY&@CRLF&"Right most cordinate: "&$rScrRezX&@CRLF&"Bottom most cordinate: "&$rScrRezY)
      EndIf
      $i += 1
   WEnd
EndFunc

P.S. If you have more questions about this problem,  I found 'Superuser' topic that discuses similar problem. PM me and I'll give the link.

Edited by McLEMUR

The loneliness is when even SPAM does not come...

Link to comment
Share on other sites

  • 2 years later...

This is a bit off-topic, but still relevant. Is there a way to set a given display as main display, and also check which display is currently the main one? Windows lacks a shortcut for "Make this my main display" checkbox and it would be sooooo useful. 

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...