C:\home\SVGCats_src\src\CatsPropBar.cpp
1|// CatsPropBar.cpp : インプリメンテーション ファイル 2|// 3| 4|#include "mixer_precomp.h" 5|#ifdef USES_MXP_AUTOINC 6| #include "SVGCat.ah" 7|#endif 8|#include "CatsPropBar.h" 9| 10| 11|//#include <afxpriv.h> 12|#define WM_SIZEPARENT 0x0361 // lParam = &AFX_SIZEPARENTPARAMS 13| 14| 15|#ifdef _DEBUG 16|#define new DEBUG_NEW 17|#undef THIS_FILE 18|static char THIS_FILE[] = __FILE__; 19|#endif 20| 21|///////////////////////////////////////////////////////////////////////////// 22|// CCatsPropBar ダイアログ 23| 24| 25| 26|/*********************************************************************** 27| 1. <<< [CCatsPropBar::CCatsPropBar] 初期化する >>> 28|************************************************************************/ 29|CCatsPropBar::CCatsPropBar() 30|{ 31| //{{AFX_DATA_INIT(CCatsPropBar) 32| // メモ - ClassWizard はこの位置にマッピング用のマクロを追加または削除します。 33| //}}AFX_DATA_INIT 34| m_bCreated = false; 35| m_bVisible = false; 36| m_bDocking = false; 37| m_bFirstMoveDone = false; 38| m_bPrevParentIconic = false; 39| m_prevParentRc.top = 0; m_prevParentRc.right = 0; 40| m_X = 0; 41| m_Y = 0; 42|} 43| 44| 45|void CCatsPropBar::DoDataExchange(CDataExchange* pDX) 46|{ 47| CInitDialogBar::DoDataExchange(pDX); 48| //{{AFX_DATA_MAP(CCatsPropBar) 49| // メモ - ClassWizard はこの位置にマッピング用のマクロを追加または削除します。 50| //}}AFX_DATA_MAP 51|} 52| 53| 54|BEGIN_MESSAGE_MAP(CCatsPropBar, CInitDialogBar) 55| //{{AFX_MSG_MAP(CCatsPropBar) 56| ON_MESSAGE(WM_INITDIALOG, OnInitDialog) 57| ON_WM_SIZE() 58| //}}AFX_MSG_MAP 59| //ON_WM_MOVE() 60| //ON_MESSAGE(WM_SIZEPARENT, OnSizeParent) 61|END_MESSAGE_MAP() 62| 63|///////////////////////////////////////////////////////////////////////////// 64|// CCatsPropBar メッセージ ハンドラ 65| 66| 67| 68|/*********************************************************************** 69| 2. <<< [CCatsPropBar::Create] ウィンドウを作成する >>> 70|************************************************************************/ 71|BOOL CCatsPropBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, 72| UINT nStyle, UINT nID, BOOL bChange, bool bParentShow ) 73|{ 74| BOOL r; 75| 76| r = CInitDialogBar::Create( pParentWnd, lpszTemplateName, nStyle, nID, bChange ); 77| m_Parent = (CFrameWnd*)pParentWnd; 78| m_bParentShow = bParentShow; 79| m_bCreated = true; 80| m_bNotFloatingYet = true; 81| ((CMainFrame*)pParentWnd)->ShowControlBar( this, FALSE, FALSE ); 82| 83| /* m_X, m_Y をウィンドウ右上座標からスクリーン座標に変える */ 84| m_Parent->GetWindowRect( &m_prevParentRc ); 85| m_X += m_prevParentRc.right; m_Y += m_prevParentRc.top; 86| 87| return r; 88|} 89| 90| 91|BOOL CCatsPropBar::Create(CWnd * pParentWnd, UINT nIDTemplate, 92| UINT nStyle, UINT nID, BOOL bChange, bool bParentShow ) 93|{ 94| BOOL r; 95| 96| r = Create( pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID, bChange, bParentShow ); 97| 98| return r; 99|} 100| 101| 102|BOOL CCatsPropBar::OnInitDialog() 103|{ 104| CInitDialogBar::OnInitDialogBar(); 105| 106| return TRUE; // コントロールにフォーカスを設定しないとき、戻り値は TRUE となります 107| // 例外: OCX プロパティ ページの戻り値は FALSE となります 108|} 109| 110| 111| 112|/*********************************************************************** 113| 3. <<< [CCatsPropBar::SetVisible] 表示状態を変更する >>> 114|************************************************************************/ 115|void CCatsPropBar::SetVisible( bool bVisible ) 116|{ 117| if ( m_bCreated ) { 118| if ( m_bVisible != bVisible ) { 119| if ( bVisible && m_bParentShow && ! GetShown() ) Show(); 120| else if ( GetShown() ) Hide(); 121| } 122| } 123| m_bVisible = bVisible; 124|} 125| 126| 127| 128|/*********************************************************************** 129| 4. <<< [CCatsPropBar::SetDocking] ドッキング状態を変更する >>> 130|************************************************************************/ 131|void CCatsPropBar::SetDocking( bool bDocking ) 132|{ 133| POINT point; 134| RECT parentRc; 135| RECT rc; 136| UINT dockingPos; 137| 138| if ( m_bCreated ) { 139| 140| if ( ( m_EnableDocking_Style & CBRS_ALIGN_ANY ) == 0 ) 141| bDocking = false; 142| 143| m_bDocking = ( ! IsFloating() ); 144| 145| if ( m_bDocking != bDocking && GetShown() ) { 146| if ( bDocking ) { 147| 148| /* 最も近い位置にドッキングさせる */ 149| m_Parent->GetClientRect( &parentRc ); 150| m_Parent->ClientToScreen( &parentRc ); 151| GetWindowRect( &rc ); 152| if ( rc.top < parentRc.top && m_EnableDocking_Style & CBRS_ALIGN_TOP ) 153| dockingPos = AFX_IDW_DOCKBAR_TOP; 154| else if ( rc.bottom < parentRc.bottom && m_EnableDocking_Style & CBRS_ALIGN_BOTTOM ) 155| dockingPos = AFX_IDW_DOCKBAR_BOTTOM; 156| else if ( rc.left < parentRc.left && m_EnableDocking_Style & CBRS_ALIGN_LEFT ) 157| dockingPos = AFX_IDW_DOCKBAR_LEFT; 158| else if ( rc.right > parentRc.right && m_EnableDocking_Style & CBRS_ALIGN_RIGHT ) 159| dockingPos = AFX_IDW_DOCKBAR_RIGHT; 160| else if ( m_EnableDocking_Style & (CBRS_ALIGN_TOP | CBRS_ALIGN_BOTTOM) ) { 161| if ( (rc.top + rc.bottom) < (parentRc.top + parentRc.bottom) ) 162| dockingPos = AFX_IDW_DOCKBAR_TOP; 163| else 164| dockingPos = AFX_IDW_DOCKBAR_BOTTOM; 165| } 166| else if ( m_EnableDocking_Style & (CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT) ) { 167| if ( (rc.left + rc.right) < (parentRc.left + parentRc.right) ) 168| dockingPos = AFX_IDW_DOCKBAR_LEFT; 169| else 170| dockingPos = AFX_IDW_DOCKBAR_RIGHT; 171| } 172| else 173| error(); 174| 175| m_Parent->DockControlBar( this, dockingPos, NULL ); 176| } 177| else { 178| 179| /* ドッキングを解除する */ 180| SyncXY(); 181| point.x = m_X; point.y = m_Y; 182| m_Parent->FloatControlBar( this, point ); 183| } 184| } 185| } 186| m_bDocking = bDocking; 187|} 188| 189| 190| 191|/*********************************************************************** 192| 5. <<< [CCatsPropBar::EnableDocking] ドッキング可能な辺を設定する >>> 193|【引数】 194| ・DWORD style; 辺。 参照→CControlBar::EnableDocking 195| ・bool bDoking; ドッキング状態も変更するかどうか 196|************************************************************************/ 197|void CCatsPropBar::EnableDocking( DWORD style, bool bDocking ) 198|{ 199| m_EnableDocking_Style = style; 200| CInitDialogBar::EnableDocking( style ); 201| if ( bDocking ) SetDocking( style != 0 ); 202|} 203| 204| 205| 206|/*********************************************************************** 207| 6. <<< [CCatsPropBar::SetFloatPos] ウィンドウの位置を動かす(スクリーン座標指定) >>> 208|【引数】 209| ・int x,y; ウィンドウ左上の位置(スクリーン座標) 210|************************************************************************/ 211|void CCatsPropBar::SetFloatPos( int x, int y ) 212|{ 213| m_X = x; m_Y = y; 214| 215| if ( m_bCreated && ! m_bDocking ) { 216| POINT point; 217| 218| point.x = m_X; point.y = m_Y; 219| m_Parent->FloatControlBar( this, point ); 220| } 221|} 222| 223| 224| 225|/*********************************************************************** 226| 7. <<< [CCatsPropBar::SetFloatStepPos] ウィンドウの位置を動かす(右上ウィンドウ座標指定) >>> 227|【引数】 228| ・int x,y; ウィンドウ左上の位置(右上ウィンドウ座標) 229|************************************************************************/ 230|void CCatsPropBar::SetFloatStepPos( int x, int y ) 231|{ 232| SetFloatPos( x + m_prevParentRc.right, y + m_prevParentRc.top ); 233|} 234| 235| 236| 237|/*********************************************************************** 238| 8. <<< [CCatsPropBar::OnUpdate] m_Parent::OnUpdate(this) が呼ばれたときの処理 >>> 239|************************************************************************/ 240|void CCatsPropBar::OnUpdate() 241|{ 242| RECT rect; 243| int sc_w, sc_h; 244| 245| if ( m_bFirstMoveDone && ! m_bNotFloatingYet && ! m_Parent->IsIconic() ) { 246| 247| m_bVisible = (IsWindowVisible() != 0); // m_Parent->IsIconic()==false のとき false になってしまう。 248| 249| 250| /* おかしな値になっていないかチェックする */ 251| /* 非表示状態では、rect.left, r, u, b とも -32000 になる */ 252| if ( m_bVisible ) { 253| GetWindowRect( &rect ); 254| 255| sc_w = GetSystemMetrics( SM_CXFULLSCREEN ); 256| sc_h = GetSystemMetrics( SM_CYFULLSCREEN ); 257| if ( rect.left < -sc_w ) return; 258| if ( rect.left > sc_w*2 ) return; 259| if ( rect.top < -sc_h ) return; 260| if ( rect.top > sc_h*2 ) return; 261| 262| m_X = rect.left - m_DX; 263| m_Y = rect.top - m_DY; 264| } 265| } 266|} 267| 268| 269| 270|/*********************************************************************** 271| 9. <<< [CCatsPropBar::OnChgParentShow] 親ウィンドウの表示状態が変わったときの処理 >>> 272|【補足】 273|・親ウィンドウの表示状態を設定してからこの関数を呼び出してください。 274|************************************************************************/ 275|void CCatsPropBar::OnChgParentShow() 276|{ 277| bool bParentShowOrIconic = 278| ( m_Parent->IsWindowVisible() != 0 || m_Parent->IsIconic() ); 279| 280| if ( m_bCreated ) { 281| if ( m_bParentShow != bParentShowOrIconic && ! m_bDocking ) { 282| if ( m_bVisible && bParentShowOrIconic && ! GetShown() ) Show(); 283| else if ( GetShown() ) Hide(); 284| } 285| } 286| m_bParentShow = bParentShowOrIconic; 287|} 288| 289| 290| 291|/*********************************************************************** 292| 10. <<< [CCatsPropBar::OnParentMove] 親ウィンドウの CWnd::OnMove が呼ばれたときの処理 >>> 293|【引数】 294| ・int x,y; ウィンドウ左上の位置 295|【補足】 296|・以下の条件でこの関数は呼ばれます。 297| ・親ウィンドウが生成された後 298| ・親ウィンドウを動かした後 299| ・親ウィンドウを最小化、最大化、元に戻すを行った後 300|************************************************************************/ 301|void CCatsPropBar::OnParentMove( int x, int y ) 302|{ 303| int dx, dy; 304| RECT parentRc; 305| 306| /* m_Parent->OnCreate をリターンした後でできる初期化処理をする */ 307| if ( ! m_bFirstMoveDone ) { 308| if ( ! m_Parent->IsWindowVisible() ) return; 309| if ( m_Parent->IsIconic() ) return; 310| 311| m_bFirstMoveDone = true; 312| m_bParentShow = true; 313| 314| if ( m_bVisible ) { 315| Show(); 316| if ( ! m_bDocking && MoveInScreen() ) { 317| POINT point; 318| 319| point.x = m_X; point.y = m_Y; 320| m_Parent->FloatControlBar( this, point ); 321| } 322| } 323| 324| /* この関数の後半の処理で使う変数の初期化をする */ 325| m_Parent->GetWindowRect( &m_prevParentRc ); 326| } 327| 328| /* プロパティバーをメインウィンドウの動きに合わせる */ 329| if ( ! m_Parent->IsIconic() && ! m_bPrevParentIconic ) { 330| m_Parent->GetWindowRect( &parentRc ); 331| dx = parentRc.right - m_prevParentRc.right; 332| dy = parentRc.top - m_prevParentRc.top; 333| 334| SyncXY(); 335| SetFloatPos( m_X + dx, m_Y + dy ); 336| m_prevParentRc = parentRc; 337| } 338| 339| m_bPrevParentIconic = (IsIconic() != 0); 340|} 341| 342|void CCatsPropBar::OnParentSize( UINT nType, int cx, int cy ) 343|{ 344| if ( ! m_bNotFloatingYet ) 345| m_bDocking = ! IsFloating(); 346| 347| OnParentMove( 0,0 ); 348|} 349| 350| 351| 352|/*********************************************************************** 353| 11. <<< [CCatsPropBar::Show] (内部用)表示状態にする >>> 354|【補足】 355|・表示状態の変更は CCatsPropBar::SetVisible を呼び出してください。 356|・GetWindowRect の使えない状態については、CatsPropBar.svg を参照。 357|************************************************************************/ 358|void CCatsPropBar::Show() 359|{ 360| POINT point; 361| RECT rect; 362| bool bMoved; 363| 364| if ( ! m_bFirstMoveDone ) return; 365| 366| ASSERT( m_Parent->IsWindowVisible() ); /* 親ウィンドウを表示状態にしてから呼び出してください */ 367| 368| /* 現在位置を取得する */ 369| if ( m_bNotFloatingYet ) { 370| point.x = m_X; point.y = m_Y; 371| m_Parent->FloatControlBar( this, point ); 372| GetWindowRect( &rect ); 373| m_DX = rect.left - point.x; 374| m_DY = rect.top - point.y; 375| } 376| 377| if ( ! m_bDocking ) bMoved = MoveInScreen(); 378| else bMoved = false; 379| 380| 381| /* バーを表示する */ 382| if ( m_bNotFloatingYet ) { 383| point.x = m_X; point.y = m_Y; 384| m_Parent->FloatControlBar( this, point ); 385| m_Parent->ShowControlBar( this, TRUE, FALSE ); 386| 387| if ( m_bDocking ) { 388| m_bVisible = true; 389| SetDocking( true ); 390| } 391| } 392| else { 393| if ( bMoved ) { 394| point.x = m_X; point.y = m_Y; 395| m_Parent->FloatControlBar( this, point ); 396| } 397| m_Parent->ShowControlBar( this, TRUE, FALSE ); 398| } 399| 400| m_bNotFloatingYet = false; 401|} 402| 403| 404| 405|/*********************************************************************** 406| 12. <<< [CCatsPropBar::Hide] (内部用)非表示状態にする >>> 407|【補足】 408|・表示状態の変更は CCatsPropBar::SetVisible を呼び出してください。 409|************************************************************************/ 410|void CCatsPropBar::Hide() 411|{ 412| SyncXY(); 413| m_Parent->ShowControlBar( this, FALSE, FALSE ); 414|} 415| 416| 417| 418|/*********************************************************************** 419| 13. <<< [CCatsPropBar::MoveInScreen] (内部用)画面の中に移動する >>> 420|【引数】 421| ・返り値 : 移動したかどうか 422|【補足】 423|・この関数は、m_X, m_Y を変更するだけです。 実際のウィンドウの位置の変更は 424| 行いません。 425|************************************************************************/ 426|bool CCatsPropBar::MoveInScreen() 427|{ 428| bool bMoved; 429| RECT rect; 430| int sc_w, sc_h; 431| 432| GetWindowRect( &rect ); 433| 434| sc_w = GetSystemMetrics( SM_CXFULLSCREEN ); 435| sc_h = GetSystemMetrics( SM_CYFULLSCREEN ); 436| 437| if ( rect.left - m_DX < 0 ) { rect.left = m_DX; bMoved = true; } 438| if ( rect.right + m_DX > sc_w ) { rect.left -= (rect.right + m_DX) - sc_w; bMoved = true; } 439| if ( rect.top - m_DY < 0 ) { rect.top = m_DY; bMoved = true; } 440| if ( rect.bottom - m_DY - 2*m_DX > sc_h ) { rect.top -= (rect.bottom - m_DY - 2*m_DX ) - sc_h; bMoved = true; } 441| // m_DX, m_DY の誤差は、MFC のバグ? 442| 443| if ( bMoved ) 444| { m_X = rect.left - m_DX; m_Y = rect.top - m_DY; } 445| 446| return bMoved; 447|} 448| 449| 450| 451|/*********************************************************************** 452| 14. <<< [CCatsPropBar::SyncXY] (内部用)ウィンドウの位置をオブジェクトに反映させる >>> 453|************************************************************************/ 454|void CCatsPropBar::SyncXY() 455|{ 456| if ( GetShown() && ! m_Parent->IsIconic() ) { 457| RECT rect; 458| int sc_w, sc_h; 459| 460| GetWindowRect( &rect ); 461| 462| /* おかしな値になっていないかチェックする */ 463| /* 非表示状態では、rect.left, r, u, b とも -32000 になる */ 464| { 465| sc_w = GetSystemMetrics( SM_CXFULLSCREEN ); 466| sc_h = GetSystemMetrics( SM_CYFULLSCREEN ); 467| if ( rect.left < -sc_w ) error(); 468| if ( rect.left > sc_w*2 ) error(); 469| if ( rect.top < -sc_h ) error(); 470| if ( rect.top > sc_h*2 ) error(); 471| } 472| 473| m_X = rect.left - m_DX; 474| m_Y = rect.top - m_DY; 475| } 476| 477| if ( IsWindowVisible() ) 478| m_bDocking = ! IsFloating(); 479|} 480| 481| 482| 483|void CCatsPropBar::OnSize( UINT nType, int cx, int cy ) 484|{ 485| CListBox* list = (CListBox*)GetDlgItem( IDC_Propertys ); 486| RECT rc; 487| 488| if ( list == NULL ) return; 489| 490| list->GetWindowRect( &rc ); 491| ScreenToClient( &rc ); 492| rc.right = cx - rc.left; 493| rc.bottom = cy - rc.left; 494| list->MoveWindow( &rc ); 495|} 496| 497| 498|#if 0 499| 500|/* OnSizeは来るけど、OnMove は来ない。*/ 501|void CCatsPropBar::OnMove(int x, int y) 502|{ 503|} 504| 505| 506|/* WM_SIZEPARENT は来ない */ 507|LRESULT CCatsPropBar::OnSizeParent(WPARAM, LPARAM lParam) 508|{ 509| AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam; 510| 511| // only resize the window if doing layout and not just rect query 512|// if (lpLayout->hDWP != NULL) 513|// AfxRepositionWindow(lpLayout, m_hWnd, &lpLayout->rect); 514| 515| // always adjust the rectangle after the resize 516|// int nHandleSize = m_tracker.m_nHandleSize; 517|// ::InflateRect(&lpLayout->rect, -nHandleSize, -nHandleSize); 518| 519| return 0; 520|} 521| 522|/* ウィンドウを動かしても何もメッセージは来ない */ 523|BOOL CCatsPropBar::PreTranslateMessage(MSG* pMsg) 524|{ 525| #if 0 526| switch ( pMsg->message ) { 527| case WM_SIZEPARENT: { 528| return FALSE; 529| } 530| case WM_MOUSEMOVE: { 531| return FALSE; 532| } 533| } 534| #endif 535| 536| return CInitDialogBar::PreTranslateMessage(pMsg); 537|} 538| 539|#endif 540| 541| 542|