News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Using AdjustWindowRect with a dialog box

Started by zedd151, March 15, 2025, 02:58:28 PM

Previous topic - Next topic

zedd151

Quote from: sinsi on March 09, 2025, 07:56:24 AMIf you want to get a particular client size try using 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
¯\_(ツ)_/¯   :azn:

'As we don't do "requests", show us your code first.'  -  hutch—

NoCforMe

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.
Assembly language programming should be fun. That's why I do it.

zedd151

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.
¯\_(ツ)_/¯   :azn:

'As we don't do "requests", show us your code first.'  -  hutch—

sinsi

;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


NoCforMe

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.
Assembly language programming should be fun. That's why I do it.

zedd151

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:

¯\_(ツ)_/¯   :azn:

'As we don't do "requests", show us your code first.'  -  hutch—

sinsi

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:


zedd151

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:
¯\_(ツ)_/¯   :azn:

'As we don't do "requests", show us your code first.'  -  hutch—

zedd151

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.
¯\_(ツ)_/¯   :azn:

'As we don't do "requests", show us your code first.'  -  hutch—

sinsi

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.

zedd151

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:
¯\_(ツ)_/¯   :azn:

'As we don't do "requests", show us your code first.'  -  hutch—

zedd151

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?
You cannot view this attachment.

Here is what I actually see on screen (screenshot of upper left corner of screen):
You cannot view this attachment.
¯\_(ツ)_/¯   :azn:

'As we don't do "requests", show us your code first.'  -  hutch—

sinsi

What happens if you change the code to this
invoke MoveWindow, hWin, rct.left, rct.top, eax, edx, TRUEIt 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

zedd151

He he. I'll tinker with it some more. brb
¯\_(ツ)_/¯   :azn:

'As we don't do "requests", show us your code first.'  -  hutch—

zedd151

You cannot view this attachment.

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.
¯\_(ツ)_/¯   :azn:

'As we don't do "requests", show us your code first.'  -  hutch—