[MFC] Memorarea si restaurarea pozitiei ferestrei principale

MFC FAQs, tips & tricks (forum moderat)

[MFC] Memorarea si restaurarea pozitiei ferestrei principale

Mesajde nmg » 02 Aug 2007, 10:39

Intrebare: Cum pot memora pozitia unei ferestre si utliza la urmatoare afisare a acesteia?

Raspuns: Implementarea unei astfel de comportament este extrem de simpla si implica utilizarea
functiilor virtuale OnDestroy() si ActivateFrame().

In functie de implementarea dorita, datele se pot salva intr-un fisier config sau in registry,
ca in cazul de fata.

Pentru salvarea pozitiei ferestrei se supraincarca functia OnDestroy():

Cod: Selectaţi tot
#define KEY         "Main"
#define SECTION "Setari\\Position"

void CMainFrame::OnDestroy()
{
   // get current position:
   WINDOWPLACEMENT wp;
   ::ZeroMemory(&wp, sizeof(wp));   
   GetWindowPlacement(&wp);

   // save data to registry
   theApp.WriteProfileBinary(SECTION, KEY, (LPBYTE)&wp, sizeof(WINDOWPLACEMENT));

   // destroy the window   
   CFrameWnd::OnDestroy();   
}


Pentru restaurarea ferestrei in pozitia initiala se supraincarca functia ActivateFrame (int nCmdShow):

Cod: Selectaţi tot
void CMainFrame::ActivateFrame(int nCmdShow)
{
    // do default:
    CFrameWnd::ActivateFrame(nCmdShow);

    // read position from the registry:
    UINT n = 0;
    WINDOWPLACEMENT* pWp = NULL;

    theApp.GetProfileBinary(SECTION, KEY, (LPBYTE*)&pWp, &n);

    // restore the window position:
    if(n == sizeof(WINDOWPLACEMENT))
        SetWindowPlacement(pWp);

    // clean up our mess:
    delete [] pWp;
}
Ultima oară modificat de Ovidiu Cucu pe 01 Sep 2009, 19:02, modificat de 5 ori în total.
Motiv: structura intrebare/raspuns
nmg
Junior
Junior
 
Mesaje: 25
Membru din: 12 Iul 2007, 07:36

Memorarea si restaurarea pozitiei ferestrei principale (2)

Mesajde mesajflaviu » 24 Aug 2009, 15:46

O alta metoda de a memora/restaura pozitia ferestrei :

1. Se salveaza pozitia ferestrei in OnClose:
Cod: Selectaţi tot
void CMainFrame::OnClose()
{
   // TODO: Add your message handler code here and/or call default
   
    // Save main window position
    CWinApp* pApp = AfxGetApp();
    WINDOWPLACEMENT wp;
    GetWindowPlacement(&wp);
    pApp->WriteProfileInt("Frame", "Status", wp.showCmd);
    pApp->WriteProfileInt("Frame", "Top",    wp.rcNormalPosition.top);
    pApp->WriteProfileInt("Frame", "Left",   wp.rcNormalPosition.left);
    pApp->WriteProfileInt("Frame", "Bottom", wp.rcNormalPosition.bottom);
    pApp->WriteProfileInt("Frame", "Right",  wp.rcNormalPosition.right);

   CMDIFrameWnd::OnClose();
}

2. Se restaureaza in PreCreateWindow:
Cod: Selectaţi tot
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
   if( !CMDIFrameWnd::PreCreateWindow(cs) )
      return FALSE;
   // TODO: Modify the Window class or styles here by modifying
   //  the CREATESTRUCT cs

    // Restore main window position
    CWinApp* pApp = AfxGetApp();
    int s, t, b, r, l;

    // only restore if there is a previously saved position
    if ( -1 != (s = pApp->GetProfileInt("Frame", "Status",   -1)) &&
         -1 != (t = pApp->GetProfileInt("Frame", "Top",      -1)) &&
         -1 != (l = pApp->GetProfileInt("Frame", "Left",     -1)) &&
         -1 != (b = pApp->GetProfileInt("Frame", "Bottom",   -1)) &&
         -1 != (r = pApp->GetProfileInt("Frame", "Right",    -1)))
   {
      // restore the window's status
      pApp->m_nCmdShow = s;

      // restore the window's width and height
      cs.cx = r - l;
      cs.cy = b - t;

      // the following correction is needed when the taskbar is
      // at the left or top and it is not "auto-hidden"
      RECT workArea;
      SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0);

      l += workArea.left;
      t += workArea.top;

      // make sure the window is not completely out of sight
      int max_x = GetSystemMetrics(SM_CXSCREEN) - GetSystemMetrics(SM_CXICON);
      int max_y = GetSystemMetrics(SM_CYSCREEN) - GetSystemMetrics(SM_CYICON);

      cs.x = min(l, max_x);
      cs.y = min(t, max_y);
   }
   return TRUE;
}



Next FAQ >>
mesajflaviu
Membru
Membru
 
Mesaje: 187
Membru din: 10 Sep 2008, 21:40

Memorarea si restaurarea pozitiei ferestrei principale (3)

Mesajde mesajflaviu » 29 Oct 2009, 10:56

Prima solutie din acest topic funtioneaza pentru aplicatii SDI. O solutie imbunatatita care este OK si pentru MDI este urmatoarea:

  1. Se creeaza o variabila membru te tip boolean pentru CMainFrame : m_bOnce , care se initializeaza in CMainFrame::PreCreateWindow cu valoarea TRUE : m_bOnce = TRUE.
  2. In CMainFrame::DestroyWindow se salveaza pozitia ferestrei.
    Cod: Selectaţi tot
    void CMainFrame::OnDestroy()
    {
       SaveBarState(_T("bar_state"));
       WINDOWPLACEMENT wp;
       GetWindowPlacement(&wp);
       AfxGetApp()->WriteProfileBinary("MainFrame", "WP", (LPBYTE)&wp, sizeof(wp));

       CMDIFrameWnd::OnDestroy();   
    }
  3. In CMainFrame::OnShowWindow se restaureaza pozitia memorata a ferestrei. Variabila m_bOnce este folosita pentru a ne asigura ca acest lucru se face o singura data.
    Cod: Selectaţi tot
    void CMainFrame::OnShowWindow(BOOL bShow, UINT nStatus)
    {
       CMDIFrameWnd::OnShowWindow(bShow, nStatus);
       
       if(bShow && ! IsWindowVisible() && m_bOnce)
       {
          m_bOnce = FALSE;
          UINT nBytes = 0;
          WINDOWPLACEMENT *lwp;
          if(AfxGetApp()->GetProfileBinary("MainFrame", "WP", (LPBYTE*)&lwp, &nBytes))
          {
             SetWindowPlacement(lwp);
             delete []lwp;
          }
       }
    }


Next FAQ >>
mesajflaviu
Membru
Membru
 
Mesaje: 187
Membru din: 10 Sep 2008, 21:40


Înapoi la MFC

Cine este conectat

Utilizatorii ce navighează pe acest forum: Yahoo [Bot] şi 1 vizitator