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