Fenstervergrößerung nur in bestimmten Seitenverhältnis erlauben
-
Schönen guten Abend zusammen!

wie der Titel schon vermuten lässt, würde ich gerne das 'resizen' des Fenster auf ein bestimmtes Seitenverhältnis begrenzen: Verändert der Benutzer die Größe, soll sich die entsprechende andere Seite automatisch mit anpassen, so das das Verhältnis gewahrt bleibt
. Hätte jemand eine Idee, wie ich das realisieren könnte?Mein Ansatz war Folgender:
case WM_SIZE: iX = LOWORD(lParam); iY = HIWORD(lParam); BITMAP bmInfo; GetObject(hiCurrent, sizeof(BITMAP), &bmInfo); double f = (double)bmInfo.bmWidth / (double)bmInfo.bmHeight; // Seitenverhältnis errechnen if((double)iX / (double)iY != f) { //SetWindowPos(hWnd, NULL, 0, 0, f * iY, iY, SWP_NOMOVE | SWP_NOZORDER); RECT rc; GetWindowRect(hWnd, &rc); MoveWindow(hWnd, rc.left, rc.top, f * iY, iY, TRUE); } break;Aber irgendwie ließ sich das Fenster danach gar nicht mehr verändern. Mit SetWindowPos (auskommentiert) hat es ebenfalls nicht funktioniert.
Hat jmd. eine Idee? Wäre sehr dankbar!
MfG Daniel
-
mit WM_SIZING
Martin
-
jo! genau ich habe da mal was zusammengeschustert.
Das funktioniert astrein und sehr benutzerfreundlich (für die mausfreaks)#include <windows.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); BOOL AdjustWindowRatio(LPRECT lpRect, float fRatio, int nWindowEdge); int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) { WNDCLASS wcs; HWND hWnd; MSG msg; ZeroMemory(&wcs, sizeof(WNDCLASS)); wcs.hInstance = hInstance; wcs.style = CS_HREDRAW | CS_VREDRAW; wcs.lpfnWndProc = WndProc; wcs.cbClsExtra = 0; wcs.cbWndExtra = 0; wcs.hCursor = LoadCursor(NULL, IDC_ARROW); wcs.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcs.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wcs.lpszClassName = L"HomeToGo"; wcs.lpszMenuName = NULL; if (!RegisterClass(&wcs)) return 0; hWnd = CreateWindow(L"HomeToGO", L"Home To Go", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, (LPVOID)lpCmdLine); ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static float fRatio = 1.5; RECT rect; switch (uMsg) { case WM_CREATE: GetWindowRect(hWnd, &rect); AdjustWindowRatio(&rect, fRatio, WMSZ_BOTTOMRIGHT); MoveWindow(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; case WM_SIZING: AdjustWindowRatio((LPRECT)lParam, fRatio, wParam); return 0; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } } BOOL AdjustWindowRatio(LPRECT lpRect, float fRatio, int nWindowEdge) { int nAvg, nWidth, nHeight; switch (nWindowEdge) { case WMSZ_LEFT: case WMSZ_RIGHT: nAvg = (int)((lpRect->right - lpRect->left) / fRatio); break; case WMSZ_TOP: case WMSZ_BOTTOM: nAvg = (int)((lpRect->bottom - lpRect->top) * fRatio); break; case WMSZ_TOPLEFT: case WMSZ_TOPRIGHT: case WMSZ_BOTTOMLEFT: case WMSZ_BOTTOMRIGHT: nAvg = (int)(((lpRect->right - lpRect->left) / fRatio + (lpRect->bottom - lpRect->top) * fRatio) / 2.0); break; } nWidth = (int)(nAvg * fRatio); nHeight = (int)(nAvg / fRatio); if (( (lpRect->right - lpRect->left) != nAvg) || ( (lpRect->bottom - lpRect->top) != nAvg)) { switch (nWindowEdge) { case WMSZ_BOTTOM: case WMSZ_BOTTOMRIGHT: case WMSZ_RIGHT: lpRect->right = lpRect->left + nWidth; lpRect->bottom = lpRect->top + nHeight; break; case WMSZ_LEFT: case WMSZ_BOTTOMLEFT: lpRect->left = lpRect->right - nWidth; lpRect->bottom = lpRect->top + nHeight; break; case WMSZ_TOP: case WMSZ_TOPRIGHT: lpRect->right = lpRect->left + nWidth; lpRect->top = lpRect->bottom - nHeight; break; case WMSZ_TOPLEFT: lpRect->left = lpRect->right - nWidth; lpRect->top = lpRect->bottom - nHeight; break; } } return TRUE; }have fun
-
Beim Ändern der Fenstergröße sendet Windows die Nachricht WM_SIZE. Darin sind in lParam die neuen Maße des Fensters angegeben. Mit SetWindowPos() kannst Du die Größe neu setzen.
-
Das ist doch schwachsinn...
Wenn man das so macht, flackert das Fenster doch...Einfach WM_SIZING abfangen, (LPRECT)lParam ist dann das Fenster-RECT und wParam die Ecke, an der der user zieht.
-
Wieso sollte man das überhaupt machen wollen?
Wenn man irgendwas nur in einem bestimmten Seitenverhältnis darstellen möchte kann man ja die Darstellung im Client-Bereich des Fensters entsprechend machen, z.B. so dass oben und unten bzw. seitlich 2 Balken freibleiben wenn das Seitenverhältnis nicht passt.
Ist IMO immer noch userfreundlicher als beim Resizen des Fensters einzugreifen.
-
Danke erstmal für eure Antworten! (Und sry, dass ich mich jetzt erst melde
)Script-Styler Dein Code funktioniert soweit, danke!
hustbear's Vorschlag gefällt mir allerdings noch besser nur:
Irgendwie bekomme ich es nicht gebackten, die Bitmap entsprechenden dem Seitenverhältnis in mein Client-Bereich zu blitten.
Zum Darstellen verwende ich StretchBlt. Aber die Berechnungen gehen irgendwie immer schief
.Das Seitenverhältnis berechne ich doch mit:
verhaeltnis = bitmap_breite / bitmap_hoehe;oder?
Wenn nun wnd_x meine Client-Fensterbreite und wnd_y meinte Client-Fensterhöhe ist und bmp_x bzw. bmp_y entsprechend die Breite bzw. der Höhe der Bitmap, wie berechne ich dann gemäß dem Seitenverhältnis die neue Bitmap-Breite/Höhe, damit die Bitmap in mein Client passt? Glaube es ist ja trivial, aber es will nicht funktionieren
.Ich danke schonmal für euer Interesse!

-
this->push();
-
Müsste doch etwa so gehen:
// in: // bmp_w, bmp_h = width/height der bitmap // wnd_w, wnd_h = width/height des verwendbaren bereichs im fenster // out: // view_w, view_h = width/height des bereichs den wir zur ausgabe verwenden // 1. versuch mit der max. breite und angepasster höhe view_w = wnd_w; view_h = (bmp_h * wnd_w) / bmp_w; // gucken ob höhe noch ok ist if (view_h > wnd_h) { // 2. versuch mit der max. höhe und angepasster breite view_h = wnd_h; view_w = (bmp_w * wnd_h) / bmp_h; } // fertig int offset_x = (wnd_w - view_w) / 2; int offset_y = (wnd_h - view_h) / 2; // ...
-
Hmm, haste auch float benutzt, bei int geht ja was verloren.