Sarkahn 0 Newbie Poster

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!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.