ExtPopupMenuWnd.cpp
上传用户:sesekoo
上传日期:2020-07-18
资源大小:21543k
文件大小:735k
源码类别:

界面编程

开发平台:

Visual C++

  1. return;
  2. if( bAdvOperation && ( GetSite().GetAnimated() == NULL ) )
  3. {
  4. m_AnimationType = __AT_CONTENT_DISPLAY;
  5. HWND hWndOwn = m_hWnd;
  6. _StartAnimation();
  7. if( ! ::IsWindow( hWndOwn ) )
  8. return;
  9. }
  10. _tipWnd.Hide();
  11. }
  12. CExtPopupMenuTipWnd::e_tip_style_t CExtPopupMenuWnd::_CoolTipGetStyle() const
  13. {
  14. ASSERT_VALID( this );
  15. if( _IsPalette() )
  16. return g_eTtsPaletteMenu;
  17. return g_eTtsClassicMenu;
  18. }
  19. CMap < CExtPopupMenuWnd *, CExtPopupMenuWnd *, INT, INT > CExtPopupMenuWnd::ItemFocusTracker_t::g_map;
  20. CExtPopupMenuWnd::ItemFocusTracker_t::ItemFocusTracker_t( const CExtPopupMenuWnd & _Popup )
  21. : m_Popup( _Popup )
  22. {
  23. ASSERT_VALID( ( &(m_Popup) ) );
  24. FocusChangingRegister();
  25. }
  26. CExtPopupMenuWnd::ItemFocusTracker_t::ItemFocusTracker_t( const CExtPopupMenuWnd * pPopup )
  27. : m_Popup( *pPopup )
  28. {
  29. ASSERT_VALID( ( &(m_Popup) ) );
  30. FocusChangingRegister();
  31. }
  32. CExtPopupMenuWnd::ItemFocusTracker_t::~ItemFocusTracker_t()
  33. {
  34. ASSERT_VALID( ( &(m_Popup) ) );
  35. FocusChangingUnRegister();
  36. }
  37. void CExtPopupMenuWnd::ItemFocusTracker_t::FocusChangingRegister()
  38. {
  39. ASSERT_VALID( ( &(m_Popup) ) );
  40. INT i = 0;
  41. if( g_map.Lookup(
  42. const_cast < CExtPopupMenuWnd * > ( &(m_Popup) ),
  43. i
  44. )
  45. )
  46. {
  47. ASSERT( i >= 1 );
  48. i++;
  49. }
  50. else
  51. i = 1;
  52. g_map.SetAt(
  53. const_cast < CExtPopupMenuWnd * > ( &(m_Popup) ),
  54. i
  55. );
  56. }
  57. void CExtPopupMenuWnd::ItemFocusTracker_t::FocusChangingUnRegister()
  58. {
  59. ASSERT_VALID( ( &(m_Popup) ) );
  60. INT i = 0;
  61. if( ! g_map.Lookup(
  62. const_cast < CExtPopupMenuWnd * > ( &(m_Popup) ),
  63. i
  64. )
  65. )
  66. return;
  67. ASSERT( i >= 1 );
  68. i--;
  69. if( i == 0 )
  70. g_map.RemoveKey(
  71. const_cast < CExtPopupMenuWnd * > ( &(m_Popup) )
  72. );
  73. else
  74. g_map.SetAt(
  75. const_cast < CExtPopupMenuWnd * > ( &(m_Popup) ),
  76. i
  77. );
  78. }
  79. bool CExtPopupMenuWnd::ItemFocusTracker_t::FocusChangingIsRegistered()
  80. {
  81. ASSERT_VALID( ( &(m_Popup) ) );
  82. INT i = 0;
  83. if( g_map.Lookup(
  84. const_cast < CExtPopupMenuWnd * > ( &(m_Popup) ),
  85. i
  86. )
  87. )
  88. {
  89. ASSERT( i >= 1 );
  90. return true;
  91. }
  92. else
  93. return false;
  94. }
  95. bool CExtPopupMenuWnd::ItemFocusTracker_t::FocusChangingIsInProgress( const CExtPopupMenuWnd * pPopup )
  96. {
  97. if( pPopup == NULL )
  98. return false;
  99. ASSERT_VALID( pPopup );
  100. INT i = 0;
  101. if( ! g_map.Lookup(
  102. const_cast < CExtPopupMenuWnd * > ( pPopup ),
  103. i
  104. )
  105. )
  106. return false;
  107. ASSERT( i >= 1 );
  108. return true;
  109. }
  110. bool CExtPopupMenuWnd::_ItemFocusChangingIsInProgress() const
  111. {
  112. ASSERT_VALID( this );
  113. if( _CancelingGet() )
  114. return false;
  115. bool bRetVal = CExtPopupMenuWnd::ItemFocusTracker_t::FocusChangingIsInProgress( this );
  116. return bRetVal;
  117. }
  118. void CExtPopupMenuWnd::_ItemFocusCancel(
  119. BOOL bRepaint,
  120. BOOL bCancelTip, // = TRUE
  121. BOOL bDelayHiding // = FALSE
  122. )
  123. {
  124. ASSERT_VALID( this );
  125. if( !_FindCustomizeMode() )
  126. {
  127. HWND hWndOwn = m_hWnd;
  128. if( bCancelTip )
  129. _CoolTipHide();
  130. if( ! ::IsWindow( hWndOwn ) )
  131. return;
  132. }
  133. if( m_nCurIndex != IDX_NOTHING )
  134. {
  135. CRect rcCurrItem;
  136. _GetItemRect( m_nCurIndex, rcCurrItem );
  137. if( ! rcCurrItem.IsRectEmpty() )
  138. InvalidateRect( &rcCurrItem );
  139. }
  140. ItemFocusTracker_t _ift( this );
  141. if( m_nCurIndex < 0 )
  142. {
  143. m_nCurIndex = IDX_NOTHING;
  144. } // if( m_nCurIndex < 0 )
  145. else
  146. {
  147. ASSERT( m_nCurIndex < m_items_all.GetSize() );
  148. MENUITEMDATA & mi = ItemGetInfo(m_nCurIndex);
  149. if( mi.IsInplaceEdit() )
  150. {
  151. mi.SetTempSelectedInplaceEditText( NULL );
  152. CWnd * pWndInplace = mi.GetInplaceEditPtr();
  153. if( pWndInplace != NULL )
  154. {
  155. ASSERT_VALID( pWndInplace );
  156. ASSERT( pWndInplace->GetSafeHwnd() != NULL && (::IsWindow(pWndInplace->GetSafeHwnd())) );
  157. if( (pWndInplace->GetStyle() & WS_VISIBLE) != 0 )
  158. pWndInplace->ShowWindow( SW_HIDE );
  159. } // if( pWndInplace != NULL )
  160. }
  161. mi.SetSelected( false );
  162. ITEMCOVERINGNOTIFICATON _icn(
  163. this,
  164. NULL,
  165. ITEMCOVERINGNOTIFICATON::__EICN_CANCEL,
  166. m_nCurIndex
  167. ); 
  168. m_nCurIndex = IDX_NOTHING;
  169. HWND hWndOwn = m_hWnd;
  170. _icn.Notify();
  171. m_bSuspendTips = _icn.m_bSuspendTips;
  172. if( ! ::IsWindow( hWndOwn ) )
  173. return;
  174. if( mi.IsPopup() )
  175. {
  176. CExtPopupMenuWnd * pPopup = mi.GetPopup();
  177. ASSERT_VALID( pPopup );
  178. if( bDelayHiding && (! pPopup->m_bDelayedHiding ) && pPopup->GetSafeHwnd() != NULL )
  179. {
  180. pPopup->m_bDelayedHiding = true;
  181. ASSERT( g_nTimeDelayedHiding > 0 );
  182. pPopup->SetTimer( ID_TIMER_ITEM_HIDE_DELAY, g_nTimeDelayedHiding, NULL );
  183. }
  184. else
  185. {
  186. INT nSaved = pPopup->m_nFadeOutAnimationStepCount;
  187. pPopup->m_nFadeOutAnimationStepCount = -1;
  188. pPopup->_OnCancelMode();
  189. pPopup->m_nFadeOutAnimationStepCount = nSaved;
  190. if( ! ::IsWindow( hWndOwn ) )
  191. return;
  192. }
  193. }
  194. } // else from if( m_nCurIndex < 0 )
  195. // update status bar message
  196. CWnd * pWndOwner = GetOwner();
  197. if( pWndOwner != NULL )
  198. CExtControlBar::stat_SetMessageString( pWndOwner );
  199. if( bRepaint && ::IsWindowVisible(GetSafeHwnd()) )
  200. {
  201. CClientDC dc( this );
  202. _DoPaint( dc );
  203. }
  204. _ift.FocusChangingUnRegister();
  205. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  206. _KeyTipsShow( true );
  207. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  208. KillTimer( ID_TIMER_AUTO_EXPAND );
  209. }
  210. bool CExtPopupMenuWnd::_CanStartLevelTracking()
  211. {
  212. ASSERT_VALID( this );
  213. return true;
  214. }
  215. bool CExtPopupMenuWnd::_OnMouseWheel(
  216. WPARAM wParam,
  217. LPARAM lParam,
  218. bool & bNoEat
  219. )
  220. {
  221. ASSERT_VALID( this );
  222. if( _IsResizingMode() )
  223. {
  224. bNoEat = false;
  225. return true;
  226. }
  227. TranslateMouseWheelEventData_t _td( this, wParam, lParam, bNoEat );
  228. if( _td.Notify() )
  229. {
  230. bNoEat = _td.m_bNoEat;
  231. return true;
  232. }
  233. return true;
  234. }
  235. const UINT CExtPopupMenuWnd::g_nMsgInstantiatePopupMenu =
  236. ::RegisterWindowMessage(
  237. _T("CExtPopupMenuWnd::g_nMsgInstantiatePopupMenu")
  238. );
  239. CExtPopupMenuWnd::INSTANTIATEPOPUPMENUNOTIFICATION::INSTANTIATEPOPUPMENUNOTIFICATION(
  240. CRuntimeClass * pMenuRTC,
  241. CObject * pQuerySrc,
  242. LPARAM lParam
  243. )
  244. : m_pMenuRTC( pMenuRTC )
  245. , m_pQuerySrc( pQuerySrc )
  246. , m_lParam( lParam )
  247. , m_pCreatedPopupMenuInstance( NULL )
  248. {
  249. }
  250. void CExtPopupMenuWnd::INSTANTIATEPOPUPMENUNOTIFICATION::Notify( HWND hWndNotifyTarget )
  251. {
  252. ASSERT( hWndNotifyTarget != NULL && ::IsWindow( hWndNotifyTarget ) );
  253. ::SendMessage( hWndNotifyTarget, CExtPopupMenuWnd::g_nMsgInstantiatePopupMenu, (*this), 0L );
  254. }
  255. CExtPopupMenuWnd::INSTANTIATEPOPUPMENUNOTIFICATION::
  256. operator WPARAM()
  257. {
  258. return WPARAM( this );
  259. }
  260. CExtPopupMenuWnd::INSTANTIATEPOPUPMENUNOTIFICATION &
  261. CExtPopupMenuWnd::INSTANTIATEPOPUPMENUNOTIFICATION::
  262. FromWPARAM( WPARAM wParam )
  263. {
  264. INSTANTIATEPOPUPMENUNOTIFICATION * pIPMN =
  265. reinterpret_cast < INSTANTIATEPOPUPMENUNOTIFICATION * > ( wParam );
  266. ASSERT( pIPMN != NULL );
  267. return (*pIPMN);
  268. }
  269. CExtPopupMenuWnd * CExtPopupMenuWnd::InstantiatePopupMenu(
  270. HWND hWndNotifyTarget,
  271. CRuntimeClass * pMenuRTC,
  272. CObject * pQuerySrc,
  273. LPARAM lParam // = 0L
  274. )
  275. {
  276. ASSERT( pMenuRTC != NULL );
  277. ASSERT( pMenuRTC->IsDerivedFrom(RUNTIME_CLASS(CExtPopupMenuWnd)) );
  278. if( hWndNotifyTarget != NULL && ::IsWindow( hWndNotifyTarget ) )
  279. {
  280. HWND hWnd = hWndNotifyTarget;
  281. for( ; hWnd != NULL; )
  282. {
  283. INSTANTIATEPOPUPMENUNOTIFICATION _ipmn( pMenuRTC, pQuerySrc, lParam );
  284. _ipmn.Notify( hWndNotifyTarget );
  285. if( _ipmn.m_pCreatedPopupMenuInstance != NULL )
  286. {
  287. ASSERT_VALID( _ipmn.m_pCreatedPopupMenuInstance );
  288. ASSERT( _ipmn.m_pCreatedPopupMenuInstance->IsKindOf( pMenuRTC ) );
  289. return _ipmn.m_pCreatedPopupMenuInstance;
  290. }
  291. __EXT_MFC_LONG_PTR dwStyle = ::__EXT_MFC_GetWindowLong( hWnd, GWL_STYLE );
  292. if( ( dwStyle & WS_CHILD ) == 0 )
  293. {
  294. CWnd * pWnd = CWnd::FromHandlePermanent( hWnd );
  295. if( pWnd != NULL && pWnd->IsKindOf( RUNTIME_CLASS(CFrameWnd) ) )
  296. {
  297. pWnd = pWnd->GetParentFrame();
  298. if( pWnd != NULL )
  299. {
  300. hWnd = pWnd->m_hWnd;
  301. continue;
  302. }
  303. }
  304. break;
  305. } // if( ( dwStyle & WS_CHILD ) == 0 )
  306. hWnd = ::GetParent( hWnd );
  307. } // for( ; hWnd != NULL; )
  308. } // if( hWndNotifyTarget != NULL && ::IsWindow( hWndNotifyTarget ) )
  309. CExtPopupMenuWnd * pPopup = STATIC_DOWNCAST( CExtPopupMenuWnd, pMenuRTC->CreateObject() );
  310. ASSERT_VALID( pPopup );
  311. return pPopup;
  312. }
  313. CSize CExtPopupMenuWnd::ResizingMinSizeGet() const
  314. {
  315. ASSERT_VALID( this );
  316. return m_sizeResizingMin;
  317. }
  318. void CExtPopupMenuWnd::ResizingMinSizeSet( CSize _size )
  319. {
  320. ASSERT_VALID( this );
  321. m_sizeResizingMin = _size;
  322. }
  323. CSize CExtPopupMenuWnd::ResizingMaxSizeGet() const
  324. {
  325. ASSERT_VALID( this );
  326. return m_sizeResizingMax;
  327. }
  328. void CExtPopupMenuWnd::ResizingMaxSizeSet( CSize _size )
  329. {
  330. ASSERT_VALID( this );
  331. m_sizeResizingMax = _size;
  332. }
  333. bool CExtPopupMenuWnd::_IsResizingMode() const
  334. {
  335. ASSERT_VALID( this );
  336. return m_bHelperResizingMode;
  337. }
  338. void CExtPopupMenuWnd::_DoResizing(
  339. CPoint ptScreenClick,
  340. bool bVerticalOnlyResizing
  341. )
  342. {
  343. ASSERT_VALID( this );
  344. _ItemFocusCancel( TRUE, TRUE );
  345. _SetCapture();
  346. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  347. _KeyTipsShow( false );
  348. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  349. HWND hWndOwn = GetSafeHwnd();
  350. ASSERT( hWndOwn != NULL && ::IsWindow( hWndOwn ) );
  351. bool bReCreateShadow = ( m_ctrlShadow.GetSafeHwnd() != NULL ) ? true : false;
  352. MSG msg;
  353. CPoint ptMove;
  354. CSize _sizeMin( ResizingMinSizeGet() ), _sizeMax( ResizingMaxSizeGet() ),
  355. _sizeShift, _sizeLast, _sizeCurrent, _sizeInitial, _sizeAdjust, _sizeControlAdjust,
  356. _sizeClientCurrent, _sizeClientInitial( m_rcClient.right - m_rcClient.left, m_rcClient.bottom - m_rcClient.top );
  357. CRect rcWnd;
  358. GetWindowRect( &rcWnd );
  359. _sizeLast = _sizeCurrent = _sizeInitial = rcWnd.Size();
  360. ::SetCapture( hWndOwn );
  361. while( ::IsWindow( hWndOwn ) && _IsResizingMode() )
  362. {
  363. ::WaitMessage();
  364. if( ! ::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
  365. continue;
  366. switch( msg.message )
  367. {
  368. case WM_LBUTTONUP:
  369. case WM_NCLBUTTONUP:
  370. case WM_MBUTTONUP:
  371. case WM_NCMBUTTONUP:
  372. case WM_RBUTTONUP:
  373. case WM_NCRBUTTONUP:
  374. case WM_KEYDOWN:
  375. ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
  376. case WM_CANCELMODE:
  377. case WM_ACTIVATEAPP:
  378. m_bHelperResizingMode = false;
  379. continue;
  380. case WM_MOUSEMOVE:
  381. {
  382. ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
  383. if( ! ::GetCursorPos( &ptMove ) )
  384. continue;
  385. if( bVerticalOnlyResizing )
  386. _sizeShift.cx = 0;
  387. else
  388. _sizeShift.cx = ptMove.x - ptScreenClick.x;
  389. _sizeShift.cy = ptMove.y - ptScreenClick.y;
  390. _sizeCurrent = _sizeInitial + _sizeShift;
  391. _sizeAdjust = _sizeCurrent;
  392. _sizeCurrent.cx = max( _sizeCurrent.cx, _sizeMin.cx );
  393. _sizeCurrent.cy = max( _sizeCurrent.cy, _sizeMin.cy );
  394. _sizeCurrent.cx = min( _sizeCurrent.cx, _sizeMax.cx );
  395. _sizeCurrent.cy = min( _sizeCurrent.cy, _sizeMax.cy );
  396. if( _sizeLast == _sizeCurrent )
  397. continue;
  398. _sizeAdjust -= _sizeCurrent;
  399. _sizeControlAdjust = _sizeCurrent - _sizeLast;
  400. _sizeLast = _sizeCurrent;
  401. rcWnd.right = rcWnd.left + _sizeCurrent.cx;
  402. rcWnd.bottom = rcWnd.top + _sizeCurrent.cy;
  403. _sizeClientCurrent = _sizeClientInitial + _sizeShift - _sizeAdjust;
  404. m_rcClient.right = m_rcClient.left + _sizeClientCurrent.cx;
  405. m_rcClient.bottom = m_rcClient.top + _sizeClientCurrent.cy;
  406. _DoAdjustControlMetrics( _sizeControlAdjust );
  407.    if( bReCreateShadow )
  408. m_ctrlShadow.DestroyWindow();
  409. MoveWindow( &rcWnd, FALSE );
  410.    if( bReCreateShadow )
  411. m_ctrlShadow.Create( hWndOwn, PmBridge_GetPM()->GetMenuShadowSize() );
  412. _SyncItems();
  413. _RecalcLayoutImpl();
  414. RedrawWindow(
  415. NULL,
  416. NULL,
  417. RDW_INVALIDATE|RDW_ERASE
  418. //|RDW_UPDATENOW|RDW_ERASENOW
  419. |RDW_FRAME|RDW_ALLCHILDREN
  420. );
  421. CExtPaintManager::stat_PassPaintMessages();
  422. }
  423. continue;
  424. } // switch( msg.message )
  425. if( ! ::AfxGetThread() -> PumpMessage() )
  426. {
  427. m_bHelperResizingMode = false;
  428. break;
  429. }
  430. } // while( ::IsWindow( hWndOwn ) && _IsResizingMode() )
  431. ::ReleaseCapture();
  432. }
  433. void CExtPopupMenuWnd::_DoAdjustControlMetrics(
  434. CSize _sizeAdjust
  435. )
  436. {
  437. ASSERT_VALID( this );
  438. _sizeAdjust;
  439. }
  440. bool CExtPopupMenuWnd::_OnMouseMove(
  441. UINT nFlags,
  442. CPoint point,
  443. bool & bNoEat
  444. )
  445. {
  446. ASSERT_VALID( this );
  447. if( GetSafeHwnd() == NULL )
  448. return false;
  449. if( ! m_bAnimFinished )
  450. return true;
  451. if( _IsResizingMode() )
  452. {
  453. bNoEat = true;
  454. return false;
  455. }
  456. CExtPopupMenuSite & _site = GetSite();
  457. if( _site.IsShutdownMode()
  458. || _site.IsEmpty()
  459. || _site.GetAnimated() != NULL
  460. )
  461. return true;
  462. TranslateMouseMoveEventData_t _td( this, nFlags, point, bNoEat );
  463. if( _td.Notify() )
  464. {
  465. bNoEat = _td.m_bNoEat;
  466. return true;
  467. }
  468. CPoint ptScreenClick( point );
  469. ClientToScreen( &ptScreenClick );
  470. HWND hWndFromPoint = ::WindowFromPoint( ptScreenClick );
  471. if( hWndFromPoint != NULL
  472. && (::__EXT_MFC_GetWindowLong(hWndFromPoint,GWL_STYLE)&WS_CHILD) != 0
  473. && ::GetParent(hWndFromPoint) == m_hWnd
  474. )
  475. {
  476. CWnd * pWnd = CWnd::FromHandlePermanent( hWndFromPoint );
  477. if( pWnd != NULL )
  478. {
  479. int nCount = ItemGetCount();
  480. for( int i = 0; i < nCount; i++ )
  481. {
  482. MENUITEMDATA & mi = ItemGetInfo( i );
  483. if( !mi.IsInplaceEdit() )
  484. continue;
  485. if( ((LPVOID)mi.GetInplaceEditPtr()) != ((LPVOID)pWnd) )
  486. continue;
  487. if( m_nCurIndex == i )
  488. break;
  489. HWND hWndOwn = m_hWnd;
  490. _ItemFocusSet( i, FALSE, TRUE, TRUE );
  491. if( ! ::IsWindow( hWndOwn ) )
  492. return true;
  493. break;
  494. } // for( int i = 0; i < nCount; i++ )
  495. } // if( pWnd != NULL )
  496. bNoEat = true;
  497. return false;
  498. }
  499. HWND hWndFocus = ::GetFocus();
  500. if( hWndFocus != NULL
  501. && (::__EXT_MFC_GetWindowLong(hWndFocus,GWL_STYLE)&WS_CHILD) != 0
  502. && ::GetParent(hWndFocus) == m_hWnd
  503. )
  504. return true;
  505. if( !_PtInWndArea(point) )
  506. {
  507. if( m_pWndParentMenu != NULL
  508. && m_pWndParentMenu->GetSafeHwnd() != NULL
  509. )
  510. {
  511. ASSERT_VALID( m_pWndParentMenu );
  512. CPoint point = ptScreenClick;
  513. m_pWndParentMenu->ScreenToClient( &point );
  514. if( ptScreenClick == m_ptTrackWatched )
  515. {
  516. m_ptTrackWatched.x = m_ptTrackWatched.y = 0;
  517. return true;
  518. }
  519. HWND hWndOwn = m_hWnd;
  520. if( m_pWndParentMenu->_OnMouseMove(
  521. nFlags,
  522. point,
  523. bNoEat
  524. )
  525. )
  526. {
  527. if( ! ::IsWindow( hWndOwn ) )
  528. return true;
  529. m_nLastMousePick = IDX_NOTHING;
  530. if( bNoEat )
  531. return false;
  532. if( ::IsWindow(hWndOwn)
  533. && ((::__EXT_MFC_GetClassLong(hWndOwn,GWL_STYLE))&WS_VISIBLE) != 0
  534. )
  535. _OnCancelMode();
  536. return true;
  537. }
  538. if( ! ::IsWindow( hWndOwn ) )
  539. return true;
  540. }
  541. if( GetSite().GetCapture() == this )
  542. {
  543. HWND hWndTest = hWndFromPoint;
  544. for( ; true; )
  545. {
  546. if( (::__EXT_MFC_GetWindowLong(hWndTest,GWL_STYLE)&WS_CHILD) != 0 )
  547. hWndTest = ::GetParent( hWndTest );
  548. else
  549. break;
  550. }
  551. CWnd * pWndTest = CWnd::FromHandlePermanent( hWndTest );
  552. CExtPopupMenuWnd * pPopup = DYNAMIC_DOWNCAST( CExtPopupMenuWnd, pWndTest );
  553. if( pPopup != NULL )
  554. {
  555. bool bAllowReAssignCapture = false;
  556. CExtPopupMenuWnd * pTestPopup = pPopup;
  557. for( ; pTestPopup != NULL; pTestPopup = pTestPopup->GetParentMenuWnd() )
  558. {
  559. if( pTestPopup == this )
  560. {
  561. bAllowReAssignCapture = true;
  562. break;
  563. }
  564. }
  565. if( bAllowReAssignCapture )
  566. {
  567. CExtPopupMenuWnd * pPrevPopup = NULL;
  568. pTestPopup = pPopup;
  569. for( ; pTestPopup != NULL;  )
  570. {
  571. pTestPopup->m_nDelayedFocusItemIndex = IDX_NOTHING;
  572. pTestPopup->KillTimer( ID_TIMER_ITEM_FOCUS_DELAY );
  573. pTestPopup->KillTimer( ID_TIMER_ITEM_HIDE_DELAY );
  574. pTestPopup->m_bDelayedHiding = false;
  575. pTestPopup->m_nLastMousePick = IDX_NOTHING;
  576. if( pPrevPopup != NULL )
  577. {
  578. INT nIndex, nCount = pTestPopup->ItemGetCount();
  579. for( nIndex = 0; nIndex < nCount; nIndex++ )
  580. {
  581. MENUITEMDATA & _mii = pTestPopup->ItemGetInfo( nIndex );
  582. if( ! _mii.IsPopup() )
  583. continue;
  584. CExtPopupMenuWnd * pChildPopup = _mii.GetPopup();
  585. if( pChildPopup == pPrevPopup )
  586. {
  587. if( pTestPopup->m_nCurIndex != nIndex )
  588. {
  589. pTestPopup->_ItemFocusSet( nIndex, TRUE, TRUE, FALSE, FALSE );
  590. pTestPopup->m_nLastMousePick = nIndex;
  591. }
  592. break;
  593. }
  594. }
  595. }
  596. pPrevPopup = pTestPopup;
  597. pTestPopup = pTestPopup->GetParentMenuWnd();
  598. }
  599. //::ReleaseCapture();
  600. pPopup->_SetCapture();
  601. CPoint point = ptScreenClick;
  602. pPopup->ScreenToClient( &point );
  603. return true; //pPopup->_OnMouseMove( nFlags, point, bNoEat );
  604. }
  605. }
  606. HWND hWndOwn = m_hWnd;
  607. if( m_nCurIndex >= 0 && m_nLastMousePick >= 0 )
  608. {
  609. MENUITEMDATA & _mii = ItemGetInfo( m_nCurIndex );
  610. if( ! _mii.IsPopup() )
  611. {
  612. _ItemFocusCancel( TRUE );
  613. if( ! ::IsWindow( hWndOwn ) )
  614. return true;
  615. }
  616. else
  617. {
  618. if( _mii.GetPopup()->m_nCurIndex < 0 )
  619. {
  620. _ItemFocusCancel( TRUE );
  621. if( ! ::IsWindow( hWndOwn ) )
  622. return true;
  623. }
  624. } // if( ! _mii.IsPopup() )
  625. } // if( m_nCurIndex >= 0 && m_nLastMousePick >= 0 )
  626. else if( m_nCurIndex != IDX_NOTHING )
  627. {
  628. bool bAlt =
  629. ( (::GetAsyncKeyState(VK_MENU)&0x8000) != 0 )
  630. ? true : false;
  631. if( (! bAlt) && (TrackFlagsGet()&TPMX_SELECT_ANY) == 0 && m_nLastMousePick != IDX_NOTHING )
  632. _ItemFocusCancel( TRUE );
  633. if( ! ::IsWindow( hWndOwn ) )
  634. return true;
  635. } // else if( m_nCurIndex != IDX_NOTHING )
  636. } // if( m_nCurIndex >= 0 && m_nLastMousePick >= 0 )
  637. m_nLastMousePick = IDX_NOTHING;
  638. return false;
  639. }
  640. int nCurIndex = _HitTest(point);
  641. if( nCurIndex == IDX_EXPAND )
  642. {
  643. HWND hWndOwn = m_hWnd;
  644. _ItemFocusCancel( TRUE );
  645. if( ! ::IsWindow( hWndOwn ) )
  646. return true;
  647. _SetCapture();
  648. if( g_bMenuDelayExpanding )
  649. {
  650. // _SetCapture();
  651. if( m_nWaitingExpandTickCount == 0 )
  652. {
  653. SetTimer(
  654. ID_TIMER_DELAY_EXPAND,
  655. ID_TOTAL_DELAY_EXPAND/ID_FREQ_DELAY_EXPAND,
  656. NULL
  657. );
  658. m_nWaitingExpandTickCount = 1;
  659. }
  660. } // if( g_bMenuDelayExpanding )
  661. return true;
  662. }
  663. if( _IsTearOff() && nCurIndex == IDX_TEAROFF )
  664. {
  665. HWND hWndOwn = m_hWnd;
  666. _ItemFocusCancel( TRUE, FALSE );
  667. if( ! ::IsWindow( hWndOwn ) )
  668. return true;
  669. _SetCapture();
  670. HCURSOR hCursor = ::LoadCursor( NULL, IDC_SIZEALL );
  671. ASSERT( hCursor != NULL );
  672. ::SetCursor( hCursor );
  673. if( g_bMenuShowCoolTips
  674. && GetSite().GetCapture() == this
  675. )
  676. {
  677. CRect rcItem;
  678. _GetItemRect(nCurIndex,rcItem);
  679. ClientToScreen( &rcItem );
  680. bool bShowTip = (!m_bSuspendTips);
  681. CExtPopupMenuTipWnd & _tipWnd = GetTip();
  682. if( _tipWnd.GetSafeHwnd() != NULL )
  683. {
  684. CRect rcExcludeArea = _tipWnd.GetExcludeArea();
  685. if( rcExcludeArea == rcItem )
  686. bShowTip = false;
  687. } // if( _tipWnd.GetSafeHwnd() != NULL )
  688. if( bShowTip )
  689. {
  690. CExtSafeString sTipText;
  691. g_ResourceManager->LoadString( sTipText, ID_EXT_TEAR_OFF_MENU_TIP );
  692. if( sTipText.IsEmpty() )
  693. sTipText = _T("Drag to make this menu float");
  694. _tipWnd.SetText( sTipText );
  695. _tipWnd.SetTipStyle(
  696. g_eTtsTearOffCaption // _CoolTipGetStyle()
  697. );
  698. VERIFY(
  699. _tipWnd.Show(
  700. this,
  701. rcItem
  702. )
  703. );
  704. } // if( bShowTip )
  705. }
  706. return true;
  707. }
  708. HWND hWndOwn = m_hWnd;
  709. if( _StartScrolling(nCurIndex) )
  710. return true;
  711. if( ! ::IsWindow( hWndOwn ) )
  712. return true;
  713. //  if( m_nCurIndex == IDX_RIBBON_FILE_MENU_OPTIONS_BUTTON
  714. //  || m_nCurIndex == IDX_RIBBON_FILE_MENU_EXIT_BUTTON
  715. //  )
  716. if( m_nCurIndex != nCurIndex )
  717. {
  718. CRect rcCurrItem;
  719. _GetItemRect( m_nCurIndex, rcCurrItem );
  720. if( ! rcCurrItem.IsRectEmpty() )
  721. InvalidateRect( &rcCurrItem );
  722. }
  723. if( nCurIndex == IDX_RIBBON_FILE_MENU_OPTIONS_BUTTON
  724. || nCurIndex == IDX_RIBBON_FILE_MENU_EXIT_BUTTON
  725. )
  726. {
  727. if( m_nCurIndex >= 0
  728. && ItemGetInfo( m_nCurIndex ).IsPopup()
  729. && ItemGetInfo( m_nCurIndex ).GetPopup()->GetSafeHwnd() != NULL
  730. )
  731. return true;
  732. CRect rcCurrItem;
  733. _GetItemRect( nCurIndex, rcCurrItem );
  734. InvalidateRect( &rcCurrItem );
  735. _ItemFocusCancel( FALSE, TRUE );
  736. m_nCurIndex = nCurIndex;
  737. _SetCapture();
  738. return true;
  739. }
  740. if( nCurIndex >= 0 )
  741. {
  742. #ifdef _DEBUG
  743. int nCountOfItems = (int)m_items_all.GetSize();
  744. ASSERT( nCurIndex < nCountOfItems );
  745. #endif // _DEBUG
  746. MENUITEMDATA & mi = ItemGetInfo(nCurIndex);
  747. if( ( ( ! mi.IsEnabled() ) && ( ! g_bShowCoolTipsOverDisabledItems ) )
  748. || mi.IsSeparator()
  749. )
  750. {
  751. _ItemFocusCancel( TRUE, TRUE, TRUE );
  752. _SetCapture();
  753. return false;
  754. }
  755. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  756. const CExtCustomizeCmdTreeNode * pNode =
  757. mi.GetCmdNode();
  758. if( pNode != NULL )
  759. {
  760. ASSERT_VALID( pNode );
  761. if( (pNode->GetFlags() & __ECTN_TBB_SEPARATED_DROPDOWN) != 0 )
  762. {
  763. bool bRTL = OnQueryLayoutRTL();
  764. CRect rcDD;
  765. _GetItemRect( nCurIndex, rcDD, false );
  766. if( bRTL )
  767. rcDD.right = rcDD.left + __EXT_MENU_POPUP_ARROW_AREA_DX;
  768. else
  769. rcDD.left = rcDD.right - __EXT_MENU_POPUP_ARROW_AREA_DX;
  770. if( ! rcDD.PtInRect( point ) )
  771. {
  772. HWND hWndOwn = m_hWnd;
  773. _ItemFocusDelay();
  774. // bool bFocusAreadySet = false;
  775. // if( mi.IsPopup() )
  776. // _ItemFocusDelay( nCurIndex, &bFocusAreadySet );
  777. if( ! ::IsWindow( hWndOwn ) )
  778. return true;
  779. // if( ! bFocusAreadySet )
  780. // {
  781. _SetCapture();
  782. _ItemFocusSet(
  783. nCurIndex,
  784. FALSE,
  785. TRUE,
  786. FALSE
  787. );
  788. Invalidate( FALSE );
  789. // }
  790. if( g_bMenuShowCoolTips
  791. && (! m_bSuspendTips )
  792. // && nCurIndex != nOldCurIndex
  793. // && GetSite().GetCapture() == this
  794. && mi.GetPopup()->GetSafeHwnd() == NULL
  795. )
  796. {
  797. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  798. bool bInitCoolTip = true;
  799. if( _IsRibbonMode() )
  800. {
  801. if( mi.KeyTipGetWnd( true )->GetSafeHwnd() != NULL
  802. || mi.KeyTipGetWnd( false )->GetSafeHwnd() != NULL
  803. )
  804. bInitCoolTip = false;
  805. else
  806. {
  807. CExtPopupScreenTipWnd & _wndScreenTip = GetScreenTip();
  808. if( mi.InitSceenTip( _wndScreenTip ) )
  809. bInitCoolTip = false;
  810. }
  811. } // if( _IsRibbonMode() )
  812. if( bInitCoolTip )
  813. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  814. {
  815. CExtSafeString sTipText;
  816. mi.GetTip( sTipText );
  817. if( ! sTipText.IsEmpty() )
  818. {
  819. CRect rcItem;
  820. _GetItemRect(nCurIndex,rcItem);
  821. ClientToScreen( &rcItem );
  822. CExtPopupMenuTipWnd & _tipWnd = GetTip();
  823. _tipWnd.SetText( sTipText );
  824. _tipWnd.SetTipStyle( _CoolTipGetStyle() );
  825. VERIFY(
  826. _tipWnd.Show(
  827. this,
  828. rcItem
  829. )
  830. );
  831. } // if( ! sTipText.IsEmpty() )
  832. } // if( bInitCoolTip )
  833. } // if( g_bMenuShowCoolTips ....
  834. return true;
  835. }
  836. else
  837. if( m_nCurIndex != nCurIndex )
  838. _ItemFocusCancel( TRUE, TRUE );
  839. if( mi.GetPopup()->GetSafeHwnd() != NULL )
  840. return false;
  841. m_nCurIndex = IDX_NOTHING;
  842. }
  843. } // if( pNode != NULL )
  844. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  845. int nOldCurIndex = m_nCurIndex; 
  846. if( nOldCurIndex != nCurIndex )
  847. {
  848. HWND hWndOwn = m_hWnd;
  849. _ItemFocusDelay();
  850. bool bFocusAreadySet = false;
  851. if( mi.IsPopup() )
  852. _ItemFocusDelay( nCurIndex, &bFocusAreadySet );
  853. if( ! ::IsWindow( hWndOwn ) )
  854. return true;
  855. if( ! bFocusAreadySet )
  856. {
  857. _SetCapture();
  858. _ItemFocusSet( nCurIndex, FALSE, TRUE, FALSE, TRUE );
  859. }
  860. if( ! ::IsWindow( hWndOwn ) )
  861. return true;
  862. m_nLastMousePick = nCurIndex;
  863. MENUITEMDATA & mi = ItemGetInfo(nCurIndex);
  864. if( (! bFocusAreadySet ) && mi.IsPopup() )
  865. {
  866. CExtPopupMenuTipWnd & _tipWnd = GetTip();
  867. _tipWnd.Hide();
  868. if( mi.GetPopup()->GetSafeHwnd() == NULL )
  869. {
  870. _ItemFocusDelay( nCurIndex );
  871. if( ! ::IsWindow( hWndOwn ) )
  872. return true;
  873. }
  874. return true;
  875. }
  876. if( g_bMenuShowCoolTips
  877. && (! m_bSuspendTips )
  878. && nCurIndex != nOldCurIndex
  879. && GetSite().GetCapture() == this
  880. )
  881. {
  882. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  883. bool bInitCoolTip = true;
  884. if( _IsRibbonMode() )
  885. {
  886. if( mi.KeyTipGetWnd( true )->GetSafeHwnd() != NULL
  887. || mi.KeyTipGetWnd( false )->GetSafeHwnd() != NULL
  888. )
  889. bInitCoolTip = false;
  890. else
  891. {
  892. CExtPopupScreenTipWnd & _wndScreenTip = GetScreenTip();
  893. if( mi.InitSceenTip( _wndScreenTip ) )
  894. bInitCoolTip = false;
  895. }
  896. } // if( _IsRibbonMode() )
  897. if( bInitCoolTip )
  898. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  899. {
  900. CExtSafeString sTipText;
  901. mi.GetTip( sTipText );
  902. if( ! sTipText.IsEmpty() )
  903. {
  904. CRect rcItem;
  905. _GetItemRect(nCurIndex,rcItem);
  906. ClientToScreen( &rcItem );
  907. CExtPopupMenuTipWnd & _tipWnd = GetTip();
  908. _tipWnd.SetText( sTipText );
  909. _tipWnd.SetTipStyle( _CoolTipGetStyle() );
  910. VERIFY(
  911. _tipWnd.Show(
  912. this,
  913. rcItem
  914. )
  915. );
  916. } // if( ! sTipText.IsEmpty() )
  917. } // if( bInitCoolTip )
  918. } // if( g_bMenuShowCoolTips ....
  919. } // if( nOldCurIndex != nCurIndex )
  920. return (nOldCurIndex == nCurIndex) ? false : true;
  921. } // if( nCurIndex >= 0 )
  922. return false;
  923. }
  924. void CExtPopupMenuWnd::_ItemFocusDelay(
  925. int nItemIndex, // = IDX_NOTHING
  926. bool * p_bFocusAreadySet // = NULL
  927. )
  928. {
  929. ASSERT_VALID( this );
  930. if( p_bFocusAreadySet != NULL )
  931. (*p_bFocusAreadySet) = false;
  932. HWND hWndOwn = m_hWnd;
  933. if( ! ::IsWindow( hWndOwn ) )
  934. return;
  935. if( nItemIndex >= 0 )
  936. {
  937. MENUITEMDATA & mii = ItemGetInfo( nItemIndex );
  938. if( mii.IsPopup() )
  939. {
  940. CExtPopupMenuWnd * pPopup = mii.GetPopup();
  941. ASSERT_VALID( pPopup );
  942. bool bPopupAlreadyOpen = false;
  943. if( pPopup->GetSafeHwnd() != NULL )
  944. {
  945. int nCount = ItemGetCount();
  946. for( int i = 0; i < nCount; i++ )
  947. {
  948. MENUITEMDATA & mii_child = ItemGetInfo( i );
  949. if( i == nItemIndex )
  950. continue;
  951. if( ! mii_child.IsPopup() )
  952. continue;
  953. CExtPopupMenuWnd * pChildPopup = mii_child.GetPopup();
  954. ASSERT_VALID( pChildPopup );
  955. if( pChildPopup->GetSafeHwnd() == NULL )
  956. continue;
  957. INT nSaved = pChildPopup->m_nFadeOutAnimationStepCount;
  958. pChildPopup->m_nFadeOutAnimationStepCount = -1;
  959. pChildPopup->_OnCancelMode();
  960. pChildPopup->m_nFadeOutAnimationStepCount = nSaved;
  961. if( ! ::IsWindow( hWndOwn ) )
  962. return;
  963. }
  964. bPopupAlreadyOpen = true;
  965. pPopup->m_bDelayedHiding = false;
  966. pPopup->KillTimer( ID_TIMER_ITEM_HIDE_DELAY );
  967. pPopup->_ItemFocusCancel( TRUE, FALSE, FALSE );
  968. {
  969. CClientDC dc( pPopup );
  970. pPopup->_DoPaint( dc );
  971. }
  972. pPopup->_SetCapture();
  973. m_nDelayedFocusItemIndex = IDX_NOTHING;
  974. KillTimer( ID_TIMER_DELAY_EXPAND );
  975. if( m_nCurIndex >= 0 )
  976. {
  977. MENUITEMDATA & mii_old = ItemGetInfo( m_nCurIndex );
  978. mii_old.SetSelected( false );
  979. }
  980. m_nCurIndex = nItemIndex;
  981. mii.SetSelected( true );
  982. {
  983. CClientDC dc( this );
  984. _DoPaint( dc );
  985. }
  986. if( p_bFocusAreadySet != NULL )
  987. (*p_bFocusAreadySet) = true;
  988. return;
  989. }
  990. }
  991. }
  992. ItemFocusTracker_t _ift( this );
  993. if( m_nDelayedFocusItemIndex != nItemIndex )
  994. {
  995. if( m_nDelayedFocusItemIndex >= 0 )
  996. KillTimer( ID_TIMER_ITEM_FOCUS_DELAY );
  997. //m_nDelayedFocusItemIndex = IDX_NOTHING;
  998. }
  999. if( nItemIndex < 0 )
  1000. {
  1001. m_nDelayedFocusItemIndex = IDX_NOTHING;
  1002. return;
  1003. }
  1004. if( m_nDelayedFocusItemIndex == nItemIndex )
  1005. return;
  1006. ASSERT( nItemIndex>=0 && nItemIndex<m_items_all.GetSize() );
  1007. m_nDelayedFocusItemIndex = nItemIndex;
  1008. ASSERT( ItemGetInfo(m_nDelayedFocusItemIndex).IsPopup() );
  1009. ITEMCOVERINGNOTIFICATON _icn(
  1010. this,
  1011. NULL,
  1012. ITEMCOVERINGNOTIFICATON::__EICN_DELAY,
  1013. m_nDelayedFocusItemIndex
  1014. );
  1015. _icn.Notify();
  1016. m_bSuspendTips = _icn.m_bSuspendTips;
  1017. if( ! ::IsWindow( hWndOwn ) )
  1018. return;
  1019. KillTimer( ID_TIMER_AUTO_EXPAND );
  1020. ASSERT( g_nTimeDelayedDisplaying > 0 );
  1021. SetTimer( ID_TIMER_ITEM_FOCUS_DELAY, g_nTimeDelayedDisplaying, NULL );
  1022. _ift.FocusChangingUnRegister();
  1023. }
  1024. int CExtPopupMenuWnd::_GetMaxScrollPos()
  1025. {
  1026. ASSERT_VALID( this );
  1027. ASSERT( m_bScrollingAvailable );
  1028. CRect rcClient;
  1029. _GetClientRect( &rcClient );
  1030. int nClientHeight =
  1031. rcClient.Height();
  1032. CRect rcMB = OnQueryMenuBorderMetrics();
  1033. int nMenuShadowSize = OnQueryMenuShadowSize();
  1034. int nMaxScrollPos = m_sizeFullItems.cy;
  1035. nMaxScrollPos += rcMB.top + rcMB.bottom;
  1036. nMaxScrollPos += nMenuShadowSize;
  1037. nMaxScrollPos -= nClientHeight;
  1038. //ASSERT( nMaxScrollPos > 0 );
  1039. nMaxScrollPos = max( 0, nMaxScrollPos );
  1040. if( m_bExpandAvailable )
  1041. nMaxScrollPos += _GetSpecBtnHeight(); // xpand btn
  1042. if( _IsTearOff() )
  1043. nMaxScrollPos += _GetTearOffCaptionHeight();
  1044. return -nMaxScrollPos;
  1045. }
  1046. void CExtPopupMenuWnd::OnTimer(__EXT_MFC_UINT_PTR nIDEvent) 
  1047. {
  1048. ASSERT_VALID( this );
  1049. switch( nIDEvent )
  1050. {
  1051. case ID_TIMER_AUTO_EXPAND:
  1052. {
  1053. if( m_nCurIndex >= 0 )
  1054. {
  1055. MENUITEMDATA & mii = ItemGetInfo( m_nCurIndex );
  1056. if( mii.IsInplaceEdit() )
  1057. {
  1058. CWnd * pWnd = mii.GetInplaceEditPtr();
  1059. if( pWnd->GetSafeHwnd() != NULL
  1060. && ::GetFocus() == pWnd->m_hWnd
  1061. )
  1062. return;
  1063. }
  1064. if( mii.IsPopup()
  1065. && mii.GetPopup()->GetSafeHwnd() != NULL
  1066. )
  1067. {
  1068. KillTimer( nIDEvent );
  1069. return;
  1070. }
  1071. }
  1072. KillTimer( nIDEvent );
  1073. _DoExpand();
  1074. }
  1075. return;
  1076. case ID_TIMER_FADE_OUT_ANIMATION:
  1077. {
  1078. if( m_nFadeOutAnimationStepIndex < m_nFadeOutAnimationStepCount )
  1079. {
  1080. CExtPopupMenuWnd * pPopup;
  1081. for( pPopup = this; pPopup != NULL; pPopup = pPopup->m_pWndParentMenu )
  1082. {
  1083. if( pPopup->GetSafeHwnd() == NULL )
  1084. continue;
  1085. ASSERT( g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL );
  1086. if( (pPopup->GetStyle()&WS_VISIBLE) == 0 )
  1087. continue;
  1088. if( m_nFadeOutAnimationStepIndex == 0 )
  1089. {
  1090. pPopup->m_bHelperAnimationControllerDetected = true;
  1091. if( (pPopup->GetExStyle()&(__EXT_MFC_WS_EX_LAYERED|WS_EX_TRANSPARENT)) != (__EXT_MFC_WS_EX_LAYERED|WS_EX_TRANSPARENT) )
  1092. pPopup->ModifyStyleEx( 0, (__EXT_MFC_WS_EX_LAYERED|WS_EX_TRANSPARENT) );
  1093. pPopup->EnableWindow( FALSE );
  1094. }
  1095. BYTE nAlpha = (BYTE)
  1096. ::MulDiv(
  1097. m_nFadeOutAnimationStepCount - m_nFadeOutAnimationStepIndex - 1,
  1098. 255,
  1099. m_nFadeOutAnimationStepCount
  1100. );
  1101. g_PaintManager.m_pfnSetLayeredWindowAttributes( pPopup->m_hWnd, 0, nAlpha, __EXT_MFC_LWA_ALPHA );
  1102. if( pPopup->m_ctrlShadow.GetSafeHwnd() != NULL
  1103. && (pPopup->m_ctrlShadow.GetStyle()&WS_VISIBLE)
  1104. )
  1105. pPopup->m_ctrlShadow.UpdateWindowLayer( nAlpha );
  1106. CExtPaintManager::stat_PassPaintMessages();
  1107. } // for( pPopup = this; pPopup != NULL; pPopup = pPopup->m_pWndParentMenu )
  1108. m_nFadeOutAnimationStepIndex ++;
  1109. } // if( m_nFadeOutAnimationStepIndex < m_nFadeOutAnimationStepCount )
  1110. else
  1111. {
  1112. KillTimer( nIDEvent );
  1113. if( m_ctrlShadow.GetSafeHwnd() != NULL )
  1114. m_ctrlShadow.DestroyWindow();
  1115. CExtPopupMenuWnd * pPopup = this;
  1116. for( ; pPopup != NULL; )
  1117. {
  1118. VERIFY( pPopup->_BuildItems( NULL, true ) );
  1119. //pPopup->_DeleteFadeOutMenu();
  1120. if( pPopup->m_ctrlShadow.GetSafeHwnd() != NULL
  1121. && (pPopup->m_ctrlShadow.GetStyle()&WS_VISIBLE)
  1122. )
  1123. pPopup->m_ctrlShadow.DestroyWindow();
  1124. HWND hWnd = pPopup->m_hWnd;
  1125. pPopup = pPopup->m_pWndParentMenu;
  1126. ::DestroyWindow( hWnd );
  1127. }
  1128. } // else from if( m_nFadeOutAnimationStepIndex < m_nFadeOutAnimationStepCount )
  1129. }
  1130. return;
  1131. case ID_TIMER_DELAY_EXPAND:
  1132. {
  1133. if( m_nWaitingExpandTickCount <
  1134. ID_TOTAL_DELAY_EXPAND
  1135. )
  1136. {
  1137. if( m_nWaitingExpandTickCount <= 1 )
  1138. m_nWaitingExpandTickCount = 0;
  1139. m_nWaitingExpandTickCount +=
  1140. ID_FREQ_DELAY_EXPAND;
  1141. return;
  1142. }
  1143. VERIFY( KillTimer(ID_TIMER_DELAY_EXPAND) );
  1144. m_nWaitingExpandTickCount = 0;
  1145. if( m_bExpandAvailable
  1146. && (!m_bExpandWasPressed)
  1147. && ( GetSite().GetAnimated() == NULL )
  1148. )
  1149. { // if expand can be performed
  1150. CPoint point;
  1151. if( ! ::GetCursorPos(&point) )
  1152. return;
  1153. ScreenToClient( &point );
  1154. CRect rcExpand;
  1155. _GetItemRect( IDX_EXPAND, rcExpand );
  1156. if( rcExpand.PtInRect(point) )
  1157. _DoExpand();
  1158. } // if expand can be performed
  1159. }
  1160. return;
  1161. case ID_TIMER_SCROLLING:
  1162. {
  1163. HWND hWndOwn = m_hWnd;
  1164. _ItemFocusDelay();
  1165. if( ! ::IsWindow( hWndOwn ) )
  1166. return;
  1167. if( m_nCurIndex >= 0 )
  1168. {
  1169. _ItemFocusCancel(TRUE);
  1170. if( ! ::IsWindow( hWndOwn ) )
  1171. return;
  1172. }
  1173. CPoint point;
  1174. if( ! ::GetCursorPos(&point) )
  1175. return;
  1176. ScreenToClient( &point );
  1177. m_nScrollingDirection = 0;
  1178. CRect rcItem;
  1179. _GetItemRect(IDX_SCROLL_TOP,rcItem);
  1180. if( m_nAcceleratedPixelsPerStepCurrent > g_nAcceleratedPixelsPerStepMax )
  1181. m_nAcceleratedPixelsPerStepCurrent = g_nAcceleratedPixelsPerStepMax;
  1182. if( rcItem.PtInRect(point) )
  1183. {
  1184. m_nScrollingDirection = m_nAcceleratedPixelsPerStepCurrent; // __SCROLLING_PIXEL_STEP
  1185. }
  1186. else
  1187. {
  1188. _GetItemRect(IDX_SCROLL_BOTTOM,rcItem);
  1189. if( rcItem.PtInRect(point) )
  1190. m_nScrollingDirection = -m_nAcceleratedPixelsPerStepCurrent; // (-__SCROLLING_PIXEL_STEP);
  1191. }
  1192. m_nDyScrollOffset += m_nScrollingDirection;
  1193. bool bKillThisTimer =
  1194. (m_nScrollingDirection == 0) ? true : false;
  1195. if( m_nDyScrollOffset > 0 )
  1196. {
  1197. m_nDyScrollOffset = 0;
  1198. bKillThisTimer = true;
  1199. }
  1200. else
  1201. {
  1202. int nMaxScrollPos = _GetMaxScrollPos();
  1203. if( m_nDyScrollOffset < nMaxScrollPos )
  1204. {
  1205. m_nDyScrollOffset = nMaxScrollPos;
  1206. bKillThisTimer = true;
  1207. }
  1208. }
  1209. if( bKillThisTimer )
  1210. {
  1211. VERIFY( KillTimer(ID_TIMER_SCROLLING) );
  1212. m_nAcceleratedPixelsPerStepCurrent = __SCROLLING_PIXEL_STEP;
  1213. m_nAcceleratedMilliSecondsPassed = 0;
  1214. m_nScrollingDirection = 0;
  1215. }
  1216. else
  1217. {
  1218. if( g_bUseAcceleratedMenuScrolling )
  1219. {
  1220. INT nAcceleratedIncreasePercent = g_nAcceleratedIncreasePercent;
  1221. INT nAcceleratedIncreaseStep = g_nAcceleratedIncreaseStep;
  1222. if( nAcceleratedIncreaseStep >= 0
  1223. && nAcceleratedIncreasePercent > 0
  1224. )
  1225. {
  1226. if( m_nAcceleratedMilliSecondsPassed >= nAcceleratedIncreaseStep )
  1227. {
  1228. m_nAcceleratedMilliSecondsPassed = 0;
  1229. INT nStepPx =
  1230. ::MulDiv(
  1231. m_nAcceleratedPixelsPerStepCurrent,
  1232. 100,
  1233. __SCROLLING_PIXEL_STEP
  1234. );
  1235. nStepPx +=
  1236. ::MulDiv(
  1237. nStepPx,
  1238. nAcceleratedIncreasePercent,
  1239. 100
  1240. );
  1241. m_nAcceleratedPixelsPerStepCurrent =
  1242. ::MulDiv(
  1243. nStepPx,
  1244. __SCROLLING_PIXEL_STEP,
  1245. 100
  1246. );
  1247. } // if( m_nAcceleratedMilliSecondsPassed >= nAcceleratedIncreaseStep )
  1248. else
  1249. {
  1250. m_nAcceleratedMilliSecondsPassed += ID_PERIOD_SCROLLING;
  1251. } // else from if( m_nAcceleratedMilliSecondsPassed >= nAcceleratedIncreaseStep )
  1252. }
  1253. } // if( g_bUseAcceleratedMenuScrolling )
  1254. }
  1255. _CachedRectsEmpty();
  1256. Invalidate( FALSE );
  1257. }
  1258. return;
  1259. case ID_TIMER_ITEM_HIDE_DELAY:
  1260. {
  1261. KillTimer( nIDEvent );
  1262. if( ! m_bDelayedHiding )
  1263. return;
  1264. INT nSaved = m_nFadeOutAnimationStepCount;
  1265. m_nFadeOutAnimationStepCount = -1;
  1266. _OnCancelMode();
  1267. m_nFadeOutAnimationStepCount = nSaved;
  1268. return;
  1269. }
  1270. case ID_TIMER_ITEM_FOCUS_DELAY:
  1271. {
  1272. if( GetSite().GetAnimated() != NULL )
  1273. return;
  1274. KillTimer( nIDEvent );
  1275. if( GetSite().IsShutdownMode() )
  1276. return;
  1277. Invalidate( FALSE );
  1278. if( m_nDelayedFocusItemIndex >= 0 )
  1279. {
  1280. ASSERT( m_nDelayedFocusItemIndex>=0 && m_nDelayedFocusItemIndex<m_items_all.GetSize() );
  1281. ASSERT( ItemGetInfo(m_nDelayedFocusItemIndex).IsPopup() );
  1282. CRect rcItem;
  1283. _GetItemRect(m_nDelayedFocusItemIndex,rcItem);
  1284. CPoint point;
  1285. if( ! ::GetCursorPos( &point ) )
  1286. return;
  1287. ScreenToClient( &point );
  1288. if( rcItem.PtInRect(point) )
  1289. {
  1290. HWND hWndOwn = m_hWnd;
  1291. _ItemFocusSet(
  1292. m_nDelayedFocusItemIndex,
  1293. TRUE,
  1294. TRUE,
  1295. FALSE
  1296. );
  1297. if( ! ::IsWindow( hWndOwn ) )
  1298. return;
  1299. }
  1300. } // if( m_nDelayedFocusItemIndex >= 0 )
  1301. m_nDelayedFocusItemIndex = IDX_NOTHING;
  1302. }
  1303. return;
  1304. default:
  1305. CExtPopupBaseWnd::OnTimer(nIDEvent);
  1306. break; // default
  1307. } // switch( nIDEvent )
  1308. }
  1309. CExtPopupMenuWnd * CExtPopupMenuWnd::_GetCapture()
  1310. {
  1311. if( (TrackFlagsGet()&TPMX_NO_SITE) != 0 )
  1312. return this;
  1313. return GetSite().GetCapture();
  1314. }
  1315. void CExtPopupMenuWnd::_SetCapture()
  1316. {
  1317. ASSERT_VALID( this );
  1318. if( (TrackFlagsGet()&TPMX_NO_SITE) != 0 )
  1319. return;
  1320. ASSERT( !_FindCustomizeMode() );
  1321. CExtPopupMenuSite & _site = GetSite();
  1322. if( GetSafeHwnd() != NULL )
  1323. {
  1324. ASSERT( ::IsWindow(GetSafeHwnd()) );
  1325. _site.SetCapture( this );
  1326. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  1327. _KeyTipsShow( true );
  1328. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  1329. }
  1330. else
  1331. _site.SetCapture( NULL );
  1332. }
  1333. void CExtPopupMenuWnd::_ReleaseCapture()
  1334. {
  1335. ASSERT_VALID( this );
  1336. ASSERT( !_FindCustomizeMode() );
  1337. CExtPopupMenuSite & _site = GetSite();
  1338. if( _site.IsEmpty()
  1339. || _site.IsShutdownMode()
  1340. )
  1341. return;
  1342. if( _site.GetCapture() == this )
  1343. _site.SetCapture( NULL );
  1344. }
  1345. int CExtPopupMenuWnd::_GetNextItem(
  1346. next_item_t nit
  1347. )
  1348. {
  1349. ASSERT_VALID( this );
  1350. int nCountOfItems = (int)m_items_all.GetSize();
  1351. bool bCanExpand = false;
  1352. if( m_bExpandAvailable
  1353. && (!m_bExpandWasPressed)
  1354. )
  1355. {
  1356. if( IsAllItemsRarelyUsed() )
  1357. return IDX_EXPAND;
  1358. bCanExpand = true;
  1359. }
  1360. if( nit == __NI_NOTHING
  1361. || nCountOfItems == 0
  1362. )
  1363. {
  1364. if( bCanExpand )
  1365. return IDX_EXPAND;
  1366. return IDX_NOTHING;
  1367. }
  1368. if( nit == __NI_ANY
  1369. && m_nCurIndex >= 0
  1370. )
  1371. return m_nCurIndex;
  1372. if( m_nCurIndex < 0 )
  1373. {
  1374. INT iter = 0;
  1375. for( ; iter < m_items_all.GetSize(); ++iter )
  1376. {
  1377. MENUITEMDATA & mi = ItemGetInfo( iter );
  1378. if( mi.IsEnabled()
  1379. && mi.IsDisplayed()
  1380. )
  1381. return mi.GetIndex();
  1382. }
  1383. if( bCanExpand )
  1384. return IDX_EXPAND;
  1385. return IDX_NOTHING;
  1386. } // if( m_nCurIndex < 0 )
  1387. if( nit == __NI_ROW_NEXT )
  1388. {
  1389. if( nCountOfItems < 2 )
  1390. {
  1391. if( bCanExpand )
  1392. return IDX_EXPAND;
  1393. return IDX_NOTHING;
  1394. }
  1395. INT iter = m_nCurIndex;
  1396. if( ! ItemGetInfo( iter ).IsIconMode() )
  1397. return _GetNextItem( __NI_NEXT );
  1398. CRect rcCurrItem;
  1399. _GetItemRect( iter, rcCurrItem, false );
  1400. for( ; iter < m_items_all.GetSize(); ++iter )
  1401. {
  1402. MENUITEMDATA & mi = ItemGetInfo( iter );
  1403. if( mi.IsDisplayed()
  1404. && ItemPaletteRowWrapGet( iter )
  1405. )
  1406. {
  1407. ++iter;
  1408. break;
  1409. }
  1410. }
  1411. int nPotentialIdx = IDX_NOTHING;
  1412. for( ; iter < m_items_all.GetSize(); ++iter )
  1413. {
  1414. MENUITEMDATA & mi = ItemGetInfo( iter );
  1415. if( (! mi.IsEnabled() )
  1416. || (! mi.IsDisplayed() )
  1417. )
  1418. continue;
  1419. CRect rcItem;
  1420. _GetItemRect( iter, rcItem, false );
  1421. if( rcItem.left >= rcCurrItem.left )
  1422. return mi.GetIndex();
  1423. else if(
  1424. ItemPaletteRowWrapGet( iter )
  1425. && nPotentialIdx != IDX_NOTHING
  1426. )
  1427. break;
  1428. nPotentialIdx = iter;
  1429. }
  1430. if( nPotentialIdx == IDX_NOTHING
  1431. && bCanExpand
  1432. )
  1433. return IDX_EXPAND;
  1434. return nPotentialIdx;
  1435. } // if( nit == __NI_ROW_NEXT )
  1436. if( nit == __NI_ROW_PREV )
  1437. {
  1438. if( nCountOfItems < 2 )
  1439. return IDX_NOTHING;
  1440. INT iter = m_nCurIndex;
  1441. if( ! ItemGetInfo( iter ).IsIconMode() )
  1442. return _GetNextItem( __NI_PREV );
  1443. CRect rcCurrItem;
  1444. _GetItemRect( iter, rcCurrItem, false );
  1445. for( ; (iter+1) > 0; --iter )
  1446. {
  1447. MENUITEMDATA & mi = ItemGetInfo( iter );
  1448. if( mi.IsDisplayed()
  1449. && ItemPaletteRowWrapGet( iter )
  1450. && iter != m_nCurIndex
  1451. )
  1452. break;
  1453. }
  1454. int nPotentialIdx = IDX_NOTHING;
  1455. for( ; (iter+1) > 0; --iter )
  1456. {
  1457. if( ItemPaletteRowWrapGet( iter )
  1458. && nPotentialIdx != IDX_NOTHING
  1459. )
  1460. break;
  1461. MENUITEMDATA & mi = ItemGetInfo( iter );
  1462. if( (! mi.IsEnabled() )
  1463. || (! mi.IsDisplayed() )
  1464. )
  1465. continue;
  1466. CRect rcItem;
  1467. _GetItemRect( iter, rcItem, false );
  1468. if( rcItem.right <= rcCurrItem.right )
  1469. return mi.GetIndex();
  1470. nPotentialIdx = iter;
  1471. }
  1472. if( nPotentialIdx == IDX_NOTHING
  1473. && bCanExpand
  1474. )
  1475. return IDX_EXPAND;
  1476. return nPotentialIdx;
  1477. } // if( nit == __NI_ROW_PREV )
  1478. if( nit == __NI_NEXT )
  1479. {
  1480. if( nCountOfItems < 2 )
  1481. {
  1482. if( bCanExpand )
  1483. return IDX_EXPAND;
  1484. return IDX_NOTHING;
  1485. }
  1486. INT iter = m_nCurIndex + 1;
  1487. for( ; iter < m_items_all.GetSize(); ++iter )
  1488. {
  1489. MENUITEMDATA & mi = ItemGetInfo( iter );
  1490. if( mi.IsEnabled() && mi.IsDisplayed() )
  1491. return mi.GetIndex();
  1492. }
  1493. if( bCanExpand )
  1494. return IDX_EXPAND;
  1495. if( m_nCurIndex == 0 )
  1496. return IDX_NOTHING;
  1497. iter = 0;
  1498. INT iter2 = m_nCurIndex - 1;
  1499. do
  1500. {
  1501. MENUITEMDATA & mi = ItemGetInfo( iter );
  1502. if( mi.IsEnabled() && mi.IsDisplayed() )
  1503. return mi.GetIndex();
  1504. iter++;
  1505. } while( iter != iter2 );
  1506. return IDX_NOTHING;
  1507. } // if( nit == __NI_NEXT )
  1508. if( nit == __NI_PREV )
  1509. {
  1510. if( nCountOfItems < 2 )
  1511. return IDX_NOTHING;
  1512. if( m_nCurIndex != 0 )
  1513. {
  1514. int nIndex = m_nCurIndex - 1;
  1515. INT iter = nIndex;
  1516. for( ; true;  )
  1517. {
  1518. MENUITEMDATA & mi = ItemGetInfo( iter );
  1519. if( mi.IsEnabled() && mi.IsDisplayed() )
  1520. return mi.GetIndex();
  1521. if( nIndex == 0 )
  1522. break;
  1523. --iter;
  1524. --nIndex;
  1525. }
  1526. } // if( m_nCurIndex != 0 )
  1527. int nIndex = m_nCurIndex + 1;
  1528. INT iter2 = nIndex;
  1529. INT iter = INT(m_items_all.GetSize()) - 1;
  1530. do
  1531. {
  1532. MENUITEMDATA & mi = ItemGetInfo( iter );
  1533. if( mi.IsEnabled() && mi.IsDisplayed() )
  1534. return mi.GetIndex();
  1535. iter--;
  1536. } while( iter != iter2 );
  1537. return IDX_NOTHING;
  1538. } // if( nit == __NI_PREV )
  1539. return IDX_NOTHING;
  1540. }
  1541. const ACCEL * CExtPopupMenuWnd::_GetTranslatedContextHelpAccel() const
  1542. {
  1543. if( ! g_bTranslateContextHelpCmd )
  1544. return NULL;
  1545. return &g_accelContextHelp;
  1546. }
  1547. bool CExtPopupMenuWnd::_OnKeyDown(
  1548. UINT nChar,
  1549. UINT nRepCnt,
  1550. UINT nFlags,
  1551. bool & bNoEat
  1552. )
  1553. {
  1554. ASSERT_VALID( this );
  1555. nFlags;
  1556. ASSERT( m_hWndCmdReceiver != NULL );
  1557. ASSERT( ::IsWindow(m_hWndCmdReceiver) );
  1558. nRepCnt;
  1559. if( GetSafeHwnd() == NULL )
  1560. return true;
  1561. if( ! m_bAnimFinished )
  1562. return true;
  1563. if( _IsResizingMode() )
  1564. return true;
  1565. CExtPopupMenuSite & _site = GetSite();
  1566. if( _site.IsShutdownMode()
  1567. || _site.IsEmpty()
  1568. || _site.GetAnimated() != NULL
  1569. )
  1570. return true;
  1571. TranslateKeyboardEventData_t _td( this, nChar, nRepCnt, nFlags, bNoEat );
  1572. if( _td.Notify() )
  1573. {
  1574. bNoEat = _td.m_bNoEat;
  1575. return true;
  1576. }
  1577. bool bAlt =
  1578. ( (::GetAsyncKeyState(VK_MENU)&0x8000) != 0 )
  1579. ? true : false;
  1580. bool bCtrl =
  1581. ( (::GetAsyncKeyState(VK_CONTROL)&0x8000) != 0 )
  1582. ? true : false;
  1583. bool bShift =
  1584. ( (::GetAsyncKeyState(VK_SHIFT)&0x8000) != 0 )
  1585. ? true : false;
  1586. HWND hWndFocus = ::GetFocus();
  1587. if( hWndFocus != NULL
  1588. && (::__EXT_MFC_GetWindowLong(hWndFocus,GWL_STYLE)&WS_CHILD) != 0
  1589. && ::GetParent(hWndFocus) == m_hWnd
  1590. && ( nChar != VK_RETURN
  1591. || m_nCurIndex < 0
  1592. || (! ItemGetInfo(m_nCurIndex).IsInplaceEdit() )
  1593. )
  1594. )
  1595. {
  1596. if( bAlt )
  1597. PostMessage( WM_CANCELMODE );
  1598. else if( nChar == VK_ESCAPE )
  1599. SetFocus();
  1600. else if( (nChar == VK_INSERT || nChar == _T('C')) && bCtrl )
  1601. ::SendMessage( hWndFocus, WM_COPY, 0, 0 );
  1602. else if( ( nChar == _T('X') && bCtrl )
  1603. || ( nChar == VK_DELETE && bShift )
  1604. )
  1605. ::SendMessage( hWndFocus, WM_CUT, 0, 0 );
  1606. else if( ( nChar == _T('V') && bCtrl )
  1607. || ( nChar == VK_INSERT && bShift )
  1608. )
  1609. ::SendMessage( hWndFocus, WM_PASTE, 0, 0 );
  1610. else if( nChar == VK_DELETE )
  1611. ::SendMessage( hWndFocus, CExtPopupMenuWnd::CInPlaceEditWnd::g_nMsgDeleteSelection, 0, 0 );
  1612. else if( nChar == _T('A') && bCtrl )
  1613. ::SendMessage( hWndFocus, CExtPopupMenuWnd::CInPlaceEditWnd::g_nMsgSelectAll, 0, 0 );
  1614. else
  1615. bNoEat = true;
  1616. return (!bNoEat);
  1617. }
  1618. next_item_t nit = __NI_NOTHING;
  1619. if( nChar == VK_TAB && (! ( bCtrl || bAlt ) ) )
  1620. {
  1621. if( _IsPalette()
  1622. && ItemGetCount() > 0
  1623. && m_nCurIndex >= 0
  1624. && m_nCurIndex <= (ItemGetCount() - 1)
  1625. && ItemGetInfo(m_nCurIndex).IsToolButton()
  1626. )
  1627. nChar = bShift ? VK_LEFT : VK_RIGHT;
  1628. else
  1629. nChar = bShift ? VK_UP : VK_DOWN;
  1630. }
  1631. bool bRTL = OnQueryLayoutRTL();
  1632. if( bRTL
  1633. && ( nChar == VK_LEFT
  1634. || nChar == VK_RIGHT
  1635. )
  1636. )
  1637. nChar = (nChar == VK_LEFT) ? VK_RIGHT : VK_LEFT;
  1638. switch( nChar )
  1639. {
  1640. case VK_MENU:
  1641. _EndSequence();
  1642. return true;
  1643. case VK_SPACE:
  1644. return true;
  1645. case VK_F4:
  1646. {
  1647. if( m_nCurIndex < 0 )
  1648. return true;
  1649. MENUITEMDATA & mi = ItemGetInfo( m_nCurIndex );
  1650. if( mi.IsExtraMark() )
  1651. return true;
  1652. if( ! ( mi.IsInplaceEdit() && mi.IsPopup() ) )
  1653. return true;
  1654. if( mi.GetPopup()->GetSafeHwnd() == NULL )
  1655. {
  1656. HWND hWndOwn = m_hWnd;
  1657. _ItemFocusSet(
  1658. m_nCurIndex,
  1659. TRUE,
  1660. TRUE
  1661. );
  1662. if( ! ::IsWindow( hWndOwn ) )
  1663. return true;
  1664. }
  1665. return true;
  1666. }
  1667. case VK_RETURN:
  1668. {
  1669. if( m_nCurIndex < 0 )
  1670. {
  1671. INT nPos = ItemDefaultFind();
  1672. if( nPos < 0 )
  1673. return true; // break;
  1674. _ItemFocusSet(
  1675. nPos,
  1676. FALSE,
  1677. TRUE,
  1678. TRUE
  1679. );
  1680. }
  1681. MENUITEMDATA & mi = ItemGetInfo( m_nCurIndex );
  1682. if( mi.IsInplaceEdit() )
  1683. {
  1684. CWnd * pWndInplace = mi.GetInplaceEditPtr();
  1685. if( pWndInplace != NULL )
  1686. {
  1687. ASSERT_VALID( pWndInplace );
  1688. ASSERT( pWndInplace->GetSafeHwnd() != NULL && (::IsWindow(pWndInplace->GetSafeHwnd())) );
  1689. if( mi.IsAllowInplaceEditActivation() )
  1690. {
  1691. if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 )
  1692. {
  1693. CRect rcInplaceEdit;
  1694. _GetItemRect( m_nCurIndex, rcInplaceEdit );
  1695. rcInplaceEdit =
  1696. mi.AdjustInplaceEditRect(
  1697. rcInplaceEdit,
  1698. OnQueryLayoutRTL()
  1699. );
  1700. pWndInplace->SetWindowPos(
  1701. NULL,
  1702. rcInplaceEdit.left, rcInplaceEdit.top,
  1703. rcInplaceEdit.Width(), rcInplaceEdit.Height(),
  1704. SWP_NOZORDER|SWP_NOOWNERZORDER
  1705. |SWP_NOACTIVATE|SWP_SHOWWINDOW
  1706. );
  1707. pWndInplace->SetFocus();
  1708. } // if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 )
  1709. else
  1710. {
  1711. bNoEat = true;
  1712. return false;
  1713. }
  1714. } // if( mi.IsAllowInplaceEditActivation() )
  1715. } // if( pWndInplace != NULL )
  1716. return true;
  1717. }
  1718. if( mi.IsExtraMark() && (! _FindHelpMode() ) )
  1719. {
  1720. ASSERT( mi.GetExtraMarkCallback() != NULL );
  1721. mi.GetExtraMarkCallback()( this, &mi );
  1722. CClientDC dc( this );
  1723. _DoPaint( dc );
  1724. return true;
  1725. } // if( mi.IsExtraMark() ....
  1726. if( mi.IsExecutableCmdID()
  1727. || ( mi.IsPopup()
  1728. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  1729. && mi.GetCmdNode() != NULL
  1730. && (mi.GetCmdNode()->GetFlags()&__ECTN_TBB_SEPARATED_DROPDOWN) != 0
  1731. && (mi.GetCmdNode()->GetFlags()&(__ECTN_TBB_COLOR|__ECTN_TBB_UNDO_REDO)) != 0
  1732. #else // (!defined __EXT_MFC_NO_CUSTOMIZE)
  1733. && ( mi.GetPopup()->IsKindOf( RUNTIME_CLASS(CExtPopupColorMenuWnd) )
  1734. #if (!defined __EXT_MFC_NO_UNDO_REDO_POPUP)
  1735. || mi.GetPopup()->IsKindOf( RUNTIME_CLASS(CExtPopupUndoRedoMenuWnd) )
  1736. #endif // (!defined __EXT_MFC_NO_UNDO_REDO_POPUP)
  1737. )
  1738. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  1739. )
  1740. )
  1741. {
  1742. if( !( mi.GetCmdDeliverCb() != NULL
  1743. && mi.GetCmdDeliverCb()( this, &mi )
  1744. )
  1745. )
  1746. {
  1747. _CancelingSet();
  1748. _EndSequenceEx( mi );
  1749. }
  1750. return true;
  1751. }
  1752. } // case VK_RETURN
  1753. case VK_RIGHT:
  1754. {
  1755. if( _IsPalette()
  1756. && ItemGetCount() > 0
  1757. && m_nCurIndex >= 0
  1758. && m_nCurIndex <= (ItemGetCount() - 1)
  1759. && (! ItemGetInfo(m_nCurIndex).IsPopup() )
  1760. )
  1761. {
  1762. nit = __NI_NEXT;
  1763. break;
  1764. }
  1765. bool bSendChangeMenu = false;
  1766. if( m_nCurIndex < 0 )
  1767. {
  1768. if( m_items_all.GetSize() == 0 )
  1769. return true; // false;
  1770. // nit = __NI_ANY;
  1771. bSendChangeMenu = true;
  1772. }
  1773. else
  1774. {
  1775. MENUITEMDATA & mi = ItemGetInfo(m_nCurIndex);
  1776. if( !mi.IsPopup() )
  1777. {
  1778. bSendChangeMenu = true;
  1779. }
  1780. else
  1781. {
  1782. if( mi.GetPopup()->GetSafeHwnd() == NULL )
  1783. {
  1784. HWND hWndOwn = m_hWnd;
  1785. _ItemFocusDelay();
  1786. if( ! ::IsWindow( hWndOwn ) )
  1787. return true;
  1788. _ItemFocusSet(
  1789. m_nCurIndex,
  1790. TRUE,
  1791. TRUE
  1792. );
  1793. if( ! ::IsWindow( hWndOwn ) )
  1794. return true;
  1795. }
  1796. }
  1797. }
  1798. if( bSendChangeMenu && nChar==VK_RIGHT )
  1799. {
  1800. ASSERT( m_hWndCmdReceiver != NULL );
  1801. ASSERT( ::IsWindow(m_hWndCmdReceiver) );
  1802. if( CExtToolControlBar::g_bMenuTracking )
  1803. ::PostMessage(
  1804. m_hWndCmdReceiver,
  1805. bRTL ? CExtPopupMenuWnd::g_nMsgPopupPrev : CExtPopupMenuWnd::g_nMsgPopupNext,
  1806. 0,
  1807. LPARAM( this )
  1808. );
  1809. return true;
  1810. }
  1811. }
  1812. break; // case VK_RIGHT
  1813. case VK_ESCAPE:
  1814. if( m_bTopLevel )
  1815. {
  1816. _EndSequence();
  1817. return true;
  1818. }
  1819. case VK_LEFT:
  1820. if( nChar == VK_LEFT
  1821. && _IsPalette()
  1822. && ItemGetCount() > 0
  1823. && m_nCurIndex >= 0
  1824. )
  1825. {
  1826. nit = __NI_PREV;
  1827. break;
  1828. }
  1829. else if( m_pWndParentMenu == NULL )
  1830. {
  1831. if( CExtToolControlBar::g_bMenuTracking )
  1832. ::PostMessage(
  1833. m_hWndCmdReceiver,
  1834. bRTL ? CExtPopupMenuWnd::g_nMsgPopupNext : CExtPopupMenuWnd::g_nMsgPopupPrev,
  1835. 0,
  1836. LPARAM( this )
  1837. );
  1838. return true;
  1839. }
  1840. else
  1841. {
  1842. ASSERT( !m_bTopLevel );
  1843. int nParentCurIndex =
  1844. m_pWndParentMenu->m_nCurIndex;
  1845. ASSERT(
  1846. nParentCurIndex >= 0
  1847. &&
  1848. nParentCurIndex <=
  1849. m_pWndParentMenu->m_items_all.GetSize()
  1850. );
  1851. HWND hWndOwn = m_hWnd;
  1852. //::ReleaseCapture();
  1853. m_pWndParentMenu->_SetCapture();
  1854. m_pWndParentMenu->_ItemFocusCancel(
  1855. FALSE
  1856. );
  1857. m_pWndParentMenu->_ItemFocusSet(
  1858. nParentCurIndex,
  1859. FALSE,
  1860. TRUE
  1861. );
  1862. if( ! ::IsWindow( hWndOwn ) )
  1863. return true;
  1864. m_pWndParentMenu->_SetCapture();
  1865. return true;
  1866. }
  1867. // case VK_ESCAPE:
  1868. // _EndSequence();
  1869. // return true;
  1870. case VK_UP:
  1871. if( nChar == VK_UP
  1872. && ItemGetCount() > 0
  1873. && 0 <= m_nCurIndex
  1874. && m_nCurIndex < ItemGetCount()
  1875. && (! ItemGetInfo(m_nCurIndex).IsIconMode() )
  1876. )
  1877. nit = __NI_PREV;
  1878. else
  1879. nit = _IsPalette() ? __NI_ROW_PREV : __NI_PREV;
  1880. break; // case VK_UP
  1881. case VK_DOWN:
  1882. if( IsKeyPressed( VK_CONTROL ) )
  1883. {
  1884. if( m_bExpandAvailable )
  1885. _DoExpand();
  1886. return true;
  1887. }
  1888. if( ItemGetCount() > 0
  1889. && 0 <= m_nCurIndex
  1890. && m_nCurIndex < ItemGetCount()
  1891. && (! ItemGetInfo(m_nCurIndex).IsIconMode() )
  1892. )
  1893. nit = __NI_NEXT;
  1894. else
  1895. nit = _IsPalette() ? __NI_ROW_NEXT : __NI_NEXT;
  1896. break; // case VK_DOWN
  1897. case VK_NEXT:
  1898. nit = __NI_PAGE_DOWN;
  1899. break; // case VK_NEXT
  1900. case VK_PRIOR:
  1901. nit = __NI_PAGE_UP;
  1902. break; // case VK_PRIOR
  1903. default:
  1904. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  1905. if( _KeyTipsEnabledGet() )
  1906. { // BLOCK: key tip processing
  1907. if( ( _T('A') <= nChar && nChar <= _T('Z') )
  1908. || ( _T('0') <= nChar && nChar <= _T('9') )
  1909. )
  1910. {
  1911. if( _KeyTipsTranslate( nChar ) )
  1912. return true;
  1913. }
  1914. } // BLOCK: key tip processing
  1915. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  1916. { // BLOCK: try analyze quick char access
  1917. if( IsKeyPressed(VK_SHIFT)
  1918. || IsKeyPressed(VK_CONTROL)
  1919. // || IsKeyPressed(VK_MENU)
  1920. // || ( (nFlags & (1<<29)) != 0 ) // ALT pressed?
  1921. )
  1922. return false;
  1923. BYTE lpKeyState[256];
  1924. ::GetKeyboardState( lpKeyState );
  1925. UINT wScanCode = ::MapVirtualKey( nChar, 0 );
  1926. HKL hKeyboardLayout =
  1927. ::GetKeyboardLayout(
  1928. ( ::AfxGetThread() ) -> m_nThreadID
  1929. );
  1930. #if (defined _UNICODE)
  1931. TCHAR szChar[2] = { _T(''), _T('') };
  1932. ::ToUnicodeEx( nChar, wScanCode, lpKeyState, szChar, 1, 1, hKeyboardLayout );
  1933. WORD nMapped = WORD( szChar[0] );
  1934. #else
  1935. WORD nMapped = 0;
  1936. ::ToAsciiEx( nChar, wScanCode, lpKeyState, &nMapped, 1, hKeyboardLayout );
  1937. //TCHAR szChar[2] = { (TCHAR)nMapped, _T('') };
  1938. #endif
  1939. BOOL bSearchDisplayedOnly = FALSE;
  1940. INT nNextIdx =
  1941. ItemFindByAccessChar(
  1942. (TCHAR)nMapped,
  1943. m_nCurIndex,
  1944. TRUE,
  1945. bSearchDisplayedOnly
  1946. );
  1947. if( (! bSearchDisplayedOnly )
  1948. && nNextIdx >= 0
  1949. && m_bExpandAvailable
  1950. && (! m_bExpandWasPressed )
  1951. )
  1952. {
  1953. MENUITEMDATA & miNext = ItemGetInfo( nNextIdx );
  1954. if( (! miNext.IsDisplayed() )
  1955. && ( ItemFindByAccessChar(
  1956. (TCHAR)nMapped,
  1957. nNextIdx,
  1958. TRUE,
  1959. bSearchDisplayedOnly
  1960. ) >= 0
  1961. || miNext.IsPopup()
  1962. )
  1963. )
  1964. {
  1965. KillTimer( ID_TIMER_DELAY_EXPAND );
  1966. bool bSavedMenuExpandAnimation = g_bMenuExpandAnimation;
  1967. g_bMenuExpandAnimation = false;
  1968. _DoExpand();
  1969. _EndAnimation();
  1970. KillTimer( ID_TIMER_ANIMATION );
  1971. m_bAnimFinished = true;
  1972. GetSite().SetAnimated( NULL );
  1973. _DoReCreateShadows();
  1974. g_bMenuExpandAnimation = bSavedMenuExpandAnimation;
  1975. CClientDC dc( this );
  1976. _DoPaint( dc );
  1977. }
  1978. if( miNext.IsPopup() )
  1979. {
  1980. _ItemFocusSet( nNextIdx, TRUE, TRUE, TRUE );
  1981. return true;
  1982. }
  1983. }
  1984. if( nNextIdx < 0
  1985. && m_nCurIndex >= 0
  1986. && ItemFindByAccessChar(
  1987. (TCHAR)nMapped,
  1988. -1,
  1989. TRUE,
  1990. bSearchDisplayedOnly
  1991. )
  1992. == m_nCurIndex
  1993. )
  1994. { // if only 1 with this char
  1995. MENUITEMDATA & mi = ItemGetInfo( m_nCurIndex );
  1996. if( mi.IsInplaceEdit() && (!mi.IsPopup()) )
  1997. {
  1998. CWnd * pWndInplace = mi.GetInplaceEditPtr();
  1999. if( pWndInplace != NULL )
  2000. {
  2001. ASSERT_VALID( pWndInplace );
  2002. ASSERT( pWndInplace->GetSafeHwnd() != NULL && (::IsWindow(pWndInplace->GetSafeHwnd())) );
  2003. if( mi.IsAllowInplaceEditActivation() )
  2004. {
  2005. if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 )
  2006. {
  2007. CRect rcInplaceEdit;
  2008. _GetItemRect( m_nCurIndex, rcInplaceEdit );
  2009. rcInplaceEdit =
  2010. mi.AdjustInplaceEditRect(
  2011. rcInplaceEdit,
  2012. OnQueryLayoutRTL()
  2013. );
  2014. pWndInplace->SetWindowPos(
  2015. NULL,
  2016. rcInplaceEdit.left, rcInplaceEdit.top,
  2017. rcInplaceEdit.Width(), rcInplaceEdit.Height(),
  2018. SWP_NOZORDER|SWP_NOOWNERZORDER
  2019. |SWP_NOACTIVATE|SWP_SHOWWINDOW
  2020. );
  2021. } // if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 )
  2022. pWndInplace->SetFocus();
  2023. } // if( mi.IsAllowInplaceEditActivation() )
  2024. } // if( pWndInplace != NULL )
  2025. return true;
  2026. } // if( mi.IsInplaceEdit() && (!mi.IsPopup()) )
  2027. if( mi.IsExtraMark() && (! _FindHelpMode() ) )
  2028. {
  2029. ASSERT( mi.GetExtraMarkCallback() != NULL );
  2030. mi.GetExtraMarkCallback()( this, &mi );
  2031. CClientDC dc( this );
  2032. _DoPaint( dc );
  2033. return true;
  2034. } // if( mi.IsExtraMark() ...
  2035. if( mi.IsPopup() )
  2036. {
  2037. _ItemFocusSet( m_nCurIndex, TRUE, TRUE );
  2038. return true;
  2039. }
  2040. if( mi.IsExecutableCmdID() )
  2041. {
  2042. if( !( mi.GetCmdDeliverCb() != NULL
  2043. && mi.GetCmdDeliverCb()( this, &mi )
  2044. )
  2045. )
  2046. _EndSequenceEx( mi );
  2047. return true;
  2048. } // if( mi.IsExecutableCmdID() )
  2049. } // if only 1 with this char
  2050. if( m_nCurIndex != nNextIdx
  2051. && nNextIdx >= 0
  2052. )
  2053. {
  2054. HWND hWndOwn = m_hWnd;
  2055. _ItemFocusSet( nNextIdx, TRUE, TRUE );
  2056. if( ! ::IsWindow( hWndOwn ) )
  2057. return true;
  2058. if( ItemFindByAccessChar(
  2059. (TCHAR)nMapped,
  2060. nNextIdx
  2061. ) < 0
  2062. )
  2063. { // if only 1 with this char
  2064. MENUITEMDATA & mi =
  2065. ItemGetInfo( nNextIdx );
  2066. if( mi.IsInplaceEdit() && (!mi.IsPopup()) )
  2067. {
  2068. CWnd * pWndInplace = mi.GetInplaceEditPtr();
  2069. if( pWndInplace != NULL )
  2070. {
  2071. ASSERT_VALID( pWndInplace );
  2072. ASSERT( pWndInplace->GetSafeHwnd() != NULL && (::IsWindow(pWndInplace->GetSafeHwnd())) );
  2073. if( mi.IsAllowInplaceEditActivation() )
  2074. {
  2075. if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 )
  2076. {
  2077. CRect rcInplaceEdit;
  2078. _GetItemRect( nNextIdx, rcInplaceEdit );
  2079. rcInplaceEdit =
  2080. mi.AdjustInplaceEditRect(
  2081. rcInplaceEdit,
  2082. OnQueryLayoutRTL()
  2083. );
  2084. pWndInplace->SetWindowPos(
  2085. NULL,
  2086. rcInplaceEdit.left, rcInplaceEdit.top,
  2087. rcInplaceEdit.Width(), rcInplaceEdit.Height(),
  2088. SWP_NOZORDER|SWP_NOOWNERZORDER
  2089. |SWP_NOACTIVATE|SWP_SHOWWINDOW
  2090. );
  2091. } // if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 )
  2092. pWndInplace->SetFocus();
  2093. } // if( mi.IsAllowInplaceEditActivation() )
  2094. } // if( pWndInplace != NULL )
  2095. return true;
  2096. } // if( mi.IsInplaceEdit() && (!mi.IsPopup()) )
  2097. if( mi.IsExtraMark() && (! _FindHelpMode() ) )
  2098. {
  2099. ASSERT( mi.GetExtraMarkCallback() != NULL );
  2100. mi.GetExtraMarkCallback()( this, &mi );
  2101. CClientDC dc( this );
  2102. _DoPaint( dc );
  2103. return true;
  2104. } // if( mi.IsExtraMark() ...
  2105. if( mi.IsExecutableCmdID()
  2106. //&& ( ! mi.IsPopup() )
  2107. && _GetCapture() == this
  2108. )
  2109. {
  2110. if( !( mi.GetCmdDeliverCb() != NULL
  2111. && mi.GetCmdDeliverCb()( this, &mi )
  2112. )
  2113. )
  2114. {
  2115. _CancelingSet();
  2116. _EndSequenceEx( mi );
  2117. }
  2118. return true;
  2119. } // if( mi.IsExecutableCmdID() )
  2120. } // if only 1 with this char
  2121. return true;
  2122. }
  2123. } // BLOCK: try analyze quick char access
  2124. { // BLOCK: help key processing
  2125. const ACCEL * pAccel = _GetTranslatedContextHelpAccel();
  2126. if( m_nCurIndex >= 0
  2127. && pAccel != NULL
  2128. && nChar == WPARAM(pAccel->key)
  2129. && (pAccel->fVirt&(FSHIFT|FCONTROL|FALT)) ==
  2130. ( 0
  2131. | ( bShift ? (FSHIFT) : 0 )
  2132. | ( bCtrl ? (FCONTROL) : 0 )
  2133. | ( bAlt ? (FALT) : 0 )
  2134. )
  2135. )
  2136. {
  2137. MENUITEMDATA & mi = ItemGetInfo( m_nCurIndex );
  2138. if( ( ! mi.IsPopup() ) && ( ! mi.IsExtraMark() ) )
  2139. {
  2140. UINT nHitTestCmdID = mi.GetCmdID();
  2141. bNoEat = false;
  2142. _EndSequence();
  2143. ::AfxGetApp()->WinHelp( nHitTestCmdID, HELP_CONTEXT );
  2144. return true;
  2145. } // if( ( ! mi.IsPopup() ) && ( ! mi.IsExtraMark() ) )
  2146. } // if( m_nCurIndex >= 0 ...
  2147. } // BLOCK: help key processing
  2148. } // switch( nChar )
  2149. if( nit != __NI_NOTHING )
  2150. {
  2151. int nItemIndex = _GetNextItem(nit);
  2152. if( m_items_all.GetSize() > 0
  2153. && nItemIndex >= 0
  2154. && nItemIndex != m_nCurIndex
  2155. )
  2156. {
  2157. HWND hWndOwn = m_hWnd;
  2158. _ItemFocusSet(
  2159. nItemIndex,
  2160. FALSE,
  2161. TRUE
  2162. );
  2163. if( ! ::IsWindow( hWndOwn ) )
  2164. return true;
  2165. return true; // false;
  2166. }
  2167. if( nItemIndex == IDX_EXPAND )
  2168. {
  2169. ASSERT( m_bExpandAvailable );
  2170. ASSERT( !m_bExpandWasPressed );
  2171. int nItemIndex = m_nCurIndex;
  2172. HWND hWndOwn = m_hWnd;
  2173. _DoExpand();
  2174. if( ! ::IsWindow( hWndOwn ) )
  2175. return true;
  2176. if( nItemIndex >= 0 )
  2177. {
  2178. HWND hWndOwn = m_hWnd;
  2179. _ItemFocusSet(
  2180. nItemIndex,
  2181. FALSE,
  2182. //m_bAnimFinished
  2183. ( GetSite().GetAnimated() == NULL )
  2184. ? TRUE : FALSE
  2185. );
  2186. if( ! ::IsWindow( hWndOwn ) )
  2187. return true;
  2188. int i = _GetNextItem(__NI_NEXT);
  2189. _ItemFocusSet(
  2190. (i>0) ? i : nItemIndex,
  2191. FALSE,
  2192. //m_bAnimFinished
  2193. ( GetSite().GetAnimated() == NULL )
  2194. ? TRUE : FALSE
  2195. );
  2196. if( ! ::IsWindow( hWndOwn ) )
  2197. return true;
  2198. }
  2199. return true;
  2200. }
  2201. } // if( nit != __NI_NOTHING )
  2202. return false;
  2203. }
  2204. INT CExtPopupMenuWnd::ItemFindByText(
  2205. __EXT_MFC_SAFE_LPCTSTR sText,
  2206. INT nStartIdx, // = -1
  2207. BOOL bRestartAt0 // = TRUE
  2208. ) const
  2209. {
  2210. bRestartAt0;
  2211. ASSERT_VALID( this );
  2212. if( sText == NULL || sText[0] == _T('') )
  2213. {
  2214. ASSERT( FALSE );
  2215. return -1;
  2216. }
  2217. int nCount = (int)m_items_all.GetSize(); //ItemGetCount();
  2218. int nIdx = (nStartIdx >= 0) ? (nStartIdx + 1) : 0;
  2219. for( ; nIdx < nCount; nIdx++ )
  2220. {
  2221. const MENUITEMDATA & mi = ItemGetInfo(nIdx);
  2222. // if( !mi.AccelCharIsSet() )
  2223. // continue;
  2224. // if( !mi.IsDisplayed() )
  2225. // continue;
  2226. // if( !mi.IsEnabled() )
  2227. // continue;
  2228. if( _tcscmp( sText, mi.GetText() ) == 0 )
  2229. {
  2230. if( nStartIdx != nIdx )
  2231. return nIdx;
  2232. }
  2233. } // for( nIdx = nStartIdx; nIdx < nCount; nIdx++ )
  2234. if( nStartIdx == 0 )
  2235. return -1;
  2236. for( nIdx = 0; nIdx<nStartIdx; nIdx++ )
  2237. {
  2238. const MENUITEMDATA & mi = ItemGetInfo(nIdx);
  2239. // if( !mi.AccelCharIsSet() )
  2240. // continue;
  2241. // if( !mi.IsDisplayed() )
  2242. // continue;
  2243. // if( !mi.IsEnabled() )
  2244. // continue;
  2245. if( _tcscmp( sText, mi.GetText() ) == 0 )
  2246. {
  2247. if( nStartIdx != nIdx )
  2248. return nIdx;
  2249. }
  2250. } // for( nIdx = 0; nIdx<nStartIdx; nIdx++ )
  2251. return -1;
  2252. }
  2253. INT CExtPopupMenuWnd::ItemFindByAccessChar(
  2254. __EXT_MFC_SAFE_TCHAR chrAccess,
  2255. INT nStartIdx, // = -1
  2256. BOOL bRestartAt0, // = TRUE
  2257. BOOL bSearchDisplayedOnly // = TRUE
  2258. ) const
  2259. {
  2260. ASSERT_VALID( this );
  2261. if( chrAccess == _T('') )
  2262. return -1;
  2263. TCHAR szChar[2] = { chrAccess, _T('') };
  2264. ::CharUpper( szChar );
  2265. int cAccelSearch = szChar[0];
  2266. if( cAccelSearch == _T('') )
  2267. return -1;
  2268. int nCount = (int)m_items_all.GetSize(); //ItemGetCount();
  2269. int nIdx = ( nStartIdx >= 0 ) ? ( nStartIdx + 1 ) : 0;
  2270. if( nIdx >= nCount && bRestartAt0 )
  2271. nIdx = 0;
  2272. for( ; nIdx < nCount; nIdx++ )
  2273. {
  2274. const MENUITEMDATA & mi = ItemGetInfo(nIdx);
  2275. if( ! mi.AccelCharIsSet() )
  2276. continue;
  2277. if( ! mi.IsDisplayed() )
  2278. {
  2279. if( bSearchDisplayedOnly )
  2280. continue;
  2281. }
  2282. if( ! mi.IsEnabled() )
  2283. continue;
  2284. TCHAR cAccel = mi.AccelCharGet();
  2285. if( cAccelSearch == cAccel )
  2286. {
  2287. if( nStartIdx != nIdx )
  2288. return nIdx;
  2289. }
  2290. } // for( nIdx = nStartIdx; nIdx < nCount; nIdx++ )
  2291. if( nStartIdx == 0 )
  2292. return -1;
  2293. for( nIdx = 0; nIdx<nStartIdx; nIdx++ )
  2294. {
  2295. const MENUITEMDATA & mi = ItemGetInfo(nIdx);
  2296. if( ! mi.AccelCharIsSet() )
  2297. continue;
  2298. if( ! mi.IsDisplayed() )
  2299. {
  2300. if( bSearchDisplayedOnly )
  2301. continue;
  2302. }
  2303. if( ! mi.IsEnabled() )
  2304. continue;
  2305. TCHAR cAccel = mi.AccelCharGet();
  2306. if( cAccelSearch == cAccel )
  2307. {
  2308. if( nStartIdx != nIdx )
  2309. return nIdx;
  2310. }
  2311. } // for( nIdx = 0; nIdx<nStartIdx; nIdx++ )
  2312. return -1;
  2313. }
  2314. BOOL CExtPopupMenuWnd::IsCmdKeyActivation(
  2315. LPARAM lParam // = 0
  2316. )
  2317. {
  2318. if( (lParam & (1<<29)) != 0 ) // ALT pressed?
  2319. return TRUE;
  2320. static int nTestKeys[] = {
  2321. VK_MENU,VK_RMENU,VK_LMENU,
  2322. VK_CONTROL,VK_RCONTROL,VK_LCONTROL,
  2323. VK_SHIFT,VK_RSHIFT,VK_LSHIFT
  2324. };
  2325. for( int i=0; i<sizeof(nTestKeys)/sizeof(int); i++ )
  2326. {
  2327. if( IsKeyPressed(nTestKeys[i]) )
  2328. {
  2329. // if( nTestKeys[i] == VK_CONTROL
  2330. // || nTestKeys[i] == VK_RCONTROL
  2331. // || nTestKeys[i] == VK_LCONTROL
  2332. // )
  2333. // {
  2334. // if( IsKeyPressed(VK_DOWN) )
  2335. // return FALSE;
  2336. // }
  2337. return TRUE;
  2338. }
  2339. }
  2340. return FALSE;
  2341. }
  2342. INT CExtPopupMenuWnd::ItemGetCount() const
  2343. {
  2344. ASSERT_VALID( this );
  2345. INT nCountOfItems = INT(m_items_all.GetSize());
  2346. return nCountOfItems;
  2347. }
  2348. INT CExtPopupMenuWnd::ItemFindPosForCmdID(
  2349. UINT nCmdID,
  2350. INT nPosStart // = -1
  2351. ) const
  2352. {
  2353. ASSERT_VALID( this );
  2354. INT nPos = (nPosStart < 0) ? 0 : nPosStart + 1;
  2355. INT nCount = ItemGetCount();
  2356. for( ; nPos < nCount; nPos++ )
  2357. {
  2358. UINT nCmdID2 = ItemGetCmdID( nPos );
  2359. if( nCmdID == nCmdID2 )
  2360. return nPos;
  2361. }
  2362. return -1; // not found
  2363. }
  2364. UINT CExtPopupMenuWnd::ItemGetCmdID( // menu_item_type_t values can be returned
  2365. INT nPos
  2366. ) const
  2367. {
  2368. ASSERT_VALID( this );
  2369. ASSERT( GetTrackingMenu() != this );
  2370. INT nCountOfItems = ItemGetCount();
  2371. if( nPos < 0 || nPos >= nCountOfItems )
  2372. {
  2373. ASSERT( FALSE );
  2374. return TYPE_SEPARATOR;
  2375. }
  2376. const MENUITEMDATA & mi = ItemGetInfo(nPos);
  2377. UINT nCmdID = mi.GetCmdID();
  2378. return nCmdID;
  2379. }
  2380. bool CExtPopupMenuWnd::ItemSetPopupIcon(
  2381. INT nPos,
  2382. HICON hIcon // = NULL // no icon by default
  2383. )
  2384. {
  2385. ASSERT_VALID( this );
  2386. CExtCmdIcon _icon;
  2387. if( hIcon != NULL )
  2388. _icon.AssignFromHICON( hIcon, false );
  2389. return ItemSetPopupIcon( nPos, _icon );
  2390. }
  2391. bool CExtPopupMenuWnd::ItemSetPopupIcon(
  2392. INT nPos,
  2393. const CExtCmdIcon & _icon
  2394. )
  2395. {
  2396. ASSERT_VALID( this );
  2397. ASSERT( GetTrackingMenu() != this );
  2398. INT nCountOfItems = ItemGetCount();
  2399. if( nPos < 0 || nPos >= nCountOfItems )
  2400. {
  2401. ASSERT( FALSE );
  2402. return false;
  2403. }
  2404. MENUITEMDATA & mi = ItemGetInfo( nPos );
  2405. return mi.SetPopupIcon( _icon );
  2406. }
  2407. bool CExtPopupMenuWnd::ItemSetPopupText(
  2408. INT nPos,
  2409. __EXT_MFC_SAFE_LPCTSTR sText // NULL if empty
  2410. )
  2411. {
  2412. ASSERT_VALID( this );
  2413. ASSERT( GetTrackingMenu() != this );
  2414. INT nCountOfItems = ItemGetCount();
  2415. if( nPos < 0 || nPos >= nCountOfItems )
  2416. {
  2417. ASSERT( FALSE );
  2418. return false;
  2419. }
  2420. MENUITEMDATA & mi = ItemGetInfo(nPos);
  2421. if( !mi.SetPopupText( sText ) )
  2422. return false;
  2423. mi.MeasureItem( NULL );
  2424. return true;
  2425. }
  2426. bool CExtPopupMenuWnd::ItemSetPopupAccelText(
  2427. INT nPos,
  2428. __EXT_MFC_SAFE_LPCTSTR sText // NULL if empty
  2429. )
  2430. {
  2431. ASSERT_VALID( this );
  2432. ASSERT( GetTrackingMenu() != this );
  2433. INT nCountOfItems = ItemGetCount();
  2434. if( nPos < 0 || nPos >= nCountOfItems )
  2435. {
  2436. ASSERT( FALSE );
  2437. return false;
  2438. }
  2439. MENUITEMDATA & mi = ItemGetInfo(nPos);
  2440. bool bRetVal = mi.SetPopupAccelText( sText );
  2441. if( bRetVal )
  2442. _SyncItems();
  2443. return bRetVal;
  2444. }
  2445. CExtCmdIcon & CExtPopupMenuWnd::ItemGetIcon( INT nPos )
  2446. {
  2447. ASSERT_VALID( this );
  2448. ASSERT( GetTrackingMenu() != this );
  2449. INT nCountOfItems = ItemGetCount();
  2450. if( nPos < 0 || nPos >= nCountOfItems )
  2451. {
  2452. ASSERT( FALSE );
  2453. static CExtCmdIcon g_EmptyIcon;
  2454. return g_EmptyIcon;
  2455. }
  2456. const MENUITEMDATA & mi = ItemGetInfo(nPos);
  2457. CExtCmdIcon & _icon = ((MENUITEMDATA &)mi).GetIcon();
  2458. return _icon;
  2459. }
  2460. const CExtCmdIcon & CExtPopupMenuWnd::ItemGetIcon( INT nPos ) const
  2461. {
  2462. ASSERT_VALID( this );
  2463. return
  2464. ( const_cast < CExtPopupMenuWnd * > ( this ) )
  2465. -> ItemGetIcon( nPos );
  2466. }
  2467. CExtPopupMenuWnd::MENUITEMDATA & CExtPopupMenuWnd::ItemGetInfo( INT nPos )
  2468. {
  2469. ASSERT_VALID( this );
  2470. INT nCountOfItems = ItemGetCount();
  2471. if( nPos < 0 || nPos >= nCountOfItems )
  2472. {
  2473. ASSERT( FALSE );
  2474. AfxThrowNotSupportedException();
  2475. }
  2476. return _GetItemRef( nPos );
  2477. }
  2478. const CExtPopupMenuWnd::MENUITEMDATA & CExtPopupMenuWnd::ItemGetInfo( INT nPos ) const
  2479. {
  2480. ASSERT_VALID( this );
  2481. INT nCountOfItems = ItemGetCount();
  2482. if( nPos < 0 || nPos >= nCountOfItems )
  2483. {
  2484. ASSERT( FALSE );
  2485. AfxThrowNotSupportedException();
  2486. }
  2487. return _GetItemRef( nPos );
  2488. }
  2489. CExtSafeString CExtPopupMenuWnd::ItemGetText( INT nPos ) const
  2490. {
  2491. ASSERT_VALID( this );
  2492. ASSERT( GetTrackingMenu() != this );
  2493. INT nCountOfItems = ItemGetCount();
  2494. if( nPos < 0 || nPos >= nCountOfItems )
  2495. {
  2496. ASSERT( FALSE );
  2497. return CExtSafeString( _T("") );
  2498. }
  2499. const MENUITEMDATA & mi = ItemGetInfo( nPos );
  2500. return CExtSafeString( mi.GetText() );
  2501. }
  2502. CExtSafeString CExtPopupMenuWnd::ItemGetAccelText( INT nPos ) const
  2503. {
  2504. ASSERT_VALID( this );
  2505. ASSERT( GetTrackingMenu() != this );
  2506. INT nCountOfItems = ItemGetCount();
  2507. if( nPos < 0 || nPos >= nCountOfItems )
  2508. {
  2509. ASSERT( FALSE );
  2510. return CExtSafeString( _T("") );
  2511. }
  2512. const MENUITEMDATA & mi = ItemGetInfo(nPos);
  2513. return CExtSafeString( mi.GetAccelText() );
  2514. }
  2515. bool CExtPopupMenuWnd::ItemIsDisplayed(
  2516. INT nPos
  2517. ) const
  2518. {
  2519. const MENUITEMDATA & mi = ItemGetInfo( nPos );
  2520. return mi.IsDisplayed();
  2521. }
  2522. void CExtPopupMenuWnd::ItemSetDisplayed(
  2523. INT nPos,
  2524. bool bForceDisplayed // = true
  2525. )
  2526. {
  2527. MENUITEMDATA & mi = ItemGetInfo( nPos );
  2528. mi.SetForceDisplayed( bForceDisplayed );
  2529. _SyncItems();
  2530. }
  2531. CExtPopupMenuWnd * CExtPopupMenuWnd::ItemGetPopup(
  2532. INT nPos
  2533. )
  2534. {
  2535. ASSERT_VALID( this );
  2536. ASSERT( GetTrackingMenu() != this );
  2537. const CExtPopupMenuWnd * pChild =
  2538. ( (const CExtPopupMenuWnd *) this) ->
  2539. ItemGetPopup( nPos );
  2540. if( pChild == NULL )
  2541. return NULL;
  2542. return
  2543. const_cast
  2544. < CExtPopupMenuWnd * >
  2545. (pChild);
  2546. }
  2547. CExtPopupMenuWnd::TEAROFFNOTIFICATON *
  2548. CExtPopupMenuWnd::TEAROFFNOTIFICATON::
  2549. g_pCurrentTEAROFFNOTIFICATON = NULL;
  2550. CExtPopupMenuWnd::TEAROFFNOTIFICATON::
  2551. TEAROFFNOTIFICATON(
  2552. CExtPopupMenuWnd * pPopup,
  2553. const POINT & ptScreenStartPos
  2554. )
  2555. : m_hWndTearOff( NULL )
  2556. , m_hWndHelperPopup( pPopup->GetSafeHwnd() )
  2557. , m_hWndHelperFloat( NULL )
  2558. , m_bHelperForceFloatInvisible( false )
  2559. , m_pPopup( pPopup )
  2560. , m_pHelperTearOffBar( NULL )
  2561. , m_ptScreenStartPos( ptScreenStartPos )
  2562. , m_sizeTearOffArea( 5, 5 )
  2563. , m_rcHelperScreenStartArea( ptScreenStartPos, ptScreenStartPos )
  2564. , m_rcCustomFloatPos( 0, 0, 0, 0 )
  2565. , m_bHelperMenuAreasUpdated( false )
  2566. , m_eTONT( CExtPopupMenuWnd::__ETONT_BEGIN )
  2567. , m_bCanceled( false )
  2568. , m_bFinished( false )
  2569. {
  2570. m_rcHelperScreenStartArea.InflateRect( m_sizeTearOffArea );
  2571. ASSERT_VALID( m_pPopup );
  2572. ASSERT( m_hWndHelperPopup != NULL && ::IsWindow(m_hWndHelperPopup) );
  2573. }
  2574. CExtPopupMenuWnd::TEAROFFNOTIFICATON::
  2575. ~TEAROFFNOTIFICATON()
  2576. {
  2577. CExtHookSink::RemoveAllWndHooks();
  2578. }
  2579. bool CExtPopupMenuWnd::TEAROFFNOTIFICATON::
  2580. Notify()
  2581. {
  2582. HWND hWndNotifyTarget = m_pPopup->GetCmdReceiverHWND();
  2583. if( hWndNotifyTarget == NULL || (! ::IsWindow(hWndNotifyTarget) ) )
  2584. return false;
  2585. m_eTONT = CExtPopupMenuWnd::__ETONT_BEGIN;
  2586. ::SendMessage(
  2587. hWndNotifyTarget,
  2588. CExtPopupMenuWnd::g_nMsgTearOff,
  2589. *this,
  2590. 0L
  2591. );
  2592. if( m_hWndTearOff == NULL
  2593. || (! ::IsWindow(m_hWndTearOff) )
  2594. || m_bCanceled
  2595. )
  2596. return false;
  2597. m_pHelperTearOffBar = NULL;
  2598. CWnd * pWnd = CWnd::FromHandlePermanent( m_hWndTearOff );
  2599. if( pWnd != NULL )
  2600. {
  2601. m_pHelperTearOffBar =
  2602. DYNAMIC_DOWNCAST( CExtControlBar, pWnd );
  2603. if( m_pHelperTearOffBar != NULL )
  2604. {
  2605. if( m_pHelperTearOffBar->m_pDockSite == NULL )
  2606. {
  2607. ASSERT( FALSE );
  2608. m_pHelperTearOffBar = NULL;
  2609. }
  2610. }
  2611. }
  2612. return DoDefaultTearOff();
  2613. }
  2614. bool CExtPopupMenuWnd::TEAROFFNOTIFICATON::
  2615. DoDefaultTearOff()
  2616. {
  2617. g_pCurrentTEAROFFNOTIFICATON = this;
  2618. m_eTONT = CExtPopupMenuWnd::__ETONT_UPDATE;
  2619. m_bHelperForceFloatInvisible = false;
  2620. if( m_hWndHelperFloat == NULL )
  2621. {
  2622. if( m_pHelperTearOffBar != NULL )
  2623. {
  2624. if( m_pHelperTearOffBar->IsFloating() )
  2625. m_hWndHelperFloat =
  2626. m_pHelperTearOffBar->
  2627. GetParentFrame()->
  2628. GetSafeHwnd();
  2629. } // if( m_pHelperTearOffBar != NULL )
  2630. else
  2631. m_hWndHelperFloat = m_hWndTearOff;
  2632. } // if( m_hWndHelperFloat == NULL )
  2633. if( m_hWndHelperFloat != NULL )
  2634. {
  2635. ASSERT( m_hWndHelperFloat != NULL && ::IsWindow(m_hWndHelperFloat) );
  2636. CExtHookSink::SetupHookWndSink( m_hWndHelperFloat );
  2637. } // if( m_hWndHelperFloat != NULL )
  2638. for( ; !( m_bFinished || m_bCanceled); )
  2639. {
  2640. if( ! ::IsWindow(m_hWndHelperPopup) )
  2641. break;
  2642. if( ! ::IsWindow(m_hWndTearOff) )
  2643. {
  2644. m_bFinished = false;
  2645. m_bCanceled = true;
  2646. break;
  2647. }
  2648. CExtPopupMenuWnd::PassMsgLoop( false );
  2649. DoStep();
  2650. CExtPaintManager::stat_PassPaintMessages();
  2651. } // for( ; !( m_bFinished || m_bCanceled); )
  2652. ::ReleaseCapture();
  2653. CExtHookSink::RemoveAllWndHooks();
  2654. if( ::IsWindow(m_hWndHelperPopup) )
  2655. {
  2656. ASSERT_VALID( m_pPopup );
  2657. HWND hWndNotifyTarget = m_pPopup->GetCmdReceiverHWND();
  2658. if( hWndNotifyTarget != NULL && ::IsWindow(hWndNotifyTarget) )
  2659. {
  2660. m_eTONT = CExtPopupMenuWnd::__ETONT_FINISH;
  2661. ::SendMessage(
  2662. hWndNotifyTarget,
  2663. CExtPopupMenuWnd::g_nMsgTearOff,
  2664. *this,
  2665. 0L
  2666. );
  2667. } // if( hWndNotifyTarget != NULL && ::IsWindow(hWndNotifyTarget) )
  2668. if( ::IsWindow(m_hWndHelperPopup) )
  2669. {
  2670. ASSERT_VALID( m_pPopup );
  2671. if( (m_pPopup->GetStyle()&WS_VISIBLE) == 0 )
  2672. {
  2673. CExtToolControlBar::_CloseCustomMenusAll();
  2674. CExtPopupMenuWnd::CancelMenuTracking();
  2675. if( CExtToolControlBar::g_bMenuTracking )
  2676. CExtToolControlBar::_CloseTrackingMenus();
  2677. } // if( (m_pPopup->GetStyle()&WS_VISIBLE) == 0 )
  2678. } // if( ::IsWindow(m_hWndHelperPopup) )
  2679. } // if( ::IsWindow(m_hWndHelperPopup) )
  2680. if( LPVOID(g_pCurrentTEAROFFNOTIFICATON) == LPVOID(this) )
  2681. g_pCurrentTEAROFFNOTIFICATON = NULL;
  2682. return m_bFinished;
  2683. }
  2684. void CExtPopupMenuWnd::TEAROFFNOTIFICATON::DoStep(
  2685. bool bFinalStep // = false
  2686. )
  2687. {
  2688. bFinalStep;
  2689. if( m_bFinished )
  2690. return;
  2691. if( (! ::IsWindow(m_hWndTearOff) )
  2692. || (! ::IsWindow(m_hWndHelperPopup) )
  2693. || ( m_pPopup == NULL )
  2694. || ( CWnd::FromHandlePermanent(m_hWndHelperPopup) != m_pPopup )
  2695. )
  2696. return;
  2697. ASSERT_VALID( m_pPopup );
  2698. HWND hWndNotifyTarget = m_pPopup->GetCmdReceiverHWND();
  2699. ASSERT( hWndNotifyTarget != NULL && ::IsWindow(hWndNotifyTarget) );
  2700. m_eTONT = CExtPopupMenuWnd::__ETONT_UPDATE;
  2701. ::SendMessage(
  2702. hWndNotifyTarget,
  2703. CExtPopupMenuWnd::g_nMsgTearOff,
  2704. *this,
  2705. 0L
  2706. );
  2707. if( m_pHelperTearOffBar != NULL
  2708. && m_pHelperTearOffBar->GetSafeHwnd() != NULL
  2709. && m_pHelperTearOffBar->m_pDockSite->GetSafeHwnd() != NULL
  2710. )
  2711. {
  2712. ASSERT_VALID( m_pHelperTearOffBar );
  2713. ASSERT( m_pHelperTearOffBar->GetSafeHwnd() == m_hWndTearOff );
  2714. ASSERT_VALID( m_pHelperTearOffBar->m_pDockSite );
  2715. CPoint ptCursorScreen;
  2716. if( ! ::GetCursorPos( &ptCursorScreen ) )
  2717. {
  2718. m_bCanceled = true;
  2719. return;
  2720. }
  2721. if( PtInTearOffArea(ptCursorScreen) )
  2722. {
  2723. if( (m_pPopup->GetStyle()&WS_VISIBLE) == 0 )
  2724. {
  2725. if( m_pHelperTearOffBar->IsVisible() )
  2726. m_pHelperTearOffBar->m_pDockSite->
  2727. ShowControlBar( m_pHelperTearOffBar, FALSE, FALSE );
  2728. m_bHelperForceFloatInvisible = true;
  2729. CExtPaintManager::stat_PassPaintMessages();
  2730. m_pPopup->SetWindowPos(
  2731. NULL, 0, 0, 0, 0,
  2732. SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOREDRAW
  2733. |SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE
  2734. // |SWP_NOSENDCHANGING
  2735. );
  2736. CExtPopupMenuWnd * pPopup = m_pPopup->GetParentMenuWnd();
  2737. for( int iNL = 0; pPopup != NULL; pPopup = pPopup->GetParentMenuWnd(), iNL++ )
  2738. {
  2739. pPopup->m_ShadowCMBA.PostReShadow();
  2740. pPopup->m_ShadowMain.PostReShadow();
  2741. CClientDC dc( pPopup );
  2742. pPopup->_DoPaint( dc );
  2743. }
  2744. CClientDC dc( m_pPopup );
  2745. m_pPopup->_DoPaint( dc );
  2746. m_bHelperForceFloatInvisible = false;
  2747. } // if( (m_pPopup->GetStyle()&WS_VISIBLE) == 0 )
  2748. if( m_pPopup->m_ctrlShadow.GetSafeHwnd() != NULL
  2749. && (m_pPopup->m_ctrlShadow.GetStyle()&WS_VISIBLE) == 0
  2750. )
  2751. m_pPopup->m_ctrlShadow.ShowWindow( SW_SHOWNA );
  2752. } // if( PtInTearOffArea(ptCursorScreen) )
  2753. else
  2754. {
  2755. bool bDoRecreateShadow = false;
  2756. if( ! m_bHelperMenuAreasUpdated )
  2757. {
  2758. m_bHelperMenuAreasUpdated = true;
  2759. if( m_pHelperTearOffBar->IsVisible() )
  2760. {
  2761. m_pHelperTearOffBar->m_pDockSite->
  2762. ShowControlBar( m_pHelperTearOffBar, FALSE, FALSE );
  2763. CExtPaintManager::stat_PassPaintMessages();
  2764. bDoRecreateShadow = true;
  2765. if( m_pHelperTearOffBar->IsFloating() )
  2766. {
  2767. CRect rcFloatingArea;
  2768. m_pHelperTearOffBar->GetParentFrame()->
  2769. GetWindowRect( &rcFloatingArea );
  2770. if( ! m_pPopup->_IsFloatingAreaInstersectsWithMenu(
  2771. rcFloatingArea
  2772. )
  2773. )
  2774. bDoRecreateShadow = false;
  2775. } // if( m_pHelperTearOffBar->IsFloating() )
  2776. } // if( m_pHelperTearOffBar->IsVisible() )
  2777. } // if( ! m_bHelperMenuAreasUpdated )
  2778. #if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
  2779. if( (! m_pHelperTearOffBar->IsFixedDockStyle())
  2780. && ( m_pHelperTearOffBar->AutoHideModeGet() )
  2781. )
  2782. {
  2783. m_pHelperTearOffBar->AutoHideModeSet( false, false, true, true );
  2784. bDoRecreateShadow = true;
  2785. }
  2786. #endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
  2787. if( bDoRecreateShadow )
  2788. {
  2789. CExtPaintManager::stat_PassPaintMessages();
  2790. m_pPopup->_DoReCreateShadows();
  2791. }
  2792. { // block
  2793. CExtPopupMenuWnd * pPopup = m_pPopup;
  2794. for( ; pPopup != NULL; pPopup = pPopup->GetParentMenuWnd() )
  2795. {
  2796. if( ( pPopup->GetStyle() & WS_VISIBLE ) != 0
  2797. && pPopup->m_ctrlShadow.GetSafeHwnd() != NULL
  2798. )
  2799. {
  2800. CExtPaintManager::stat_PassPaintMessages();
  2801. pPopup->m_ctrlShadow.SetWindowPos(
  2802. pPopup, 0, 0, 0, 0,
  2803. SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_SHOWWINDOW
  2804. );
  2805. }
  2806. }
  2807. } // block
  2808. if( (m_pPopup->GetStyle()&WS_VISIBLE) != 0 )
  2809. m_pPopup->ShowWindow( SW_HIDE );
  2810. if( m_pPopup->m_ctrlShadow.GetSafeHwnd() != NULL
  2811. && (m_pPopup->m_ctrlShadow.GetStyle()&WS_VISIBLE) != 0
  2812. )
  2813. m_pPopup->m_ctrlShadow.ShowWindow( SW_HIDE );
  2814. CPoint ptFloat(
  2815. ptCursorScreen.x - 30,
  2816. ptCursorScreen.y - 10
  2817. );
  2818. CRect rcParentFrame;
  2819. m_pHelperTearOffBar->GetParentFrame()->GetWindowRect( &rcParentFrame );
  2820. if( rcParentFrame.TopLeft() != ptFloat )
  2821. {
  2822. CExtPaintManager::stat_PassPaintMessages();
  2823. m_pHelperTearOffBar->FloatControlBar(
  2824. ptFloat
  2825. );
  2826. }
  2827. if( m_hWndHelperFloat == NULL
  2828. && m_pHelperTearOffBar != NULL
  2829. && m_pHelperTearOffBar->IsFloating()
  2830. )
  2831. {
  2832. m_hWndHelperFloat =
  2833. m_pHelperTearOffBar->
  2834. GetParentFrame()->
  2835. GetSafeHwnd();
  2836. ASSERT(
  2837. m_hWndHelperFloat != NULL
  2838. && ::IsWindow( m_hWndHelperFloat )
  2839. );
  2840. CExtHookSink::SetupHookWndSink( m_hWndHelperFloat );
  2841. } // if( m_hWndHelperFloat == NULL )
  2842. if( ! m_pHelperTearOffBar->IsVisible() )
  2843. m_pHelperTearOffBar->m_pDockSite->
  2844. ShowControlBar( m_pHelperTearOffBar, TRUE, FALSE );
  2845. CRect rcTearOffBar;
  2846. m_pHelperTearOffBar->GetWindowRect( &rcTearOffBar );
  2847. CExtPopupMenuWnd * pPopup = m_pPopup;
  2848. for( int iNL = 0; pPopup != NULL; pPopup = pPopup->GetParentMenuWnd(), iNL++ )
  2849. {
  2850. if( (pPopup->GetStyle()&WS_VISIBLE) == 0 )
  2851. continue;
  2852. CRect rcPopup;
  2853. pPopup->GetWindowRect( &rcPopup );
  2854. CRect rcIntersecton;
  2855. if( ! rcIntersecton.IntersectRect(
  2856. &rcTearOffBar,
  2857. &rcPopup
  2858. )
  2859. )
  2860. continue;
  2861. CClientDC dc( pPopup );
  2862. pPopup->_DoPaint( dc );
  2863. }
  2864. } // else from if( PtInTearOffArea(ptCursorScreen) )
  2865. } // if( m_pHelperTearOffBar != NULL ...
  2866. else
  2867. {
  2868. m_bCanceled = true; // this mode not supported yet
  2869. return;
  2870. } // else from if( m_pHelperTearOffBar != NULL ...
  2871. if( ::GetCapture() != m_hWndTearOff )
  2872. ::SetCapture( m_hWndTearOff );
  2873. }
  2874. bool CExtPopupMenuWnd::_IsFloatingAreaInstersectsWithMenu(
  2875. const RECT & rcFloatingArea,
  2876. bool bAnalyzeParents // = true
  2877. ) const
  2878. {
  2879. ASSERT_VALID( this );
  2880. ASSERT( GetSafeHwnd() != NULL );
  2881. CRect rcWnd;
  2882. ::GetWindowRect( GetSafeHwnd(), &rcWnd );
  2883. CRect rcIntersecton;
  2884. if( rcIntersecton.IntersectRect(
  2885. &rcWnd,
  2886. &rcFloatingArea
  2887. )
  2888. )
  2889. return true;
  2890. if( ! bAnalyzeParents )
  2891. return false;
  2892. const CExtPopupMenuWnd * pParentMenuWnd = GetParentMenuWnd();
  2893. if( pParentMenuWnd == NULL )
  2894. return false;
  2895. return
  2896. pParentMenuWnd->_IsFloatingAreaInstersectsWithMenu(
  2897. rcFloatingArea,
  2898. true
  2899. );
  2900. }
  2901. bool CExtPopupMenuWnd::TEAROFFNOTIFICATON::
  2902. PtInTearOffArea( const POINT & ptScreen ) const
  2903. {
  2904. ASSERT( m_sizeTearOffArea.cx >= 0 && m_sizeTearOffArea.cy >= 0 );
  2905. bool bRetVal =
  2906. m_rcHelperScreenStartArea.PtInRect( ptScreen )
  2907. ? true : false;
  2908. if( bRetVal )
  2909. return true;
  2910. if( ! ::IsWindow( m_hWndHelperPopup ) )
  2911. return false;
  2912. ASSERT_VALID( m_pPopup );
  2913. CRect rcTearOff;
  2914. m_pPopup->_GetItemRect( CExtPopupMenuWnd::IDX_TEAROFF, rcTearOff, false );
  2915. m_pPopup->ClientToScreen( &rcTearOff );
  2916. rcTearOff.InflateRect( 0, 15 );
  2917. bRetVal =
  2918. rcTearOff.PtInRect( ptScreen )
  2919. ? true : false;
  2920. return bRetVal;
  2921. }
  2922. CExtPopupMenuWnd::TEAROFFNOTIFICATON::
  2923. operator WPARAM() const
  2924. {
  2925. return WPARAM( this );
  2926. }
  2927. CExtPopupMenuWnd::TEAROFFNOTIFICATON *
  2928. CExtPopupMenuWnd::TEAROFFNOTIFICATON::
  2929. FromWPARAM( WPARAM wParam )
  2930. {
  2931. TEAROFFNOTIFICATON * pTON =
  2932. reinterpret_cast < TEAROFFNOTIFICATON * > ( wParam );
  2933. ASSERT( pTON != NULL );
  2934. return pTON;
  2935. }
  2936. bool CExtPopupMenuWnd::TEAROFFNOTIFICATON::_OnMouseWheel(
  2937. WPARAM wParam,
  2938. LPARAM lParam
  2939. )
  2940. {
  2941. __PROF_UIS_MANAGE_STATE;
  2942. wParam;
  2943. lParam;
  2944. if( LPVOID(g_pCurrentTEAROFFNOTIFICATON) != LPVOID(this) )
  2945. return false;
  2946. return true;
  2947. }
  2948. bool CExtPopupMenuWnd::TEAROFFNOTIFICATON::_OnMouseMove(
  2949. UINT nFlags,
  2950. CPoint point
  2951. )
  2952. {
  2953. __PROF_UIS_MANAGE_STATE;
  2954. nFlags;
  2955. point;
  2956. if( LPVOID(g_pCurrentTEAROFFNOTIFICATON) != LPVOID(this) )
  2957. return false;
  2958. DoStep( true );
  2959. return true;
  2960. }
  2961. bool CExtPopupMenuWnd::TEAROFFNOTIFICATON::_OnMouseClick(
  2962. UINT nFlags,
  2963. CPoint point
  2964. )
  2965. {
  2966. __PROF_UIS_MANAGE_STATE;
  2967. nFlags;
  2968. point;
  2969. if( LPVOID(g_pCurrentTEAROFFNOTIFICATON) != LPVOID(this) )
  2970. return false;
  2971. switch( nFlags)
  2972. {
  2973. case WM_NCLBUTTONUP:
  2974. case WM_NCRBUTTONUP:
  2975. case WM_NCMBUTTONUP:
  2976. case WM_LBUTTONUP:
  2977. case WM_RBUTTONUP:
  2978. case WM_MBUTTONUP:
  2979. DoStep( true );
  2980. m_bFinished = true;
  2981. if( ::IsWindow( m_hWndHelperPopup ) )
  2982. ::PostMessage( m_hWndHelperPopup, WM_CANCELMODE, 0L, 0L );
  2983. break;
  2984. }
  2985. return true;
  2986. }
  2987. bool CExtPopupMenuWnd::TEAROFFNOTIFICATON::_OnKeyDown(
  2988. UINT nChar,
  2989. UINT nRepCnt,
  2990. UINT nFlags
  2991. )
  2992. {
  2993. __PROF_UIS_MANAGE_STATE;
  2994. nChar;
  2995. nRepCnt;
  2996. nFlags;
  2997. if( LPVOID(g_pCurrentTEAROFFNOTIFICATON) != LPVOID(this) )
  2998. return false;
  2999. DoStep( true );
  3000. m_bFinished = true;
  3001. if( ::IsWindow( m_hWndHelperPopup ) )
  3002. ::PostMessage( m_hWndHelperPopup, WM_CANCELMODE, 0L, 0L );
  3003. return true;
  3004. }
  3005. bool CExtPopupMenuWnd::TEAROFFNOTIFICATON::OnHookWndMsg(
  3006. LRESULT & lResult,
  3007. HWND hWndHooked,
  3008. UINT nMessage,
  3009. WPARAM & wParam,
  3010. LPARAM & lParam
  3011. )
  3012. {
  3013. __PROF_UIS_MANAGE_STATE;
  3014. if( m_hWndHelperFloat != NULL
  3015. && ::IsWindow( m_hWndHelperFloat )
  3016. && m_hWndHelperPopup != NULL
  3017. && ::IsWindow( m_hWndHelperPopup )
  3018. )
  3019. {
  3020. ASSERT_VALID( m_pPopup );
  3021. bool bUpdateShadows = false;
  3022. m_bHelperForceFloatInvisible = false;
  3023. switch( nMessage )
  3024. {
  3025. case WM_SHOWWINDOW:
  3026. bUpdateShadows = true;
  3027. if( wParam == 0 )
  3028. m_bHelperForceFloatInvisible = true;
  3029. break;
  3030. case WM_SIZE:
  3031. case WM_WINDOWPOSCHANGED:
  3032. if( m_pHelperTearOffBar == NULL )
  3033. {
  3034. __EXT_MFC_LONG_PTR dwStyle = ::__EXT_MFC_GetWindowLong(m_hWndHelperFloat,GWL_STYLE);
  3035. bUpdateShadows = ( (dwStyle&WS_VISIBLE) != 0 ) ? true : false;
  3036. }
  3037. break;
  3038. default:
  3039. if( nMessage == CExtPopupMenuWnd::g_nMsgCustomFloatPos )
  3040. {
  3041. if( ((HWND)wParam) == m_hWndHelperFloat )
  3042. {
  3043. bUpdateShadows = true;
  3044. LPRECT pRectCustomFloatPos = (LPRECT)lParam;
  3045. ASSERT( pRectCustomFloatPos != NULL );
  3046. m_rcCustomFloatPos = (*pRectCustomFloatPos);
  3047. } // if( ((HWND)wParam) == m_hWndHelperFloat )
  3048. } // if( nMessage == CExtPopupMenuWnd::g_nMsgCustomFloatPos )
  3049. break;
  3050. } // switch( nMessage )
  3051. if( bUpdateShadows )
  3052. {
  3053. lResult =
  3054. CExtHookSink::OnHookWndMsg(
  3055. lResult,
  3056. hWndHooked,
  3057. nMessage,
  3058. wParam,
  3059. lParam
  3060. );
  3061. CExtPopupMenuWnd * pPopup = m_pPopup;
  3062. for( ; pPopup != NULL;
  3063. pPopup = pPopup->GetParentMenuWnd()
  3064. )
  3065. {
  3066. if( ! pPopup->_IsPopupWithShadows() )
  3067. continue;
  3068. pPopup->Invalidate();
  3069. }
  3070. m_rcCustomFloatPos.SetRectEmpty();
  3071. CExtPaintManager::stat_PassPaintMessages();
  3072. return true;
  3073. } // if( bUpdateShadows )
  3074. }
  3075. return 
  3076. CExtHookSink::OnHookWndMsg(
  3077. lResult,
  3078. hWndHooked,
  3079. nMessage,
  3080. wParam,
  3081. lParam
  3082. );
  3083. }
  3084. void CExtPopupMenuWnd::_DoReCreateShadows()
  3085. {
  3086. ASSERT( GetSafeHwnd() != NULL );
  3087. m_ShadowMain.Destroy();
  3088. m_ShadowCMBA.Destroy();
  3089. if( m_ctrlShadow.GetSafeHwnd() == NULL )
  3090. ShowWindow( SW_HIDE );
  3091. CExtPopupMenuWnd * pWndParentMenu = GetParentMenuWnd();
  3092. if( pWndParentMenu == NULL )
  3093. {
  3094. CWnd * pWndTLP = GetTopLevelParent();
  3095. if( pWndTLP != NULL )
  3096. pWndTLP->UpdateWindow();
  3097. CExtPaintManager::stat_PassPaintMessages();
  3098. }
  3099. else
  3100. {
  3101. ASSERT( pWndParentMenu->GetSafeHwnd() != NULL );
  3102. pWndParentMenu->_DoReCreateShadows();
  3103. }
  3104. SetWindowPos(
  3105. NULL, 0, 0, 0, 0,
  3106. SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOREDRAW
  3107. |SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE
  3108. // |SWP_NOSENDCHANGING
  3109. );
  3110. CClientDC dc( this );
  3111. _DoPaint( dc );
  3112. }
  3113. void CExtPopupMenuWnd::_DoTearOff()
  3114. {
  3115. ASSERT_VALID( this );
  3116. ASSERT( ! _FindCustomizeMode() );
  3117. POINT ptScreen = { 0, 0 };
  3118. if( ! ::GetCursorPos( &ptScreen ) )
  3119. return;
  3120. _CoolTipHide();
  3121. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  3122. _KeyTipsShow( false );
  3123. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  3124. TEAROFFNOTIFICATON _ton( this, ptScreen );
  3125. _ton.Notify();
  3126. }
  3127. void CExtPopupMenuWnd::_DoExpand()
  3128. {
  3129. ASSERT_VALID( this );
  3130. ASSERT( ! _FindCustomizeMode() );
  3131. HWND hWndOwn = m_hWnd;
  3132. _ItemFocusDelay();
  3133. if( ! ::IsWindow( hWndOwn ) )
  3134. return;
  3135. _CoolTipHide( false );
  3136. if( ! ::IsWindow( hWndOwn ) )
  3137. return;
  3138. if( ( GetSite().GetAnimated() != NULL )
  3139. || _CoolTipIsVisible()
  3140. )
  3141. return;
  3142. m_bHelperReCreateDynamicShadowAtTheEndOfNearestAnimation = false;
  3143. bool bDynamicShadowMode = false;
  3144. if( m_ctrlShadow.GetSafeHwnd() != NULL )
  3145. {
  3146. bDynamicShadowMode = true;
  3147. m_bHelperReCreateDynamicShadowAtTheEndOfNearestAnimation = true;
  3148. }
  3149. ASSERT( m_bExpandAvailable );
  3150. ASSERT( !m_bExpandWasPressed );
  3151. ASSERT( ::IsWindow(GetSafeHwnd()) );
  3152. ASSERT( ( GetSite().GetAnimated() == NULL ) );
  3153. m_bExpandWasPressed = true;
  3154. CSize m_sizeFullItems2 = m_sizeFullItems;
  3155. _SyncItems();
  3156. _RecalcLayoutImpl();
  3157. if( m_sizeFullItems != m_sizeFullItems2)
  3158. { // if size of all items was changed
  3159. //  ASSERT(
  3160. //  m_sizeFullItems.cx >= m_sizeFullItems2.cx
  3161. //  && m_sizeFullItems.cy >= m_sizeFullItems2.cy
  3162. //  );
  3163. CRect rcWndOld;
  3164. GetWindowRect( &rcWndOld );
  3165. VERIFY(
  3166. SetWindowRgn(
  3167. NULL,
  3168. FALSE
  3169. )
  3170. );
  3171. if( ! bDynamicShadowMode )
  3172. {
  3173. ShowWindow( SW_HIDE );
  3174. ASSERT( !IsWindowVisible() );
  3175. } // if( ! bDynamicShadowMode )
  3176. if( !rcWndOld.IsRectEmpty() )
  3177. {
  3178. CWnd * pWndTLP = GetTopLevelParent();
  3179. if( pWndTLP != NULL )
  3180. {
  3181. ASSERT_VALID( pWndTLP );
  3182. if( pWndTLP->IsWindowVisible() )
  3183. {
  3184. CRect rcTLP;
  3185. pWndTLP->GetWindowRect( &rcTLP );
  3186. if( !rcTLP.IsRectEmpty() )
  3187. {
  3188. CRect rcIntersection;
  3189. if( rcIntersection.IntersectRect(
  3190. &rcTLP,
  3191. &rcWndOld
  3192. )
  3193. )
  3194. pWndTLP->UpdateWindow();
  3195. } // if( !rcTLP.IsRectEmpty() )
  3196. } // if( pWndTLP->IsWindowVisible() )
  3197. } // if( pWndTLP != NULL )
  3198. } // if( !rcWndOld.IsRectEmpty() )
  3199. _FreeWinObjects();
  3200. ASSERT( GetSafeHwnd() != NULL && ::IsWindow(GetSafeHwnd()) );
  3201. ASSERT( ( GetSite().GetAnimated() == NULL ) );
  3202. m_bAnimFinished = false;
  3203. m_AnimationType = __AT_CONTENT_DISPLAY;
  3204. ASSERT( GetSafeHwnd() != NULL && ::IsWindow(GetSafeHwnd()) );
  3205. // adjust screen position
  3206. CRect rcWnd = _CalcTrackRect();
  3207. ASSERT( GetSafeHwnd() != NULL && ::IsWindow(GetSafeHwnd()) );
  3208. if( rcWnd.top != rcWndOld.top
  3209. && rcWnd.bottom != rcWndOld.bottom
  3210. && m_ctrlShadow.GetSafeHwnd() != NULL
  3211. )
  3212. {
  3213. m_ctrlShadow.DestroyWindow();
  3214. m_bHelperReCreateDynamicShadowAtTheEndOfNearestAnimation = false;
  3215. }
  3216. if( m_rgnWnd.GetSafeHandle() != NULL )
  3217. {
  3218. ASSERT( m_bExcludeAreaSpec );
  3219. ASSERT( m_bCombineWithEA );
  3220. ASSERT( m_eCombineAlign != __CMBA_NONE );
  3221. CRgn rgnTmp;
  3222. VERIFY( rgnTmp.CreateRectRgn(0,0,0,0) );
  3223. rgnTmp.CopyRgn( &m_rgnWnd );
  3224. ASSERT( rgnTmp.GetSafeHandle() != NULL );
  3225. VERIFY(
  3226. SetWindowRgn(
  3227. (HRGN)rgnTmp.Detach(),
  3228. FALSE
  3229. )
  3230. );
  3231. } // if( m_rgnWnd.GetSafeHandle() != NULL )
  3232. m_bAnimFinished = true;
  3233. m_ePlaySoundOnAnimationFinished =
  3234. CExtSoundPlayer::__ON_MENU_EXPAND_CLICKED;
  3235. m_AnimationType =
  3236. g_bMenuExpandAnimation
  3237. ? __AT_CONTENT_EXPAND
  3238. : __AT_CONTENT_DISPLAY
  3239. ;
  3240. HWND hWndOwn = m_hWnd;
  3241. _StartAnimation();
  3242. if( ! ::IsWindow( hWndOwn ) )
  3243. return;
  3244. if( m_AnimationType == __AT_NONE )
  3245. {
  3246. m_AnimationType = __AT_CONTENT_DISPLAY;
  3247. _StartAnimation();
  3248. if( ! ::IsWindow( hWndOwn ) )
  3249. return;
  3250. ASSERT( m_AnimationType == __AT_CONTENT_DISPLAY );
  3251. }
  3252. if( m_bScrollingAvailable
  3253. || _IsTearOff()
  3254. )
  3255. _RecalcLayoutImpl();
  3256. SetWindowPos(
  3257. NULL,
  3258. rcWnd.left, rcWnd.top, rcWnd.Width(), rcWnd.Height(),
  3259. SWP_NOACTIVATE|SWP_SHOWWINDOW|SWP_NOZORDER
  3260. );
  3261. ASSERT( IsWindowVisible() );
  3262. } // if size of all items was changed
  3263. else
  3264. UpdateWindow();
  3265. ASSERT( m_hWndCmdReceiver != NULL );
  3266. ASSERT( ::IsWindow(m_hWndCmdReceiver) );
  3267. ::SendMessage(
  3268. m_hWndCmdReceiver,
  3269. g_nMsgNotifyMenuExpanded,
  3270. 0,
  3271. LPARAM( this )
  3272. );
  3273. //  if( bRestoreShadow )
  3274. //  {
  3275. //  CExtPopupMenuWnd * pPopup = this;
  3276. //  HWND hWndOwn = m_hWnd;
  3277. //  for( ; true; )
  3278. //  {
  3279. //  PassMsgLoop( false );
  3280. //  if( ! ::IsWindow(hWndOwn) )
  3281. //  return;
  3282. //  CWnd * pWndPermanent = CWnd::FromHandlePermanent( hWndOwn );
  3283. //  if( pWndPermanent == NULL )
  3284. //  return;
  3285. //  if( pWndPermanent != pPopup )
  3286. //  return;
  3287. //  if( m_bAnimFinished )
  3288. //  break;
  3289. //  }
  3290. //  if( m_ctrlShadow.GetSafeHwnd() != NULL )
  3291. //  m_ctrlShadow.DestroyWindow();
  3292. //  m_ctrlShadow.Create( m_hWnd, PmBridge_GetPM()->GetMenuShadowSize() );
  3293. //  }
  3294. }
  3295. bool CExtPopupMenuWnd::IsAllItemsRarelyUsed() const
  3296. {
  3297. ASSERT_VALID( this );
  3298. INT _iter = 0;
  3299. for( ; _iter < m_items_all.GetSize(); ++_iter )
  3300. {
  3301. const MENUITEMDATA & mi = ItemGetInfo( _iter );
  3302. if( mi.IsDisplayed() || mi.IsExtraMark() )
  3303. return false;
  3304. } // for( ; _iter != m_items_all.end(); ++_iter )
  3305. return true;
  3306. }
  3307. void CExtPopupMenuWnd::_SyncItems()
  3308. {
  3309. ASSERT_VALID( this );
  3310. ASSERT( m_hWndCmdReceiver != NULL );
  3311. ASSERT( ::IsWindow(m_hWndCmdReceiver) );
  3312. if( _IsPalette() )
  3313. {
  3314. _SyncItemsPalette();
  3315. return;
  3316. }
  3317. CExtPaintManager * pPM = PmBridge_GetPM();
  3318. ASSERT_VALID( pPM );
  3319. DWORD dwTrackFlags = TrackFlagsGet();
  3320. INT nIconAreaWidthLager = __EXT_MENU_ICON_CX + __EXT_MENU_GAP * 2;
  3321. nIconAreaWidthLager = pPM->UiScalingDo( nIconAreaWidthLager, CExtPaintManager::__EUIST_X );
  3322. int nItemIndex = 0, nItemCount = (int)m_items_all.GetSize();
  3323. for( ; nItemIndex < nItemCount; nItemIndex++ )
  3324. {
  3325. MENUITEMDATA & _mii = ItemGetInfo( nItemIndex );
  3326. int nWidth = _mii.GetIconAreaWidth();
  3327. nIconAreaWidthLager =
  3328. max( nIconAreaWidthLager, nWidth );
  3329. _mii.CacheRectsEmpty();
  3330. } // for( ; nItemIndex < nItemCount; nItemIndex++ )
  3331. nIconAreaWidthLager = 
  3332. max( nIconAreaWidthLager, pPM->GetMenuIconAreaWidth() );
  3333. for( nItemIndex = 0; nItemIndex < nItemCount; nItemIndex++ )
  3334. {
  3335. MENUITEMDATA & _mii = ItemGetInfo( nItemIndex );
  3336. _mii.UpdateIconAreaWidth( nIconAreaWidthLager );
  3337. } // for( nItemIndex = 0; nItemIndex < nItemCount; nItemIndex++ )
  3338. m_bExpandAvailable = false;
  3339. // m_sizeFullItems.cx = m_sizeFullItems.cy = 1; // - 2.28
  3340. m_sizeFullItems.cx = m_sizeFullItems.cy = 0; // + 2.28
  3341. bool bFullViewMode =
  3342. ( m_bExpandWasPressed
  3343. || ( (dwTrackFlags&TPMX_NO_HIDE_RARELY) != 0 )
  3344. ) ? true : false;
  3345. int nSeparatorIndex = -1;
  3346. int nDisplayedCount = 0;
  3347. for( nItemIndex = 0; nItemIndex < nItemCount; nItemIndex++ )
  3348. {
  3349. MENUITEMDATA & _mii = ItemGetInfo( nItemIndex );
  3350. _mii.SetIndex( nItemIndex );
  3351. if( bFullViewMode )
  3352. {
  3353. _mii.SetDisplayed( true );
  3354. nDisplayedCount ++;
  3355. if( _mii.IsPopup() )
  3356. {
  3357. ASSERT( _mii.GetPopup() != NULL );
  3358. _mii.GetPopup()->_SyncItems();
  3359. } // if( _mii.IsPopup() )
  3360. } // if( bFullViewMode )
  3361. else
  3362. {
  3363. if( _mii.IsPopup() )
  3364. {
  3365. ASSERT( _mii.GetPopup() != NULL );
  3366. _mii.GetPopup()->_SyncItems();
  3367. CExtCmdItem * pCmdItem = _mii.GetCmd();
  3368. if( pCmdItem != NULL )
  3369. {
  3370. bool bRarelyUsed =
  3371. ( (!_FindCustomizeMode())
  3372. && pCmdItem->StateIsRarelyUsed()
  3373. ) ? true : false;
  3374. if( bRarelyUsed )
  3375. {
  3376. _mii.SetDisplayed( false );
  3377. } // if( bRarelyUsed )
  3378. else
  3379. {
  3380. _mii.SetDisplayed( true );
  3381. nDisplayedCount ++;
  3382. nSeparatorIndex = -1;
  3383. } // else from if( bRarelyUsed )
  3384. } // if( pCmdItem != NULL )
  3385. else if( _mii.IsAllItemsRarelyUsed() )
  3386. {
  3387. _mii.SetDisplayed( false );
  3388. } // else if( _mii.IsAllItemsRarelyUsed() )
  3389. else
  3390. { // if at least one displayed
  3391. _mii.SetDisplayed( true );
  3392. nDisplayedCount ++;
  3393. nSeparatorIndex = -1;
  3394. } // if at least one displayed
  3395. } // if( _mii.IsPopup() )
  3396. else if( _mii.IsSeparator() )
  3397. {
  3398. if( nSeparatorIndex >= 0 || nDisplayedCount == 0 )
  3399. {
  3400. _mii.SetDisplayed( false );
  3401. } // if( nSeparatorIndex >= 0 || nDisplayedCount == 0 )
  3402. else
  3403. {
  3404. _mii.SetDisplayed( true );
  3405. nDisplayedCount ++;
  3406. nSeparatorIndex = nItemIndex;
  3407. } // else from if( nSeparatorIndex >= 0 || nDisplayedCount == 0 )
  3408. } // else if( _mii.IsSeparator() )
  3409. else
  3410. { // if command item
  3411. CExtCmdItem * pCmdItem = _mii.GetCmd();
  3412. if( pCmdItem == NULL || _mii.IsExtraMark() )
  3413. {
  3414. _mii.SetDisplayed( true );
  3415. nDisplayedCount ++;
  3416. nSeparatorIndex = -1;
  3417. } // if( pCmdItem == NULL || _mii.IsExtraMark() )
  3418. else if( pCmdItem->StateIsRarelyUsed() )
  3419. {
  3420. _mii.SetDisplayed( false );
  3421. } // else if( pCmdItem->StateIsRarelyUsed() )
  3422. else
  3423. { // if basic command or frequently used
  3424. _mii.SetDisplayed( true );
  3425. nDisplayedCount ++;
  3426. nSeparatorIndex = -1;
  3427. } // if basic command or frequently used
  3428. } // if command item
  3429. } // else from if( bFullViewMode )
  3430. if( _mii.IsDisplayed() )
  3431. {
  3432. m_sizeFullItems.cy += _mii.GetMeasuredHeight();
  3433. int nMeasuredWidth = _mii.GetMeasuredWidth();
  3434. if( m_sizeFullItems.cx < nMeasuredWidth )
  3435. m_sizeFullItems.cx = nMeasuredWidth;
  3436. } // if( _mii.IsDisplayed() )
  3437. else
  3438. {
  3439. ASSERT( ! m_bExpandWasPressed );
  3440. m_bExpandAvailable = true;
  3441. } // else from if( _mii.IsDisplayed() )
  3442. } // for( nItemIndex = 0; nItemIndex < nItemCount; nItemIndex++ )
  3443. if( nSeparatorIndex >= 0 )
  3444. { // remove last separator
  3445. ASSERT( ! bFullViewMode );
  3446. MENUITEMDATA & _mii = ItemGetInfo( nSeparatorIndex );
  3447. ASSERT( _mii.IsSeparator() );
  3448. ASSERT( _mii.IsDisplayed() );
  3449. _mii.SetDisplayed( false );
  3450. m_sizeFullItems.cy -= _mii.GetMeasuredHeight();
  3451. } // if( nSeparatorIndex >= 0 )
  3452. if( GetSafeHwnd() != NULL
  3453. && IsSyncFullRowItems()
  3454. )
  3455. {
  3456. CRect rcMB = OnQueryMenuBorderMetrics();
  3457. CRect rcClient;
  3458. _GetClientRect( &rcClient );
  3459. m_sizeFullItems.cx = rcClient.Width() - rcMB.left - rcMB.right;
  3460. }
  3461. static const INT nMixDx = 80;
  3462. if( m_sizeFullItems.cx < nMixDx )
  3463. m_sizeFullItems.cx = nMixDx;
  3464. }
  3465. void CExtPopupMenuWnd::_SyncItemsPalette()
  3466. {
  3467. ASSERT_VALID( this );
  3468. ASSERT( m_hWndCmdReceiver != NULL );
  3469. ASSERT( ::IsWindow(m_hWndCmdReceiver) );
  3470. m_bExpandAvailable = false;
  3471. m_sizeFullItems.cx = m_sizeFullItems.cy = 0;
  3472. int nItemIndex = 0, nCountOfItems = (int)m_items_all.GetSize();
  3473. for( nItemIndex = 0; nItemIndex < nCountOfItems; nItemIndex++ )
  3474. {
  3475. MENUITEMDATA & _mii = ItemGetInfo( nItemIndex );
  3476. _mii.CacheRectsEmpty();
  3477. _mii.SetToolButton();
  3478. bool bIconMode = true;
  3479. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  3480. CExtCustomizeCmdTreeNode * pNode = _mii.GetCmdNode();
  3481. if( pNode != NULL )
  3482. {
  3483. DWORD dwDipslayStyle = pNode->GetFlags() & __ECTN_DISPLAY_MASK;
  3484. if( dwDipslayStyle == __ECTN_DISPLAY_TEXT_AND_IMAGE
  3485. || dwDipslayStyle == __ECTN_DISPLAY_TEXTONLY_ALWAYS
  3486. )
  3487. bIconMode = false;
  3488. }
  3489. else
  3490. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  3491. {
  3492. LPCTSTR strText = _mii.GetText();
  3493. if( strText != NULL
  3494. && _tcslen( strText ) > 0
  3495. )
  3496. bIconMode = false;
  3497. }
  3498. _mii.SetIconMode( bIconMode );
  3499. _mii.SetIndex( nItemIndex );
  3500. _mii.SetDisplayed( true );
  3501. _mii.UpdateIconAreaWidth( 0 );
  3502. _mii.MeasureItem( NULL );
  3503. if( _mii.IsPopup() )
  3504. {
  3505. ASSERT( _mii.GetPopup() != NULL );
  3506. _mii.GetPopup()->_SyncItems();
  3507. } // if( _mii.IsPopup() )
  3508. } // for( nItemIndex = 0; nItemIndex < nCountOfItems; nItemIndex++ )
  3509. CRect rcMB = OnQueryMenuBorderMetrics();
  3510. int x = 0, y = 0;
  3511. int xRow = x, dyRow = 0, dxMaxRow = 0, nRowStart = 0;
  3512. for( nItemIndex = 0; nItemIndex < nCountOfItems; nItemIndex++ )
  3513. {
  3514. MENUITEMDATA & mi = ItemGetInfo( nItemIndex );
  3515. if( ! mi.IsDisplayed() )
  3516. continue;
  3517. bool bWrap = _IsPaletteItemWrap( nItemIndex );
  3518. const RECT & rcBase = mi.GetBaseRect();
  3519. if( mi.IsSeparator() )
  3520. bWrap = true;
  3521. int nWidth = rcBase.right - rcBase.left;
  3522. int nHeight = rcBase.bottom-rcBase.top;
  3523. dyRow = max( dyRow, nHeight );
  3524. xRow += nWidth;
  3525. if( mi.IsInplaceEdit() )
  3526. xRow += (nItemIndex == 0) ? __EXT_MENU_GAP : (__EXT_MENU_GAP*2);
  3527. // else
  3528. // xRow += (nRowStart == nItemIndex) ? 0 : __EXT_MENU_GAP;
  3529. xRow += 2;
  3530. dxMaxRow = max( dxMaxRow, xRow );
  3531. if( bWrap )
  3532. {
  3533. dxMaxRow = max( dxMaxRow, xRow );
  3534. xRow = x;
  3535. y += dyRow;
  3536. dyRow = 0;
  3537. if( mi.IsSeparator() )
  3538. y +=
  3539. PmBridge_GetPM()->GetSeparatorHeight()
  3540. + __EXT_MENU_GAP
  3541. ;
  3542. nRowStart = nItemIndex + 1;
  3543. }
  3544. } // for( nItemIndex = 0; nItemIndex < nCountOfItems; nItemIndex++ )
  3545. dxMaxRow = max( dxMaxRow, xRow );
  3546. m_sizeFullItems.cx = dxMaxRow + rcMB.left + rcMB.right + __EXT_MENU_GAP;
  3547. m_sizeFullItems.cy = y + dyRow + __EXT_MENU_GAP;
  3548. if( m_sizeFullItems.cx < 20 )
  3549. m_sizeFullItems.cx = 20;
  3550. if( m_sizeFullItems.cy < 10 )
  3551. m_sizeFullItems.cy = 10;
  3552. }
  3553. void CExtPopupMenuWnd::ResetPaletteWrapping(
  3554. bool bCreateToolBarWrapping, // = false
  3555. int nIndexFirst, // = 0
  3556. int nIndexLast // = -1
  3557. )
  3558. {
  3559. ASSERT_VALID( this );
  3560. if( ! _IsPalette() )
  3561. return;
  3562. int nCountOfItems = ItemGetCount();
  3563. if( nCountOfItems == 0 )
  3564. return;
  3565. if( nIndexFirst < 0 || nIndexFirst >= nCountOfItems )
  3566. return;
  3567. if( nIndexLast < 0 || nIndexLast >= nCountOfItems )
  3568. nIndexLast = nCountOfItems - 1;
  3569. if( nIndexFirst >= nIndexLast )
  3570. return;
  3571. int nIndex, nSummaryWidth = 0;
  3572. static const int nAdjustStep = __EXT_MENU_GAP*2;
  3573. for( nIndex = nIndexFirst; nIndex <= nIndexLast; nIndex ++ )
  3574. {
  3575. MENUITEMDATA & mi = ItemGetInfo( nIndex );
  3576. mi.SetToolWrap( false );
  3577. if( ! bCreateToolBarWrapping )
  3578. continue;
  3579. if( mi.IsSeparator() )
  3580. continue;
  3581. int nWidth = mi.GetBaseRect().Width() + nAdjustStep;
  3582. nSummaryWidth += nWidth;
  3583. } // for( nIndex = nIndexFirst; nIndex <= nIndex; nIndex ++ )
  3584. if( ! bCreateToolBarWrapping )
  3585. return;
  3586. static const int nAdjustWidth = 150;
  3587. if( nSummaryWidth < nAdjustWidth )
  3588. return;
  3589. int dxRow = 0;
  3590. int nApproxRowWidth = ::MulDiv( nSummaryWidth, 25, 100 );
  3591. if( nApproxRowWidth < nAdjustWidth )
  3592. nApproxRowWidth = nAdjustWidth;
  3593. for( nIndex = nIndexFirst; nIndex <= nIndexLast; nIndex ++ )
  3594. {
  3595. MENUITEMDATA & mi = ItemGetInfo( nIndex );
  3596. if( mi.IsSeparator() )
  3597. {
  3598. dxRow = 0;
  3599. continue;
  3600. }
  3601. int nWidth = mi.GetBaseRect().Width() + nAdjustStep;
  3602. if( dxRow >= nApproxRowWidth
  3603. //|| nIndex == nIndexLast
  3604. )
  3605. {
  3606. if( nIndex > nIndexFirst
  3607. //&& nIndex != nIndexLast
  3608. )
  3609. {
  3610. MENUITEMDATA & mi = ItemGetInfo( nIndex - 1 );
  3611. mi.SetToolWrap( true );
  3612. dxRow = nWidth;
  3613. continue;
  3614. }
  3615. mi.SetToolWrap( true );
  3616. dxRow = 0;
  3617. continue;
  3618. }
  3619. dxRow += nWidth;
  3620. } // for( nIndex = nIndexFirst; nIndex <= nIndex; nIndex ++ )
  3621. }
  3622. const CExtPopupMenuWnd * CExtPopupMenuWnd::ItemGetPopup(
  3623. INT nPos
  3624. ) const
  3625. {
  3626. ASSERT_VALID( this );
  3627. ASSERT( GetTrackingMenu() != this );
  3628. INT nCountOfItems = ItemGetCount();
  3629. if( nPos < 0 || nPos >= nCountOfItems )
  3630. {
  3631. ASSERT( FALSE );
  3632. return NULL;
  3633. }
  3634. const MENUITEMDATA & mi = ItemGetInfo(nPos);
  3635. /*
  3636. UINT nCmdID = mi.GetCmdID();
  3637. if( nCmdID != TYPE_POPUP )
  3638. return NULL;
  3639. ASSERT( mi.IsPopup() );
  3640. */
  3641. if( !mi.IsPopup() )
  3642. return NULL;
  3643. return mi.GetPopup();
  3644. }
  3645. BOOL CExtPopupMenuWnd::ItemRemove(
  3646. INT nPos // = -1 // remove all
  3647. )
  3648. {
  3649. ASSERT_VALID( this );
  3650. ASSERT( GetTrackingMenu() != this );
  3651. if( nPos < 0 )
  3652. {
  3653. if( ! _BuildItems( NULL, false ) )
  3654. {
  3655. ASSERT( FALSE );
  3656. return FALSE;
  3657. }
  3658. _SyncItems();
  3659. return TRUE;
  3660. } // if( nPos < 0 )
  3661. INT nCountOfItems = ItemGetCount();
  3662. if( nPos >= nCountOfItems )
  3663. {
  3664. ASSERT( FALSE );
  3665. return FALSE;
  3666. }
  3667. MENUITEMDATA & mi = ItemGetInfo(nPos);
  3668. if( mi.IsPopup() )
  3669. {
  3670. mi.GetPopup()->_OnCancelMode();
  3671. VERIFY( mi.GetPopup()->_BuildItems( NULL, false ) );
  3672. mi.DestroyPopup();
  3673. }
  3674. m_items_all.RemoveAt( nPos );
  3675. ASSERT( nCountOfItems == m_items_all.GetSize() + 1 );
  3676. m_nCurIndex = -1;
  3677. _SyncItems();
  3678. return TRUE;
  3679. }
  3680. INT CExtPopupMenuWnd::ItemRemoveAllSeparators()
  3681. {
  3682. ASSERT_VALID( this );
  3683. ASSERT( GetTrackingMenu() != this );
  3684. INT nCountOfItems = ItemGetCount(), nIndex = 0, nCountRemoved = 0;
  3685. for( ; nIndex < nCountOfItems; )
  3686. {
  3687. MENUITEMDATA & mi = ItemGetInfo(nIndex);
  3688. if( mi.IsSeparator() )
  3689. {
  3690. m_items_all.RemoveAt( nIndex );
  3691. nCountOfItems --;
  3692. nCountRemoved ++;
  3693. }
  3694. else
  3695. nIndex ++;
  3696. }
  3697. m_nCurIndex = -1;
  3698. if( nCountRemoved > 0 )
  3699. _SyncItems();
  3700. return nCountRemoved;
  3701. }
  3702. BOOL CExtPopupMenuWnd::ItemInsertSpecPopup( // insert specific popup implementation
  3703. CExtPopupMenuWnd * pSpecPopup,
  3704. INT nPos, // = -1 // append
  3705. __EXT_MFC_SAFE_LPCTSTR sText, // = NULL
  3706. HICON hIcon // = NULL
  3707. )
  3708. {
  3709. ASSERT_VALID( this );
  3710. ASSERT( pSpecPopup != NULL );
  3711. CExtCmdIcon icon;
  3712. if( hIcon != NULL )
  3713. icon.AssignFromHICON( hIcon, false );
  3714. return
  3715. ItemInsertSpecPopup( // insert specific popup implementation
  3716. pSpecPopup,
  3717. nPos,
  3718. sText,
  3719. icon
  3720. );
  3721. }
  3722. BOOL CExtPopupMenuWnd::ItemInsertSpecPopup( // insert specific popup implementation
  3723. CExtPopupMenuWnd * pSpecPopup,
  3724. INT nPos, // -1 - append
  3725. __EXT_MFC_SAFE_LPCTSTR sText,
  3726. const CExtCmdIcon & icon
  3727. )
  3728. {
  3729. ASSERT_VALID( this );