News:

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

resize window while maintaining aspect ratio?

Started by NiceGuy, August 25, 2006, 11:37:37 PM

Previous topic - Next topic

NiceGuy

hello, my first question here, though I've been lurking this forum for some time trying to learn assembly and windows programming. ok, now for the question, is there some way to set a window to resize in forced aspect ratio when manually resizing it?

PBrennick

If you are manually resizing the window, just grab any corner and it will resize while maintaining the proper ratio.  This does not seem to be a programming question, am I missing something?

Paul
The GeneSys Project is available from:
The Repository or My crappy website

jdoe

Not sure to understand you well but from what I understand your want the window to resize by a predefined ratio when the user resize it.

For that I would set a custom WindowProc and get the WM_WINDOWPOSCHANGED message. This way you can have the control on the window size with an SetWindowPos API call. Don't forget the (SWP_NOZORDER or SWP_NOCOPYBITS) for the uFlags parameter. You can set a custom WindowProc from a window handle with an SetWindowLong API call with the (GWL_WNDPROC) for the nIndex parameter.

I hope this is helping you a little.




NiceGuy

ok sorry, I was a bit fuzzy in my query. in certain programs, when dragging and resizing the window, it will keep the same aspect ratio. for example, if the window is a perfect square, you can can make it smaller or bigger, but it will still remain a perfect square. I've seen this mostly in image viewing and video playing software. so I was wondering if this is something you will (as suggested by jdoe) have to do manually by capturing some resize message, or if there is some predefined window style that you can set, which automagically forces this resizing behaviour.

ToutEnMasm

Hello,
There is no defined style to keep a square when the size is moving.
You have to capture the WM_SIZE message for the window of which you want to keep the look.
Then movewindow with that you want.
                                     ToutEnMasm


sinsi

Have a look at WM_SIZING - this will let you restrict height/width.
From the Platform SDK:
QuoteThe WM_SIZING message is sent to a window that the user is resizing. By processing this message, an application can monitor the size and position of the drag rectangle and, if needed, change its size or position.
Light travels faster than sound, that's why some people seem bright until you hear them.

ToutEnMasm

Hello,
If you want to play with messages , there is also the WM_MOVING message,provided informations are differents for each of them but the action is the same,make a calcul and move the window.
                                    ToutEnMasm

w0lfshad3

#7
this isn't an asm question but here it is:

"keeping aspect ratio" is done in 2 ways AFAIK:

Assemble this buggy code of mine for example http://wolfshade.home.ro/mem_leak.asm it will keep the ratio of the rectangles by doing some WM_SIZE logic(this is translated into asm from Checker3 example in the book i'm mentioning below).

Using mapping mode, look up SetMapMode() API reference, you are looking for MM_ISOTROPIC i believe, it will keep logical x equal to logical y. This will branch out to a more vast chapter: look up Charles Petzold, Programming Windows 5th edition, Chapter 5, "The GDI mapping mode"

P.S.These are client area methods, if you refer to the whole window i do not know however i believe you can manipulate that from WM_SIZE with a function and a handle to the whole window.

NiceGuy

thanks for the help guys! and yes, although I'm programming this in assembly, it's not an assembly related question per se. but I didn't find a specific windows api forum.

Tedd

C'mon guys, it's a simple enough question, yet you all seem to have missed the point ::) (Okay, almost all :wink)

First stop - look at the WM_SIZING message. You get this when the window is being resized, but before the size is actually changed.
So, you need to know the required ratio in advance (which you should already have by the window size.)
Then, catch the WM_SZING message.. and see which edge/corner is being resized. If the height is being modified, then take the new height and multiply it by your ratio to get the correct value for the width, and modify the rect structure accordingly; similarly if the width is being changed. In the case of a corner being pulled, you'll have to decide whether you prefer width over height and then use one to modify the other.
Modify the rect, and return TRUE - voila!
No snowflake in an avalanche feels responsible.

PBrennick

Very nice, Tedd.

Personally, I feel that this type of thing should NOT be done.  It interferes with what the user wants by forcing the user into a rigid framework.  I cannot recommend this, I beleive the user should be left to make his/her own decision.
Paul
The GeneSys Project is available from:
The Repository or My crappy website

w0lfshad3

#11
Right on Tedd, experience sais it  :U

I didn't even know of the WM_SIZING message wich in turn also gives justice to what PBrennick said, and the reason i haven't stumbled upon it so far. My method would've worked alltough a lot more complicated, involving getting the system area handle or whats it called and resizing the whole window based on the ratio of the client area perhaps(or i would've had to reasearch if i can set MM_ISOTROPIC to solve the problem alone).

I'm having some trouble with getting it in asm, and don't feel like it today after some people sought they should show me some of their valor with their uncanny comments no doubt in my "dilema" thread, so i had to flame them.

Basicly:
LOCAL rect:RECT
.if message == WM_SIZING
    mov eax, wParam
    mov edx, lParam
    mov rect, edx;

here edx should contain an address after this operation but i'm not sure, its a pointer to a rectangle look up WM_SIZING in reference

   .if eax == WMSZ_BOTTOM;

for example, you need to process the rest too, lookup the reference for the rest of the WMSZ_... macros

        mov eax, rect.bottom;

from here you need to test if eax(rect.bottom in this case wich is height; point 0,0 is upper left thus lower right is x, y) increases or decreases value then set width accordingly. If height is modified +-z then +-z the width according to a ratio; 1:1 will keep the 4:3 aspect ratio i believe.
   Do the same for the rest of the messages(with respective calculations of course), WMSZ_BOTTOMLEFT and WMSZ_BOTTOMRIGHT you might want to process togheter. The problem is i do not know at this very moment how do you pick the new value when you finish resizing a window edge.
   Note: i never done this before nor finished doing it now, i don't guarantee it will work, or if i will finish it.
Also take note that if you master the ampping mode you could do this in one shot calling SetMapMode(hdc, MM_ISOTROPIC) and achieve teh 1:1 effect in one shot. I haven't tried anything with it feel free to experiment. Again note that the hdc back there is a hdc to the whole window not just the client area.

NiceGuy

thanks Tedd, yes WM_SIZING sounds like the right message to use. as for reasons for this, I'm playing around with writing a small image viewer and I wanted to add an option to have forced aspect ratio when resizing the window.

w0lfshad3

With SetMapMode(MM_ISOTROPIC) you'll display the image ration-like no matter what you do to the window.
I highly suggest you use it, otherwise you'll just duplicate/overwrite the internal windows logic(at best).