C++ Builder Snippets  

Position und Grösse der Formulare in der Registry speichern:
 
Zu den Grundfunktionalitäten einer guten Anwendung gehört heutzutage die Fähigkeit, Benutzereinstellungen für Fenstergrösse und -Position zu speichern und beim Programmstart das Fenster so darzustellen, wie es verlassen wurde.

Funktion SaveFormPosition() speichert die Fenstereinstellungen in der Registry und RestoreFormPosition() liest diese aus und weist die Grössen- und Positionsangaben dem Fenster zu. Je nach Einzelfall kann entschieden werden, ob diese im rechner- oder benutzerspezifischen Teil der Registry abgelegt werden. Wird das Programm bei einer Netzwerkinstallation auf verschiedenen Rechnern (mit evtl. unterschiedlich grossen Monitoren) aufgerufen, macht HKEY_LOCAL_MACHINE mehr Sinn, anderenfalls ist HKEY_CURRENT_USER angebracht.

Je nach Anwendung muss ebenfalls entschieden werden, ob die Fensterposition (z.B. beim Überlagern durch die Taskleiste) entsprechend automatisch korrigiert werden soll. Im folgenden Beispiel wird die automatische Positionskorrektur mit Hilfe des Parameters bool blFitToWorkArea, der der Funktion RestoreFormPosition() übergeben wird, aktiviert. In diesem Fall wird die tatsächliche Grösse des Desktop-Arbeitsbereichs (ohne Taskleiste) mit Hilfe des API-Aufrufs SystemParametersInfo(SPI_GETWORKAREA, 0, &rWorkArea, 0) ermittelt und das Fenster ggf. angepasst dargestellt.
//--- xyz.h ---
#define REG_MAINKEY           "\\Software\\Company\\ProgName"

//--- xyz.cpp ---
#include <registry.hpp>

//---------------------------------------------------------------------------
// Speichert Position und Grösse des Formulars in die Registry
//---------------------------------------------------------------------------
// Parameter:
//----------------
// TForm * pForm : Zeiger auf den Formular, dessen Einstellungen gesichert
//                 werden sollen
//---------------------------------------------------------------------------
void SaveFormPosition(TForm * pForm)
{
  TRegistry *pReg = new TRegistry;
  AnsiString slActiveKey = AnsiString(REG_MAINKEY) + "\\" +
    pForm -> Name + "\\";
  try
  {
    pReg -> RootKey = HKEY_LOCAL_MACHINE;
    pReg -> OpenKey(slActiveKey, true);

    if(pForm -> WindowState == wsMaximized)
      { pReg -> WriteBool("Maximized", true); }
    else { pReg -> WriteBool("Maximized", false); }
    pReg -> WriteInteger("WinLeft",   pForm -> Left);
    pReg -> WriteInteger("WinTop",    pForm -> Top);
    pReg -> WriteInteger("WinWidth",  pForm -> Width);
    pReg -> WriteInteger("WinHeight", pForm -> Height);
    if(pReg != NULL) { delete pReg; pReg = NULL; }
  }
  catch(...)
  {
    if(pReg != NULL) { delete pReg; pReg = NULL; }
  }
}
//---------------------------------------------------------------------------
// Stellt die Position und Grösse des Formulars wieder her
//---------------------------------------------------------------------------
// Parameter:
// ---------------------
// TForm * pForm        : Zeiger auf das Formular, dessen Einstellungen
//                        wiederhergestellt werden sollen
// bool blFitToWorkArea : Flag "Formulardimensionen an Arbeitsbereich des
//                        Desktops anpassen"
//---------------------------------------------------------------------------
void RestoreFormPosition(TForm * pForm, bool blFitToWorkArea)
{
  TRegistry *pReg = new TRegistry;
  bool blFormMax = false;
  AnsiString slActiveKey = AnsiString(REG_MAINKEY) + "\\" +
    pForm -> Name + "\\";
  try
  {
    pReg -> RootKey = HKEY_LOCAL_MACHINE;
    if(pReg -> KeyExists(AnsiString(REG_MAINKEY) + "\\" + pForm -> Name))
    {
      pReg -> OpenKey(slActiveKey, true);
      blFormMax    = pReg -> ReadBool   ("Maximized");

      // Fenstergrösse wiederherstellen:
      if (!blFormMax)
      {
        pForm -> WindowState = wsNormal;
        pForm -> Top    = pReg -> ReadInteger("WinTop");
        pForm -> Left   = pReg -> ReadInteger("WinLeft");
        pForm -> Width  = pReg -> ReadInteger("WinWidth");
        pForm -> Height = pReg -> ReadInteger("WinHeight");

        // Falls an Arbeitsbereich des Desktops anpassen:
        if(blFitToWorkArea)
        {
          TRect rWorkArea;
          SystemParametersInfo(SPI_GETWORKAREA, 0, &rWorkArea, 0);

          // ggf. Fensterhöhe anpassen:
          pForm -> Height = pForm -> Height <= rWorkArea.Bottom - rWorkArea.Top ?
            pForm -> Height : rWorkArea.Bottom - rWorkArea.Top;
          // ggf. Fensterbreite anpassen:
          pForm -> Width = pForm -> Width <= rWorkArea.Right - rWorkArea.Left ?
            pForm -> Width : rWorkArea.Right - rWorkArea.Left;
          // ggf. vertikale Position anpassen:
          if(pForm -> Top < rWorkArea.Top) pForm -> Top = rWorkArea.Top;
          else if(pForm -> Top + pForm -> Height > rWorkArea.Bottom)
            pForm -> Top = rWorkArea.Bottom - pForm -> Height;
          // ggf. horizontale Position anpassen:
          if(pForm -> Left < rWorkArea.Left) pForm -> Left = rWorkArea.Left;
          else if(pForm -> Left + pForm -> Width > rWorkArea.Right)
            pForm -> Left = rWorkArea.Right - pForm -> Width;
        }
      }
      else pForm -> WindowState = wsMaximized;
    }
    if(pReg != NULL) { delete pReg; pReg = NULL; }
  }
  catch(...)
  {
    if(pReg != NULL) { delete pReg; pReg = NULL; }
  }
}

Anwendungsbeispiel für die Funktionen RestoreFormPosition() und SaveFormPosition():
//---------------------------------------------------------------------------
// Wiederherstellen der Fensterposition beim Programmstart:
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
  RestoreFormPosition(this, true);
}

//---------------------------------------------------------------------------
// Speichern der Fensterposition beim Beenden des Programms:
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
  SaveFormPosition(this);
}



© '99-2000 by S. Kreutzmann