Sign in to follow this  
Bozebo

c++ windows api minimum resize dimensions

Recommended Posts

I am working on an OpenGL application which I am going to use as a general sandbox to make a basic framework. There are a lot of things to handle, and one of them is resizing the window. I have everything working brilliantly, except minimum resize dimensions. According to this page on the msdn, it should not be a difficult task. So I went ahead and worked on my WndProc function to work out a solution.
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
  switch(message){
    case WM_GETMINMAXINFO: //window size/position is going to change
    /*
        Intercept lParam pointer to MINMAXINFO structure and apply custom 
        dimensions
    */
    lParam->ptMinTrackSize.x = (long)windowMinWidth;
    lParam->ptMinTrackSize.y = (long)windowMinHeight;
    return 0;

    //other cases excluded
  }
}
According to the msdn, lParam will be a pointer to a MINMAXINFO structure, of which I can edit the ptMinTrackSize point structure and so create nice minimum dimensions for the window. But, lParam is not a pointer according to the compiler, yet msdn says clearly that it is a "Pointer to a MINMAXINFO structure..." I tried a few other things which didn't work but the code above is the best way I can present the issue. I can't find any examples of minimum dimensions which are not visual basic or some other rubbish. So what is the solution to get around Microsoft's bad documentation? Thanks [Edited by - Bozebo on April 23, 2010 6:55:52 AM]

Share this post


Link to post
Share on other sites
You need to cast the LPARAM value to the desired pointer type.


MINMAXINFO* MinMaxInfo = reinterpret_cast<MINMAXINFO*>(lParam);

// or

MINMAXINFO* MinMaxInfo = (MINMAXINFO*)lParam;








[edit]
This is done frequently in WM_ messages.

Also, if I remember correctly, WM_GETMINMAXINFO only affects the parent window. If you are trying to provide some kind of size constraints for child windows, you will need to handle them yourself in one of the sizing or move messages.

[Edited by - Rattrap on April 23, 2010 7:41:27 AM]

Share this post


Link to post
Share on other sites
case WM_GETMINMAXINFO:
( ( MINMAXINFO * )lParam )->ptMinTrackSize.x = windowMinWidth;
( ( MINMAXINFO * )lParam )->ptMinTrackSize.y = windowMinHeight;

return 0;




Shit, gamedev was halting again, I could have pwned you Rattrap...

Share this post


Link to post
Share on other sites
Going back to my Win32 wrapper code, the way I implemented size constraints was using the WM_WINDOWPOSCHANGING message.

You can adjust the cx (width) and cy (height) of the WINDOWPOS structure passed through the LPARAM (just like how we demonstrated before) to the values you want.

Share this post


Link to post
Share on other sites
Wow thanks it works nicely.

It seems odd that the structure has to be altered every resize event, is there a way provided to make the change once at the app initialisation? ie. is there another way to get that pointer other than the WM_GETMINMAXINFO message?

Share this post


Link to post
Share on other sites
I believe the WM_GETMINMAXINFO is only sent once, during the window creation. So you really only set it once.

That is also why I use WM_WINDOWPOSCHANGING. That one you do process during every resize, but you can change the values each time.

Share this post


Link to post
Share on other sites
I have only seen this solution. But I wouldn't worry about it. At one hand, I'm not sure that it is called on resize and mouse move, I mean it is called at one complete resize (I think). And altering the struct means two value assignments. So I wouldn't worry about it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Rattrap
I believe the WM_GETMINMAXINFO is only sent once, during the window creation. So you really only set it once.

That is also why I use WM_WINDOWPOSCHANGING. That one you do process during every resize, but you can change the values each time.


Used a message box within the event to see when it is called. It seems it is called first on window creation then again every time the window is resized, moved, maximised or minimised. I suppose the processing overhead doesn't really matter, but it's that kind of thinking that leads to inefficient programming. Then again, who needs high frame rates while they are resizing the game window?
It is just that I like to do everything the best possible way, if there is a better solution even if mine works nicely I will endeavor to follow the best practice and best performance.

Thanks for the help everyone.

Share this post


Link to post
Share on other sites
But again: when is it called?
Once per a full/complete resize.
Why are you so afraid of performance? You will get a performance hit (believe me, it will be a 0.00001% hit) once per a resize. Maybe never. Maybe two times through the running time of the program.

Get over it!

Share this post


Link to post
Share on other sites
Quote:
Original post by Bozebo
I suppose the processing overhead doesn't really matter, but it's that kind of thinking that leads to inefficient programming. Then again, who needs high frame rates while they are resizing the game window?


This is the important part of that statement. In this case it really isn't inefficient programming, since it is the nature of the beast (Win32). While it doesn't really seem very efficient, this really is the only way to implement this desired functionality on the desired platform. And it really is a small price to pay, especially when you look at all that goes on when a resize occurs. At least 5 message are handled (by you or DefWindowProc) when just MoveWindow is called: WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED, WM_MOVE, WM_SIZE, and WM_NCCALCSIZE.

What is more likely to affect your frame rates on a resize isn't a couple of memory assignment, it's going to be all of the processing you have to do behind the scenes to readjust your opengl/directx/etc frames to match the new window size.

[edit]
You beat me this time scezs :)

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

Sign in to follow this