Fenstergröße anpassen

Slazer

Mitglied
Hallo,
Wenn ich ein Fenster unter Windows erstelle, kann ich nur die absoluten Maße angeben. Der Clienbereich hat aber dann nicht die richtige Größe. Sind die Maße der Fensterränder immer gleich, oder sind die unterschiedlich? Wie kann ich diese auslesen?
 
Es ist tatsächlich nicht ganz einfach, ein Fenster so gross zu machen, dass der resultierende Clientbereich exakt eine vorgebene Grösse hat. Erstens sind da natürlich Titel und Rahmen, aber was erschwerend noch dazukommt sind eventuell Menüsleisten, Statusbalken und -- ganz übel -- Scrollbalken.

Ich habe mir mal folgende Routine gebastelt, die auch tatsächlich (!) funktioniert:
Code:
void CMeinView::SetSize( int width, int height )
{
  int counter = 0; //- nur 5 Versuche!
  CRect rectMain, rectClient;
  for ( GetClientRect( rectClient ); 
        ( counter < 5 ) && ( rectClient.Width() != width || rectClient.Height() != height ); 
        ++counter, GetClientRect( rectClient ) )
  {
    TRACE( "rectClient: %d, %d\n", rectClient.Width(), rectClient.Height() );
    
    GetParent()->GetWindowRect( rectMain );
    int borderwidth = rectMain.Width() - rectClient.Width();
    int borderheight = rectMain.Height() - rectClient.Height();
    GetParent()->MoveWindow( rectMain.left, rectMain.top, width + borderwidth, height + borderheight );
    ((CFrameWnd*)GetParent())->RecalcLayout();
  }
}
Das habe ich mit MFC gemacht - ich denke aber, dass es die entsprechenden Funktionen auch als Nicht-Methoden in der WinAPI gibt. Meine Routine funktioniert übrigens für Framewindows. Falls du das nicht brauchst, kannst du den Kram mit GetParent() weglassen (es wird das Fenster selbst geändert) und auch RecalcLayout() fällt weg.

Hilft dir das weiter?
 
Es gibt auch die Win32-Methode AdjustWindowRect(Ex), die je nach BOOL die zugehörige Client/Window-Size ausrechnet. Die berücksichtigt aber dummerweise keine umgeklappten Menüs und Scrollbars.

Die funktioniert allerdings auch ohne HWND. Wenn das Fenster bereits existiert, ist's wohl besser, die Funktion von Kachelator zu nehmen, die geht auf Nummer sicher.
 
hm ich versteh nicht recht wie man die funktion benutzt!
kannst du des mir mal genau erklären mit parameter etc.
 
Versuch es mal so:
Code:
  RECT rect;
  // gewünschte linke obere Ecke von Clientarea
  rect.left   = 100;
  rect.top    = 100;
  // gewünschte rechte untere Ecke von Clientarea
  rect.right  = 200;
  rect.bottom = 200;

  // welchen Style hat das Fenster?
  DWORD dwStyle = WS_OVERLAPPED;

  // hat es ein Menü?  
  BOOL bMenu = FALSE;

  int iResult = AdjustWindowRect( &rect, dwStyle, bMenu );
  if ( iResult == 0 )
  {
    // hat nicht geklappt
    MessageBox( 0, "Fehler bei AdjustWindowRect()", "Au ha!", MB_ICONERROR );   
  }
  else
  {
    // rect enthält jetzt die benötigte Fenstergrösse und kann zum Positionieren verwendet werden
    SetWindowPos( hwndVonMeinemFenster, 
                  0, 
                  rect.left,              rect.top, 
                  rect.right - rect.left, rect.bottom - rect.top, 
                  SWP_NOZORDER );
  }
 
Ist zwar lange her, aber es muss trotzdem mal gesagt werden:

Sowas macht man mit GetSystemMetrics().

Daran ist überhaupt nichts kompliziert.

lg Max
 
Nicht? Du mußt dir alle Bordertypen je nach Style raussuchen und aufaddieren, die Caption, falls vorhanden, das Menü, falls vorhanden.

Und alles das kannst du mit einem Aufruf per AdjustWindowRect(Ex) erledigen.

Warum das Rad neu erfinden, runder wird es nicht.
 
Zurück