954,498 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Maintain Aspect Ratio with Windows API

This is a way to force a given aspect ratio of a window any time the user tries to resize or cascade it.

double aspectRatio = 640.0 / 480.0;
WPARAM sideBeingDragged = 0;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;

        case WM_SIZING:
            sideBeingDragged = wParam;
        break;

        case WM_WINDOWPOSCHANGING:
        {
            WINDOWPOS * winPos = (WINDOWPOS*)lParam;

            // Adjust window dimensions to maintain aspect ratio
            switch( sideBeingDragged )
            {
                case WMSZ_BOTTOM:
                case WMSZ_TOPRIGHT:
                    winPos->cx = (int)( (double)winPos->cy * aspectRatio );
                break;

                case WMSZ_RIGHT:
                case WMSZ_BOTTOMLEFT:
                case WMSZ_BOTTOMRIGHT:
                    winPos->cy = (int)( (double)winPos->cx / aspectRatio );
                break;

                case WMSZ_TOP:
                {
                    // Adjust the x position of the window to make it appear
                    // that the bottom right side is anchored
                    WINDOWPOS old = *winPos;

                    winPos->cx = (int)( (double)winPos->cy * aspectRatio );

                    winPos->x += old.cx - winPos->cx;;
                }
                break;

                case WMSZ_LEFT:
                case WMSZ_TOPLEFT:
                {
                    // Adjust the y position of the window to make it appear
                    // the bottom right side is anchored. TOPLEFT resizing
                    // will move the window around if you don't do this
                    WINDOWPOS old = *winPos;
                    winPos->cy = (int)( (double)winPos->cx / aspectRatio ); 
                    
                    winPos->y += old.cy - winPos->cy;
                }
                break;
            }
        }
        break;

        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
        break;
    }
    return 0;
}


I'm really not familiar with the Windows API, nor do I want to be. I only learned as much as I needed to in order to get this working. If there is a better or easier way to do this, I'd love to know!

Sarkahn
Newbie Poster
4 posts since Jul 2010
Reputation Points: 10
Solved Threads: 0
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: