[MFC] Cum salvam dimensiunile si pozitia aplicatiei?

Despre MFC, ATL si alte biblioteci C++ de la Microsoft (forum moderat)
Post Reply
User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

[MFC] Cum salvam dimensiunile si pozitia aplicatiei?

Post by Ovidiu Cucu » 03 Aug 2011, 11:29

Intrebare
Cum salvam dimensiunile si pozitia ferestrei aplicatiei si cum le refacem atunci cand o lansam din nou?

Solutie
Se poate salva in registry o structura tip WINDOWPLACEMENT care tine informatii despre pozitionarea ferestrei in ecran.
  1. In functia InitInstance a aplicatiei chemam SetRegistryKey careia, prin conventie ii pasam numele companiei.

    Code: Select all

    BOOL CMyApplication::InitInstance()
    {
       // Change the registry key under which our settings are stored.
       SetRegistryKey(_T("Codexpert.ro"));
       // ...
    }
  2. In clasa ferestrei principale, adaugam numele cheii si valorii din registry.

    Code: Select all

    // MainFrm.h
    
    class CMainFrame : public CMDIFrameWnd
    {
       static LPCTSTR const m_pszRegSection;
       static LPCTSTR const m_pszRegPlacement;
    // ...
    };

    Code: Select all

    // MainFrm.cpp
    
    LPCTSTR const CMainFrame::m_pszRegSection = _T("main_frame");
    LPCTSTR const CMainFrame::m_pszRegPlacement = _T("placement");
  3. Implementam functiile de salvare/incarcare in/din registry.

    Code: Select all

    class CMainFrame : public CMDIFrameWnd
    {
       // ...
    private:
       void _SavePlacement();
       void _LoadPlacement();
    };

    Code: Select all

    void CMainFrame::_SavePlacement()
    {
       CWinApp* pApp = AfxGetApp();
    
       const int nSize = sizeof(WINDOWPLACEMENT);
       WINDOWPLACEMENT wndpl = {nSize};
       GetWindowPlacement(&wndpl);
       pApp->WriteProfileBinary(m_pszRegSection, m_pszRegPlacement, (LPBYTE)&wndpl, nSize);
    }

    Code: Select all

    void CMainFrame::_LoadPlacement()
    {
       CWinApp* pApp = AfxGetApp();
       
       UINT nBytes = 0;
       LPBYTE pData = NULL;
       if(pApp->GetProfileBinary(m_pszRegSection, m_pszRegPlacement, &pData, &nBytes))
       {
          LPWINDOWPLACEMENT lpWndpl = (LPWINDOWPLACEMENT)pData;
          if(SW_SHOWMINIMIZED == lpWndpl->showCmd)
          {
             lpWndpl->showCmd = SW_SHOWNORMAL;
          }
          SetWindowPlacement(lpWndpl);
          delete []pData;
       }
    }
  4. In fine, apelam _SavePlacement si _LoadPlacement, de exemplu in handlerele mesajelor WM_CREATE, respectiv WM_CLOSE.

    Code: Select all

    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
       if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
          return -1;
    
       _LoadPlacement();
       // ...
    }

    Code: Select all

    void CMainFrame::OnClose() 
    {
       _SavePlacement();
       CMDIFrameWnd::OnClose();
    }
Note
  • Exista un mic bug in Windows: itemul "Restore" din meniul system devine disabled daca setam flagul SW_SHOWMINIMIZED. De aceea in solutia de mai sus, _LoadPlacement il inlocuieste cu SW_SHOWNORMAL. Ramane la latitudinea fiecaruia sa decida o alta rezolvare in acasta situatie.
Vezi si << Back to MFC index



Post Reply