プロパティシート
ウィンドウ内にモードレス&チャイルドなプロパティシートを埋め込むたくらみ。そもそもCPropertySheetはモーダルか、モードレス(といっても非チャイルドのダイアログ)としての使い方しかしないようなので、MSDNではよくわかりませんでした。で、手探りでごにょごにょ。ちなみに、想定してるアプリケーションはダイアログベースのやつです。なので、この処理はOnInitDialogに書きます。
001 // プロパティシートにプロパティページを追加する。 002 m_cPropSheet.AddPage( &m_cPropSE ); 003 m_cPropSheet.AddPage( &m_cPropThread ); 004 005 // プロパティシートを作る。 006 m_cPropSheet.Create( this, WS_CHILD | WS_VISIBLE ); 007 008 // プロパティシートの位置あわせ。 009 CRect rc; 010 // 現在のウィンドウサイズを得る。 011 m_cPropSheet.GetWindowRect( &rc ); 012 // (420,0)の位置に持ってくる。 013 rc.OffsetRect( 420 - rc.left, -rc.top ); 014 // あと、幅も縮める。 015 rc.right -= 200; 016 TRACE2( "%d,%d,", rc.left, rc.top ); 017 TRACE2( "%d,%d\n", rc.right, rc.bottom ); 018 // 動かす。 019 m_cPropSheet.MoveWindow( &rc ); 020 021 // プロパティシートの中のタブコントロールの位置合わせ。 022 CTabCtrl* pTabCtrl = m_cPropSheet.GetTabControl(); 023 // 現在のサイズを得る。 024 pTabCtrl->GetWindowRect( &rc ); 025 TRACE2( "Before: %d,%d,", rc.left, rc.top ); 026 TRACE2( "%d,%d\n", rc.right, rc.bottom ); 027 // クライアント座標に変換。多分ちょっとずれてる 028 pTabCtrl->ScreenToClient( &rc ); 029 //rc.OffsetRect( -rc.left, -rc.top ); // こっちでも大丈夫っぽい 030 // プロパティシートと同じサイズ縮める。 031 rc.right -= 200; 032 // 動かす。 033 pTabCtrl->MoveWindow( &rc ); 034 pTabCtrl->GetWindowRect( &rc ); 035 TRACE2( "After: %d,%d,", rc.left, rc.top ); 036 TRACE2( "%d,%d\n", rc.right, rc.bottom ); 037 CPoint ptTabCtrl = rc.TopLeft(); 038 039 if( false ){ // じつはこんな面倒なことしなくてよかった 040 // この関数でプロパティページを置くべき位置が求まるらしい。 041 pTabCtrl->AdjustRect( FALSE, &rc ); 042 rc.OffsetRect( -ptTabCtrl ); 043 for( int i = 0; i < m_cPropSheet.GetPageCount(); ++i ){ 044 CPropertyPage* pPropPage = m_cPropSheet.GetPage( i ); 045 if( pPropPage->GetSafeHwnd() == NULL ){ 046 // なぜかNULLになることがある。 047 continue; 048 } 049 pPropPage->MoveWindow( &rc ); 050 } 051 } 052
今ひとつ不正確な点は、タブコントロールの位置です。ClientToScreenでそれっぽい位置には来るのですが、本来はもう少し右下に来るようです。