CFrameWnd 雑記 |
Last Updated: Dec.19,2006 |
使用しているコンパイラは、Microsoft Visual C++ 6.0 です。これ以外のバージョンでは記述と食い違うことがあるかも知れません。 |
アプリケーションのメインウィンドウの位置とサイズを保存し、次回の起動時に復元する処理は是非とも実装したい機能です。この機能を CFrameWnd の派生クラス CMainFrame において、実装してみたいと思います。
まず、ウィンドウの位置を保存する関数です。
// ウィンドウの位置を保存する void CMainFrame::SaveWindowPlacement() { WINDOWPLACEMENT wp; GetWindowPlacement(&wp); AfxGetApp()->WriteProfileBinary( _T("Settings"), _T("Window"), (LPBYTE)&wp, sizeof(WINDOWPLACEMENT)); }
上記の関数は、現在のウィンドウの状態を GetWindowPlacement で取得して、レジストリ(あるいは ini ファイル)に保存するものです。WriteProfileBinary を使っているのは少々手抜きなので、気に入らなければ、WINDOWPLACEMENT のメンバから、rcNormalPosition と showCmd の値を保存するように修正してください。showCmd を保存する理由は、最大表示だった場合を考慮するためです。最大表示の場合の rcNormalPosition の値は、最大化する前の通常表示のときの値になっています。
あとはこの関数を、OnDestroy で呼び出します。
void CMainFrame::OnDestroy() { SaveWindowPlacement(); CFrameWnd::OnDestroy(); }
今度はウィンドウの位置を復元する関数を作成します。注意してほしいのは、WINDOWPLACEMENT の showCmd メンバの値が、SW_SHOWMAXIMIZED(最大表示)のときのみ、AfxGetApp()->m_nCmdShow に代入している部分です。これにより、アプリケーションは最大表示されることになります。また、アプリケーションで通常表示にすると、前回通常表示だったときの位置とサイズが復元されます。
// ウィンドウ位置を復元する void CMainFrame::InitWindowPlacement(CREATESTRUCT& cs) { WINDOWPLACEMENT wp; LPBYTE pData; UINT nSize; if (AfxGetApp()->GetProfileBinary( _T("Settings"), _T("Window"), &pData, &nSize)) { ASSERT(nSize == sizeof(WINDOWPLACEMENT)); ::CopyMemory(&wp, pData, sizeof(WINDOWPLACEMENT)); delete [] pData; cs.x = wp.rcNormalPosition.left; cs.y = wp.rcNormalPosition.top; cs.cx = wp.rcNormalPosition.right - wp.rcNormalPosition.left; cs.cy = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; if (wp.showCmd == SW_SHOWMAXIMIZED) AfxGetApp()->m_nCmdShow = SW_SHOWMAXIMIZED; } }
このメンバ関数は、PreCreateWindow で呼び出します。
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if (!CFrameWnd::PreCreateWindow(cs)) return FALSE; InitWindowPlacement(cs); return TRUE; }
アプリケーションで使用するフォントデータの保存・復元用の関数です。こちらもよく使います。
void CMainFrame::InitFontData(CFont* pFont) { LOGFONT lf; LPBYTE pData; UINT nSize; if (AfxGetApp()->GetProfileBinary( _T("Settings"), _T("Font"), &pData, &nSize)) { ASSERT(nSize == sizeof(LOGFONT)); ::CopyMemory(&lf, pData, sizeof(LOGFONT)); delete [] pData; if (pFont->CreateFontIndirect(&lf)) return; } pFont->CreatePointFont(10*14, _T("FixedSys")); } void CMainFrame::SaveFontData(CFont* pFont) { LOGFONT lf; pFont->GetLogFont(&lf); AfxGetApp()->WriteProfileBinary( _T("Settings"), _T("Font"), (LPBYTE)&lf, sizeof(LOGFONT)); }
WriteProfileBinary は、構造体をそのままで扱えるので、とても便利です。ただし、_UNICODE ビルドと _MBCS ビルドで構造体のサイズが違う場合がありますので、そのあたりは注意して使用する必要があります。
Back | Copyright (c) 2003, 2006 AOK. All Rights Reserved. |