Jump to content
benners

Koda Object Inspector vs WinGetpos

Recommended Posts

I am writing a function that when run moves a gui to the bottom of the screen, just above the taskbar. The issue I have is with getting the correct width and height. A simple gui knocked up in Koda is shown (in the object window) in Koda to have a width of 530 and a height of 146. However when trying to get the width and height of the gui to calculate the x and y, WinGetPos[2] and WinGetPos[3] report different values than Koda.

The Koda one gives a better placement and I was wondering what, if any, different properties are they reading.

 I have tried getting different system metrics like borders, captions etc and adding them to values returned from WinGetClientSize but most just end up at the same values of WinGetPos and ended up adding a focus border value to pad the values.

The code below works on my PC (Win 7) and I have tried different themes Aero, classsic etc and it places the gui where intended. Just out of curiosity though, I would like to know why the differing values. Also attached a pic of what the gui looks like on my PC.

#include <GUIConstantsEx.au3>
#include <WinAPISys.au3>

Local $h_GUI = GUICreate('Test', 515, 108, -1, -1)
_GA_GUISetToTaskbar($h_GUI)
GUISetState(@SW_SHOW, $h_GUI)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func _GA_GUISetToTaskbar($h_GUI)
    Local Const $SM_CXFOCUSBORDER = 32

    Local $i_Border = _WinAPI_GetSystemMetrics($SM_CXFOCUSBORDER)

    ; get the working area - taskbar
    Local $t_RECT = _WinAPI_GetWorkArea()

    ; get window height and width
    Local $ai_Pos = WinGetPos($h_GUI)

    WinMove($h_GUI, '', DllStructGetData($t_RECT, 'Right') - ($ai_Pos[2] + $i_Border), DllStructGetData($t_RECT, 'Bottom') - ($ai_Pos[3] + $i_Border))
;~  WinMove($h_GUI, '', DllStructGetData($t_RECT, 'Right') - 530, DllStructGetData($t_RECT, 'Bottom') - 146)
EndFunc   ;==>_GA_GUISetToTaskbar

; Koda Object Inspector
; Width = 530
; Height = 146

; WinGetPos
; Width = 521
; Height = 137

; GUICreate (Koda Code)
; Width = 515
; Height = 108

; WinGetClientSize
; Width = 515
; Height = 108

; _WinAPI_GetSystemMetrics
; $SM_CXFOCUSBORDER = 8
; $SM_CXFIXEDFRAME = 3
; $SM_CYCAPTION = 23

 

GUI.png

Share this post


Link to post
Share on other sites

Try that instead :

#include <GUIConstantsEx.au3>
#include <WinAPISys.au3>

Local $h_GUI = GUICreate('Test', 515, 108, -1, -1)
_GA_GUISetToTaskbar($h_GUI)
GUISetState(@SW_SHOW, $h_GUI)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func _GA_GUISetToTaskbar($h_GUI)
    ; get the working area - taskbar
    Local $t_RECT = _WinAPI_GetWorkArea()

    ; get window height and width
    Local $ai_Pos = WinGetPos($h_GUI)

    WinMove($h_GUI, '', $t_RECT.Right - $ai_Pos[2], $t_RECT.Bottom - $ai_Pos[3])
EndFunc   ;==>_GA_GUISetToTaskbar

 

Share this post


Link to post
Share on other sites

Cheers NIne. I just used the help file example to post. I had used _WinAPI_GetWorkArea().right and _WinAPI_GetWorkArea().left but obviously no capacity to error check and had previously placed it in the same way. I just didn't look right.

The issue still remains with the placement though as the values returned do not match the ones from Koda. On My PC the gui is placed slightly behind the taskbar and a few pixels left of the screen. No biggie, it doesn't affect the program but I'm a bit nitpicky and prefer the gui to be placed slightly better 🧐

Do you know why the width and height values differ?

Share this post


Link to post
Share on other sites

When you define a GUI in Koda, the sizes reflect the client area, whereas WinGetPos returns the true dimensions of the window.  On my Win7 it is perfect. 

image.png.d52c912d999e5f823cdf12427cc4c077.png

Do you have defined a scale in your system (like 125%) ?

Share this post


Link to post
Share on other sites

I Do yes. This system is set at 150 DPI with a resolution of 3840 x 2160. I have reduced it back to the default DPI and 1920 x 1080 still the same. Must be the Aero theme. I can check for theme usage and pad the x and y to compensate.

GUI.png.4e936af0b21b1f3748f8da122970cc25.png

If I add this at the start of the script, the box places correctly, so it is the Aero theme.

DllCall("uxtheme.dll", "none", "SetThemeAppProperties", "int", 0)

Thanks Nine.

Edited by benners
Update

Share this post


Link to post
Share on other sites

I Did. The result is the pic in my last post. I just thought if Koda is getting the values that work, surely I could. I could then add the function to my udf and it should be theme independant.

Share this post


Link to post
Share on other sites

I made some tests with Koda.

1595413568_kodacode.png.9938f3f418464d12463e29596cbb75a7.png

Koda always adds me 1 pixel width & height in the generated code (no big deal)
I typed 108 / 515 in The Object inspector and the code generated is 109 / 516 as you can see in the pic above (and this happened in all Forms I ever created with Koda)

This being said, in benners' script, I placed these lines just after the GUI definition :

Local $aGetClient = WinGetClientSize($h_GUI)
ConsoleWrite("Client " & $aGetClient[0] & "   " & $aGetClient[1] & @lf)

Local $aGetPos = WinGetPos($h_GUI)
ConsoleWrite("Window " & $aGetPos[2] & "   " & $aGetPos[3] & @lf)

Console Results :

Client 515   108
Window 521   140

Which are more or less the sizes benners indicated in his commented lines of the script ("more or less" because of the couple of pixels concerning WinGetPos height, which depends on the OS as Nine discussed in another thread)

There's a problem in the sizes of both pics uploaded by benners :
* 1st pic (in his 1st post) is 556 x 153 pixels, which is much more than AutoIt's window size 521 x 140
* 2nd pic (in another of his post) is only 378 x 130 (in fact it's less than that, as there's a Desktop background surrounding it)

So let's forget Koda for a while : why benners' pics don't have (more or less) the 521 x 140 window size, as Nine's uploaded pic ?
(by the way, it would be a good habit in all these cases to upload only the window, without any surrounding background)

I just confirmed this in the test forum : AutoIt forum script never resizes an uploaded pic (even if you upload small or huge pics), it changes the resolution to lower it a bit, but it never resizes any pic. (edit: which means that when you download a pic from the Forum, it always has the same size as OP's uploaded pic, according to my tests [if a forum member thinks this is false, please let us know, thanks])

And as benners (I think) didn't resize his pics before uploading them, then there is definitely an issue in his pictures sizes. Shouldn't he try first to check what parameters, scale, theme... has to be modified so he can produce a perfect GUI whose size matches exactly WinGetPos ?

When this step will be done, then (maybe) the sizes in Koda Object inspector and Koda generated code will be the same, There's no use to focus on Koda now, before the picture size (the GUI window size) isn't 100% correct.

Good luck & fingers crossed :)

Edited by pixelsearch
infos on AutoIt's forum script

Share this post


Link to post
Share on other sites

Hi pixelsearch,

Yep the pictures were resized. I use Winsnap and have the value of resize set to 70% so it saves forum space, not much but some, especially as they were only for a visual.

The first one was a snapshot of a Window just so folks could see the border and caption styles which may indicate other valuers needed to be added, perhaps using the _WinAPI_GetSystemMetrics.

The second was a snapshot of a region, just drawn by me to illustrate the GUI slightly behind the taskbar, hence the desktop background.

I did some more tests on 150% and 100% using the posted code. The values returned are commented again. My thinking with Koda was it was reading and calculating values for sizes that I wasn't aware of with my code. If someone knew which values, maybe again based on returns from _WinAPI_GetSystemMetrics and different parameters such as borders or captions, that I could use those parameters and get the same values for WinMove no matter the theme.

#include <GUIConstantsEx.au3>
#include <WinAPISys.au3>

Local $h_GUI = GUICreate('Test', 515, 108, -1, -1)
_GA_GUISetToTaskbar($h_GUI)
GUISetState(@SW_SHOW, $h_GUI)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func _GA_GUISetToTaskbar($h_GUI)
    ; get the working area - taskbar
    Local $t_RECT = _WinAPI_GetWorkArea()

    ; get window height and width
    Local $ai_Pos = WinGetPos($h_GUI)

    WinMove($h_GUI, '', $t_RECT.Right - $ai_Pos[2], $t_RECT.Bottom - $ai_Pos[3])

    ConsoleWrite($ai_Pos[2] & @CRLF & $ai_Pos[3])
EndFunc   ;==>_GA_GUISetToTaskbar

; DPI Scaling
; 150% 9 point Segoe UI @ 144 pixels per inch
; 3840 x 2160
; width 521
; height 141

; 150% 9 point Segoe UI @ 144 pixels per inch
; 1920 x 1080
; width 521
; height 141

; 100% 9 point Segoe UI @ 96 pixels per inch
; 1920 x 1080
; width 521
; height 136

; 100% 9 point Segoe UI @ 96 pixels per inch
; 3840 x 2160
; width 521
; height 136

 

Edited by benners
typo

Share this post


Link to post
Share on other sites

Hey, it's a bit difficult to analyze these numbers since data set is limited.

For horizontal, this looks ok. 515 + 2 x 3 = 521 (3 pixels on each side)

For vertical, titlebar comes into play. Playing with numbers I have come up with this (maybe totally off, and numbers may be coincidences :) )

Microsoft points to pixels ratio is = DPI/72

For the 2 data sets that can be used from your last post:

1) 100% - 96 dpi - 108 - 136

2) 150% - 144 dpi - 108 - 141

Differences are:

1) 136 - 108 = 28

2) 141 - 108 = 33

Subtract titlebar (= 23):

1) 28 - 23 = 5

2) 33 - 23 = 10

If these resultants were somehow scaled with windows scaling and dpi then, and tied to a point system rather than pixels:

Lets say fixed point is p

pixels(p) = round(p*(dpi/72)*(scaling/100))

Both 5 and 10 can be found like this when p = 3.5

Conspiracy is :) p = (aspect ratio * 2) rounded down to 3.5

Aspect ration = 1920 / 1080 = 1.7777...78

p = 3.55555...56 (rounded down to 3.5)

Easy to check if you play with aspect/scaling and dpi. 

This would give the final result:

1) 23 + round(3.5 * (96/72) * (100/100)) = 23 + round(4.6666...67) = 23 + 5 = 28

2) 23 + round(3.5 * (144/72) * (150/100)) = 23 + round(10.5) = 23 + 10 = 33

 

* round(10.5) should round to 11, right? It is like a break even point of some sorts. 3.4999 results in a number less than 10.5. So idk. Maybe only first decimal is taken so p becomes 3.4.

Now, the :idiot: must go back to figuring out coords in Excel ><

Edited by GokAy

Share this post


Link to post
Share on other sites

Cheers for the maths GokAy. I'll have a look at adding some sort of calculation if needed. Most displays that I use are 100% scaling anyway, just a couple with higher scaling.

Share this post


Link to post
Share on other sites

Maybe this will be useful:

I use this piece of code in some of my projects to calculate maximal height of window (ClientSize used in GUICreate) minus height of bottom Tray area

$tray_h = WinGetPos("[CLASS:Shell_TrayWnd]") ; "classname=Shell_TrayWnd"
    If @error Then ; to be sure in case of error
        $tray_h = 50
    Else
        $tray_h = $tray_h[3] ; 32/46
    EndIf

    ; get height of title/frame of window (could be different in XP/Aero motive)
    $vtit = DllCall('user32.dll', 'int', 'GetSystemMetrics', 'int', $SM_CYCAPTION)
    $vtit = $vtit[0] ; 19 nebo 26
    $vfr = DllCall('user32.dll', 'int', 'GetSystemMetrics', 'int', $SM_CYDLGFRAME)
    $vfr = $vfr[0] ; 3

    $width = 400
    $height = @DesktopHeight - $tray_h - $vtit - 2*$vfr
    $Form1 = GUICreate("Title", $width, $height, -1, 0, BitOR($GUI_SS_DEFAULT_GUI,$WS_MAXIMIZEBOX,$WS_SIZEBOX))

 

Edited by Zedna

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

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...