Quote from: sinsi on March 09, 2025, 07:56:24 AMIf you want to get a particular client size try using AdjustWindowRect (https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-adjustwindowrect).
The problem with that is, that this is a dialog box not a window. I played around with this today a lttle bit.
MoveWindow expects parameters: x position, y position, width, height; and not a RECT structure which AdjustWindowRect does use. I would still have do some wrangling similar to this code to work as expected.
This code is the current window resizing code from my dialog box template source, not my experiments with AdjustWindowRect. I don't mind doing it this way, but if there is a different (possibly better) way, I am willing to try it.
;; resizing Client Area to exact dimensions, specified by cwidth and cheight
invoke GetWindowRect, hWin, addr rct ;; get window current dimensions.
mov eax, rct.right ;; obtain current window width by subtracting left boundary
sub eax, rct.left ;; from the right boundary
mov wwid, eax ;; store current window width
mov eax, rct.bottom ;; obtain current window height by subtracting top boundary
sub eax, rct.top ;; from the bottom boundary
mov whgt, eax ;; store current window height
invoke GetClientRect, hWin, addr rct ;; get client area current dimensions.
mov eax, rct.right ;; obtain current client width by subtracting left boundary
sub eax, rct.left ;; from the right boundary
mov cwid, eax ;; store current client area width
mov eax, rct.bottom ;; obtain current client height by subtracting top boundary
sub eax, rct.top ;; from the bottom boundary
mov chgt, eax ;; store client area height
;; calculate the difference between desired client area width and current client area width
mov eax, cwidth
sub eax, cwid
;; adjust the window width according to the difference calculated above
add wwid, eax
;; calculate the difference between desired client area height and current client area height
mov eax, cheight
sub eax, chgt
;; adjust the window height according to the difference calculated height
add whgt, eax
;; center the main window
;; obtain client area of the desktop, not including the task bar
invoke SystemParametersInfoA, SPI_GETWORKAREA, 0, addr rct, 0
;; center window width
mov eax, rct.right
sub eax, wwid
sar eax, 1
mov x, eax
;; center window height
mov eax, rct.bottom
sub eax, whgt
sar eax, 1
mov y, eax
;; implement the centering of the resized main window
invoke MoveWindow, hWin, x, y, wwid, whgt, TRUE
Once you understand the difference between window and client rectangles, you'll have no problems.
Window positions: relative to (0,0) of the area the window exists within (the desktop).
Client positions: relative to (0,0) of the window.
Quote from: NoCforMe on March 15, 2025, 03:16:54 PMOnce you understand the difference between window and client rectangles, you'll have no problems.
I know the difference. Thats why all the wrangling in that code. I was asking to see if sinsi had a way I could use AdjustWindowRect with a dialog box, rather than a window created with CreateWindowEx (If he has done it before), since he suggested using AdjustWindowRect rather than the code that I used for the same purpose.
;client_rect has your desired size
invoke AdjustWindowRect,addr client_rect,WS_VISIBLE or WS_OVERLAPPEDWINDOW,0
mov ecx,offset client_rect
mov eax,[ecx].RECT.right
mov edx,[ecx].RECT.bottom
sub eax,[ecx].RECT.left ;x
sub edx,[ecx].RECT.top ;y
Quote from: zedd151 on March 15, 2025, 03:25:17 PMI was asking to see if sinsi had a way I could use AdjustWindowRect with a dialog box, rather than a window created with CreateWindowEx (If he has done it before), since he suggested using AdjustWindowRect rather than the code that I used for the same purpose.
A dialog is exactly the same as any other window in this regard. In my programs which use a dialog as the main program window, one of the first things I do is to center the dialog on the desktop using
SetWindowPos(). All the other window sizing and positioning routines will work as well.
Actually I posted this question in the wrong thread. I had meant to post it in the 'gdiplus tests' thread.
The client area there, is determined by the dimensions of the loaded image.
Even after adjusting the window rectangle to the client area size, more code is still needed to center the window. I am going to put my existing code into a procedure rather than leaving it in WndProc in its entirety. May not be the best possible way (using my existing code), but it does indeed get the job done. Thanks sinsi for the example code though. :smiley:
Quote from: sinsi on March 15, 2025, 04:46:57 PM;client_rect has your desired size
invoke AdjustWindowRect,addr client_rect,WS_VISIBLE or WS_OVERLAPPEDWINDOW,0
mov ecx,offset client_rect
mov eax,[ecx].RECT.right
mov edx,[ecx].RECT.bottom
sub eax,[ecx].RECT.left ;x
sub edx,[ecx].RECT.top ;y
Oops, x and y should obviously be width and height :rolleyes:
Argh!!!!
Ok, I'll play with it again. :tongue:
But later on today, I have yard work to do...
It wasn't obvious last night, or I was just too tired to notice. I took your word for it... but it never quite turned out as expected. So I tinkered with it, and of course things got worse. :rolleyes: :biggrin:
I can do yard work later. :eusa_dance: I am a world renowned procrastinator with such things. :biggrin:
Okay if I am correct, with this code the window should be the correct size but at x=0 and y=0 and need only centering now.
.if uMsg == WM_INITDIALOG
;; fill RECT with desired client area dimensions
mov rct.left, 0
mov rct.top, 0
mov rct.right, cwidth ; 240
mov rct.bottom, cheight ; 240
; rct has your desired size
invoke AdjustWindowRect, addr rct, WS_VISIBLE or WS_OVERLAPPEDWINDOW, 0
lea ecx, rct
mov eax, [ecx].RECT.right
mov edx, [ecx].RECT.bottom
sub eax, [ecx].RECT.left ; new window width in eax
sub edx, [ecx].RECT.top ; new window height in edx
invoke MoveWindow, hWin, 0, 0, eax, edx, TRUE
Prior to centering the window, I tested this code first.
However Window x is not zero, but is 7. Window y position is at zero, as it should be. :rolleyes:
The client area is properly sized to the specified dimensions as it should be.
I am having a N00B moment. (Or senior moment?)
I could center it like this (starting with x=7 instead of x=0), but I'm kinda OCD for some things.
Actually, the adjusted rectangle is -8, -31, 248, 248.
This is because your client x,y is 0,0 so converting it to a window will take into account things like the border and title bar.
You still have to have code to centre it though.
Quote from: sinsi on March 16, 2025, 02:18:19 AMActually, the adjusted rectangle is -8, -31, 248, 248.
This is because your client x,y is 0,0 so converting it to a window will take into account things like the border and title bar.
You still have to have code to centre it though.
I did not look at the RECT structure values after the adjustment, just the changes in dialog box Window location and size after the AdjustWindowRect call. :rolleyes:
I know that I still have to center it, I was just testing the result of these changes.
In the end, it might not be much less code than my original resizing and centering code.
I'll work on centering it now... :biggrin:
Okay, this better demonstrates the issue that I see:
;; fill RECT with desired client area dimensions
mov rct.left, 0
mov rct.top, 0
mov rct.right, cwidth ; 240
mov rct.bottom, cheight ; 240
; rct has your desired size
invoke AdjustWindowRect, addr rct, WS_VISIBLE or WS_OVERLAPPEDWINDOW, 0
lea ecx, rct
mov eax, [ecx].RECT.right
mov edx, [ecx].RECT.bottom
sub eax, [ecx].RECT.left ; new window width
sub edx, [ecx].RECT.top ; new window height
invoke MoveWindow, hWin, 0, 0, eax, edx, TRUE
invoke GetWindowRect, hWin, addr rct
fn lstrcpy, addr buffer, "rct.left = "
invoke lstrcat, addr buffer, str$(rct.left)
invoke lstrcat, addr buffer, addr crlf
fn lstrcat, addr buffer, "rct.top = "
invoke lstrcat, addr buffer, str$(rct.top)
invoke lstrcat, addr buffer, addr crlf
fn lstrcat, addr buffer, "rct.right = "
invoke lstrcat, addr buffer, str$(rct.right)
invoke lstrcat, addr buffer, addr crlf
fn lstrcat, addr buffer, "rct.bottom = "
invoke lstrcat, addr buffer, str$(rct.bottom)
invoke MessageBox, 0, addr buffer, 0, 0
After moving the window I called GetWindowRect to obtain the window RECT which is where the window is supposed to be. But when the window is shown, x is 0+7 (rct.left). I do not know how to reconcile this apparent discrepancy.
Am I missing something here?
image_2025-03-15_120110735.png
Here is what I actually see on screen (screenshot of upper left corner of screen):
untitled.PNG
What happens if you change the code to this
invoke MoveWindow, hWin, rct.left, rct.top, eax, edx, TRUE
It should be slightly off the top and left of the screen edges.
Here is my attempt
.if uMsg == WM_INITDIALOG
;; fill RECT with desired client area dimensions
mov rct.left, 0
mov rct.top, 0
mov rct.right, cwidth ; 240
mov rct.bottom, cheight ; 240
; rct has your desired size
invoke AdjustWindowRect, addr rct, WS_VISIBLE or WS_OVERLAPPEDWINDOW, 0
invoke SystemParametersInfoA, SPI_GETWORKAREA, 0, addr rctD, 0
;window_width = (rct.right - rct.left)
;window_heighth = (rct.bottom - rct.top)
mov ecx,rct.right
mov edx,rct.bottom
sub ecx,rct.left ;window width
sub edx,rct.top ;window height
;desktop_width = rctD.right
;desktop_height = rctD.bottom
mov esi,rctD.right
mov edi,rctD.bottom
;desktop left/top should always be 0
;sub esi,rctD.left ;desktop width
;sub edi,rctD.top ;desktop height
;window_x = desktop_width - window_width / 2
;window_y = desktop_height - window_height / 2
sub esi,ecx
sub edi,edx
shr esi,1 ;window x
shr edi,1 ;window y
invoke MoveWindow,hWin,esi,edi,ecx,edx,TRUE
He he. I'll tinker with it some more. brb
untitled.PNG
Now the upper left corner of the client area is at 0,0 on the screen not the window, which its upper left corner is off screen. :biggrin:
I am going to center it with SystemParametersInfoA, SPI_GETWORKAREA, and see where the window gets placed.
It is centering from left to right in the correct position. :thumbsup:
But from top of screen to the top of the dialog box is 310 pixels.
From the bottom of the dialog box to the top of the task bar is 317 pixels. :thdn:
Whoops. That was without the AdjustWindowRect call...
With AdjustWindowRect it is
from top of screen to the top of the dialog box is 290 pixels.
From the bottom of the dialog box to the top of the task bar is 297 pixels. wtf?
left-right centering is still correct.
Odd. Just odd...
A short time later:
For completeness, I tested my original dialog template with my own resize and centering code.
The results are the same as using AdjustWidowRect.
top-bottom centering is off in my code as well, while left-right centering is perfect.
Maybe an issue with SystemParametersInfoA?? My original centering code also uses that function.
I had not checked this prior using my original code, I had just assumed that the dialog box was centered (at least +/- 1 pixel).
I am going to check my dialog box in the .rc file.
Maybe the window style is not WS_OVERLAPPEDWINDOW.... Will investigate and report my findings... that could be the problem.
No, the dialog box window style in the .rc file was fine.
This issue is really driving me nutz! :biggrin:
Both the latest 'resize and center using AdjustWindowRect' version, and the original 'homemade resize and center' version attached.
Doesn't seem to be a problem here.
zedd dialog.png
Desktop working area is 1920x1032
832*2=1664, 1664+256=1920 so horizontally centred.
376*2=752, 752+279=1031 so vertically centred (1 pixel off because AdjustWindowRect adds 31 to the top).
Are you taking into account that the task bar is not included in the desktop work area? If that is the case, I'm stumped.
I'll just leave it be, even if the height centering is not pixel perfect. But several pixels off for me.
I'm done with all of this.
Thanks for your help on this, btw. Now I gotta move on to other things. :biggrin:
Quote from: zedd151 on March 16, 2025, 09:30:12 AMAre you taking into account that the task bar is not included in the desktop work area
Quote from: sinsi on March 16, 2025, 09:17:28 AMDesktop working area is 1920x1032
Then I'm stumped.
I am going to run a simple test with a 'normal' Window, using the same methods used here, to see if using a dialog box is the issue for me.
If it too is off by more than one pixel on centering, than it is only a ME issue. :rolleyes:
Zedd: You're doing two things here, resizing the dialog window, and centering it on the desktop.
I haven't looked enough into your resizing code to be of any help. However, regarding the centering part, here's what I use in all my dialog-based programs to center the dialog on the desktop. It's simpler than what you're trying to do and works flawlessly.
I put these 3 statements in the dialog's WM_INITDIALOG code, and the rest is a small subroutine:
; Put this in your WM_INITDIALOG handler:
CALL GetDesktopWindow
INVOKE CenterDialog, EAX, hWin
INVOKE SetWindowPos, hWin, HWND_TOP, EAX, EDX, 0, 0, SWP_NOSIZE
;============================================
; CenterDialog (parentWinHandle, dialogHandle)
;
; Centers dialog on parent window.
;
; Returns:
; EAX = x-position for dialog
; EDX = y-position
;============================================
CenterDialog PROC parentWinHandle:HWND, dlgHandle:HWND
LOCAL gpRect1:RECT, gpRect2:RECT
INVOKE GetWindowRect, parentWinHandle, ADDR gpRect1
INVOKE GetWindowRect, dlgHandle, ADDR gpRect2
MOV EAX, gpRect1.right
SUB EAX, gpRect1.left
SHR EAX, 1
MOV EDX, gpRect2.right
SUB EDX, gpRect2.left
SHR EDX, 1
SUB EAX, EDX
ADD EAX, gpRect1.left
MOV ECX, EAX ;Stash x-pos.
MOV EAX, gpRect1.bottom
SUB EAX, gpRect1.top
SHR EAX, 1
MOV EDX, gpRect2.bottom
SUB EDX, gpRect2.top
SHR EDX, 1
SUB EAX, EDX
ADD EAX, gpRect1.top
MOV EDX, EAX ;y-pos.
MOV EAX, ECX ;Recover x-pos.
RET
CenterDialog ENDP
This code can be used to center any window over any other window, like when you open a second dialog from a main dialog.
Thanks David, but I am not centering a dialog box on another window. I am using a dialog box as main window, and centering it on the desktop.
My code performs the same task as using AdjustWindowRect and SystemParametersInfoA. And both center the vertical but are both off by several pixels. Both meaning my code, and sinsi's method using AdjustWindowRect.
I have used all sorts of code to center Windows on the desktop in the over the years, this is the first time that I recall anything not centering properly.
When centered properly, either dimension should either be exact, or only off by one pixel(if the window or dialog box has an odd number of pixels in either dimension, or the 'work area' has an odd number of pixels vertically).
Anyway, aside from running a couple if tests with window centering (not dialog boxes) to see if I get similar results, I am about done with all of this.
Maybe I am just too nitpicky.
Quote from: zedd151 on March 16, 2025, 12:07:23 PMThanks David, but I am not centering a dialog box on another window. I am using a dialog box as main window, and centering it on the desktop.
Yes; you're centering your window (a dialog, which is a window) on another window (the desktop, which is also a window).
That's exactly what my code does.
It's all windows, all the way down ...
Quote from: NoCforMe on March 16, 2025, 01:07:42 PMYes; you're centering your window (a dialog, which is a window) on another window (the desktop, which is also a window).
Ok. :tongue:
I don't see how your code will do anything different than either my code, or sinsi's. Other than being a different method of performing the same task.
There is a MoveWindow, hMain, 0, 0, 666, 444, 0 in the code, so the window should stick to the upper left corner. Guess what? It doesn't. It still did under Windows 7, IIRC :cool:
0 WinRect left
0 WinRect top
666 WinRect right
444 WinRect bottom
0 ClientRect left
0 ClientRect top
650 ClientRect right
385 ClientRect bottom
(https://i.postimg.cc/ThDbRm8z/tmp.png) (https://postimages.org/)
Yes Jochen, I had used GetWindowRect in my original "resize and center" code, as shown in post #1.
sinsi had suggested AdjustWindowRect rather than my method.
Upon closer inspection, the dialog box is not exactly centered +/- 1 pixel in both directions as it should be. On the vertical, there is a discrepancy for me, no matter which method I had tried. The client area size is always correct after adjustments.
The dialog box is always 3-4 pixels higher than where it should be.
I have given up altogether since in the grand scheme of things, it is only a minor detail only noteworthy for nitpicky, OCD prone guys like me. :biggrin:
The desktop window is always at 0, 0 which is what I am centering the dialog box on. Hope this clarifies a bit.
The point is that since Windows 10 the sizing zone left & right (but not on top) is outside the visible window. Microsoft plays tricks on us :cool:
Quote from: jj2007 on March 17, 2025, 12:21:35 AMThe point is that since Windows 10 the sizing zone left & right (but not on top) is outside the visible window. Microsoft plays tricks on us :cool:
Ok. Possibly due to the Metro interface?
I'm gonna test some of the code here on Windows 7... That will take a while, since I don't currently have it on either computer. It only takes 5-7 minutes to get it up and running.... but real life may get in the way...
Quote from: jj2007 on March 17, 2025, 12:21:35 AMThe point is that since Windows 10 the sizing zone left & right (but not on top) is outside the visible window.
Also the alignment vertically is also affected.
I tested the same program on both windows 10 and windows 7.
On windows 7, lo and behold, centering is as perfect as it can get (within +/- 1 pixel). :thumbsup:
On windows 10, however the dialog box is indeed higher by a few pixels. :rolleyes:
Windows 7
(https://i.postimg.cc/YhgM6pSg/win7.png) (https://postimg.cc/YhgM6pSg)
windows 10
(https://i.postimg.cc/PCQH72Y5/win10.png) (https://postimg.cc/PCQH72Y5)
Thanks Jochen. If you would have mentioned this yesterday, woulda saved me a lot of trouble, and hair. (Been figuratively 'pulling my hair out' trying to figure out this discrepancy) :tongue:
Now I know I can simply disregard any slight off-centeredness from now on, most likely not any error in the code, but Windows 10's fault.
Now the big question is, "is the misalignment always the same number of pixels, or does vary by screen size?" Testing will need to be done by those with huge "home theatre sized" monitors, down to a monitor with 1024x768 screen dimensions.
Program tested also attached. You may need to adjust the following parameters for your screen size. For the test, I incremented these parameters so the dialog box just kissed either the top of screen, or top of the task bar. This was done to clearly see how exacting the vertical centering was, or not, at a glance without having to open the screenshot in paint and zoom in.
cwidth equ 820 ; desired client area width
cheight equ 820 ; desired client area height
For anyone else reading this topic,
While jj2007's post #27 does not solve this issue described here, at least it does give a (not so good) reason why it was difficult to perfectly center my dialog box on the desktop in Windows 10. In Windows 7, using the same code, the dialog box does get perfectly centered. (within a +/- 1 pixel tolerance).
Damn Microsoft, you've done it again.
:biggrin:
Problem not solved, but at least we know why. :smiley:
We'll just have to live with it. :tongue:
Maybe they fixed it in Windows 11?
One thing I noticed, your Windows 7 window has a border whereas the Windows 10 window doesn't seem to.
I seriously doubt that.
Windows 10 dialog boxes have a 1 pixel wide border around the perimeter, is that what you meant? They don't have a wide looking border as they did in Windows 7. You can still drag the edge to resize though ...
You have never examined a screenshot (zoomed in) with mspaint, or similar? Never done any gui graphics design? :tongue:
Quote from: sinsi on March 17, 2025, 07:48:44 AMMaybe they fixed it in Windows 11?
Unlikely, because it's a
feature: it creates a 5mm or so zone (seemingly) outside the window that is shaded and serves for sizing. It makes our lives more difficult, but it does actually look better than on previous Windows versions.
Quote from: zedd151 on March 17, 2025, 03:12:38 AMProblem not solved, but at least we know why. :smiley:
Yes, your computer is weird
Quote from: zedd151 on March 17, 2025, 03:12:38 AMWe'll just have to live with it. :tongue:
You will, I'm fine with it (since it seems to be OK on
my computer) :biggrin:
Quote from: zedd151 on March 17, 2025, 08:17:54 AMYou have never examined a screenshot (zoomed in) with mspaint, or similar? Never done any gui graphics design? :tongue:
How droll :rolleyes:
Quote from: sinsi on March 17, 2025, 08:39:05 PMQuote from: zedd151 on March 17, 2025, 08:17:54 AMYou have never examined a screenshot (zoomed in) with mspaint, or similar? Never done any gui graphics design? :tongue:
How droll :rolleyes:
To check specifically for exact placement of graphics elements, and things of that nature. And yes, to check exact placement of centered widows and dialog boxes.
I often use mspaint for such things, zooming in to 800% to see the individual pixels better. (The version from xp, of course) :biggrin:
Naturally, I assumed that everyone did something similar from time to time.
BTW, Zedd, you do know about using WinSpy to check on the position of windows, right?
Very useful tool. Can also be used to move/resize things dynamically on-screen to make them line up.
Never heard of it, to be honest.
Why not use? DS_CENTER in your resource script's STYLE declaration?
COLLEGE_GAME DIALOGEX 10,10,1000,260
FONT 12,"Sitka Text",400,255,0
STYLE 0x90800800 ;its the 800
EXSTYLE 0x00000200
BEGIN
END
Quote from: BugCatcher on March 18, 2025, 05:30:32 AMWhy not use? DS_CENTER in your resource script's STYLE declaration?
COLLEGE_GAME DIALOGEX 10,10,1000,260
FONT 12,"Sitka Text",400,255,0
STYLE 0x90800800
EXSTYLE 0x00000200
BEGIN
END
Because where the original example was from, the dialog box client area was resized to accommodate a user chosen image file. Then re-centered to the desktop window, to accommodate the newly resized dialog box. :smiley:
The desired client area dimensions were not always known at program startup, or when assembling the program in the first place. (A place holder width and height were equates there) but once an image was selected by the user, the dialog box is resized, and the new centering coordinates are calculated to move and resize the dialog box.
Quote from: zedd151 on March 18, 2025, 05:07:11 AMNever heard of it, to be honest.
(Referring to WinSpy)
You ought to try it. Lets you click on any "object" (window) you can see on the desktop, gives you the window and client RECT values (plus lots of other useful info, like the styles the window is using), and lets you dynamically change all those values.
It might help you see out where things are ending up on your desktop, and maybe help figure out why ...
You can download it here (https://sourceforge.net/projects/winspyex/). (Old version, but works fine.)