Last Updated 2004/08/04
Programming Tips Visual C++ MFC ウィンドウ  索 引 
ウィンドウ状態保存復元
2004/08/04

ウィンドウのサイズや状態をアプリケーション起動時に復元する.

メインフレームの WM_CLOSE などでウィンドウ状態を保存する.

    WINDOWPLACEMENT wp;
    if( GetWindowPlacement(&wp) ) {
        SaveWindowPlacement(&wp);
    }


void CMainFrame::SaveWindowPlacement(LPWINDOWPLACEMENT pwp)
{

    CString strBuffer;
    strBuffer.Format("%i:%i:%i:%i:%i:%i:%i:%i:%i:%i",
                    pwp->flags, pwp->showCmd,
                    pwp->ptMinPosition.x, pwp->ptMinPosition.y,
                    pwp->ptMaxPosition.x, pwp->ptMaxPosition.y,
                    pwp->rcNormalPosition.left,
                    pwp->rcNormalPosition.top,
                    pwp->rcNormalPosition.right,
                    pwp->rcNormalPosition.bottom);

    AfxGetApp()->WriteProfileString("Setting", "WinPos", strBuffer);

    // 画面分割の大きさ
    int iCur, iMin;
    // 上下分割の大きさ
    m_wndSplitter.GetRowInfo(0, iCur, iMin);
    AfxGetApp()->WriteProfileInt("Setting", "View", iCur);

    // リストビュー各カラムサイズ
    CMyView *pView = GetActiveView();
    // ヘッダの数
    int iHeader = pView->GetListCtrl().GetHeaderCtrl()->GetItemCount();
    LVCOLUMN lvCol;
    lvCol.mask = LVCF_WIDTH;
    strBuffer.Empty();
    for( int iCnt = 0; iCnt < iHeader; iCnt++ ) {
        pView->GetListCtrl().GetColumn(iCnt, &lvCol);
        CString strColSize;
        strColSize.Format("%i", lvCol.cx);
        if( strBuffer.IsEmpty() )
            strBuffer += strColSize;
        else
            strBuffer += (":" + strColSize);
    }
    AfxGetApp()->WriteProfileString("Setting", "ListPos", strBuffer);
}



メインフレームの WM_CREATE などでウィンドウ状態を復元する.

        WINDOWPLACEMENT wp;
        if( LoadWindowPlacement(&wp) ) {
            // SetWindowPlacement では最大化などの場合不具合を起こす
            // 以下の様にする
            wp.flags = 0;
            UINT uiCmd = wp.showCmd;
            wp.showCmd = 0;
            SetWindowPlacement(&wp);
            if( uiCmd == SW_SHOWMAXIMIZED ) {
                PostMessage(WM_SYSCOMMAND, SC_MAXIMIZE);
            }
        }


BOOL CMainFrame::LoadWindowPlacement(LPWINDOWPLACEMENT pwp)
{
    CString strBuffer = AfxGetApp()->GetProfileString("Setting", "WinPos");

    if( strBuffer.IsEmpty() )
        return FALSE;

    int cRead = _stscanf(strBuffer,
                    "%i:%i:%i:%i:%i:%i:%i:%i:%i:%i",
                    &pwp->flags,
                    &pwp->showCmd,
                    &pwp->ptMinPosition.x, &pwp->ptMinPosition.y,
                    &pwp->ptMaxPosition.x, &pwp->ptMaxPosition.y,
                    &pwp->rcNormalPosition.left,
                    &pwp->rcNormalPosition.top,
                    &pwp->rcNormalPosition.right,
                    &pwp->rcNormalPosition.bottom
                    );

    if( cRead != 10 )
        return FALSE;

    // 画面分割の大きさ
    // 上下分割の大きさ
    int iCy = AfxGetApp()->GetProfileInt("Setting", "View", 200);
    m_wndSplitter.SetRowInfo(0, iCy, 0);
    m_wndSplitter.RecalcLayout();

    // リストビュー各カラムサイズ
    // 取得した値をリストビューに渡す
    AfxGetApp()->GetProfileString("Setting", "ListPos", strBuffer);

    return TRUE;
}


参照
前後のTips
ウィンドウ状態保存復元

DSS ProgrammingTipsCGI Ver2.02