[MFC] Memorarea si restaurarea pozitiei ferestrei principale

Despre MFC, ATL si alte biblioteci C++ de la Microsoft (forum moderat)
Post Reply
nmg
Junior
Junior
Posts: 43
Joined: 12 Jul 2007, 07:36

[MFC] Memorarea si restaurarea pozitiei ferestrei principale

Post by 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():

Code: Select all

#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):

Code: Select all

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;
}
<< Back to MFC index
Last edited by Ovidiu Cucu on 08 Aug 2011, 18:46, edited 6 times in total.
Reason: structura intrebare/raspuns



mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Memorarea si restaurarea pozitiei ferestrei principale (2)

Post by mesajflaviu » 24 Aug 2009, 15:46

O alta metoda de a memora/restaura pozitia ferestrei :

1. Se salveaza pozitia ferestrei in OnClose:

Code: Select all

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:

Code: Select all

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;
}
<< Back to MFC index

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Memorarea si restaurarea pozitiei ferestrei principale (3)

Post by 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.

    Code: Select all

    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.

    Code: Select all

    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;
    		}
    	}
    }
<< Back to MFC index

Post Reply