Crossware

Table of Contents        Previous topic       Next topic       

Using the Custom AppWizard or Project Template->Tutorial - Creating an Extension with the AppWizard->Finalising Support for your Dialog Box->Restoring the Dialog Position

We will now add the code that will restore the position of your dialog box.

The position will be obtained by a call to MFC function GetWindowPlacement().  The information returned by this function can be directly used in MFC function SetWindowPlacement() to position the dialog box.

We will save the information returned by GetWindowPlacement() in a private file.  We will use the standard MFC CArchive method of saving data to this file so that further information can be save to it as additional features require it.

SerializeWindowPosition() is a function located in Extension.cpp  which conveniently loads and saves the WINDOWPLACEMENT structure to the archive file.

We use the g_MessageDlgPosition.length to indicate whether or not the contents of g_MessageDlgPosition are valid.  If g_MessageDlgPosition.length is zero then g_MessageDlgPosition has not been initialised.

Open ExtensionState.cpp and add the following bold lines:

const char AttributeFilename[] = "MyExtension.sav";
#define SCHEMA 1
WINDOWPLACEMENT g_MessageDlgPosition; // zero filled

CExtensionState::CExtensionState()
{
 ResetState();
 nExtensionCount++;
 // is there a status file?
 CString strPath = g_strProgramPath; // includes trailing backslash
 strPath += AttributeFilename;
 CFileStatus Status;
 if (CFile::GetStatus(strPath, Status))
 {
   // file exists
   CFile File;
   if (File.Open(strPath, CFile::modeRead))
   {
     CArchive ar(&File, CArchive::load);
     LONG nSchema;
     ar >> nSchema;
     SerializeWindowPosition(ar, &g_MessageDlgPosition);
     ar.Close();
     File.Close();
   }
 }
 g_pMessageDlg = new CMessageDlg();
 g_pMessageDlg->SetExtensionState(this);
}

CExtensionState::~CExtensionState()
{
 nExtensionCount--;
 if (nExtensionCount == 0)
 {
   // close all dialogs when no CExtensionState instances left
   if (g_pMessageDlg)
   {
     g_MessageDlgPosition.length = sizeof(WINDOWPLACEMENT);
     g_pMessageDlg->GetWindowPlacement(&g_MessageDlgPosition);
     g_pMessageDlg->DestroyWindow();
   }
   // save data to status file
   CString strPath = g_strProgramPath; // includes trailing backslash
   strPath += AttributeFilename;
   CFile File;
   if (File.Open(strPath, CFile::modeCreate | CFile::modeWrite))
   {
     CArchive ar(&File, CArchive::store);
     ar << (LONG)SCHEMA;
     SerializeWindowPosition(ar, &g_MessageDlgPosition);
     ar.Close();
     File.Close();
   }
 }
}

Open MessageDlg.cpp and add the following bold lines:

extern CMessageDlg* g_pMessageDlg;
extern WINDOWPLACEMENT g_MessageDlgPosition;

void CMessageDlg::OnClose()
{
 g_MessageDlgPosition.length = sizeof(WINDOWPLACEMENT);
 GetWindowPlacement(&g_MessageDlgPosition);
 g_pMessageDlg = NULL;
 DestroyWindow();
 //CDialog::OnClose();
}

Right mouse click on MessageDlg.cpp and select ClassWizard from the context menu.  Select CMessageDlg as  the Object ID, scroll down the Messages and select WM_INITDIALOG.  Click on Add Function to create function OnInitDialog(). Click on Edit Code to edit this function.  Add the following bold lines:

BOOL CMessageDlg::OnInitDialog()
{
 CDialog::OnInitDialog();
    
 if (g_MessageDlgPosition.length != 0)
    SetWindowPlacement(&g_MessageDlgPosition);
    
 return TRUE;  // return TRUE unless you set the focus to a control
   // EXCEPTION: OCX Property Pages should return FALSE
}