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!