News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Calculating window size based on desired client area

Started by NoCforMe, April 08, 2012, 10:08:07 PM

Previous topic - Next topic

NoCforMe

So I needed to do this in a program: determine the correct size for a window, given a specific client area size. I first tried using the Win32 API function designed for this purpose, AdjustWindowRect():


LOCAL gpRect:RECT

MOV gpRect.left, 0
MOV EAX, DesiredClientAreaWidth
MOV gpRect.right, EAX
MOV gpRect.top, 0
MOV EAX, DesiredClientAreaHeight
MOV gpRect.bottom, EAX

INVOKE AdjustWindowRect, ADDR gpRect, $winStyles, TRUE
INVOKE SetWindowPos, hWin, HWND_TOP, 0, 0, gpRect.right, gpRect.bottom, SWP_NOMOVE


Well, I can only tell you, folks, that this doesn't work correctly, at least not on my system (Windows 2000 Pro here). Close, but no cigar.

So next, I tried doing this "by hand", using values returned from GetSystemMetrics():
LOCAL gpRect:RECT

INVOKE GetWindowRect, StatusWinHandle, ADDR gpRect
MOV EAX, gpRect.bottom
SUB EAX, gpRect.top
MOV SBheight, EAX

INVOKE GetClientRect, winHandle, ADDR gpRect
MOV EAX, SBheight
ADD gpRect.bottom, EAX
INVOKE GetSystemMetrics, SM_CYFRAME
ADD gpRect.bottom, EAX
INVOKE GetSystemMetrics, SM_CYMENU
ADD gpRect.bottom, EAX


Again, it was close (actually closer than using AdjustWindowRect() ), but not exact. This bothered me.

Then it struck me, like a thunderbolt. Duh! Why monkey around with any of this stuff? Windows already gives me a perfectly straightforward way of determining the difference between window size and client size (which is what I'm after here)--just use GetWindowRect() and GetClientRect() and take the differences between them, which has to be the difference between window and client sizes (and no need to fart around with styles, presence or absence of menu, etc.):

; Get difference betwixt window & client rects:
LOCAL gpRect:RECT, wX:DWORD, wY:DWORD

INVOKE GetWindowRect, winHandle, ADDR gpRect
MOV EAX, gpRect.right
SUB EAX, gpRect.left
MOV wX, EAX
MOV EAX, gpRect.bottom
SUB EAX, gpRect.top
MOV wY, EAX
INVOKE GetClientRect, winHandle, ADDR gpRect
MOV EAX, wX
SUB EAX, gpRect.right
MOV AmountToAdjustWindowWidth, EAX
MOV EAX, wY
SUB EAX, gpRect.bottom
MOV AmountToAdjustWindowHeight, EAX

; Adjust window dimensions to give needed client area:
MOV EAX, DesiredClientWidth
ADD EAX, AmountToAdjustWindowWidth
MOV EDX, DesiredClientHeight
ADD EDX, AmountToAdjustWindowHeight
INVOKE SetWindowPos, hWin, HWND_TOP, 0, 0, EAX, EDX, SWP_NOMOVE


Works perfectly! (My apologies to those who figured this out a long time ago.)

MichaelW

I also ended up coding my own procedure to do this, because virtually all of my windows have the WS_OVERLAPPED style, and per Microsoft this style, for whatever reason, is not compatible with AdjustWindowRect.
eschew obfuscation