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

界面编程

开发平台:

Visual C++

  1. rcRectRgn,
  2. m_ctrlShadow.IsAvailable(),
  3. nSizeShadow,
  4. this
  5. );
  6. if( hRegion == NULL )
  7. {
  8. ASSERT( FALSE );
  9. return NULL;
  10. }
  11. if( ( m_ptTrack.x + rcWnd.Width() ) > rcDesktop.right )
  12. m_bFlipHorz = true;
  13. if( ( m_ptTrack.y + rcWnd.Height() ) > rcDesktop.bottom )
  14. m_bFlipVert = true;
  15. if( pSize != NULL )
  16. {
  17. pSize->cx = rcWnd.Width();
  18. pSize->cy = rcWnd.Height();
  19. }
  20. } // rectangle cases
  21. break;
  22. default:
  23. ASSERT( FALSE );
  24. return NULL;
  25. } // switch( eTS )
  26. return hRegion;
  27. }
  28. void CExtPopupScreenTipWnd::_DoPaint(
  29. CDC & dcPaint,
  30. bool bUseBackBuffer // = true
  31. )
  32. {
  33. //ASSERT_VALID( this );
  34. if( m_cmdScreenTip.IsEmpty() )
  35. {
  36. CExtPopupMenuTipWnd::_DoPaint( dcPaint, bUseBackBuffer );
  37. return;
  38. }
  39. CDC & dc = dcPaint;
  40. CRect rcLayout;
  41. GetClientRect( &rcLayout );
  42. HRGN hRegion = CreateRectRgnIndirect( &rcLayout );
  43. GetWindowRgn( hRegion );
  44. CRgn * pRegion = CRgn::FromHandle( hRegion );
  45. CExtPaintManager * pPM = PmBridge_GetPM();
  46. ASSERT_VALID( pPM );
  47. e_tip_style_t eTS = GetTipStyle();
  48. switch( eTS )
  49. {
  50. case __ETS_BALLOON:
  51. case __ETS_BALLOON_NO_ICON:
  52. {
  53. CBrush brushWindow;
  54. brushWindow.CreateSolidBrush(
  55. //pPM->GetColor( COLOR_INFOBK, this )
  56. ::GetSysColor( COLOR_INFOBK )
  57. );
  58. CBrush brushFrame;
  59. brushFrame.CreateSolidBrush(
  60. //pPM->GetColor( COLOR_3DDKSHADOW, this )
  61. ::GetSysColor( COLOR_3DDKSHADOW )
  62. );
  63. CBrush brushInnerFrame;
  64. brushInnerFrame.CreateSolidBrush(
  65. //pPM->GetColor( COLOR_3DFACE, this)
  66. ::GetSysColor( COLOR_3DFACE )
  67. );
  68. // frame
  69. dc.FillRgn( pRegion, &brushWindow );
  70. dc.FrameRgn( pRegion, &brushInnerFrame, 3, 3 );
  71. dc.FrameRgn( pRegion, &brushFrame, 1, 1 );
  72. // adjust icon's area
  73. rcLayout.DeflateRect( m_sizeRounders.cx, m_sizeRounders.cy, 0, 0 );
  74. if( eTS != __ETS_BALLOON_NO_ICON && (! m_icon.IsEmpty() ) )
  75. rcLayout.left += m_sizeRenderingIcon.cx + m_nIconMarginDX;
  76. int nIconVertPos = m_sizeRounders.cy;
  77. if( m_bFlipVert )
  78. {
  79. rcLayout.OffsetRect( 0, m_sizeLeader.cy );
  80. nIconVertPos += m_sizeLeader.cy;
  81. }
  82. pPM->ScreenTip_Paint( dc, rcLayout, m_cmdScreenTip, this );
  83. } // cases __ETS_BALLOON, __ETS_BALLOON_NO_ICON
  84. break;
  85. case __ETS_RECTANGLE:
  86. case __ETS_RECTANGLE_NO_ICON:
  87. case __ETS_INV_RECTANGLE:
  88. case __ETS_INV_RECTANGLE_NO_ICON:
  89. {
  90. int nSizeShadow = CalcShadowSize();
  91. ASSERT( nSizeShadow >= 0 );
  92. if( nSizeShadow > 0 )
  93. {
  94. rcLayout.DeflateRect( 0, 0, nSizeShadow, nSizeShadow );
  95. m_shadow.Paint(
  96. pPM,
  97. dc,
  98. rcLayout,
  99. CRect( 0, 0, 0, 0 ),
  100. CRect( 0, 0, 0, 0 ),
  101. nSizeShadow,
  102. 70,
  103. 95
  104. );
  105. }
  106. pPM->ScreenTip_Paint( dc, rcLayout, m_cmdScreenTip, this );
  107. } // rectangle cases
  108. break;
  109. #ifdef _DEBUG
  110. default:
  111. ASSERT( FALSE );
  112. break;
  113. #endif // _DEBUG
  114. } // switch( eTS )
  115. ::DeleteObject( hRegion );
  116. }
  117. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  118. /////////////////////////////////////////////////////////////////////////////
  119. // CExtPopupMenuWnd
  120. CExtSafeString CExtPopupMenuWnd::g_strSpecSymbols( _T("~`!@#$%^&*()_-+={}[]:;"'|\<,>.?/ ") );
  121. INT CExtPopupMenuWnd::g_nTimeDelayedDisplaying = 300;
  122. INT CExtPopupMenuWnd::g_nTimeDelayedHiding = 300;
  123. bool CExtPopupMenuWnd::g_bUseAcceleratedMenuScrolling = false;
  124. INT CExtPopupMenuWnd::g_nAcceleratedIncreaseStep = 500;
  125. INT CExtPopupMenuWnd::g_nAcceleratedIncreasePercent = 50;
  126. INT CExtPopupMenuWnd::g_nAcceleratedPixelsPerStepMax = 400;
  127. bool CExtPopupMenuWnd::g_bTranslateContextHelpCmd = false;
  128. ACCEL CExtPopupMenuWnd::g_accelContextHelp = { FVIRTKEY, VK_F1, ID_HELP };
  129. // is allowed menu item positioning without
  130. // using only & - marked text
  131. bool CExtPopupMenuWnd::g_bAllowNonAccelPositioning = false;
  132. INT CExtPopupMenuWnd::g_nDefaultFadeOutAnimationStepCount = 8;
  133. INT CExtPopupMenuWnd::g_nDefaultFadeOutAnimationEllapse = 20;
  134. INT CExtPopupMenuWnd::g_nAutoExpandTime = 4000;
  135. IMPLEMENT_DYNCREATE( CExtPopupMenuWnd, CExtPopupBaseWnd )
  136. static CTypedPtrList < CPtrList, CExtPopupMenuWnd * > g_ListDetached;
  137. CExtPopupMenuWnd::CExtPopupMenuWnd()
  138. : m_pWndParentMenu( NULL )
  139. , m_hWndCmdReceiver( NULL )
  140. , m_hWndNotifyMenuClosed( NULL )
  141. , m_nLeftAreaWidth( 0 )
  142. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  143. , m_pNode( NULL )
  144. , m_pDragSrcNode( NULL )
  145. , m_nDragSrcIdx( -1 )
  146. , m_bHelperNoRemoveSrc( false )
  147. , m_bHelperDragOverPassed( false )
  148. , m_pCustomizeSite( NULL )
  149. , m_nHelperDropIndexBefore( -1 )
  150. , m_bHelperNoHideChild( false )
  151. , m_ptHelperDragStart( 0, 0 )
  152. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  153. , m_nAcceleratedPixelsPerStepCurrent( __SCROLLING_PIXEL_STEP )
  154. , m_nAcceleratedMilliSecondsPassed( 0 )
  155. , m_sMenuCaption( _T("") )
  156. , m_sizeCaptionMeasured( 0, 0 )
  157. , m_bHelperResizingMode( false )
  158. , m_sizeResizingMin( 10, 10 )
  159. , m_sizeResizingMax( 32767, 32767 )
  160. , m_bHelperAnimationControllerDetected( false )
  161. , m_nFadeOutAnimationStepIndex( 0 )
  162. , m_nFadeOutAnimationStepCount( g_nDefaultFadeOutAnimationStepCount )
  163. , m_nFadeOutAnimationEllapse( g_nDefaultFadeOutAnimationEllapse )
  164. , m_bCanceling( false )
  165. , m_bHelperMouseBtnDownOnStart( false )
  166. , m_ptStartMousePos( -32767, -32767 )
  167. , m_bHelperReCreateDynamicShadowAtTheEndOfNearestAnimation( false )
  168. {
  169. __VPC_INC;
  170. _Init();
  171. g_ListDetached.AddTail( this );
  172. }
  173. CExtPopupMenuWnd::~CExtPopupMenuWnd()
  174. {
  175. POSITION pos = g_ListDetached.Find( this );
  176. if( pos != NULL )
  177. g_ListDetached.RemoveAt( pos );
  178. _OnCancelMode( true );
  179. if( m_bTopLevel )
  180. {
  181. VERIFY( _BuildItems( NULL, true ) );
  182. }
  183. __VPC_DEC;
  184. #ifdef _DEBUG
  185. if( m_bTopLevel )
  186. {
  187. __VPC_VERIFY_0;
  188. }
  189. #endif // _DEBUG
  190. CExtPopupMenuSite::g_DefPopupMenuSite.FadeOutInstanceRemove( this );
  191. }
  192. bool CExtPopupMenuWnd::TestHoverEnabledFromActiveHWND(
  193. HWND hWndTestFrom,
  194. HWND hWndActive, // = ::GetActiveWindow(),
  195. bool bCheckEnabled, // = true,
  196. bool bCheckVisible, // = true,
  197. bool bCheckExtPopupMenuTracking // = true
  198. )
  199. {
  200. if( bCheckExtPopupMenuTracking )
  201. {
  202. if( CExtPopupMenuWnd::IsMenuTracking() )
  203. return false;
  204. } // if( bCheckExtPopupMenuTracking )
  205. if( hWndTestFrom == NULL
  206. || ( ! ::IsWindow( hWndTestFrom ) )
  207. )
  208. return false;
  209. if( hWndActive == NULL
  210. || ( ! ::IsWindow( hWndActive ) )
  211. )
  212. return false;
  213. if( bCheckEnabled )
  214. {
  215. if( ! ::IsWindowEnabled( hWndTestFrom ) )
  216. return false;
  217. if( ! ::IsWindowEnabled( hWndActive ) )
  218. return false;
  219. } // if( bCheckEnabled )
  220. __EXT_MFC_LONG_PTR dwWndStyle;
  221. if( bCheckVisible )
  222. {
  223. dwWndStyle = ::__EXT_MFC_GetWindowLong( hWndTestFrom, GWL_STYLE );
  224. if( (dwWndStyle & WS_VISIBLE) == 0 )
  225. return false;
  226. dwWndStyle = ::__EXT_MFC_GetWindowLong( hWndActive, GWL_STYLE );
  227. if( (dwWndStyle & WS_VISIBLE) == 0 )
  228. return false;
  229. } // if( bCheckVisible )
  230. const DWORD dwTestStyles = (WS_VISIBLE|WS_POPUP);
  231. for( HWND hWndParentOfTest = ::GetParent( hWndTestFrom );
  232. hWndParentOfTest != NULL;
  233. hWndParentOfTest = ::GetParent( hWndParentOfTest )
  234. )
  235. { // walk parent popup windows of hWndTestFrom
  236. ASSERT( ::IsWindow( hWndParentOfTest ) );
  237. dwWndStyle = ::__EXT_MFC_GetWindowLong( hWndParentOfTest, GWL_STYLE );
  238. if( (dwWndStyle&dwTestStyles) == 0L )
  239. continue;
  240. if( hWndParentOfTest == hWndActive )
  241. return true;
  242. for( HWND hWndParentOfActive = hWndActive;
  243. hWndParentOfActive != NULL;
  244. hWndParentOfActive = ::GetParent( hWndParentOfActive )
  245. )
  246. { // walk parent popup windows of hWndActive
  247. ASSERT( ::IsWindow( hWndParentOfActive ) );
  248. dwWndStyle = ::__EXT_MFC_GetWindowLong( hWndParentOfActive, GWL_STYLE );
  249. if( (dwWndStyle&dwTestStyles) == 0L )
  250. continue;
  251. if( hWndParentOfActive == hWndParentOfTest )
  252. return true;
  253. } // walk parent popup windows of hWndActive
  254. } // walk parent popup windows of hWndTestFrom
  255. return false;
  256. }
  257. void CExtPopupMenuWnd::_Init()
  258. {
  259. ASSERT_VALID( this );
  260. m_nDyScrollOffset = 0;
  261. m_bTopLevel
  262. = m_bScrollingAvailable
  263. = m_bExpandAvailable
  264. = m_bExpandWasPressed
  265. = m_bCombineWithEA 
  266. = m_bSuspendTips
  267. = false;
  268. m_dwTrackFlags = 0;
  269. m_nWaitingExpandTickCount = 0;
  270. m_nCurIndex
  271. = m_nDelayedFocusItemIndex
  272. = m_nLastMousePick
  273. = IDX_NOTHING;
  274. m_bDelayedHiding = false;
  275. m_nScrollingDirection = 0;
  276. m_rcScrollTop.SetRectEmpty();
  277. m_rcScrollBottom.SetRectEmpty();
  278. m_rcExpandBtn.SetRectEmpty();
  279. m_rcTearOffBtn.SetRectEmpty();
  280. m_rcRibbonBtnOptions.SetRectEmpty();
  281. m_rcRibbonBtnExit.SetRectEmpty();
  282. m_pCbPaintCombinedCookie = NULL;
  283. m_pCbPaintCombinedContent = NULL;
  284. m_bCookieIsObject = false;
  285. _InitAnimation();
  286. }
  287. CObject * CExtPopupBaseWnd::GetCookieAsObject()
  288. {
  289. if( (!m_bCookieIsObject)
  290. || m_pCbPaintCombinedCookie == NULL
  291. )
  292. return NULL;
  293. CObject * pObj = (CObject*)m_pCbPaintCombinedCookie;
  294. ASSERT_VALID( pObj );
  295. return pObj;
  296. }
  297. bool CExtPopupBaseWnd::IsToolBtnCombinedArea() const
  298. {
  299. if( !IsKindOf( RUNTIME_CLASS(CExtPopupMenuWnd) ) )
  300. return false;
  301. CExtPopupMenuWnd * pPopup = (CExtPopupMenuWnd*)(this);
  302. if( (LPVOID)(CExtPopupMenuWnd::stat_paint_combined_menu_toolbtn)
  303. != (LPVOID)(pPopup->GetCbPaintCombinedContent())
  304. )
  305. return false;
  306. return true;
  307. }
  308. int CExtPopupMenuWnd::_GetCurIndex() const
  309. {
  310. ASSERT_VALID( this );
  311. return m_nCurIndex;
  312. }
  313. int CExtPopupMenuWnd::_GetSpecBtnHeight()
  314. {
  315. int nHeight = g_PaintManager->GetMenuExpandButtonHeight();
  316. ASSERT( nHeight > 0 );
  317. return nHeight;
  318. }
  319. CRect CExtPopupMenuWnd::OnQueryMenuBorderMetrics() const
  320. {
  321. ASSERT_VALID( this );
  322. CExtPaintManager * pPM = PmBridge_GetPM();
  323. CRect rcMB = pPM->GetMenuBorderMetrics( (CWnd*)this );
  324. ASSERT( rcMB.left >= 0 );
  325. ASSERT( rcMB.top >= 0 );
  326. ASSERT( rcMB.right >= 0 );
  327. ASSERT( rcMB.bottom >= 0 );
  328. CSize _sizeCaption = MenuCaptionMeasure();
  329. rcMB.top += _sizeCaption.cy;
  330. INT nMarginHeight = 0, nResizingCornerPartWidth = 0;
  331. pPM->MenuBottomResizingMarginGetInfo(
  332. nMarginHeight,
  333. nResizingCornerPartWidth,
  334. const_cast < CExtPopupMenuWnd * > ( this )
  335. );
  336. rcMB.bottom += nMarginHeight;
  337. return rcMB;
  338. }
  339. __EXT_MFC_SAFE_LPCTSTR CExtPopupMenuWnd::MenuCaptionTextGet() const
  340. {
  341. ASSERT_VALID( this );
  342. return LPCTSTR(m_sMenuCaption);
  343. }
  344. void CExtPopupMenuWnd::MenuCaptionTextSet(
  345. __EXT_MFC_SAFE_LPCTSTR sMenuCaption // = NULL
  346. )
  347. {
  348. ASSERT_VALID( this );
  349. m_sizeCaptionMeasured.cx = m_sizeCaptionMeasured.cy = 0;
  350. m_sMenuCaption.Empty();
  351. if( sMenuCaption != NULL )
  352. m_sMenuCaption = sMenuCaption;
  353. }
  354. CSize CExtPopupMenuWnd::MenuCaptionMeasure() const
  355. {
  356. ASSERT_VALID( this );
  357. if( m_sizeCaptionMeasured.cx > 0 && m_sizeCaptionMeasured.cy > 0 )
  358. return m_sizeCaptionMeasured;
  359. CWindowDC dc( NULL );
  360. m_sizeCaptionMeasured =
  361. PmBridge_GetPM()->MenuCaption_Measure(
  362. dc,
  363. MenuCaptionTextGet(),
  364. const_cast < CExtPopupMenuWnd * > ( this )
  365. );
  366. return m_sizeCaptionMeasured;
  367. }
  368. void CExtPopupMenuWnd::MenuCaptionPaint(
  369. CDC & dc,
  370. CRect rcMenuCaption
  371. ) const
  372. {
  373. ASSERT_VALID( this );
  374. if( m_sizeCaptionMeasured.cx <= 0
  375. || m_sizeCaptionMeasured.cy <= 0
  376. || rcMenuCaption.IsRectEmpty()
  377. || ( ! dc.RectVisible( &rcMenuCaption ) )
  378. )
  379. return;
  380. PmBridge_GetPM()->MenuCaption_Paint(
  381. dc,
  382. rcMenuCaption,
  383. MenuCaptionTextGet(),
  384. const_cast < CExtPopupMenuWnd * > ( this )
  385. );
  386. }
  387. void CExtPopupMenuWnd::_CachedRectsEmpty()
  388. {
  389. ASSERT_VALID( this );
  390. int nItemIndex = 0, nItemCount = (int)m_items_all.GetSize();
  391. for( ; nItemIndex < nItemCount; nItemIndex++ )
  392. {
  393. MENUITEMDATA & _mii = ItemGetInfo( nItemIndex );
  394. _mii.CacheRectsEmpty();
  395. } // for( ; nItemIndex < nItemCount; nItemIndex++ )
  396. }
  397. void CExtPopupMenuWnd::_RecalcTrackParms(
  398. bool bMoveWindow // = true
  399. )
  400. {
  401. ASSERT_VALID( this );
  402. ASSERT( GetSafeHwnd() != NULL );
  403. m_ptTrack = m_ptTrackOriginal;
  404. m_eCombineAlign = __CMBA_NONE;
  405. bool bPointAdjusted = true;
  406. CSize _size = _CalcTrackSize();
  407. if( m_bExcludeAreaSpec )
  408. {
  409. bool bRTL = OnQueryLayoutRTL();
  410. if( bRTL && (!m_bTopLevel) )
  411. {
  412. CExtPopupMenuWnd * pTop = m_pWndParentMenu;
  413. for( ; pTop != NULL; pTop = pTop->GetParentMenuWnd() )
  414. {
  415. if( pTop->_IsTopLevelPopup() )
  416. break;
  417. } // for( ; pTop != NULL; pTop = pTop->GetParentMenuWnd() )
  418. if( pTop != NULL )
  419. {
  420. DWORD dwTrackFlags = pTop->TrackFlagsGet();
  421. switch( (dwTrackFlags & TPMX_ALIGN_MASK) )
  422. {
  423. case TPMX_TOPALIGN:
  424. case TPMX_BOTTOMALIGN:
  425. dwTrackFlags &= ~(TPMX_ALIGN_MASK);
  426. dwTrackFlags |= TPMX_RIGHTALIGN;
  427. pTop->TrackFlagsSet( dwTrackFlags );
  428. break;
  429. } // switch( (pTop->m_dwTrackFlags & TPMX_ALIGN_MASK) )
  430. } // if( pTop != NULL )
  431. } // if( bRTL && (!m_bTopLevel) )
  432. DWORD dwTrackFlags = TrackFlagsGet();
  433. switch( (dwTrackFlags & TPMX_ALIGN_MASK) )
  434. {
  435. case TPMX_LEFTALIGN:
  436. m_ptTrack.x = m_rcExcludeArea.right;
  437. m_ptTrack.y = m_rcExcludeArea.top;
  438. break;
  439. case TPMX_RIGHTALIGN:
  440. m_ptTrack.x = m_rcExcludeArea.left - _size.cx;
  441. m_ptTrack.y = m_rcExcludeArea.top;
  442. break;
  443. case TPMX_TOPALIGN:
  444. m_ptTrack.x = m_rcExcludeArea.left;
  445. m_ptTrack.y = m_rcExcludeArea.bottom;
  446. break;
  447. case TPMX_BOTTOMALIGN:
  448. m_ptTrack.x = m_rcExcludeArea.left;
  449. m_ptTrack.y = m_rcExcludeArea.top - _size.cy;
  450. break;
  451. default:
  452. bPointAdjusted = false;
  453. break;
  454. } // switch( (dwTrackFlags & TPMX_ALIGN_MASK) )
  455. } // if( m_bExcludeAreaSpec )
  456. if( ! bPointAdjusted )
  457. {
  458. DWORD dwTrackFlags = TrackFlagsGet();
  459. if( (dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_RIGHTALIGN )
  460. m_ptTrack.x -= _size.cx;
  461. else
  462. {
  463. if( (dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_CENTERALIGN )
  464. m_ptTrack.x -= _size.cx/2;
  465. }
  466. if( (dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_BOTTOMALIGN )
  467. m_ptTrack.y -= _size.cy;
  468. else
  469. {
  470. if( (dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_VCENTERALIGN )
  471. m_ptTrack.y -= _size.cy/2;
  472. }
  473. } // if( !bPointAdjusted )
  474. if( bMoveWindow )
  475. {
  476. CRect wr = _CalcTrackRect();
  477. MoveWindow( &wr );
  478. } // if( bMoveWindow )
  479. }
  480. void CExtPopupMenuWnd::_RecalcLayoutImpl()
  481. {
  482. ASSERT_VALID( this );
  483. CRect rcClient;
  484. _GetClientRect( &rcClient );
  485. bool bTearOff = _IsTearOff();
  486. int nTearOffCaptionHeight = bTearOff ? _GetTearOffCaptionHeight() : 0;
  487. int nScrollBtnDy = _GetSpecBtnHeight();
  488. CRect rcMB = OnQueryMenuBorderMetrics();
  489. int nMenuShadowSize = 0;
  490. // OnQueryMenuShadowSize();
  491. int nScrollBottomOffsetDy = 0;
  492. if( m_bExpandAvailable )
  493. {
  494. m_rcExpandBtn.left =
  495. rcClient.left + rcMB.left;
  496. m_rcExpandBtn.right =
  497. rcClient.right - (rcMB.right + nMenuShadowSize);
  498. m_rcExpandBtn.bottom =
  499. rcClient.bottom - (rcMB.bottom + nMenuShadowSize);
  500. m_rcExpandBtn.top =
  501. m_rcExpandBtn.bottom - nScrollBtnDy;
  502. nScrollBottomOffsetDy =
  503. - m_rcExpandBtn.Height();
  504. m_rcExpandBtn.left += m_nLeftAreaWidth;
  505. m_rcExpandBtn.OffsetRect(0,-1);
  506. } // if( m_bExpandAvailable )
  507. m_rcRibbonBtnOptions.SetRectEmpty();
  508. m_rcRibbonBtnExit.SetRectEmpty();
  509. DWORD dwTrackFlags = TrackFlagsGet();
  510. if( (dwTrackFlags&TPMX_RIBBON_FILE_MENU) != 0 )
  511. {
  512. CRect rcAlign = rcClient;
  513. rcAlign.top = rcAlign.bottom - rcMB.bottom;
  514. rcAlign.right -= 7;
  515. rcAlign.DeflateRect( 0, 3 );
  516. if( (dwTrackFlags&TPMX_RIBBON_EXIT_BUTTON) != 0 )
  517. {
  518. INT nButtonWidth = 50;
  519. RIBBONFILEMENUBUTTONQUERY _rfmbq( this, TPMX_RIBBON_EXIT_BUTTON );
  520. if( _rfmbq.Notify() )
  521. {
  522. nButtonWidth = _rfmbq.m_nMeasuredWidth;
  523. ASSERT( nButtonWidth >= 0 );
  524. }
  525. m_rcRibbonBtnExit = rcAlign;
  526. m_rcRibbonBtnExit.left = m_rcRibbonBtnExit.right - nButtonWidth;
  527. rcAlign.right -= m_rcRibbonBtnExit.Width() + 5;
  528. } // if( (dwTrackFlags&TPMX_RIBBON_EXIT_BUTTON) != 0 )
  529. if( (dwTrackFlags&TPMX_RIBBON_OPTIONS_BUTTON) != 0 )
  530. {
  531. INT nButtonWidth = 50;
  532. RIBBONFILEMENUBUTTONQUERY _rfmbq( this, TPMX_RIBBON_OPTIONS_BUTTON );
  533. if( _rfmbq.Notify() )
  534. {
  535. nButtonWidth = _rfmbq.m_nMeasuredWidth;
  536. ASSERT( nButtonWidth >= 0 );
  537. }
  538. m_rcRibbonBtnOptions = rcAlign;
  539. m_rcRibbonBtnOptions.left = m_rcRibbonBtnOptions.right - nButtonWidth;
  540. rcAlign.right -= m_rcRibbonBtnOptions.Width() + 5;
  541. } // if( (dwTrackFlags&TPMX_RIBBON_OPTIONS_BUTTON) != 0 )
  542. } // if( (dwTrackFlags&TPMX_RIBBON_FILE_MENU) != 0 )
  543. if( m_bScrollingAvailable )
  544. {
  545. m_rcScrollTop.left = m_rcScrollBottom.left =
  546. rcClient.left + rcMB.left;
  547. m_rcScrollTop.right = m_rcScrollBottom.right =
  548. rcClient.right - (rcMB.right + nMenuShadowSize);
  549. m_rcScrollTop.top =
  550. rcClient.top + rcMB.top;
  551. m_rcScrollTop.bottom =
  552. m_rcScrollTop.top + nScrollBtnDy;
  553. m_rcScrollBottom.bottom =
  554. rcClient.bottom - (rcMB.bottom + nMenuShadowSize);
  555. m_rcScrollBottom.top =
  556. m_rcScrollBottom.bottom - nScrollBtnDy;
  557. m_rcScrollTop.DeflateRect(
  558. m_nLeftAreaWidth + 1,
  559. 0,
  560. 1,
  561. 0
  562. );
  563. m_rcScrollBottom.DeflateRect(
  564. m_nLeftAreaWidth + 1,
  565. 0,
  566. 1,
  567. 0
  568. );
  569. m_rcScrollBottom.OffsetRect( 0, nScrollBottomOffsetDy );
  570. m_rcScrollBottom.OffsetRect(0,-1);
  571. m_rcScrollTop.OffsetRect( 0, 1 );
  572. if( bTearOff )
  573. {
  574. m_rcScrollTop.OffsetRect( 0, nTearOffCaptionHeight );
  575. m_rcScrollBottom.OffsetRect( 0, nTearOffCaptionHeight );
  576. }
  577. } // if( m_bScrollingAvailable )
  578. if( bTearOff )
  579. {
  580. m_rcTearOffBtn.left =
  581. rcClient.left + rcMB.left;
  582. m_rcTearOffBtn.right =
  583. rcClient.right - (rcMB.right + nMenuShadowSize);
  584. m_rcTearOffBtn.top =
  585. rcClient.top + rcMB.top;
  586. m_rcTearOffBtn.bottom =
  587. m_rcTearOffBtn.top + nTearOffCaptionHeight;
  588. m_rcTearOffBtn.DeflateRect(
  589. m_nLeftAreaWidth + 1,
  590. 0,
  591. 1,
  592. 0
  593. );
  594. m_rcTearOffBtn.OffsetRect( 0, 1 );
  595. }
  596. }
  597. class CExtPopupMenuWnd::CExtPopupMenuCmdUI : public CCmdUI
  598. {
  599. public: // re-implementations only
  600. HWND m_hWndCmdReceiver;
  601. CExtPopupMenuWnd * m_pPopup;
  602. CExtPopupMenuWnd::MENUITEMDATA * m_pItemDataActive;
  603. CExtPopupMenuCmdUI(
  604. HWND hWndCmdReceiver,
  605. CExtPopupMenuWnd * pPopup
  606. )
  607. : m_hWndCmdReceiver( hWndCmdReceiver )
  608. , m_pPopup( pPopup )
  609. , m_pItemDataActive( NULL )
  610. {
  611. ASSERT( m_hWndCmdReceiver != NULL && ::IsWindow(m_hWndCmdReceiver) );
  612. ASSERT_VALID( m_pPopup );
  613. CCmdUI::m_pOther = NULL; // menu
  614. CCmdUI::m_nIndexMax = (UINT)m_pPopup->ItemGetCount();
  615. CCmdUI::m_nIndex = 0;
  616. }
  617. void SetActiveIndex( int nIndex )
  618. {
  619. ASSERT( m_hWndCmdReceiver != NULL && ::IsWindow(m_hWndCmdReceiver) );
  620. ASSERT_VALID( m_pPopup );
  621. CCmdUI::m_nIndex = (UINT)nIndex;
  622. ASSERT( CCmdUI::m_nIndex >= 0 && CCmdUI::m_nIndex < CCmdUI::m_nIndexMax );
  623. m_pItemDataActive = &m_pPopup->ItemGetInfo(nIndex);
  624. ASSERT( m_pItemDataActive != NULL );
  625. CCmdUI::m_nID = m_pItemDataActive->GetCmdID();
  626. if( m_pItemDataActive->IsPopup()
  627. || m_pItemDataActive->IsSeparator()
  628. || CExtCmdManager::IsSystemCommand( CCmdUI::m_nID )
  629. )
  630. return;
  631. CExtCmdItem * pCmdItem =
  632. g_CmdManager->CmdGetPtr(
  633. g_CmdManager->ProfileNameFromWnd(m_hWndCmdReceiver),
  634. CCmdUI::m_nID
  635. );
  636. if( pCmdItem == NULL )
  637. return;
  638. // m_pItemDataActive->SetText( pCmdItem->m_sMenuText );
  639. m_pItemDataActive->SetAccelText( pCmdItem->m_sAccelText );
  640. m_pItemDataActive->AccelCharInit();
  641. int nIconAreaWidthSaved = m_pItemDataActive->GetIconAreaWidth();
  642. m_pItemDataActive->MeasureItem( NULL );
  643. m_pItemDataActive->UpdateIconAreaWidth( nIconAreaWidthSaved );
  644. }
  645. virtual void Enable(BOOL bOn)
  646. {
  647. CCmdUI::m_bEnableChanged = TRUE;
  648. ASSERT( m_hWndCmdReceiver != NULL && ::IsWindow(m_hWndCmdReceiver) );
  649. ASSERT_VALID( m_pPopup );
  650. ASSERT( m_pItemDataActive != NULL );
  651. if( m_pItemDataActive->IsPopup() && m_pItemDataActive->GetCmd() == NULL )
  652. return;
  653. if( m_pItemDataActive->IsForceEnabled() )
  654. bOn = TRUE;
  655. m_pItemDataActive->Enable( bOn ? true : false );
  656. // m_pItemDataActive->MeasureItem( NULL );
  657. }
  658. virtual void SetRadio(BOOL bOn)
  659. {
  660. ASSERT( m_hWndCmdReceiver != NULL && ::IsWindow(m_hWndCmdReceiver) );
  661. ASSERT_VALID( m_pPopup );
  662. ASSERT( m_pItemDataActive != NULL );
  663. if( m_pItemDataActive->IsPopup() )
  664. return;
  665. m_pItemDataActive->Radio( bOn ? true : false );
  666. // m_pItemDataActive->MeasureItem( NULL );
  667. }
  668. virtual void SetCheck(int nCheck)
  669. {
  670. ASSERT_VALID( m_pPopup );
  671. ASSERT( m_pItemDataActive != NULL );
  672. if( m_pItemDataActive->IsPopup() )
  673. return;
  674. m_pItemDataActive->Indeterminate( ( nCheck >= 2 ) ? true : false );
  675. m_pItemDataActive->Check( nCheck ? true : false );
  676. // m_pItemDataActive->MeasureItem( NULL );
  677. }
  678. virtual void SetText( LPCTSTR lpszText )
  679. {
  680. ASSERT( m_hWndCmdReceiver != NULL && ::IsWindow(m_hWndCmdReceiver) );
  681. ASSERT_VALID( m_pPopup );
  682. ASSERT( m_pItemDataActive != NULL );
  683. if( lpszText == NULL )
  684. return;
  685. if( m_pItemDataActive->IsPopup() )
  686. return;
  687. m_pItemDataActive->SetText( lpszText );
  688. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  689. CExtCustomizeCmdTreeNode * pNode = m_pItemDataActive->GetCmdNode();
  690. if( pNode != NULL )
  691. {
  692. ASSERT_VALID( pNode );
  693. pNode->SetTextInMenu( lpszText );
  694. pNode->SetTextInToolbar( lpszText );
  695. } // if( pNode != NULL )
  696. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  697. m_pItemDataActive->MeasureItem( NULL );
  698. }
  699. }; // class CExtPopupMenuWnd::CExtPopupMenuCmdUI
  700. void CExtPopupMenuWnd::_UpdateCmdUI()
  701. {
  702. ASSERT_VALID( this );
  703. if( _FindHelpMode() )
  704. return;
  705. if( m_bTopLevel )
  706. {
  707. DWORD dwTrackFlags = TrackFlagsGet();
  708. if( (dwTrackFlags&TPMX_NO_CMD_UI) != 0 )
  709. return;
  710. }
  711. ASSERT( m_hWndCmdReceiver != NULL );
  712. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  713. __EXT_MFC_SAFE_LPCTSTR strProfileName = g_CmdManager->ProfileNameFromWnd(m_hWndCmdReceiver);
  714. CExtCustomizeSite * pSite = CExtCustomizeSite::GetCustomizeSite(m_hWndCmdReceiver);
  715. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  716. BOOL bDisableIfNoHndler = TRUE;
  717. CExtPopupMenuCmdUI _state( m_hWndCmdReceiver, this );
  718. bool bResyncItems = false;
  719. for( INT _iter = 0;
  720. _iter < m_items_all.GetSize();
  721. _iter++
  722. )
  723. { // walk all items
  724. _state.SetActiveIndex( _iter );
  725. ASSERT( _state.m_pItemDataActive != NULL );
  726. if( _state.m_pItemDataActive->IsNoCmdUI() )
  727. continue;
  728. if( _state.m_pItemDataActive->IsSeparator() )
  729. continue;
  730. if( _state.m_pItemDataActive->IsPopup() )
  731. {
  732. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  733. if( /* _state.m_pItemDataActive->IsInplaceEdit()
  734. &&*/ pSite != NULL
  735. && _state.m_pItemDataActive->GetCmdNode() != NULL
  736. )
  737. {
  738. UINT _nCmdIdSaved = _state.m_pItemDataActive->m_nCmdID;
  739. _state.m_nID =
  740. _state.m_pItemDataActive ->
  741. GetCmdNode() ->
  742. GetCmdID( false );
  743. ASSERT( CExtCmdManager::IsCommand( _state.m_nID ) );
  744. HWND hWndCmdReceiver =
  745. _state.m_pItemDataActive->GetCmdReceiver();
  746. ASSERT( hWndCmdReceiver != NULL );
  747. ASSERT( ::IsWindow(hWndCmdReceiver) );
  748. CWnd * pWndCmdReceiver =
  749. CWnd::FromHandle( hWndCmdReceiver );
  750. ASSERT_VALID( pWndCmdReceiver );
  751. _state.DoUpdate( pWndCmdReceiver, bDisableIfNoHndler );
  752. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  753. if( pSite != NULL
  754. && pSite->IsCustomizeMode()
  755. )
  756. _state.m_pItemDataActive->SetForceEnabled( true );
  757. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  758. _state.m_pItemDataActive->m_nCmdID = _nCmdIdSaved;
  759. _state.m_pItemDataActive->GetPopup()->_UpdateCmdUI();
  760. continue;
  761. }
  762. else
  763. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  764. {
  765. _state.m_pItemDataActive->GetPopup()->_UpdateCmdUI();
  766. continue;
  767. }
  768. }
  769. if( _state.m_pItemDataActive->IsExtraMark() )
  770. {
  771. bResyncItems = true;
  772. continue;
  773. }
  774. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  775. if( pSite != NULL
  776. && pSite->IsUserBarCommand(
  777. _state.m_pItemDataActive->GetCmdID()
  778. )
  779. && strProfileName != NULL
  780. )
  781. {
  782. _state.m_pItemDataActive->SetForceEnabled( true );
  783. CExtCmdItem * pCmdItem =
  784. g_CmdManager->CmdGetPtr(
  785. strProfileName,
  786. _state.m_pItemDataActive->GetCmdID()
  787. );
  788. ASSERT( pCmdItem != NULL );
  789. CExtToolControlBar * pUserBar =
  790. pSite->GetUserBar( _state.m_pItemDataActive->GetCmdID() );
  791. ASSERT_VALID( pUserBar );
  792. bool bCheck = pUserBar->IsVisible() ? true : false;
  793. pCmdItem->StateSetCheck( bCheck );
  794. _state.SetCheck( bCheck );
  795. continue;
  796. }
  797. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  798. if( CExtCmdManager::IsCommandNeedsSpecUpdate(
  799. _state.m_pItemDataActive->GetCmdID()
  800. )
  801. || CExtCmdManager::IsSystemCommand(
  802. _state.m_pItemDataActive->GetCmdID()
  803. )
  804. )
  805. continue;
  806. HWND hWndCmdReceiver =
  807. _state.m_pItemDataActive->GetCmdReceiver();
  808. ASSERT( hWndCmdReceiver != NULL );
  809. ASSERT( ::IsWindow(hWndCmdReceiver) );
  810. CWnd * pWndCmdReceiver =
  811. CWnd::FromHandle( hWndCmdReceiver );
  812. ASSERT_VALID( pWndCmdReceiver );
  813. _state.DoUpdate( pWndCmdReceiver, bDisableIfNoHndler );
  814. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  815. if( pSite != NULL
  816. && pSite->IsCustomizeMode()
  817. )
  818. _state.m_pItemDataActive->SetForceEnabled( true );
  819. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  820. }  // walk all items
  821. if( bResyncItems )
  822. _SyncItems();
  823. }
  824. bool CExtPopupMenuWnd::MENUITEMDATA::ConstructPopup()
  825. {
  826. ASSERT( m_iconPopup.IsEmpty() );
  827. ASSERT( m_pWndChild == NULL );
  828. m_pWndChild =
  829. CExtPopupMenuWnd::InstantiatePopupMenu(
  830. m_hWndSpecCmdReceiver,
  831. RUNTIME_CLASS(CExtPopupMenuWnd),
  832. m_pOwner
  833. );
  834. ASSERT( m_hWndSpecCmdReceiver != NULL );
  835. ASSERT( ::IsWindow(m_hWndSpecCmdReceiver) );
  836. m_pWndChild->m_hWndCmdReceiver = m_hWndSpecCmdReceiver;
  837. return true;
  838. }
  839. void CExtPopupMenuWnd::MENUITEMDATA::DestroyPopup()
  840. {
  841. VERIFY( SetPopupIcon(NULL) );
  842. if( m_pWndChild == NULL )
  843. return;
  844. if( m_pWndChild->GetSafeHwnd() != NULL
  845. && ::IsWindow( m_pWndChild->GetSafeHwnd() )
  846. )
  847. {
  848. CExtPopupMenuWnd * pPopup = m_pWndChild;
  849. // INT nSaved = pPopup->m_nFadeOutAnimationStepCount;
  850. // pPopup->m_nFadeOutAnimationStepCount = -1;
  851. pPopup->DestroyWindow();
  852. // pPopup->m_nFadeOutAnimationStepCount = nSaved;
  853. }
  854. // else
  855. // delete m_pWndChild;
  856. delete m_pWndChild;
  857. m_pWndChild = NULL;
  858. }
  859. void CExtPopupMenuWnd::MENUITEMDATA::SetCustomTip( __EXT_MFC_SAFE_LPCTSTR sTip )
  860. {
  861. m_sCustomTipText.Empty();
  862. if( sTip != NULL )
  863. m_sCustomTipText = sTip;
  864. }
  865. __EXT_MFC_SAFE_LPCTSTR CExtPopupMenuWnd::MENUITEMDATA::GetCustomTip() const
  866. {
  867. if( m_sCustomTipText.IsEmpty() )
  868. return NULL;
  869. return LPCTSTR( m_sCustomTipText );
  870. }
  871. void CExtPopupMenuWnd::MENUITEMDATA::SetExtendedText( __EXT_MFC_SAFE_LPCTSTR sExtendedText )
  872. {
  873. m_sExtendedText.Empty();
  874. if( sExtendedText != NULL )
  875. m_sExtendedText = sExtendedText;
  876. }
  877. __EXT_MFC_SAFE_LPCTSTR CExtPopupMenuWnd::MENUITEMDATA::GetExtendedText() const
  878. {
  879. if( m_sExtendedText.IsEmpty() )
  880. return NULL;
  881. return LPCTSTR( m_sExtendedText );
  882. }
  883. void CExtPopupMenuWnd::MENUITEMDATA::GetTip( CExtSafeString & sTip ) const
  884. {
  885. sTip = _T("");
  886. if( IsPopup() || IsSeparator() )
  887. return;
  888. LPCTSTR sCustomTip = GetCustomTip();
  889. if( sCustomTip != NULL )
  890. {
  891. sTip = sCustomTip;
  892. return;
  893. }
  894. if( GetCmd() == NULL )
  895. return;
  896. CExtCmdItem * pCmdItem = GetCmd();
  897. if( pCmdItem == NULL )
  898. return;
  899. UINT nTranslatedResourceCmdID = UINT(-1);
  900. switch( pCmdItem->m_nCmdID )
  901. {
  902. case SC_CLOSE:
  903. nTranslatedResourceCmdID = AFX_IDS_SCCLOSE;
  904. break;
  905. case SC_SIZE:
  906. nTranslatedResourceCmdID = AFX_IDS_SCSIZE;
  907. break;
  908. case SC_MOVE:
  909. nTranslatedResourceCmdID = AFX_IDS_SCMOVE;
  910. break;
  911. case SC_MINIMIZE:
  912. nTranslatedResourceCmdID = AFX_IDS_SCMINIMIZE;
  913. break;
  914. case SC_MAXIMIZE:
  915. nTranslatedResourceCmdID = AFX_IDS_SCMAXIMIZE;
  916. break;
  917. case SC_RESTORE:
  918. nTranslatedResourceCmdID = AFX_IDS_SCRESTORE;
  919. break;
  920. case SC_NEXTWINDOW:
  921. nTranslatedResourceCmdID = AFX_IDS_SCNEXTWINDOW;
  922. break;
  923. case SC_PREVWINDOW:
  924. nTranslatedResourceCmdID = AFX_IDS_SCPREVWINDOW;
  925. break;
  926. case SC_TASKLIST:
  927. nTranslatedResourceCmdID = AFX_IDS_SCTASKLIST;
  928. break;
  929. } // switch( pCmdItem->m_nCmdID )
  930. if( nTranslatedResourceCmdID == UINT(-1) )
  931. {
  932. sTip = pCmdItem->m_sTipStatus;
  933. return;
  934. } // if( nTranslatedResourceCmdID == UINT(-1) )
  935. if( ! g_ResourceManager->LoadString( sTip, nTranslatedResourceCmdID ) )
  936. {
  937. sTip = pCmdItem->m_sTipStatus;
  938. return;
  939. }
  940. else
  941. {
  942. int nSep = sTip.ReverseFind('n');
  943. if( nSep < 0 )
  944. return;
  945. CString sBuffer = sTip.Left( nSep );
  946. sTip = sBuffer;
  947. }
  948. }
  949. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  950. bool CExtPopupMenuWnd::MENUITEMDATA::InitSceenTip( CExtPopupScreenTipWnd & _wndScreenTip )
  951. {
  952. if( m_pOwner->GetSafeHwnd() == NULL )
  953. return false;
  954. ASSERT_VALID( m_pOwner );
  955. INT nOwnIndex = m_pOwner->ItemGetIndexOf( this );
  956. if( nOwnIndex < 0 )
  957. return false;
  958. CExtCustomizeCmdTreeNode * pNode = GetCmdNode();
  959. if( pNode == NULL )
  960. return false;
  961. ASSERT_VALID( pNode );
  962. CExtCustomizeCmdScreenTip * pCCST = pNode->CmdScreenTipFindForDisplaying();
  963. if( pCCST == NULL )
  964. return false;
  965. ASSERT_VALID( pCCST );
  966. if( pCCST->IsEmpty() )
  967. return false;
  968. CRect rcOwn( 0, 0, 0, 0 );
  969. m_pOwner->_GetItemRect( nOwnIndex, rcOwn, true );
  970. if( rcOwn.IsRectEmpty() )
  971. return false;
  972. m_pOwner->ClientToScreen( &rcOwn );
  973. if( _wndScreenTip.GetSafeHwnd() != NULL )
  974. {
  975. CRect rcExisting = _wndScreenTip.GetExcludeArea();
  976. if( rcOwn == rcExisting )
  977. return true;
  978. }
  979. _wndScreenTip.Hide();
  980. _wndScreenTip.m_cmdScreenTip = (*pCCST);
  981. //if( CExtToolControlBar::g_bToolbarShortcutKeysOnScreenTips )
  982. {
  983. CExtCmdItem * pCmdItem = GetCmd();
  984. if( pCmdItem != NULL
  985. && ( ! pCmdItem->m_sAccelText.IsEmpty() )
  986. )
  987. {
  988. CExtSafeString str = _wndScreenTip.m_cmdScreenTip.CaptionMainGet();
  989. if( ! str.IsEmpty() )
  990. {
  991. str += _T(" (");
  992. str += pCmdItem->m_sAccelText;
  993. str += _T(")");
  994. _wndScreenTip.m_cmdScreenTip.CaptionMainSet( LPCTSTR( str ) );
  995. }
  996. else
  997. {
  998. CExtSafeString str = _wndScreenTip.m_cmdScreenTip.TextMainGet();
  999. if( ! str.IsEmpty() )
  1000. {
  1001. str += _T(" (");
  1002. str += pCmdItem->m_sAccelText;
  1003. str += _T(")");
  1004. _wndScreenTip.m_cmdScreenTip.TextMainSet( LPCTSTR( str ) );
  1005. }
  1006. }
  1007. }
  1008. }
  1009. _wndScreenTip.Show( m_pOwner, rcOwn );
  1010. return true;
  1011. }
  1012. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  1013. bool CExtPopupMenuWnd::_BuildItems(
  1014. CMenu * pBuildMenu,
  1015. bool bTopLevel,
  1016. bool bNoRefToCmdMngr // = false
  1017. )
  1018. {
  1019. ASSERT_VALID( this );
  1020. #ifdef _DEBUG
  1021. if( pBuildMenu != NULL )
  1022. {
  1023. ASSERT( m_hWndCmdReceiver != NULL );
  1024. ASSERT( ::IsWindow(m_hWndCmdReceiver) );
  1025. }
  1026. #endif // _DEBUG
  1027. INT iter = 0;
  1028. for( ; iter < m_items_all.GetSize(); iter++)
  1029. {
  1030. MENUITEMDATA & mi = ItemGetInfo( iter );
  1031. if( mi.IsPopup() )
  1032. {
  1033. CExtPopupMenuWnd * pPopup = mi.GetPopup();
  1034. pPopup->m_hWndCmdReceiver = m_hWndCmdReceiver;
  1035. INT nSaved = pPopup->m_nFadeOutAnimationStepCount;
  1036. pPopup->m_nFadeOutAnimationStepCount = -1;
  1037. pPopup->_OnCancelMode();
  1038. pPopup->m_nFadeOutAnimationStepCount = nSaved;
  1039. VERIFY( pPopup->_BuildItems( NULL, false, bNoRefToCmdMngr ) );
  1040. mi.DestroyPopup();
  1041. }
  1042. } // for( ; iter < m_items_all.GetSize(); iter++)
  1043. m_items_all.RemoveAll();
  1044. if( pBuildMenu == NULL )
  1045. return true;
  1046. ASSERT( pBuildMenu->GetSafeHmenu() != NULL );
  1047. m_bTopLevel = bTopLevel;
  1048. if( m_bTopLevel )
  1049. m_pWndParentMenu = NULL;
  1050. // build items loop
  1051. bool bPrevWasSeparator = false;
  1052. int nMruUpdateIndex = -1, nInsertedIndex = 0;
  1053. int nMenuItemCount = pBuildMenu->GetMenuItemCount();
  1054. ASSERT( nMenuItemCount >= 0 );
  1055. m_items_all.RemoveAll();
  1056. for( int nItemIndex=0; nItemIndex<nMenuItemCount; nItemIndex++ )
  1057. {
  1058. UINT nMenuItemID =
  1059. pBuildMenu->GetMenuItemID( nItemIndex );
  1060. if( ID_FILE_MRU_FIRST <= nMenuItemID
  1061. && nMenuItemID <= ID_FILE_MRU_LAST
  1062. )
  1063. {
  1064. if( nMruUpdateIndex < 0 )
  1065. nMruUpdateIndex = nInsertedIndex;
  1066. continue;
  1067. }
  1068. MENUITEMDATA mi( this );
  1069. mi.SetCmdReceiver( m_hWndCmdReceiver );
  1070. VERIFY(
  1071. mi.UpdateFromMenu(
  1072. m_hWndCmdReceiver,
  1073. pBuildMenu,
  1074. nItemIndex,
  1075. bNoRefToCmdMngr
  1076. )
  1077. );
  1078. bool bIsSeparator = mi.IsSeparator();
  1079. if( bPrevWasSeparator && bIsSeparator )
  1080. continue;
  1081. bPrevWasSeparator = bIsSeparator;
  1082. if( mi.IsPopup() )
  1083. {
  1084. CMenu * pSubMenu =
  1085. pBuildMenu->GetSubMenu(nItemIndex);
  1086. ASSERT( pSubMenu != NULL );
  1087. ASSERT( pSubMenu->GetSafeHmenu() != NULL );
  1088. mi.GetPopup()->m_hWndCmdReceiver = m_hWndCmdReceiver;
  1089. mi.GetPopup()->_BuildItems( pSubMenu, false, bNoRefToCmdMngr );
  1090. mi.GetPopup()->m_pWndParentMenu = this;
  1091. }
  1092. _InsertItem( -1, mi, bNoRefToCmdMngr );
  1093. nInsertedIndex++;
  1094. } // for( int nItemIndex=0; nItemIndex<nMenuItemCount; nItemIndex++ )
  1095. ASSERT( m_items_all.GetSize() <= nMenuItemCount );
  1096. int nMruInsertCount = 0;
  1097. if( nMruUpdateIndex >= 0 && (!bNoRefToCmdMngr) )
  1098. { // insert recently opened file items
  1099. ASSERT( nMruUpdateIndex < nMenuItemCount );
  1100. CRecentFileList * pRecentFileList =
  1101. InternalFriendlyWinApp::_GetFriendlyApp()->
  1102. _GetRecentFileList();
  1103. if( pRecentFileList != NULL )
  1104. { // can be null !?
  1105. int nRecentCount =
  1106. pRecentFileList->GetSize();
  1107. TCHAR sCurrDir[_MAX_PATH+1];
  1108. ::memset(sCurrDir,0,sizeof(sCurrDir));
  1109. ::GetCurrentDirectory(_MAX_PATH,sCurrDir);
  1110. int nLenCurDir = (int)_tcslen(sCurrDir);
  1111. for( int nItemIndex=0; nItemIndex<nRecentCount; nItemIndex++ )
  1112. {
  1113. CExtSafeString sDisplayName( _T("") );
  1114. CExtSafeString sDisplayNameFullPath( _T("") );
  1115. CExtSafeString sDisplayNameMenu( _T("") );
  1116. CExtSafeString sDisplayNameTipTool( _T("") );
  1117.             sDisplayNameFullPath = ( ! pRecentFileList->m_arrNames[ nItemIndex ].IsEmpty() ) ? LPCTSTR( pRecentFileList->m_arrNames[ nItemIndex ] ) : _T("");
  1118.             pRecentFileList->GetDisplayName( *((CString *)&sDisplayName), nItemIndex, sCurrDir, nLenCurDir, TRUE );
  1119.             if( sDisplayName.IsEmpty() || sDisplayNameFullPath.IsEmpty() )
  1120. continue;
  1121.             if( g_bMRU_UseFullPathsInMenu )
  1122.                sDisplayNameMenu = sDisplayNameFullPath;
  1123.             else 
  1124.                sDisplayNameMenu = sDisplayName;
  1125.             if( g_bMRU_UseFullPathsInTipTool )
  1126.                sDisplayNameTipTool = sDisplayNameFullPath;
  1127.             else 
  1128.                sDisplayNameTipTool = sDisplayName;
  1129. UINT nCmdID = ID_FILE_MRU_FIRST + nItemIndex;
  1130. ASSERT( nCmdID <= ID_FILE_MRU_LAST );
  1131. CExtCmdItem * pCmdItem =
  1132. g_CmdManager->CmdGetPtr(
  1133. g_CmdManager->ProfileNameFromWnd( m_hWndCmdReceiver ),
  1134. nCmdID
  1135. );
  1136. if( pCmdItem == NULL )
  1137. pCmdItem =
  1138. g_CmdManager->CmdAllocPtr(
  1139. g_CmdManager->ProfileNameFromWnd( m_hWndCmdReceiver ),
  1140. nCmdID
  1141. );
  1142. ASSERT( pCmdItem != NULL );
  1143. if( pCmdItem == NULL )
  1144. return false;
  1145. int nDisplayIndex = nItemIndex+1;
  1146. if( nDisplayIndex < 10 )
  1147. pCmdItem->m_sMenuText.Format(
  1148. _T("&%d %s"),
  1149. nDisplayIndex,
  1150. sDisplayNameMenu
  1151. );
  1152. else
  1153. pCmdItem->m_sMenuText.Format(
  1154. _T("%d&%d %s"),
  1155. nDisplayIndex/10,
  1156. nDisplayIndex%10,
  1157. sDisplayNameMenu
  1158. );
  1159. CExtSafeString sRecentFileFmt1,sRecentFileFmt2;
  1160. if( ! g_ResourceManager->LoadString( sRecentFileFmt1, IDS_RECENT_FILE_FMT_1 ) )
  1161. sRecentFileFmt1 = _T("Recent file %d");
  1162. if( ! g_ResourceManager->LoadString( sRecentFileFmt2, IDS_RECENT_FILE_FMT_2 ) )
  1163. sRecentFileFmt2 = _T("Recent file %d ("%s")");
  1164. pCmdItem->m_sToolbarText.Format(
  1165. (LPCTSTR)sRecentFileFmt1,
  1166. nItemIndex + 1
  1167. );
  1168. pCmdItem->m_sTipTool.Format(
  1169. (LPCTSTR)sRecentFileFmt2,
  1170. nItemIndex + 1,
  1171. sDisplayNameTipTool
  1172. );
  1173. pCmdItem->m_sTipStatus = pCmdItem->m_sTipTool;
  1174. BOOL bInsRetVal =
  1175. ItemInsert(
  1176. nCmdID,
  1177. nMruUpdateIndex + nItemIndex
  1178. );
  1179. if( ! bInsRetVal )
  1180. {
  1181. ASSERT( FALSE );
  1182. return false;
  1183. }
  1184. nMruInsertCount++;
  1185. } // for( nItemIndex=0; nItemIndex<nRecentCount; nItemIndex++ )
  1186. } // can be null !?
  1187. if( nMruInsertCount > 0 )
  1188. {
  1189. if( ! ItemInsert(
  1190. ID_SEPARATOR,
  1191. nMruUpdateIndex + nMruInsertCount
  1192. )
  1193. )
  1194. {
  1195. ASSERT( FALSE );
  1196. return false;
  1197. }
  1198. nMruInsertCount++;
  1199. } // if( nMruInsertCount > 0 )
  1200. } // insert recently opened file items
  1201. _SyncItems();
  1202. return true;
  1203. }
  1204. void CExtPopupMenuWnd::_GetClientRect(RECT * pRectClient)
  1205. {
  1206. ASSERT_VALID( this );
  1207. ASSERT( pRectClient != NULL );
  1208. ASSERT( GetSafeHwnd() != NULL );
  1209. ::CopyRect( pRectClient, &m_rcClient );
  1210. ASSERT( pRectClient->top <= pRectClient->bottom );
  1211. ASSERT( pRectClient->left <= pRectClient->right );
  1212. }
  1213. BOOL CExtPopupMenuWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  1214. {
  1215. ASSERT_VALID( this );
  1216. if( _FindHelpMode() )
  1217. {
  1218. SetCursor( afxData.hcurHelp );
  1219. return TRUE;
  1220. }
  1221. CPoint ptCursor;
  1222. if( ::GetCursorPos(&ptCursor) )
  1223. {
  1224. ScreenToClient( &ptCursor );
  1225. int nIndex = _HitTest( ptCursor );
  1226. if( _IsTearOff() && nIndex == IDX_TEAROFF )
  1227. {
  1228. HCURSOR hCursor = ::LoadCursor( NULL, IDC_SIZEALL );
  1229. ASSERT( hCursor != NULL );
  1230. ::SetCursor( hCursor );
  1231. return TRUE;
  1232. } // if( _IsTearOff() && nIndex == IDX_TEAROFF )
  1233. if( ItemGetCount() > 0 )
  1234. {
  1235. if( nIndex >= 0 )
  1236. {
  1237. MENUITEMDATA & mi = ItemGetInfo( nIndex );
  1238. if( (! mi.IsExtraMark() )
  1239. && mi.IsInplaceEdit()
  1240. && mi.IsAllowInplaceEditActivation()
  1241. && (! _FindHelpMode() )
  1242. )
  1243. {
  1244. CRect rcItem;
  1245. _GetItemRect( nIndex, rcItem );
  1246. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  1247. #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD)
  1248. if( _FindCustomizeMode() )
  1249. {
  1250. ASSERT_VALID( mi.GetCmdNode() );
  1251. if( mi.IsSelected()
  1252. && (mi.GetCmdNode()->GetFlags() & __ECTN_TBB_RESIZABLE) != 0
  1253. )
  1254. { // if button can be resized
  1255. int nDdWidth = PmBridge_GetPM()->GetDropDividerMerics().cx / 2;
  1256. if( nDdWidth < 2 )
  1257. nDdWidth = 2;
  1258. CRect rcH( rcItem );
  1259. rcH.right = rcH.left + nDdWidth;
  1260. bool bSetCursor = false;
  1261. if( rcH.PtInRect(ptCursor) )
  1262. bSetCursor = true;
  1263. else
  1264. {
  1265. rcH = rcItem;
  1266. rcH.left = rcH.right - nDdWidth;
  1267. if( rcH.PtInRect(ptCursor) )
  1268. bSetCursor = true;
  1269. } // else from if( rcH.PtInRect(ptCursor) )
  1270. if( bSetCursor )
  1271. {
  1272. CExtLocalResourceHelper _LRH;
  1273. CWinApp * pApp = ::AfxGetApp();
  1274. ASSERT_VALID( pApp );
  1275. HCURSOR hCursor = pApp->LoadCursor( MAKEINTRESOURCE( IDC_EXT_RESIZE_H1 ) );
  1276. if( hCursor == NULL )
  1277. {
  1278. ASSERT( FALSE );
  1279. hCursor = ::LoadCursor( NULL, IDC_SIZEWE );
  1280. } // if( hCursor == NULL )
  1281. ASSERT( hCursor != NULL );
  1282. ::SetCursor( hCursor );
  1283. return TRUE;
  1284. } // if( bSetCursor )
  1285. } // if button can be resized
  1286. } // if( _FindCustomizeMode() )
  1287. else
  1288. #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD)
  1289. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  1290. {
  1291. CRect rcInplaceCtrl =
  1292. mi.AdjustInplaceEditRect(
  1293. rcItem,
  1294. OnQueryLayoutRTL()
  1295. );
  1296. if( rcInplaceCtrl.PtInRect(ptCursor) )
  1297. {
  1298. SetCursor( ::LoadCursor( NULL, IDC_IBEAM ) );
  1299. return TRUE;
  1300. } // if( rcInplaceCtrl.PtInRect(ptCursor) )
  1301. SetCursor( ::LoadCursor( NULL, IDC_ARROW ) );
  1302. } // else from if( _FindCustomizeMode() )
  1303. }
  1304. } // if( nIndex >= 0 )
  1305. } // if( ItemGetCount() > 0)
  1306. } // if( ::GetCursorPos(&ptCursor) )
  1307. return CExtPopupBaseWnd::OnSetCursor(pWnd, nHitTest, message);
  1308. }
  1309. int CExtPopupMenuWnd::_HitTest(
  1310. const CPoint & point,
  1311. bool * p_bInplaceControlArea, // = NULL
  1312. bool * p_bInplaceDropDownArea // = NULL
  1313. )
  1314. {
  1315. ASSERT_VALID( this );
  1316. if( p_bInplaceControlArea != NULL )
  1317. *p_bInplaceControlArea = false;
  1318. if( p_bInplaceDropDownArea != NULL )
  1319. *p_bInplaceDropDownArea = false;
  1320. if( GetSafeHwnd() == NULL )
  1321. return IDX_NOTHING;
  1322. CRect rcClient;
  1323. _GetClientRect( &rcClient );
  1324. if( ! rcClient.PtInRect(point) )
  1325. return IDX_NOTHING;
  1326. DWORD dwTrackFlags = TrackFlagsGet();
  1327. if( (dwTrackFlags&TPMX_RIBBON_FILE_MENU) != 0 )
  1328. {
  1329. if( (dwTrackFlags&TPMX_RIBBON_EXIT_BUTTON) != 0 )
  1330. {
  1331. CRect rcItem;
  1332. _GetItemRect(IDX_RIBBON_FILE_MENU_EXIT_BUTTON,rcItem);
  1333. if( rcItem.PtInRect(point) )
  1334. return IDX_RIBBON_FILE_MENU_EXIT_BUTTON;
  1335. } // if( (dwTrackFlags&TPMX_RIBBON_EXIT_BUTTON) != 0 )
  1336. if( (dwTrackFlags&TPMX_RIBBON_OPTIONS_BUTTON) != 0 )
  1337. {
  1338. CRect rcItem;
  1339. _GetItemRect(IDX_RIBBON_FILE_MENU_OPTIONS_BUTTON,rcItem);
  1340. if( rcItem.PtInRect(point) )
  1341. return IDX_RIBBON_FILE_MENU_OPTIONS_BUTTON;
  1342. } // if( (dwTrackFlags&TPMX_RIBBON_OPTIONS_BUTTON) != 0 )
  1343. } // if( (dwTrackFlags&TPMX_RIBBON_FILE_MENU) != 0 )
  1344. if( m_bScrollingAvailable )
  1345. {
  1346. CRect rcItem;
  1347. if( m_nDyScrollOffset != 0 )
  1348. {
  1349. _GetItemRect(IDX_SCROLL_TOP,rcItem);
  1350. if( rcItem.PtInRect(point) )
  1351. return IDX_SCROLL_TOP;
  1352. }
  1353. int nMaxScrollPos = _GetMaxScrollPos();
  1354. if( m_nDyScrollOffset != nMaxScrollPos )
  1355. {
  1356. _GetItemRect(IDX_SCROLL_BOTTOM,rcItem);
  1357. if( rcItem.PtInRect(point) )
  1358. return IDX_SCROLL_BOTTOM;
  1359. }
  1360. }
  1361. if( m_bExpandAvailable )
  1362. {
  1363. CRect rcExpand;
  1364. _GetItemRect(IDX_EXPAND,rcExpand);
  1365. if( rcExpand.PtInRect(point) )
  1366. return IDX_EXPAND;
  1367. }
  1368. if( _IsTearOff() )
  1369. {
  1370. CRect rcTearOff;
  1371. _GetItemRect(IDX_TEAROFF,rcTearOff);
  1372. if( rcTearOff.PtInRect(point) )
  1373. {
  1374. if( _FindCustomizeMode()
  1375. || _FindHelpMode()
  1376. )
  1377. return IDX_NOTHING;
  1378. return IDX_TEAROFF;
  1379. }
  1380. }
  1381. bool bRTL = OnQueryLayoutRTL();
  1382. INT iter = 0;
  1383. int nIndex = 0;
  1384. for( ; iter < m_items_all.GetSize(); iter++,nIndex++ )
  1385. {
  1386. MENUITEMDATA & mi = ItemGetInfo( iter );
  1387. if( !mi.IsDisplayed() )
  1388. continue;
  1389. CRect rcItem;
  1390. _GetItemRect( nIndex, rcItem );
  1391. if( rcItem.PtInRect(point) )
  1392. {
  1393. int nRetIndex = mi.GetIndex();
  1394. ASSERT(
  1395. nRetIndex >= 0
  1396. && nRetIndex < m_items_all.GetSize()
  1397. );
  1398. if( ( p_bInplaceControlArea != NULL
  1399. || p_bInplaceDropDownArea != NULL
  1400. )
  1401. && mi.IsInplaceEdit()
  1402. )
  1403. {
  1404. CRect rcInplaceCtrl =
  1405. mi.AdjustInplaceEditRect(
  1406. rcItem,
  1407. bRTL
  1408. );
  1409. if( p_bInplaceControlArea != NULL )
  1410. {
  1411. if( rcInplaceCtrl.PtInRect(point) )
  1412. *p_bInplaceControlArea = true;
  1413. }
  1414. if( p_bInplaceDropDownArea != NULL
  1415. && mi.IsPopup()
  1416. )
  1417. {
  1418. rcInplaceCtrl.left = rcInplaceCtrl.right;
  1419. rcInplaceCtrl.right += PmBridge_GetPM()->GetDropDownButtonWidth( this );
  1420. if( rcInplaceCtrl.PtInRect(point) )
  1421. *p_bInplaceDropDownArea = true;
  1422. }
  1423. }
  1424. return nRetIndex;
  1425. }
  1426. } // for( ; iter < m_items_all.GetSize(); iter++,nIndex++ )
  1427. return IDX_NOTHING;
  1428. };
  1429. BEGIN_MESSAGE_MAP(CExtPopupMenuWnd, CExtPopupBaseWnd)
  1430. //{{AFX_MSG_MAP(CExtPopupMenuWnd)
  1431. ON_WM_CANCELMODE()
  1432. ON_WM_TIMER()
  1433. ON_WM_SHOWWINDOW()
  1434. ON_WM_SETCURSOR()
  1435. //}}AFX_MSG_MAP
  1436. ON_WM_ACTIVATEAPP()
  1437. ON_WM_MOUSEMOVE()
  1438. ON_WM_LBUTTONDOWN()
  1439. ON_WM_LBUTTONUP()
  1440. ON_WM_LBUTTONDBLCLK()
  1441. ON_WM_MBUTTONDOWN()
  1442. ON_WM_MBUTTONUP()
  1443. ON_WM_MBUTTONDBLCLK()
  1444. ON_WM_RBUTTONDOWN()
  1445. ON_WM_RBUTTONUP()
  1446. ON_WM_RBUTTONDBLCLK()
  1447. ON_WM_KEYDOWN()
  1448. ON_WM_KEYUP()
  1449. ON_WM_SYSKEYDOWN()
  1450. ON_WM_SYSKEYUP()
  1451. ON_WM_SYSDEADCHAR()
  1452. ON_WM_CHAR()
  1453. ON_WM_GETMINMAXINFO()
  1454. __EXT_MFC_ON_WM_NCHITTEST()
  1455. END_MESSAGE_MAP()
  1456. /////////////////////////////////////////////////////////////////////////////
  1457. // CExtPopupMenuWnd message handlers
  1458. UINT CExtPopupMenuWnd::OnNcHitTest(CPoint point)
  1459. {
  1460. DWORD dwTrackFlags = TrackFlagsGet();
  1461. if( (dwTrackFlags&TPMX_RIBBON_RESIZING) != 0 )
  1462. {
  1463. CRect rcMB = PmBridge_GetPM()->GetMenuBorderMetrics( (CWnd*)this );
  1464. ASSERT( rcMB.left >= 0 );
  1465. ASSERT( rcMB.top >= 0 );
  1466. ASSERT( rcMB.right >= 0 );
  1467. ASSERT( rcMB.bottom >= 0 );
  1468. CRect rcClient;
  1469. _GetClientRect( &rcClient );
  1470. CRect rcResizingArea = rcClient;
  1471. rcResizingArea.left += rcMB.left;
  1472. rcResizingArea.right -= rcMB.right;
  1473. rcResizingArea.bottom -= rcMB.bottom;
  1474. INT nMarginHeight = 0, nResizingCornerPartWidth = 0;
  1475. PmBridge_GetPM()->MenuBottomResizingMarginGetInfo(
  1476. nMarginHeight,
  1477. nResizingCornerPartWidth,
  1478. this
  1479. );
  1480. rcResizingArea.top = rcResizingArea.bottom - nMarginHeight;
  1481. ClientToScreen( &rcResizingArea );
  1482. if( (dwTrackFlags&TPMX_RIBBON_RESIZING_VERTICAL_ONLY) != 0 )
  1483. {
  1484. if( rcResizingArea.PtInRect( point ) )
  1485. return HTBOTTOM;
  1486. }
  1487. else
  1488. {
  1489. rcResizingArea.left = rcResizingArea.right - nResizingCornerPartWidth;
  1490. if( rcResizingArea.PtInRect( point ) )
  1491. return HTBOTTOMRIGHT;
  1492. }
  1493. }
  1494. return (UINT)CExtPopupBaseWnd::OnNcHitTest( point );
  1495. }
  1496. void CExtPopupMenuWnd::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
  1497. {
  1498. CExtPopupBaseWnd::OnGetMinMaxInfo( lpMMI );
  1499. }
  1500. BOOL CExtPopupMenuWnd::LoadMenu( 
  1501. HWND hWndCmdRecv,
  1502. UINT nIDResource,
  1503. bool bPopupMenu, // = true
  1504. bool bNoRefToCmdMngr // = false
  1505. )
  1506. {
  1507. ASSERT_VALID( this );
  1508. CMenu menu;
  1509. if( ! g_ResourceManager->LoadMenu( menu, nIDResource ) )
  1510. {
  1511. ASSERT( FALSE );
  1512. return FALSE;
  1513. }
  1514. return
  1515. UpdateFromMenu(
  1516. hWndCmdRecv,
  1517. &menu,
  1518. bPopupMenu,
  1519. true,
  1520. bNoRefToCmdMngr
  1521. );
  1522. }
  1523. bool CExtPopupMenuWnd::g_bMdiWindowsMenuUsesCheckInsteadOfRadio = false;
  1524. BOOL CExtPopupMenuWnd::UpdateMdiWindowsMenu(
  1525. CWnd * pWndStartSearchMdiFrameWnd // = NULL
  1526. )
  1527. {
  1528. ASSERT_VALID( this );
  1529. ASSERT( m_hWndCmdReceiver != NULL );
  1530. ASSERT( ::IsWindow(m_hWndCmdReceiver) );
  1531. CMDIFrameWnd * pFrame = NULL;
  1532. CWnd * pWnd =
  1533. (pWndStartSearchMdiFrameWnd != NULL)
  1534. ? pWndStartSearchMdiFrameWnd
  1535. : FromHandle(m_hWndCmdReceiver) // ::AfxGetMainWnd()
  1536. ;
  1537. while( true )
  1538. {
  1539. ASSERT( pWnd != NULL );
  1540. ASSERT_VALID( pWnd );
  1541. pFrame =
  1542. DYNAMIC_DOWNCAST(
  1543. CMDIFrameWnd,
  1544. pWnd
  1545. );
  1546. if( pFrame != NULL )
  1547. break;
  1548. pWnd = pWnd->GetParentFrame();
  1549. if( pWnd == NULL )
  1550. return FALSE;
  1551. } // while( true )
  1552. if( pFrame == NULL )
  1553. return FALSE;
  1554. int nItemIndex = ItemGetCount();
  1555. if( nItemIndex > 0 )
  1556. {
  1557. MENUITEMDATA & mi = ItemGetInfo(nItemIndex-1);
  1558. if( ! mi.IsSeparator() )
  1559. {
  1560. ItemInsert(ID_SEPARATOR);
  1561. nItemIndex++;
  1562. ASSERT( nItemIndex == ItemGetCount() );
  1563. }
  1564. }
  1565. HWND m_hWndMDIClient = pFrame->m_hWndMDIClient;
  1566. ASSERT( m_hWndMDIClient != NULL );
  1567. ASSERT( ::IsWindow(m_hWndMDIClient) );
  1568. HWND hWndActiveChildFrame = (HWND)
  1569. ::SendMessage( m_hWndMDIClient, WM_MDIGETACTIVE, 0, NULL );
  1570. if( hWndActiveChildFrame != NULL )
  1571. {
  1572. ASSERT( ::IsWindow( hWndActiveChildFrame ) );
  1573. CWnd * pWndTempAnalyze =
  1574. CWnd::FromHandle( hWndActiveChildFrame );
  1575. if( pWndTempAnalyze != NULL )
  1576. {
  1577. ASSERT_VALID( pWndTempAnalyze );
  1578. CMDIChildWnd * pWndTempMDIChild =
  1579. DYNAMIC_DOWNCAST( CMDIChildWnd, pWndTempAnalyze );
  1580. if( pWndTempMDIChild != NULL
  1581. && pWndTempMDIChild->m_bPseudoInactive
  1582. && (pWndTempMDIChild->GetStyle()&WS_VISIBLE) == 0
  1583. )
  1584. hWndActiveChildFrame = NULL;
  1585. } // if( pWndTempAnalyze != NULL )
  1586. } // if( hWndActiveChildFrame != NULL )
  1587. INT nCmdID = __ID_MDIWNDLIST_FIRST;
  1588. INT nWinCount = 0;
  1589. for( INT nWin = 1; true; nWin++, nCmdID++ )
  1590. {
  1591. HWND hWndChildFrame =
  1592. ::GetDlgItem(m_hWndMDIClient, nCmdID);
  1593. if( hWndChildFrame == NULL )
  1594. break;
  1595. if( !::IsWindowVisible( hWndChildFrame ) )
  1596. continue;
  1597. nWinCount ++;
  1598. if( nWinCount <= __ID_MDIWNDLIST_COUNT )
  1599. { // if head of MDI windows list
  1600. ASSERT( ::IsWindow(hWndChildFrame) );
  1601. CString sWinName( _T("") );
  1602. CWnd::FromHandle( hWndChildFrame )-> GetWindowText( sWinName );
  1603. CExtCmdItem * pCmdItem =
  1604. g_CmdManager->CmdGetPtr(
  1605. g_CmdManager->ProfileNameFromWnd( pWndStartSearchMdiFrameWnd->GetSafeHwnd() ),
  1606. nCmdID
  1607. );
  1608. if( pCmdItem == NULL )
  1609. pCmdItem =
  1610. g_CmdManager->CmdAllocPtr(
  1611. g_CmdManager->ProfileNameFromWnd( pWndStartSearchMdiFrameWnd->GetSafeHwnd() ),
  1612. nCmdID
  1613. );
  1614. ASSERT( pCmdItem != NULL );
  1615. if( pCmdItem == NULL )
  1616. return FALSE;
  1617. pCmdItem->m_sMenuText.Format(
  1618. _T("&%d %s"),
  1619. nWinCount,
  1620. sWinName
  1621. );
  1622. pCmdItem->m_sToolbarText = pCmdItem->m_sMenuText;
  1623. CExtSafeString sDocumentNameFmt;
  1624. if( ! g_ResourceManager->LoadString( sDocumentNameFmt, IDS_DOCUMENT_NAME_FMT ) )
  1625. sDocumentNameFmt = _T("Document "%s"");
  1626. pCmdItem->m_sTipTool.Format(
  1627. (LPCTSTR)sDocumentNameFmt,
  1628. sWinName
  1629. );
  1630. pCmdItem->m_sTipStatus = pCmdItem->m_sTipTool;
  1631. bool bRadio =
  1632. (hWndChildFrame == hWndActiveChildFrame)
  1633. ? true : false;
  1634. pCmdItem->StateSetRadio( bRadio );
  1635. if( ! ItemInsert(nCmdID) )
  1636. {
  1637. ASSERT( FALSE );
  1638. return FALSE;
  1639. }
  1640. MENUITEMDATA & mi = ItemGetInfo( ItemGetCount()-1 );
  1641. if( g_bMdiWindowsMenuUsesCheckInsteadOfRadio )
  1642. mi.Check( bRadio );
  1643. else
  1644. mi.Radio( bRadio );
  1645. } // if head of MDI windows list
  1646. else
  1647. { // MDI windows list enough long, trim it
  1648. if( ! ItemInsert(TYPE_SEPARATOR) )
  1649. {
  1650. ASSERT( FALSE );
  1651. return FALSE;
  1652. }
  1653. HWND hWndSearch = pWndStartSearchMdiFrameWnd->GetSafeHwnd();
  1654. ASSERT( hWndSearch != NULL );
  1655. ASSERT( ::IsWindow(hWndSearch) );
  1656. CExtCmdItem * pCmdItem =
  1657. g_CmdManager->CmdGetPtr(
  1658. g_CmdManager->ProfileNameFromWnd( hWndSearch ),
  1659. __ID_MDIWND_DLGWINDOWS
  1660. );
  1661. if( pCmdItem == NULL )
  1662. pCmdItem =
  1663. g_CmdManager->CmdAllocPtr(
  1664. g_CmdManager->ProfileNameFromWnd( hWndSearch ),
  1665. __ID_MDIWND_DLGWINDOWS
  1666. );
  1667. ASSERT( pCmdItem != NULL );
  1668. if( pCmdItem == NULL )
  1669. return FALSE;
  1670. CExtSafeString sMoreWindows,sManageWindows;
  1671. if( ! g_ResourceManager->LoadString( sMoreWindows, IDS_MDI_MORE_WINDOWS ) )
  1672. sMoreWindows = _T("More Windows");
  1673. if( ! g_ResourceManager->LoadString( sManageWindows, IDS_MDI_MANAGE_OPENED_WINDOWS ) )
  1674. sManageWindows = _T("Manage opened document windows");
  1675. pCmdItem->m_sMenuText = sMoreWindows;
  1676. pCmdItem->m_sToolbarText = pCmdItem->m_sMenuText;
  1677. pCmdItem->m_sTipTool = sManageWindows;
  1678. pCmdItem->m_sTipStatus = pCmdItem->m_sTipTool;
  1679. if( ! ItemInsert(nCmdID) )
  1680. {
  1681. ASSERT( FALSE );
  1682. return FALSE;
  1683. }
  1684. break;
  1685. } // MDI windows list enough long, trim it
  1686. } // for( INT nWin = 1; true; nWin++, nCmdID++ )
  1687. _SyncItems();
  1688. return TRUE;
  1689. }
  1690. HMENU CExtPopupMenuWnd::ExportToMenu(
  1691. BOOL bDeep // = TRUE
  1692. ) const
  1693. {
  1694. ASSERT_VALID( this );
  1695. CMenu menu;
  1696. if( !menu.CreatePopupMenu() )
  1697. {
  1698. ASSERT( FALSE );
  1699. return NULL;
  1700. }
  1701. OSVERSIONINFO ov;
  1702.     ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  1703. VERIFY( ::GetVersionEx( &ov ) );
  1704. bool bStupidNT4XX =
  1705. (
  1706. ( ov.dwPlatformId == VER_PLATFORM_WIN32_NT )
  1707. &&
  1708. ( ov.dwMajorVersion < 5 )
  1709. );
  1710. int nCount = ItemGetCount();
  1711. for( int nItem = 0; nItem < nCount; nItem++ )
  1712. {
  1713. const MENUITEMDATA & mi =
  1714. ItemGetInfo( nItem );
  1715. if( mi.IsPopup() )
  1716. {
  1717. CExtSafeString sMiText( mi.GetText() );
  1718. CExtSafeString sMiAccelText( _T("") );
  1719. if( ( TrackFlagsGet() & TPMX_HIDE_KEYBOARD_ACCELERATORS ) == 0 )
  1720. sMiAccelText = mi.GetAccelText();
  1721. if( !sMiAccelText.IsEmpty() )
  1722. {
  1723. sMiText += _T("t");
  1724. sMiText += sMiAccelText;
  1725. }
  1726. const CExtPopupMenuWnd * pPopup = mi.GetPopup();
  1727. ASSERT( pPopup != NULL );
  1728. HMENU hPopupData;
  1729. if( bDeep )
  1730. hPopupData = pPopup->ExportToMenu();
  1731. else
  1732. hPopupData = ::CreatePopupMenu();
  1733. if( ( ! (::IsMenu(hPopupData)) )
  1734. ||
  1735. (! menu.AppendMenu(
  1736. MF_STRING|MF_POPUP,
  1737. __EXT_MFC_UINT_PTR(hPopupData),
  1738. sMiText
  1739. )
  1740. )
  1741. )
  1742. {
  1743. ASSERT( FALSE );
  1744. //continue;
  1745. }
  1746. if( bStupidNT4XX )
  1747. {
  1748. VERIFY( ::DestroyMenu( hPopupData ) );
  1749. }
  1750. continue;
  1751. } // if( mi.IsPopup() )
  1752. if( mi.IsSeparator() )
  1753. {
  1754. VERIFY( menu.AppendMenu( MF_SEPARATOR ) );
  1755. continue;
  1756. } // if( mi.IsSeparator() )
  1757. CExtSafeString sMiText( mi.GetText() );
  1758. CExtSafeString sMiAccelText( _T("") );
  1759. if( ( TrackFlagsGet() & TPMX_HIDE_KEYBOARD_ACCELERATORS ) == 0 )
  1760. sMiAccelText = mi.GetAccelText();
  1761. if( ! sMiAccelText.IsEmpty() )
  1762. {
  1763. sMiText += _T("t");
  1764. sMiText += sMiAccelText;
  1765. }
  1766. VERIFY(
  1767. menu.AppendMenu(
  1768. MF_STRING,
  1769. mi.GetCmdID(),
  1770. sMiText
  1771. )
  1772. );
  1773. } // for( int nItem = 0; nItem < nCount; nItem++ )
  1774. return menu.Detach();
  1775. }
  1776. BOOL CExtPopupMenuWnd::UpdateFromMenu( 
  1777. HWND hWndCmdRecv,
  1778. CMenu * pBuildMenu,
  1779. bool bPopupMenu, // = true
  1780. bool bTopLevel, // = true
  1781. bool bNoRefToCmdMngr // = false
  1782. )
  1783. {
  1784. ASSERT_VALID( this );
  1785. if( hWndCmdRecv != NULL )
  1786. m_hWndCmdReceiver = hWndCmdRecv;
  1787. ASSERT( m_hWndCmdReceiver != NULL );
  1788. ASSERT( ::IsWindow(m_hWndCmdReceiver) );
  1789. if( pBuildMenu == NULL
  1790. || ( !( ::IsMenu( pBuildMenu->GetSafeHmenu() ) ) )
  1791. )
  1792. {
  1793. ASSERT( FALSE );
  1794. return false;
  1795. }
  1796. if( bPopupMenu )
  1797. {
  1798. pBuildMenu = pBuildMenu->GetSubMenu(0);
  1799. if( pBuildMenu == NULL
  1800. || ( ! ( ::IsMenu( pBuildMenu->GetSafeHmenu() ) ) )
  1801. )
  1802. {
  1803. // ASSERT( FALSE );
  1804. return false;
  1805. }
  1806. }
  1807. if( ! bNoRefToCmdMngr )
  1808. {
  1809. if( ! g_CmdManager->UpdateFromMenu(
  1810. g_CmdManager->ProfileNameFromWnd( m_hWndCmdReceiver ),
  1811. pBuildMenu->GetSafeHmenu()
  1812. )
  1813. )
  1814. {
  1815. ASSERT( FALSE );
  1816. return false;
  1817. }
  1818. } // if( ! bNoRefToCmdMngr )
  1819. if( ! _BuildItems(
  1820. pBuildMenu,
  1821. bTopLevel,
  1822. bNoRefToCmdMngr
  1823. )
  1824. )
  1825. return FALSE;
  1826. return TRUE;
  1827. }
  1828. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  1829. bool CExtPopupMenuWnd::UpdateFromCmdTree(
  1830. HWND hWndCmdRecv,
  1831. CExtCustomizeCmdTreeNode * pNode,
  1832. bool bTopLevel // = true
  1833. )
  1834. {
  1835. ASSERT_VALID( this );
  1836. ASSERT_VALID( pNode );
  1837. m_pNode = pNode;
  1838. if( hWndCmdRecv != NULL )
  1839. m_hWndCmdReceiver = hWndCmdRecv;
  1840. ASSERT( m_hWndCmdReceiver != NULL );
  1841. ASSERT( ::IsWindow(m_hWndCmdReceiver) );
  1842. __EXT_MFC_SAFE_LPCTSTR strProfileName =
  1843. g_CmdManager->ProfileNameFromWnd( m_hWndCmdReceiver );
  1844. bool bCustomizeMode = false;
  1845. CExtCustomizeSite * pSite =
  1846. CExtCustomizeSite::GetCustomizeSite( m_hWndCmdReceiver );
  1847. if( pSite != NULL )
  1848. bCustomizeMode = pSite->IsCustomizeMode();
  1849. INT iter = 0;
  1850. for( ; iter < m_items_all.GetSize(); iter++)
  1851. {
  1852. MENUITEMDATA & mi = ItemGetInfo( iter );
  1853. if( mi.IsPopup() )
  1854. {
  1855. CExtPopupMenuWnd * pPopup = mi.GetPopup();
  1856. pPopup->m_hWndCmdReceiver = m_hWndCmdReceiver;
  1857. INT nSaved = pPopup->m_nFadeOutAnimationStepCount;
  1858. pPopup->m_nFadeOutAnimationStepCount = -1;
  1859. pPopup->_OnCancelMode();
  1860. pPopup->m_nFadeOutAnimationStepCount = nSaved;
  1861. VERIFY( pPopup->_BuildItems( NULL, false ) );
  1862. mi.DestroyPopup();
  1863. }
  1864. } // for( ; iter < m_items_all.GetSize(); iter++)
  1865. m_items_all.RemoveAll();
  1866. if( pNode == NULL )
  1867. return true;
  1868. ASSERT_VALID( pNode );
  1869. m_bTopLevel = bTopLevel;
  1870. if( m_bTopLevel )
  1871. m_pWndParentMenu = NULL;
  1872. // build items loop
  1873. int nMruUpdateIndex = -1, nInsertedIndex = 0;
  1874. int nMenuItemCount = pNode->GetNodeCount();
  1875. m_items_all.RemoveAll();
  1876. bool bSeparatorMode = false;
  1877. for( int nItemIndex = 0; nItemIndex < nMenuItemCount; nItemIndex++ )
  1878. {
  1879. CExtCustomizeCmdTreeNode * pChildNode =
  1880. pNode->ElementAt( nItemIndex );
  1881. ASSERT_VALID( pChildNode );
  1882. if( ( pChildNode->GetFlags() & __ECTN_GROUP_START ) )
  1883. {
  1884. if( ! bSeparatorMode )
  1885. {
  1886. bSeparatorMode = true;
  1887. VERIFY( ItemInsert( CExtPopupMenuWnd::TYPE_SEPARATOR, nInsertedIndex++ ) );
  1888. }
  1889. } // if( pChildNode->GetFlags() & __ECTN_GROUP_START )
  1890. if( pChildNode->GetFlags() & __ECTN_TBB_HIDDEN )
  1891. continue;
  1892. UINT nMenuItemID = pChildNode->GetCmdID( false );
  1893. if( ID_FILE_MRU_FIRST <= nMenuItemID
  1894. && nMenuItemID <= ID_FILE_MRU_LAST
  1895. && (! bCustomizeMode )
  1896. )
  1897. {
  1898. if( nMruUpdateIndex < 0 )
  1899. nMruUpdateIndex = nInsertedIndex;
  1900. continue;
  1901. }
  1902. MENUITEMDATA mi( this );
  1903. mi.SetCmdReceiver( m_hWndCmdReceiver );
  1904. VERIFY( mi.UpdateFromCmdTree( m_hWndCmdReceiver, pChildNode, nInsertedIndex ) );
  1905. if( ! mi.IsSeparator() )
  1906. {
  1907. bSeparatorMode = false;
  1908. CExtCmdItem * pCmdItem = NULL;
  1909. if( mi.IsPopup() )
  1910. {
  1911. CExtPopupMenuWnd * pDesc = mi.GetPopup();
  1912. pDesc->m_hWndCmdReceiver = m_hWndCmdReceiver;
  1913. pDesc->UpdateFromCmdTree( hWndCmdRecv, pChildNode, false );
  1914. pDesc->m_pWndParentMenu = this;
  1915. } // if( mi.IsPopup() )
  1916. else
  1917. {
  1918. pCmdItem = g_CmdManager->CmdGetPtr( strProfileName, mi.GetCmdID() );
  1919. /*
  1920. // HASH Added this because during our Alpha release
  1921. // some commands were deleted but the menus were
  1922. // still loaded from resource
  1923. if( pCmdItem == NULL )
  1924. continue;
  1925. */
  1926. if( pCmdItem != NULL )
  1927. mi.SetAccelText( pCmdItem->m_sAccelText );
  1928. } // else from if( mi.IsPopup() )
  1929. mi.SetText( pChildNode->GetTextInMenu( pCmdItem ) );
  1930. mi.AccelCharInit();
  1931. mi.MeasureItem( NULL );
  1932. } // if( ! mi.IsSeparator() )
  1933. _InsertItem( -1, mi );
  1934. nInsertedIndex++;
  1935. } // for( int nItemIndex = 0; nItemIndex < nMenuItemCount; nItemIndex++ )
  1936. int nMruInsertCount = 0;
  1937. if( nMruUpdateIndex >= 0 )
  1938. { // insert recently opened file items
  1939. //ASSERT( nMruUpdateIndex <= nMenuItemCount );
  1940. CRecentFileList * pRecentFileList =
  1941. InternalFriendlyWinApp::_GetFriendlyApp()->
  1942. _GetRecentFileList();
  1943. if( pRecentFileList != NULL )
  1944. { // can be null !?
  1945. int nRecentCount =
  1946. pRecentFileList->GetSize();
  1947. TCHAR sCurrDir[_MAX_PATH+1];
  1948. ::memset(sCurrDir,0,sizeof(sCurrDir));
  1949. ::GetCurrentDirectory(_MAX_PATH,sCurrDir);
  1950. int nLenCurDir = (int)_tcslen(sCurrDir);
  1951. for( int nItemIndex=0; nItemIndex<nRecentCount; nItemIndex++ )
  1952. {
  1953. CExtSafeString sDisplayName( _T("") );
  1954. CExtSafeString sDisplayNameFullPath( _T("") );
  1955. CExtSafeString sDisplayNameMenu( _T("") );
  1956. CExtSafeString sDisplayNameTipTool( _T("") );
  1957.             sDisplayNameFullPath = ( ! pRecentFileList->m_arrNames[ nItemIndex ].IsEmpty() ) ? LPCTSTR( pRecentFileList->m_arrNames[ nItemIndex ] ) : _T("");
  1958.             pRecentFileList->GetDisplayName( *((CString *)&sDisplayName), nItemIndex, sCurrDir, nLenCurDir, TRUE );
  1959.             if( sDisplayName.IsEmpty() || sDisplayNameFullPath.IsEmpty() )
  1960. continue;
  1961.             if( g_bMRU_UseFullPathsInMenu )
  1962.                sDisplayNameMenu = sDisplayNameFullPath;
  1963.             else 
  1964.                sDisplayNameMenu = sDisplayName;
  1965.             if( g_bMRU_UseFullPathsInTipTool )
  1966.                sDisplayNameTipTool = sDisplayNameFullPath;
  1967.             else 
  1968.                sDisplayNameTipTool = sDisplayName;
  1969.             UINT nCmdID = ID_FILE_MRU_FIRST + nItemIndex;
  1970. ASSERT( nCmdID <= ID_FILE_MRU_LAST );
  1971. CExtCmdItem * pCmdItem =
  1972. g_CmdManager->CmdGetPtr(
  1973. g_CmdManager->ProfileNameFromWnd( m_hWndCmdReceiver ),
  1974. nCmdID
  1975. );
  1976. if( pCmdItem == NULL )
  1977. pCmdItem =
  1978. g_CmdManager->CmdAllocPtr(
  1979. g_CmdManager->ProfileNameFromWnd( m_hWndCmdReceiver ),
  1980. nCmdID
  1981. );
  1982. ASSERT( pCmdItem != NULL );
  1983. if( pCmdItem == NULL )
  1984. return false;
  1985. int nDisplayIndex = nItemIndex+1;
  1986. if( nDisplayIndex < 10 )
  1987. pCmdItem->m_sMenuText.Format(
  1988. _T("&%d %s"),
  1989. nDisplayIndex,
  1990. sDisplayNameMenu
  1991. );
  1992. else
  1993. pCmdItem->m_sMenuText.Format(
  1994. _T("%d&%d %s"),
  1995. nDisplayIndex/10,
  1996. nDisplayIndex%10,
  1997. sDisplayNameMenu
  1998. );
  1999. CExtSafeString sRecentFileFmt1,sRecentFileFmt2;
  2000. if( ! g_ResourceManager->LoadString( sRecentFileFmt1, IDS_RECENT_FILE_FMT_1 ) )
  2001. sRecentFileFmt1 = _T("Recent file %d");
  2002. if( ! g_ResourceManager->LoadString( sRecentFileFmt2, IDS_RECENT_FILE_FMT_2 ) )
  2003. sRecentFileFmt2 = _T("Recent file %d ("%s")");
  2004. pCmdItem->m_sToolbarText.Format(
  2005. (LPCTSTR)sRecentFileFmt1,
  2006. nItemIndex + 1
  2007. );
  2008. pCmdItem->m_sTipTool.Format(
  2009. (LPCTSTR)sRecentFileFmt2,
  2010. nItemIndex + 1,
  2011. sDisplayNameTipTool
  2012. );
  2013. pCmdItem->m_sTipStatus = pCmdItem->m_sTipTool;
  2014. BOOL bInsRetVal =
  2015. ItemInsert(
  2016. nCmdID,
  2017. nMruUpdateIndex + nItemIndex
  2018. );
  2019. if( !bInsRetVal )
  2020. {
  2021. ASSERT( FALSE );
  2022. return false;
  2023. }
  2024. nMruInsertCount++;
  2025. } // for( nItemIndex=0; nItemIndex<nRecentCount; nItemIndex++ )
  2026. } // can be null !?
  2027. /*
  2028. if( nMruInsertCount > 0 )
  2029. {
  2030. if( nMruUpdateIndex > 0
  2031. && (! ItemGetInfo( nMruUpdateIndex - 1 ).IsSeparator() )
  2032. )
  2033. {
  2034. if( ! ItemInsert(
  2035. ID_SEPARATOR,
  2036. nMruUpdateIndex
  2037. )
  2038. )
  2039. {
  2040. ASSERT( FALSE );
  2041. return false;
  2042. }
  2043. nMruInsertCount++;
  2044. nMruUpdateIndex++;
  2045. }
  2046. if( ( nMruUpdateIndex + nMruInsertCount ) < m_items_all.GetSize()
  2047. && (! ItemGetInfo( nMruUpdateIndex + nMruInsertCount ).IsSeparator() )
  2048. )
  2049. {
  2050. if( ! ItemInsert(
  2051. ID_SEPARATOR,
  2052. nMruUpdateIndex + nMruInsertCount
  2053. )
  2054. )
  2055. {
  2056. ASSERT( FALSE );
  2057. return false;
  2058. }
  2059. nMruInsertCount++;
  2060. }
  2061. } // if( nMruInsertCount > 0 )
  2062. */
  2063. if( nMruInsertCount == 0
  2064. && nMruUpdateIndex > 0
  2065. && nMruUpdateIndex < (ItemGetCount()-1)
  2066. && ItemGetInfo( nMruUpdateIndex ).IsSeparator()
  2067. && ItemGetInfo( nMruUpdateIndex-1 ).IsSeparator()
  2068. )
  2069. m_items_all.RemoveAt( nMruUpdateIndex );
  2070. } // insert recently opened file items
  2071. _SyncItems();
  2072. return true;
  2073. }
  2074. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  2075. CExtPopupMenuSite & CExtPopupMenuWnd::GetSite() const
  2076. {
  2077. return CExtPopupMenuSite::g_DefPopupMenuSite;
  2078. }
  2079. CExtPopupMenuWnd * CExtPopupMenuWnd::GetTrackingMenu()
  2080. {
  2081. CExtPopupMenuWnd * pPopup =
  2082. CExtPopupMenuSite::g_DefPopupMenuSite.GetInstance();
  2083. if( !(::IsWindow(pPopup->GetSafeHwnd())) )
  2084. return NULL;
  2085. ASSERT_VALID( pPopup );
  2086. return pPopup;
  2087. }
  2088. void CExtPopupMenuWnd::CancelMenuTracking()
  2089. {
  2090. if( (! CExtPopupMenuSite::g_DefPopupMenuSite.IsEmpty() )
  2091. && (! CExtPopupMenuSite::g_DefPopupMenuSite.IsShutdownMode() )
  2092. && CExtPopupMenuWnd::TEAROFFNOTIFICATON::g_pCurrentTEAROFFNOTIFICATON == NULL
  2093. )
  2094. {
  2095. CExtPopupMenuSite::g_DefPopupMenuSite.DoneInstance();
  2096. ASSERT( CExtPopupMenuSite::g_DefPopupMenuSite.IsEmpty() );
  2097. ASSERT( !CExtPopupMenuSite::g_DefPopupMenuSite.IsShutdownMode() );
  2098. }
  2099. }
  2100. BOOL CExtPopupMenuWnd::IsMenuTracking()
  2101. {
  2102. if( CExtPopupMenuSite::g_DefPopupMenuSite.IsEmpty()
  2103. //|| CExtPopupMenuSite::g_DefPopupMenuSite.GetCapture() == NULL
  2104. )
  2105. return FALSE;
  2106. return TRUE;
  2107. }
  2108. BOOL CExtPopupMenuWnd::TrackPopupMenu(
  2109. DWORD dwTrackFlags,
  2110. int x,
  2111. int y,
  2112. LPCRECT lpRect, // = NULL
  2113. LPVOID pCbPaintCombinedCookie, // = NULL
  2114. pCbPaintCombinedContent pCbPCC, // = NULL
  2115. UINT * lpnResultCmdID, // = NULL
  2116. bool bCookieIsObject // = false
  2117. )
  2118. {
  2119. ASSERT_VALID( this );
  2120. CExtPopupMenuSite & _site = GetSite();
  2121. CExtPopupMenuWnd * pOldPopup = _site.GetInstance();
  2122. if( pOldPopup != NULL )
  2123. {
  2124. ASSERT_VALID( pOldPopup );
  2125. DWORD dwTrackFlagsOld = pOldPopup->TrackFlagsGet();
  2126. dwTrackFlagsOld |= TPMX_NO_FADE_OUT_ANIMATION;
  2127. dwTrackFlags |= TPMX_FORCE_NO_ANIMATION;
  2128. pOldPopup->TrackFlagsSet( dwTrackFlagsOld );
  2129. }
  2130. POSITION pos = g_ListDetached.GetHeadPosition();
  2131. for( ; pos != NULL; )
  2132. {
  2133. CExtPopupMenuWnd * pPopup = g_ListDetached.GetNext( pos );
  2134. if( pPopup == this )
  2135. continue;
  2136. if( pPopup->GetParentMenuWnd() != NULL )
  2137. continue;
  2138. ASSERT_VALID( pPopup );
  2139. #if (!defined __EXT_MFC_NO_RIBBON_BAR)
  2140. if( pPopup->IsKindOf( RUNTIME_CLASS(CExtRibbonPopupMenuWnd) ) )
  2141. continue;
  2142. #endif // (!defined __EXT_MFC_NO_RIBBON_BAR)
  2143. if( pPopup->GetSafeHwnd() != NULL
  2144. && (pPopup->TrackFlagsGet()&(TPMX_NO_SITE|TPMX_RIBBON_MODE)) != 0
  2145. )
  2146. {
  2147. pPopup->TrackFlagsSet( pPopup->TrackFlagsGet() | TPMX_NO_FADE_OUT_ANIMATION );
  2148. pPopup->DestroyWindow();
  2149. if( _site.GetInstance() == pPopup )
  2150. _site.DoneInstance();
  2151. CExtToolControlBar::_CloseCustomMenusAll();
  2152. CExtToolControlBar::_CloseTrackingMenus();
  2153. break;
  2154. }
  2155. }
  2156. if( (dwTrackFlags&TPMX_RIBBON_RESIZING) != 0
  2157. && (! m_ctrlShadow.IsAvailable() )
  2158. )
  2159. dwTrackFlags |= TPMX_NO_SHADOWS;
  2160. bool bLetSurfacesUpdate = false;
  2161. CExtPopupMenuTipWnd & _tipWndSite = GetSite().GetTip();
  2162. if( _tipWndSite.GetSafeHwnd() != NULL
  2163. && (_tipWndSite.GetStyle()&WS_VISIBLE) != 0
  2164. )
  2165. {
  2166. _tipWndSite.Hide();
  2167. _tipWndSite.DestroyWindow();
  2168. bLetSurfacesUpdate = true;
  2169. }
  2170. CWnd::CancelToolTips();
  2171. CExtPopupMenuTipWnd & _tipWnd = GetTip();
  2172. if( _tipWnd.GetSafeHwnd() != NULL
  2173. && (_tipWnd.GetStyle()&WS_VISIBLE) != 0
  2174. )
  2175. {
  2176. _tipWnd.Hide();
  2177. _tipWndSite.DestroyWindow();
  2178. bLetSurfacesUpdate = true;
  2179. }
  2180. if( bLetSurfacesUpdate )
  2181. CExtPaintManager::stat_PassPaintMessages();
  2182. if( lpnResultCmdID != NULL )
  2183. *lpnResultCmdID = 0;
  2184. ASSERT( m_hWndCmdReceiver != NULL );
  2185. ASSERT( ::IsWindow(m_hWndCmdReceiver) );
  2186. CWnd * pWndCmdReceiver =
  2187. CWnd::FromHandlePermanent( m_hWndCmdReceiver );
  2188. if( pWndCmdReceiver != NULL
  2189. && CExtControlBar::FindHelpMode( pWndCmdReceiver )
  2190. )
  2191. dwTrackFlags |= TPMX_HELP_CTX_MODE;
  2192. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  2193. m_pCustomizeSite =
  2194. CExtCustomizeSite::GetCustomizeSite( m_hWndCmdReceiver );
  2195. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  2196. ASSERT(
  2197. (dwTrackFlags&(TPMX_CUSTOMIZE_MODE|TPMX_HELP_CTX_MODE))
  2198. != (TPMX_CUSTOMIZE_MODE|TPMX_HELP_CTX_MODE)
  2199. );
  2200. if( (dwTrackFlags&TPMX_CUSTOMIZE_MODE) != 0 )
  2201. {
  2202. dwTrackFlags &= ~
  2203. ( TPMX_COMBINE_MASK
  2204. |TPMX_SELECT_ANY
  2205. |TPMX_DO_MESSAGE_LOOP
  2206. |TPMX_OWNERDRAW_FIXED
  2207. );
  2208. dwTrackFlags |=
  2209. TPMX_NO_SHADOWS
  2210. | TPMX_NO_DYNAMIC_SHADOWS
  2211. | TPMX_NO_HIDE_RARELY
  2212. | TPMX_NO_WM_COMMAND
  2213. | TPMX_NO_CMD_UI
  2214. ;
  2215. } // if( (dwTrackFlags&TPMX_CUSTOMIZE_MODE) != 0 )
  2216. if( (dwTrackFlags&TPMX_HELP_CTX_MODE) != 0 )
  2217. dwTrackFlags |= TPMX_NO_HIDE_RARELY;
  2218. HWND hWndCurrentFocus = ::GetFocus();
  2219. if( hWndCurrentFocus != NULL )
  2220. {
  2221. CWnd * pWndTest = CWnd::FromHandlePermanent( hWndCurrentFocus );
  2222. if( pWndTest == NULL )
  2223. {
  2224. HWND hWnd = ::GetParent( hWndCurrentFocus );
  2225. if( hWnd != NULL )
  2226. pWndTest = CWnd::FromHandlePermanent( hWnd );
  2227. } // if( pWndTest == NULL )
  2228. if( pWndTest != NULL )
  2229. {
  2230. CComboBox * pComboTest =
  2231. DYNAMIC_DOWNCAST( CComboBox, pWndTest );
  2232. if( pComboTest == NULL )
  2233. {
  2234. pWndTest = pWndTest->GetParent();
  2235. if( pWndTest != NULL )
  2236. {
  2237. pComboTest =
  2238. DYNAMIC_DOWNCAST( CComboBox, pWndTest );
  2239. }
  2240. } // if( pComboTest == NULL )
  2241. if( pComboTest != NULL
  2242. && (pComboTest->GetStyle() & (CBS_DROPDOWN|CBS_DROPDOWNLIST)) != 0
  2243. && pComboTest->GetDroppedState()
  2244. )
  2245. pComboTest->ShowDropDown( FALSE );
  2246. } // if( pWndTest != NULL )
  2247. } // if( hWndCurrentFocus != NULL )
  2248. //CExtPopupMenuSite & _site = GetSite();
  2249. bool bSiteWasEmpty = _site.IsEmpty();
  2250. if( ! bSiteWasEmpty )
  2251. {
  2252. if( _site.IsShutdownMode() )
  2253. return FALSE;
  2254. if( (TrackFlagsGet()&TPMX_NO_SITE) == 0 )
  2255. _site.DoneInstance();
  2256. }
  2257. //bool bCaptureChanged = false;
  2258. HWND hWndCapture = ::GetCapture();
  2259. CWnd * pWndCapture = FromHandlePermanent( hWndCapture );
  2260. if( pWndCapture != NULL )
  2261. {
  2262. ReleaseCapture();
  2263. if( ::IsWindow(hWndCapture) )
  2264. {
  2265. ASSERT_VALID( pWndCapture );
  2266. pWndCapture->SendMessage(WM_CANCELMODE);
  2267. }
  2268. // bCaptureChanged = true;
  2269. }
  2270. if( ! _site.IsEmpty() )
  2271. _site._Done();
  2272. ASSERT( _site.IsEmpty() );
  2273. ASSERT( !_site.IsShutdownMode() );
  2274. //  ASSERT( m_hWndCmdReceiver != NULL );
  2275. //  ASSERT( ::IsWindow(m_hWndCmdReceiver) );
  2276. if( m_hWndCmdReceiver == NULL 
  2277. || ( !::IsWindow( m_hWndCmdReceiver ) )
  2278. )
  2279. return FALSE;
  2280. // if( !bSiteWasEmpty
  2281. // || CExtToolControlBar::g_bMenuTracking
  2282. // || bCaptureChanged
  2283. // )
  2284. // {
  2285. // PassMsgLoop( CExtPopupBaseWnd::g_bEnableOnIdleCalls );
  2286. // if( ! ::IsWindow(m_hWndCmdReceiver) )
  2287. // return FALSE;
  2288. // }
  2289. // if( !_site.IsEmpty() )
  2290. // return FALSE;
  2291. ASSERT( m_bTopLevel );
  2292. ASSERT( _site.IsEmpty() );
  2293. if( (dwTrackFlags&(TPMX_CUSTOMIZE_MODE|TPMX_NO_SITE)) == 0 )
  2294. {
  2295. _site.SetInstance( this );
  2296. if( lpnResultCmdID != NULL )
  2297. _site.SetTargetCmdIdPtr( lpnResultCmdID );
  2298. }
  2299. m_dwTrackFlags = dwTrackFlags;
  2300. if( (dwTrackFlags&(TPMX_CUSTOMIZE_MODE|TPMX_HELP_CTX_MODE)) == 0 )
  2301. _UpdateCmdUI();
  2302. if( ! _TrackPopupMenu(
  2303. dwTrackFlags,
  2304. x,
  2305. y,
  2306. lpRect,
  2307. pCbPaintCombinedCookie,
  2308. pCbPCC,
  2309. bCookieIsObject
  2310. )
  2311. )
  2312. {
  2313. //ASSERT( FALSE );
  2314. if( (dwTrackFlags&(TPMX_CUSTOMIZE_MODE|TPMX_NO_SITE)) == 0 )
  2315. {
  2316. _site.DoneInstance();
  2317. ASSERT( _site.IsEmpty() );
  2318. ASSERT( !_site.IsShutdownMode() );
  2319. } // if( (dwTrackFlags&TPMX_CUSTOMIZE_MODE) == 0 )
  2320. return FALSE;
  2321. }
  2322. if( (dwTrackFlags&TPMX_DO_MESSAGE_LOOP) == 0 )
  2323. return TRUE;
  2324. // do popup menu message loop
  2325. HWND hWndThis = GetSafeHwnd();
  2326. while( IsMenuTracking() )
  2327. {
  2328. WaitMessage();
  2329. CExtPopupMenuWnd::PassMsgLoop( CExtPopupBaseWnd::g_bEnableOnIdleCalls );
  2330. if( ! ::IsWindow( hWndThis ) )
  2331. break;
  2332. } // while( IsMenuTracking() )
  2333. if( ! CExtToolControlBar::g_bMenuTracking )
  2334. {
  2335. if( (dwTrackFlags&TPMX_NO_SITE) == 0 )
  2336. {
  2337. if( _site.GetInstance() == this )
  2338. _site.DoneInstance();
  2339. // ASSERT( _site.IsEmpty() );
  2340. // ASSERT( !_site.IsShutdownMode() );
  2341. }
  2342. } // if( ! CExtToolControlBar::g_bMenuTracking )
  2343. return TRUE;
  2344. }
  2345. void CExtPopupMenuWnd::PassMsgLoop(
  2346. bool bEnableOnIdleCalls
  2347. )
  2348. {
  2349. __PROF_UIS_MANAGE_STATE;
  2350. MSG msg;
  2351. // Process all the messages in the message queue
  2352. while( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
  2353. {
  2354. if( !AfxGetThread()->PumpMessage() )
  2355. {
  2356. PostQuitMessage(0);
  2357. return;
  2358. } // if( !AfxGetThread()->PumpMessage() )
  2359. } // while( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
  2360. if( bEnableOnIdleCalls )
  2361. {
  2362. for( LONG nIdleCounter = 0L;
  2363. ::AfxGetThread()->OnIdle(nIdleCounter);
  2364. nIdleCounter ++
  2365. );
  2366. }
  2367. }
  2368. CSize CExtPopupMenuWnd::_CalcTrackSize()
  2369. {
  2370. ASSERT_VALID( this );
  2371. int nMenuShadowSize = OnQueryMenuShadowSize();
  2372. CRect rcMB = OnQueryMenuBorderMetrics();
  2373. int nXtraSzX = rcMB.left + rcMB.right + nMenuShadowSize;
  2374. int nXtraSzY = rcMB.top + rcMB.bottom + nMenuShadowSize;
  2375. CSize _size( m_sizeFullItems );
  2376. if( m_bExpandAvailable )
  2377. _size.cy += _GetSpecBtnHeight(); // expand button
  2378. _size += CSize( nXtraSzX + m_nLeftAreaWidth, nXtraSzY );
  2379. if( _size.cx < (nMenuShadowSize*2 + 10) )
  2380. _size.cx = nMenuShadowSize*2 + 10;
  2381. if( _size.cy < (nMenuShadowSize*2 + 10) )
  2382. _size.cy = nMenuShadowSize*2 + 10;
  2383. _size.cy += 1; // +/- 2.28
  2384. bool bFoundVisibleItem = false;
  2385. for( int nIndex = 0; nIndex != m_items_all.GetSize(); nIndex++ )
  2386. {
  2387. MENUITEMDATA & mi = ItemGetInfo( nIndex );
  2388. if( mi.IsDisplayed() )
  2389. {
  2390. bFoundVisibleItem = true;
  2391. break;
  2392. }
  2393. }
  2394. if( ! bFoundVisibleItem )
  2395. _size.cy += 1; // + 2.31
  2396. #if (!defined __EXT_MFC_NO_RIBBON_BAR)
  2397. CExtPopupMenuWnd * pParent = GetParentMenuWnd();
  2398. if( pParent != NULL
  2399. && pParent->_IsTopLevelPopup()
  2400. && (pParent->TrackFlagsGet()&TPMX_RIBBON_FILE_MENU) != 0
  2401. )
  2402. {
  2403. CExtRibbonGalleryPopupMenuWnd * pGalleryMenu =
  2404. DYNAMIC_DOWNCAST( CExtRibbonGalleryPopupMenuWnd, pParent );
  2405. if( pGalleryMenu != NULL )
  2406. {
  2407. CSize _sizeAdjust = pGalleryMenu->m_sizeChildControl;
  2408. _sizeAdjust.cx -= nMenuShadowSize;
  2409. _sizeAdjust.cy -= nMenuShadowSize;
  2410. _size.cx = max( _size.cx, _sizeAdjust.cx );
  2411. _size.cy = max( _size.cy, _sizeAdjust.cy );
  2412. }
  2413. }
  2414. #endif // (!defined __EXT_MFC_NO_RIBBON_BAR)
  2415. return _size;
  2416. }
  2417. CRect CExtPopupMenuWnd::_CalcTrackRect()
  2418. {
  2419. ASSERT_VALID( this );
  2420. m_eCombineAlign = __CMBA_NONE;
  2421. bool bRTL = OnQueryLayoutRTL();
  2422. CExtPaintManager::monitor_parms_t _mp;
  2423. if( m_bExcludeAreaSpec )
  2424. CExtPaintManager::stat_GetMonitorParms( _mp, m_rcExcludeArea );
  2425. else if( m_pWndParentMenu != NULL )
  2426. {
  2427. ASSERT_VALID( m_pWndParentMenu );
  2428. ASSERT( m_pWndParentMenu->GetSafeHwnd() != NULL );
  2429. ASSERT( ::IsWindow( m_pWndParentMenu->GetSafeHwnd() ) );
  2430. CExtPaintManager::stat_GetMonitorParms( _mp, m_pWndParentMenu );
  2431. } // else if( m_pWndParentMenu != NULL )
  2432. else
  2433. CExtPaintManager::stat_GetMonitorParms( _mp, m_ptTrack );
  2434. CRect rcDesktop = g_bUseDesktopWorkArea
  2435. ? _mp.m_rcWorkArea
  2436. : _mp.m_rcMonitor
  2437. ;
  2438. CSize _size = _CalcTrackSize();
  2439. bool bTearOff = _IsTearOff();
  2440. int nTearOffCaptionHeight = bTearOff ? _GetTearOffCaptionHeight() : 0;
  2441. if( bTearOff )
  2442. _size.cy += nTearOffCaptionHeight;
  2443. int nMenuShadowSize =
  2444. OnQueryMenuShadowSize();
  2445. CRect rcMB = OnQueryMenuBorderMetrics();
  2446. int nGapShift = 0;
  2447. if( ! m_bCombineWithEA )
  2448. nGapShift = rcMB.top + nMenuShadowSize;
  2449. if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == 0 && (!m_bCombineWithEA) )
  2450. {
  2451. if( m_pWndParentMenu->GetSafeHwnd() != NULL )
  2452. {
  2453. if( (m_pWndParentMenu->m_dwTrackFlags&TPMX_ALIGN_MASK) != 0 )
  2454. m_dwTrackFlags |=
  2455. m_pWndParentMenu->m_dwTrackFlags
  2456. & (~(TPMX_ALIGN_MASK|TPMX_PALETTE|TPMX_PALETTE_TB_BKGND|TPMX_RIBBON_RESIZING|TPMX_RIBBON_RESIZING_VERTICAL_ONLY));
  2457. else
  2458. {
  2459. CRect rc1;
  2460. m_pWndParentMenu->GetWindowRect( &rc1 );
  2461. if( m_pWndParentMenu->m_pWndParentMenu->GetSafeHwnd() != NULL )
  2462. {
  2463. CRect rc2;
  2464. m_pWndParentMenu->m_pWndParentMenu->GetWindowRect(&rc2);
  2465. int x1 = rc1.left + rc1.Width()/2;
  2466. int x2 = rc2.left + rc2.Width()/2;
  2467. if( x1 >= x2 )
  2468. m_dwTrackFlags |= TPMX_LEFTALIGN;
  2469. else
  2470. m_dwTrackFlags |= TPMX_RIGHTALIGN;
  2471. } // if( m_pWndParentMenu->m_pWndParentMenu->GetSafeHwnd() != NULL )
  2472. } // else from if( (m_pWndParentMenu->m_dwTrackFlags&TPMX_ALIGN_MASK) != 0 )
  2473. } // if( m_pWndParentMenu->GetSafeHwnd() != NULL )
  2474. } // if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == 0 && (!m_bCombineWithEA) )
  2475. CRect wr( m_ptTrack, _size );
  2476. int nCombineOffset = 0;
  2477. if( m_bCombineWithEA )
  2478. {
  2479. if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_TOPALIGN )
  2480. {
  2481. nCombineOffset = 1;
  2482. wr.OffsetRect( 0, -nCombineOffset );
  2483. }
  2484. if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_LEFTALIGN )
  2485. {
  2486. nCombineOffset = 1;
  2487. wr.OffsetRect( -nCombineOffset, 0 );
  2488. }
  2489. if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_BOTTOMALIGN )
  2490. {
  2491. nCombineOffset = -nMenuShadowSize - 1;
  2492. wr.OffsetRect( 0 , -nCombineOffset );
  2493. }
  2494. if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_RIGHTALIGN )
  2495. {
  2496. if( (! bRTL) || m_bTopLevel )
  2497. nCombineOffset = -nMenuShadowSize - 1;
  2498. wr.OffsetRect( -nCombineOffset, 0 );
  2499. }
  2500. } // if( m_bCombineWithEA )
  2501. if( bRTL
  2502. && ( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_TOPALIGN
  2503. || (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_BOTTOMALIGN
  2504. )
  2505. )
  2506. {
  2507. wr.OffsetRect(
  2508. - wr.Width() + m_rcExcludeArea.Width()
  2509. + nMenuShadowSize,
  2510. 0
  2511. );
  2512. }
  2513. #if (!defined __EXT_MFC_NO_RIBBON_BAR)
  2514. CExtPopupMenuWnd * pParent = GetParentMenuWnd();
  2515. if( pParent != NULL
  2516. && pParent->_IsTopLevelPopup()
  2517. && (pParent->TrackFlagsGet()&TPMX_RIBBON_FILE_MENU) != 0
  2518. && pParent->GetSafeHwnd() != NULL
  2519. )
  2520. {
  2521. CExtRibbonGalleryPopupMenuWnd * pGalleryMenu =
  2522. DYNAMIC_DOWNCAST( CExtRibbonGalleryPopupMenuWnd, pParent );
  2523. if( pGalleryMenu != NULL )
  2524. {
  2525. CRect wr;
  2526. ::GetWindowRect( pGalleryMenu->GetChildCtrlHWND(), &wr );
  2527. CSize _sizeTrack = pGalleryMenu->m_sizeChildControl;
  2528. _sizeTrack.cx = max( _sizeTrack.cx, _size.cx );
  2529. _sizeTrack.cy = max( _sizeTrack.cy, _size.cy );
  2530. _sizeTrack.cx -= nMenuShadowSize;
  2531. _sizeTrack.cy -= nMenuShadowSize;
  2532. wr.right = wr.left + _sizeTrack.cx;
  2533. wr.bottom = wr.top + _sizeTrack.cy;
  2534. m_rcClient = wr;
  2535. m_rcClient.OffsetRect( -wr.TopLeft() );
  2536. m_rcClient.DeflateRect( 0, 0, nMenuShadowSize, nMenuShadowSize );
  2537. return wr;
  2538. }
  2539. }
  2540. #endif // (!defined __EXT_MFC_NO_RIBBON_BAR)
  2541. if( wr.bottom > rcDesktop.bottom )
  2542. {
  2543. if( m_bExcludeAreaSpec )
  2544. {
  2545. wr.OffsetRect(
  2546. 0,
  2547. -wr.Height()
  2548. + m_rcExcludeArea.Height()
  2549. + nGapShift
  2550. + (m_bCombineWithEA ? nMenuShadowSize : 0)
  2551. );
  2552. } // if( m_bExcludeAreaSpec )
  2553. if( wr.bottom > rcDesktop.bottom )
  2554. wr.OffsetRect(
  2555. 0,
  2556. m_bExcludeAreaSpec
  2557. ? -(wr.bottom - rcDesktop.bottom)
  2558. : - wr.Height()
  2559. );
  2560. } // if( wr.bottom > rcDesktop.bottom )
  2561. if( wr.top < rcDesktop.top )
  2562. wr.OffsetRect( 0, rcDesktop.top - wr.top );
  2563. if( wr.right > rcDesktop.right )
  2564. {
  2565. if( (!m_bTopLevel) && m_bExcludeAreaSpec )
  2566. wr.OffsetRect(
  2567. -wr.Width() - m_rcExcludeArea.Width(),
  2568. 0
  2569. );
  2570. if( wr.right > rcDesktop.right )
  2571. wr.OffsetRect(
  2572. m_bExcludeAreaSpec
  2573. ? -(wr.right - rcDesktop.right)
  2574. : -wr.Width(),
  2575. 0
  2576. );
  2577. } // if( wr.right > rcDesktop.right )
  2578. if( wr.left < rcDesktop.left )
  2579. {
  2580. if( (!m_bTopLevel) && m_bExcludeAreaSpec )
  2581. wr.OffsetRect(
  2582. wr.Width() + m_rcExcludeArea.Width(),
  2583. 0
  2584. );
  2585. if( wr.left < rcDesktop.left )
  2586. wr.OffsetRect( rcDesktop.left - wr.left, 0 );
  2587. } // if( wr.left < rcDesktop.left )
  2588. if( m_bExcludeAreaSpec || m_bCombineWithEA )
  2589. {
  2590. CRect rcIntersection;
  2591. if( rcIntersection.IntersectRect(
  2592. &wr,
  2593. &m_rcExcludeArea
  2594. )
  2595. || m_bCombineWithEA
  2596. )
  2597. { // if need adjust with exclude area
  2598. CRect rcFree( 0, 0, 0, 0 );
  2599. if( m_rcExcludeArea.left > rcDesktop.left )
  2600. rcFree.left = m_rcExcludeArea.left - rcDesktop.left;
  2601. if( m_rcExcludeArea.right < rcDesktop.right )
  2602. rcFree.right = rcDesktop.right - m_rcExcludeArea.right;
  2603. if( m_rcExcludeArea.top > rcDesktop.top )
  2604. rcFree.top = m_rcExcludeArea.top - rcDesktop.top;
  2605. if( m_rcExcludeArea.bottom < rcDesktop.bottom )
  2606. rcFree.bottom = rcDesktop.bottom - m_rcExcludeArea.bottom;
  2607. if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_LEFTALIGN
  2608. && rcFree.right > wr.Width()
  2609. )
  2610. wr.OffsetRect(
  2611. wr.left - m_rcExcludeArea.right
  2612. + (m_bCombineWithEA ? nCombineOffset : 0)
  2613. ,
  2614. 0
  2615. );
  2616. if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_RIGHTALIGN
  2617. && rcFree.left > wr.Width()
  2618. )
  2619. wr.OffsetRect(
  2620. m_rcExcludeArea.left - wr.right
  2621. - (m_bCombineWithEA ? nCombineOffset : 0)
  2622. ,
  2623. 0
  2624. );
  2625. if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_TOPALIGN )
  2626. {
  2627. if( rcFree.bottom > wr.Height() )
  2628. wr.OffsetRect(
  2629. 0,
  2630. wr.top - m_rcExcludeArea.bottom
  2631. + (m_bCombineWithEA ? nCombineOffset : 0)
  2632. );
  2633. else
  2634. {
  2635. if( ::IsWindow(GetSafeHwnd()) )
  2636. {
  2637. CRect rcWndOld;
  2638. GetWindowRect( &rcWndOld );
  2639. ShowWindow( SW_HIDE );
  2640. _FreeWinObjects();
  2641. HWND hWndThis = GetSafeHwnd();
  2642. bool bWasCreated =
  2643. (hWndThis != NULL && ::IsWindow(hWndThis))
  2644. ? true : false;
  2645. // CExtPopupMenuWnd::PassMsgLoop(
  2646. // CExtPopupBaseWnd::g_bEnableOnIdleCalls
  2647. // );
  2648. if( bWasCreated && (!::IsWindow(hWndThis)) )
  2649. return CRect( 0, 0, 0, 0 );
  2650. if( ! rcWndOld.IsRectEmpty() )
  2651. {
  2652. CWnd * pWndTLP = GetTopLevelParent();
  2653. if( pWndTLP != NULL )
  2654. {
  2655. ASSERT_VALID( pWndTLP );
  2656. if( pWndTLP->IsWindowVisible() )
  2657. {
  2658. CRect rcTLP;
  2659. pWndTLP->GetWindowRect( &rcTLP );
  2660. if( ! rcTLP.IsRectEmpty() )
  2661. {
  2662. CRect rcIntersection;
  2663. if( rcIntersection.IntersectRect(
  2664. &rcTLP,
  2665. &rcWndOld
  2666. )
  2667. )
  2668. pWndTLP->UpdateWindow();
  2669. } // if( !rcTLP.IsRectEmpty() )
  2670. } // if( pWndTLP->IsWindowVisible() )
  2671. } // if( pWndTLP != NULL )
  2672. } // if( ! rcWndOld.IsRectEmpty() )
  2673. } // if( ::IsWindow(GetSafeHwnd()) )
  2674. m_dwTrackFlags &= ~(TPMX_ALIGN_MASK);
  2675. //m_dwTrackFlags |= TPMX_BOTTOMALIGN;
  2676. m_dwTrackFlags |= TPMX_BOTTOMALIGN; // TPMX_RIGHTALIGN;
  2677. return _CalcTrackRect();
  2678. } // else from if( rcFree.bottom > wr.Height() )
  2679. } // if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_TOPALIGN )
  2680. if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_BOTTOMALIGN
  2681. && rcFree.top > wr.Height()
  2682. )
  2683. wr.OffsetRect(
  2684. 0,
  2685. m_rcExcludeArea.top - wr.bottom
  2686. - (m_bCombineWithEA ? nCombineOffset : 0)
  2687. );
  2688. } // if need adjust with exclude area
  2689. } // if( m_bExcludeAreaSpec || m_bCombineWithEA )
  2690. if( wr.right > rcDesktop.right )
  2691. {
  2692. wr.OffsetRect( -(wr.right - rcDesktop.right), 0 );
  2693. if( m_bTopLevel )
  2694. {
  2695. m_bExcludeAreaSpec = false;
  2696. m_bCombineWithEA = false;
  2697. }
  2698. } // if( wr.right > rcDesktop.right )
  2699. if( wr.left < rcDesktop.left )
  2700. {
  2701. wr.OffsetRect( rcDesktop.left - wr.left, 0 );
  2702. if( m_bTopLevel )
  2703. {
  2704. m_bExcludeAreaSpec = false;
  2705. m_bCombineWithEA = false;
  2706. }
  2707. } // if( wr.left < rcDesktop.left )
  2708. if( wr.bottom > rcDesktop.bottom )
  2709. {
  2710. wr.OffsetRect( 0, -(wr.bottom - rcDesktop.bottom) );
  2711. if( m_bTopLevel )
  2712. {
  2713. m_bExcludeAreaSpec = false;
  2714. m_bCombineWithEA = false;
  2715. }
  2716. } // if( wr.bottom > rcDesktop.bottom )
  2717. if( wr.top < rcDesktop.top )
  2718. {
  2719. wr.OffsetRect( 0, rcDesktop.top - wr.top );
  2720. if( m_bTopLevel )
  2721. {
  2722. m_bExcludeAreaSpec = false;
  2723. m_bCombineWithEA = false;
  2724. }
  2725. } // if( wr.top < rcDesktop.top )
  2726. if( wr.bottom > rcDesktop.bottom )
  2727. {
  2728. wr.bottom = rcDesktop.bottom;
  2729. m_bScrollingAvailable = true;
  2730. } // if( wr.bottom > rcDesktop.bottom )
  2731. if( m_bCombineWithEA )
  2732. {
  2733. ASSERT( m_bExcludeAreaSpec );
  2734. if( wr.bottom == m_rcExcludeArea.top - nCombineOffset )
  2735. m_eCombineAlign = __CMBA_BOTTOM;
  2736. if( wr.top == m_rcExcludeArea.bottom  - nCombineOffset )
  2737. m_eCombineAlign = __CMBA_TOP;
  2738. if( wr.left == m_rcExcludeArea.right - nCombineOffset )
  2739. m_eCombineAlign = __CMBA_LEFT;
  2740. if( wr.right == m_rcExcludeArea.left - nCombineOffset  )
  2741. m_eCombineAlign = __CMBA_RIGHT;
  2742. if( m_eCombineAlign == __CMBA_NONE )
  2743. {
  2744. m_bCombineWithEA = false;
  2745. return _CalcTrackRect();
  2746. } // if( m_eCombineAlign == __CMBA_NONE )
  2747. // init window region
  2748. if( m_rgnWnd.GetSafeHandle() != NULL )
  2749. {
  2750. VERIFY( m_rgnWnd.DeleteObject() );
  2751. }
  2752. CRect rcExcludeArea(m_rcExcludeArea);
  2753. rcExcludeArea.InflateRect(
  2754. 0,
  2755. 0,
  2756. nMenuShadowSize,
  2757. nMenuShadowSize
  2758. );
  2759. CRect rcFullWnd(
  2760. min( wr.left, rcExcludeArea.left ),
  2761. min( wr.top, rcExcludeArea.top ),
  2762. max( wr.right, rcExcludeArea.right ),
  2763. max( wr.bottom, rcExcludeArea.bottom )
  2764. );
  2765. if( ! m_bTopLevel )
  2766. {
  2767. if( m_eCombineAlign == __CMBA_LEFT
  2768. || m_eCombineAlign == __CMBA_RIGHT
  2769. )
  2770. rcExcludeArea.DeflateRect( 0, 0, 0, nMenuShadowSize );
  2771. else if( m_eCombineAlign == __CMBA_TOP
  2772. || m_eCombineAlign == __CMBA_BOTTOM
  2773. )
  2774. rcExcludeArea.DeflateRect( 0, 0, nMenuShadowSize, 0 );
  2775. } // if( ! m_bTopLevel )
  2776. CRgn rgnAreaWnd, rgnAreaExclude;
  2777. if( (! m_rgnWnd.CreateRectRgnIndirect( &rcFullWnd ) )
  2778. || (! rgnAreaExclude.CreateRectRgnIndirect( &rcExcludeArea ) )
  2779. || (! rgnAreaWnd.CreateRectRgnIndirect( &wr ) )
  2780. || m_rgnWnd.CombineRgn(
  2781. &rgnAreaWnd,
  2782. &rgnAreaExclude,
  2783. RGN_OR
  2784. ) == ERROR
  2785. || m_rgnWnd.OffsetRgn(
  2786. -rcFullWnd.TopLeft()
  2787. ) == ERROR
  2788. )
  2789. {
  2790. if( m_rgnWnd.GetSafeHandle() != NULL )
  2791. {
  2792. VERIFY( m_rgnWnd.DeleteObject() );
  2793. }
  2794. m_bCombineWithEA = false;
  2795. return _CalcTrackRect();
  2796. }
  2797. ASSERT( m_rgnWnd.GetSafeHandle() != NULL );
  2798. m_rcClient = wr;
  2799. m_rcClient.OffsetRect( -rcFullWnd.TopLeft() );
  2800. m_rcClient.DeflateRect( 0, 0, nMenuShadowSize, nMenuShadowSize );
  2801. ASSERT( m_rcClient.top <= m_rcClient.bottom );
  2802. ASSERT( m_rcClient.left <= m_rcClient.right );
  2803. // if( bTearOff )
  2804. // m_rcClient.top += nTearOffCaptionHeight;
  2805. if( ! m_bTopLevel )
  2806. {
  2807. if( m_eCombineAlign == __CMBA_RIGHT )
  2808. rcFullWnd.OffsetRect( nMenuShadowSize + 1, 0 );
  2809. else if( m_eCombineAlign == __CMBA_LEFT )
  2810. rcFullWnd.OffsetRect( -2, 0 );
  2811. }
  2812. return rcFullWnd;
  2813. } // if( m_bCombineWithEA )
  2814. m_rcClient = wr;
  2815. m_rcClient.OffsetRect( -wr.TopLeft() );
  2816. m_rcClient.DeflateRect( 0, 0, nMenuShadowSize, nMenuShadowSize );
  2817. // if( bTearOff )
  2818. // m_rcClient.top += nTearOffCaptionHeight;
  2819. ASSERT( m_rcClient.top <= m_rcClient.bottom );
  2820. ASSERT( m_rcClient.left <= m_rcClient.right );
  2821. return wr;
  2822. }
  2823. bool CExtPopupMenuWnd::OnQueryLayoutRTL() const
  2824. {
  2825. ASSERT_VALID( this );
  2826. if( m_pWndParentMenu != NULL )
  2827. {
  2828. ASSERT_VALID( this );
  2829. return m_pWndParentMenu->OnQueryLayoutRTL();
  2830. } // if( m_pWndParentMenu != NULL )
  2831. return CExtPopupBaseWnd::OnQueryLayoutRTL();
  2832. }
  2833. void CExtPopupMenuWnd::_CancelingSet()
  2834. {
  2835. ASSERT_VALID( this );
  2836. if( m_bCanceling )
  2837. return;
  2838. m_bCanceling = true;
  2839. //if( ( GetStyle() & WS_VISIBLE ) != 0 )
  2840. {
  2841. if( m_pWndParentMenu != NULL )
  2842. {
  2843. if( ! m_pWndParentMenu->_CancelingGet() )
  2844. m_pWndParentMenu->_CancelingSet();
  2845. }
  2846. if( m_nCurIndex >= 0
  2847. && ItemGetInfo( m_nCurIndex ).IsPopup()
  2848. )
  2849. {
  2850. CExtPopupMenuWnd * pPopup = ItemGetInfo( m_nCurIndex ).GetPopup();
  2851. if( ! pPopup->_CancelingGet() )
  2852. pPopup->_CancelingSet();
  2853. }
  2854. }
  2855. }
  2856. bool CExtPopupMenuWnd::_CancelingGet() const
  2857. {
  2858. ASSERT_VALID( this );
  2859. return m_bCanceling;
  2860. }
  2861. BOOL CExtPopupMenuWnd::_TrackPopupMenu(
  2862. DWORD dwTrackFlags,
  2863. int x,
  2864. int y,
  2865. LPCRECT lpRect,
  2866. LPVOID pCbPaintCombinedCookie, // = NULL
  2867. pCbPaintCombinedContent pCbPCC, // = NULL
  2868. bool bCookieIsObject // = false
  2869. )
  2870. {
  2871. ///////////////////////////// dwTrackFlags |= TPMX_COMBINE_NONE|TPMX_FORCE_NO_ANIMATION|TPMX_NO_DYNAMIC_SHADOWS|TPMX_NO_SHADOWS;
  2872. ASSERT_VALID( this );
  2873. m_bCanceling = false;
  2874. CExtPaintManager::stat_PassPaintMessages();
  2875. ::GetCursorPos( &m_ptTrackInvoked );
  2876. m_ptTrackWatched = m_ptTrackInvoked;
  2877. if( _IsTopLevelPopup() )
  2878. m_bHelperMouseBtnDownOnStart =
  2879. ( IsKeyPressed( VK_LBUTTON )
  2880. || IsKeyPressed( VK_RBUTTON )
  2881. ) ? true : false;
  2882. else
  2883. m_bHelperMouseBtnDownOnStart = false;
  2884. if( m_bHelperMouseBtnDownOnStart )
  2885. ::GetCursorPos( &m_ptStartMousePos );
  2886. bool bForceExpandRarelyUsed = (dwTrackFlags&TPMX_NO_HIDE_RARELY)
  2887. ? true : false;
  2888. if( ! g_bMenuExpanding )
  2889. bForceExpandRarelyUsed = true;
  2890. ASSERT( m_hWndCmdReceiver != NULL );
  2891. ASSERT( ::IsWindow(m_hWndCmdReceiver) );
  2892. if( GetSafeHwnd() != NULL )
  2893. ::DestroyWindow( m_hWnd ); // fade out animation effect
  2894. CExtPopupMenuSite & _site = GetSite();
  2895. if( (!_FindCustomizeMode())
  2896. && ( _site.IsTopPopup(this)
  2897. || GetParentMenuWnd() == NULL
  2898. )
  2899. )
  2900. {
  2901. ASSERT( m_bTopLevel );
  2902. MsgPrepareMenuData_t _mpmEntireTree( this );
  2903. _mpmEntireTree.SendMessage( m_hWndCmdReceiver, false );
  2904. if( _mpmEntireTree.m_bMenuCanceled )
  2905. return FALSE;
  2906. if( _mpmEntireTree.m_bMenuChanged )
  2907. {
  2908. _SyncItems();
  2909. _UpdateCmdUI();
  2910. }
  2911. ASSERT( m_bTopLevel );
  2912. // ASSERT( _site.IsTopPopup(this) );
  2913. }
  2914. MsgPrepareMenuData_t _mpmOneTreeLevel( this );
  2915. _mpmOneTreeLevel.SendMessage( m_hWndCmdReceiver, true );
  2916. if( _mpmOneTreeLevel.m_bMenuCanceled )
  2917. return FALSE;
  2918. if( _mpmOneTreeLevel.m_bMenuChanged )
  2919. {
  2920. _SyncItems();
  2921. _UpdateCmdUI();
  2922. }
  2923. if( !_FindCustomizeMode() )
  2924. { // BLOCK: update system commands
  2925. INT iter = 0;
  2926. for(; iter < m_items_all.GetSize(); ++iter )
  2927. {
  2928. MENUITEMDATA & mi = ItemGetInfo( iter );
  2929. if( mi.IsSeparator() )
  2930. continue;
  2931. UINT nCmdID = mi.GetCmdID();
  2932. if( ! CExtCmdManager::IsSystemCommand( nCmdID ) )
  2933. continue;
  2934. WINDOWPLACEMENT wndpl;
  2935. ::memset(&wndpl,0,sizeof(WINDOWPLACEMENT));
  2936. wndpl.length = sizeof(WINDOWPLACEMENT);
  2937. VERIFY(
  2938. ::GetWindowPlacement(
  2939. mi.GetCmdReceiver(),
  2940. &wndpl
  2941. )
  2942. );
  2943. __EXT_MFC_LONG_PTR dwWndStyle = ::__EXT_MFC_GetWindowLong( mi.GetCmdReceiver(), GWL_STYLE );
  2944. __EXT_MFC_LONG_PTR dwWndExStyle = ::__EXT_MFC_GetWindowLong( mi.GetCmdReceiver(), GWL_EXSTYLE );
  2945. bool bSysCmdEnabled = false;
  2946. switch( nCmdID )
  2947. {
  2948. case SC_CLOSE:
  2949. {
  2950. bSysCmdEnabled = true;
  2951. HMENU hSysMenu = ::GetSystemMenu( mi.GetCmdReceiver(), FALSE );
  2952. MENUITEMINFO _mii;
  2953. ::memset( &_mii, 0, sizeof(MENUITEMINFO) );
  2954. _mii.cbSize = sizeof(MENUITEMINFO);
  2955. _mii.fMask = MIIM_STATE;
  2956. if( hSysMenu != NULL
  2957. && ::GetMenuItemInfo(
  2958. hSysMenu,
  2959. SC_CLOSE,
  2960. FALSE,
  2961. &_mii
  2962. )
  2963. )
  2964. {
  2965. if( (_mii.fState & MFS_DISABLED) != 0 )
  2966. bSysCmdEnabled = false;
  2967. } // if( hSysMenu != NULL ...
  2968. }
  2969. break;
  2970. case SC_SIZE:
  2971. case SC_MOVE:
  2972. if( wndpl.showCmd != SW_SHOWMINIMIZED
  2973. && wndpl.showCmd != SW_SHOWMAXIMIZED
  2974. && !g_bFullScreenMode
  2975. )
  2976. bSysCmdEnabled = true;
  2977. break;
  2978. case SC_MINIMIZE:
  2979. if( (dwWndStyle & WS_MINIMIZEBOX) != 0
  2980. && wndpl.showCmd != SW_SHOWMINIMIZED
  2981. )
  2982. bSysCmdEnabled = true;
  2983. break;
  2984. case SC_MAXIMIZE:
  2985. if( (dwWndStyle & WS_MAXIMIZEBOX) != 0
  2986. && wndpl.showCmd != SW_SHOWMAXIMIZED
  2987. && !g_bFullScreenMode
  2988. )
  2989. bSysCmdEnabled = true;
  2990. break;
  2991. case SC_RESTORE:
  2992. if( (dwWndStyle & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX)) != 0
  2993. && ( wndpl.showCmd == SW_SHOWMAXIMIZED
  2994. || wndpl.showCmd == SW_SHOWMINIMIZED
  2995. //||wndpl.showCmd == SW_SHOWNORMAL
  2996. )
  2997. )
  2998. bSysCmdEnabled = true;
  2999. break;
  3000. case SC_CONTEXTHELP:
  3001. if( (dwWndExStyle & WS_EX_CONTEXTHELP) != 0 )
  3002. bSysCmdEnabled = true;
  3003. break;
  3004. // case SC_NEXTWINDOW:
  3005. // case SC_PREVWINDOW:
  3006. // case SC_VSCROLL:
  3007. // case SC_HSCROLL:
  3008. // case SC_MOUSEMENU:
  3009. // case SC_KEYMENU:
  3010. // case SC_ARRANGE:
  3011. // case SC_TASKLIST:
  3012. // case SC_SCREENSAVE:
  3013. //#if(WINVER >= 0x0400)
  3014. // case SC_DEFAULT:
  3015. // case SC_MONITORPOWER:
  3016. // case SC_SEPARATOR:
  3017. //#endif /* WINVER >= 0x0400 */
  3018. case SC_HOTKEY:
  3019. default:
  3020. continue;
  3021. } // switch( nCmdID )
  3022. CExtCmdItem * pCmdItem =
  3023. g_CmdManager->CmdGetPtr(
  3024. g_CmdManager->ProfileNameFromWnd( m_hWndCmdReceiver ),
  3025. nCmdID
  3026. );
  3027. if( pCmdItem == NULL )
  3028. {
  3029. pCmdItem =
  3030. g_CmdManager->CmdAllocPtr(
  3031. g_CmdManager->ProfileNameFromWnd( m_hWndCmdReceiver ),
  3032. nCmdID
  3033. );
  3034. ASSERT( pCmdItem != NULL );
  3035. }
  3036. pCmdItem->StateEnable( bSysCmdEnabled );
  3037. mi.Enable( bSysCmdEnabled );
  3038. ASSERT( CExtCmdManager::IsSystemCommand( nCmdID ) );
  3039. HWND hWndItemCmdReceiver = mi.GetCmdReceiver();
  3040. HMENU hSysMenu = ::GetSystemMenu( hWndItemCmdReceiver, FALSE );
  3041. if( hSysMenu != NULL )
  3042. {
  3043. MENUITEMINFO _mii;
  3044. ::memset( &_mii, 0, sizeof(MENUITEMINFO) );
  3045. _mii.cbSize = sizeof(MENUITEMINFO);
  3046. _mii.fMask =
  3047. MIIM_CHECKMARKS|MIIM_DATA|MIIM_ID|MIIM_STATE
  3048. |MIIM_SUBMENU|MIIM_TYPE;
  3049. _mii.cch = __MAX_UI_ITEM_TEXT;
  3050. CExtSafeString sMenuItemText;
  3051. _mii.dwTypeData = sMenuItemText.GetBuffer( __MAX_UI_ITEM_TEXT );
  3052. ASSERT( _mii.dwTypeData != NULL );
  3053. if( _mii.dwTypeData != NULL )
  3054. {
  3055. if( ::GetMenuItemInfo(
  3056. hSysMenu,
  3057. nCmdID,
  3058. FALSE,
  3059. &_mii
  3060. )
  3061. )
  3062. {
  3063. sMenuItemText.ReleaseBuffer();
  3064. sMenuItemText.Replace( _T("n"), _T("") );
  3065. sMenuItemText.Replace( _T("r"), _T("") );
  3066. sMenuItemText.TrimLeft();
  3067. sMenuItemText.TrimRight();
  3068. if( ! sMenuItemText.IsEmpty() )
  3069. {
  3070. int nSep =
  3071. sMenuItemText.ReverseFind( _T('t') );
  3072. if( nSep >= 0 )
  3073. {
  3074. int nLen = sMenuItemText.GetLength();
  3075. pCmdItem->m_sAccelText = sMenuItemText.Right( nLen - nSep );
  3076. pCmdItem->m_sAccelText.TrimLeft();
  3077. pCmdItem->m_sAccelText.TrimRight();
  3078. pCmdItem->m_sMenuText = sMenuItemText.Left( nSep );
  3079. pCmdItem->m_sMenuText.TrimLeft();
  3080. pCmdItem->m_sMenuText.TrimRight();
  3081. }
  3082. else
  3083. {
  3084. pCmdItem->m_sMenuText = sMenuItemText;
  3085. pCmdItem->m_sAccelText = _T("");
  3086. }
  3087. if( pCmdItem->m_nCmdID == SC_CLOSE )
  3088. {
  3089. CWnd * pWnd = CWnd::FromHandlePermanent( hWndItemCmdReceiver );
  3090. if( pWnd != NULL
  3091. && pWnd->IsKindOf( RUNTIME_CLASS(CMDIChildWnd) )
  3092. )
  3093. pCmdItem->m_sAccelText = _T("Ctrl+F4");
  3094. }
  3095. mi.SetPopupText( pCmdItem->m_sMenuText );
  3096. mi.SetAccelText( pCmdItem->m_sAccelText );
  3097. } // if( ! sMenuItemText.IsEmpty() )
  3098. }
  3099. else
  3100. sMenuItemText.ReleaseBuffer();
  3101. } // if( _mii.dwTypeData != NULL )
  3102. if( (_mii.fState&MFS_DEFAULT) != 0 )
  3103. mi.SetDefault();
  3104. } // if( hSysMenu != NULL )
  3105. } // for(; iter < m_items_all.end(); ++iter )
  3106. } // BLOCK: update system commands
  3107. CWnd * pWndCmdReceiver =
  3108. CWnd::FromHandle( m_hWndCmdReceiver );
  3109. ASSERT_VALID( pWndCmdReceiver );
  3110. // pWndCmdReceiver->ActivateTopParent();
  3111. // pWndCmdReceiver->BringWindowToTop();
  3112. // pWndCmdReceiver->SetFocus();
  3113. //_site._Hook( true );
  3114. // adjust own data
  3115. bool bOldTopLevel = m_bTopLevel;
  3116. bool bOldExpandAvailable = m_bExpandAvailable;
  3117. DWORD dwPortedTrackFlags = m_dwTrackFlags&(TPMX_PALETTE|TPMX_PALETTE_TB_BKGND);
  3118. _Init();
  3119. m_bTopLevel = bOldTopLevel;
  3120. m_bExpandAvailable = bOldExpandAvailable;
  3121. m_dwTrackFlags = dwTrackFlags | dwPortedTrackFlags;
  3122. m_pCbPaintCombinedCookie = pCbPaintCombinedCookie;
  3123. m_pCbPaintCombinedContent = pCbPCC;
  3124. m_bCookieIsObject = bCookieIsObject;
  3125. if( !m_bTopLevel )
  3126. {
  3127. ASSERT( m_pWndParentMenu != NULL );
  3128. if( m_pWndParentMenu->m_bExpandWasPressed )
  3129. {
  3130. if( m_bExpandAvailable )
  3131. {
  3132. m_bExpandAvailable = false;
  3133. m_bExpandWasPressed = true;
  3134. _SyncItems();
  3135. }
  3136. else
  3137. m_bExpandWasPressed = true;
  3138. }
  3139. } // if( !m_bTopLevel )
  3140. else
  3141. {
  3142. if( bForceExpandRarelyUsed )
  3143. {
  3144. if( m_bExpandAvailable )
  3145. {
  3146. m_bExpandAvailable = false;
  3147. m_bExpandWasPressed = true;
  3148. _SyncItems();
  3149. }
  3150. else
  3151. m_bExpandWasPressed = true;
  3152. } // if( bForceExpandRarelyUsed )
  3153. else
  3154. _SyncItems();
  3155. } // else from if( !m_bTopLevel )
  3156. // adjust screen position
  3157. m_ptTrack.x = m_ptTrackOriginal.x = x;
  3158. m_ptTrack.y = m_ptTrackOriginal.y = y;
  3159. if( ( m_ptTrack.x < -32000 || m_ptTrack.y < -32000 )
  3160. && (dwTrackFlags&TPMX_RIBBON_MODE) == 0
  3161. )
  3162. {
  3163. if( ! ::GetCursorPos(&m_ptTrack) )
  3164. return FALSE;
  3165. }
  3166. if( lpRect != NULL )
  3167. {
  3168. m_rcExcludeArea = *lpRect;
  3169. m_bExcludeAreaSpec = true;
  3170. }
  3171. else
  3172. {
  3173. m_bExcludeAreaSpec = false;
  3174. m_rcExcludeArea.left = m_ptTrack.x - __EXCLUDE_AREA_GAP_DX;
  3175. m_rcExcludeArea.right = m_ptTrack.x + __EXCLUDE_AREA_GAP_DX;
  3176. m_rcExcludeArea.top = m_ptTrack.y - __EXCLUDE_AREA_GAP_DY;
  3177. m_rcExcludeArea.bottom = m_ptTrack.y + __EXCLUDE_AREA_GAP_DY;
  3178. }
  3179. // adjust combine with exclude area mode
  3180. m_bCombineWithEA = false;
  3181. if( m_bExcludeAreaSpec )
  3182. {
  3183. switch( (dwTrackFlags&TPMX_COMBINE_MASK) )
  3184. {
  3185. case TPMX_COMBINE_ANY_SUITABLE:
  3186. m_bCombineWithEA = true;
  3187. break;
  3188. case TPMX_COMBINE_DEFAULT:
  3189. m_bCombineWithEA =
  3190. PmBridge_GetPM()->
  3191. IsMenuMustCombineExcludeArea(
  3192. bCookieIsObject
  3193. ? ((CObject*)pCbPaintCombinedCookie)
  3194. : NULL
  3195. );
  3196. break;
  3197. } // switch( (dwTrackFlags&TPMX_COMBINE_MASK) )
  3198. } // if( m_bExcludeAreaSpec )
  3199. CSize _size = _CalcTrackSize();
  3200. bool bPointAdjusted = true;
  3201. if( m_bExcludeAreaSpec )
  3202. {
  3203. bool bRTL = OnQueryLayoutRTL();
  3204. if( bRTL && (!m_bTopLevel) )
  3205. {
  3206. CExtPopupMenuWnd * pTop = m_pWndParentMenu;
  3207. for( ; pTop != NULL; pTop = pTop->GetParentMenuWnd() )
  3208. {
  3209. if( pTop->_IsTopLevelPopup() )
  3210. break;
  3211. } // for( ; pTop != NULL; pTop = pTop->GetParentMenuWnd() )
  3212. if( pTop != NULL )
  3213. {
  3214. switch( (pTop->m_dwTrackFlags & TPMX_ALIGN_MASK) )
  3215. {
  3216. case TPMX_TOPALIGN:
  3217. case TPMX_BOTTOMALIGN:
  3218. m_dwTrackFlags &= ~(TPMX_ALIGN_MASK);
  3219. m_dwTrackFlags |= TPMX_RIGHTALIGN;
  3220. break;
  3221. } // switch( (pTop->m_dwTrackFlags & TPMX_ALIGN_MASK) )
  3222. } // if( pTop != NULL )
  3223. } // if( bRTL && (!m_bTopLevel) )
  3224. switch( (m_dwTrackFlags & TPMX_ALIGN_MASK) )
  3225. {
  3226. case TPMX_LEFTALIGN:
  3227. m_ptTrack.x = m_rcExcludeArea.right;
  3228. m_ptTrack.y = m_rcExcludeArea.top;
  3229. break;
  3230. case TPMX_RIGHTALIGN:
  3231. m_ptTrack.x = m_rcExcludeArea.left - _size.cx;
  3232. m_ptTrack.y = m_rcExcludeArea.top;
  3233. break;
  3234. case TPMX_TOPALIGN:
  3235. m_ptTrack.x = m_rcExcludeArea.left;
  3236. m_ptTrack.y = m_rcExcludeArea.bottom;
  3237. break;
  3238. case TPMX_BOTTOMALIGN:
  3239. m_ptTrack.x = m_rcExcludeArea.left;
  3240. m_ptTrack.y = m_rcExcludeArea.top - _size.cy;
  3241. break;
  3242. default:
  3243. bPointAdjusted = false;
  3244. break;
  3245. } // switch( (m_dwTrackFlags & TPMX_ALIGN_MASK) )
  3246. } // if( m_bExcludeAreaSpec )
  3247. if( ! bPointAdjusted )
  3248. {
  3249. if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_RIGHTALIGN )
  3250. m_ptTrack.x -= _size.cx;
  3251. else
  3252. {
  3253. if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_CENTERALIGN )
  3254. m_ptTrack.x -= _size.cx/2;
  3255. }
  3256. if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_BOTTOMALIGN )
  3257. m_ptTrack.y -= _size.cy;
  3258. else
  3259. {
  3260. if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_VCENTERALIGN )
  3261. m_ptTrack.y -= _size.cy/2;
  3262. }
  3263. } // if( !bPointAdjusted )
  3264. //#ifdef _DEBUG
  3265. bool bCreateResult =
  3266. //#endif // _DEBUG
  3267. _CreateHelper( pWndCmdReceiver );
  3268. //ASSERT( bCreateResult );
  3269. if( !bCreateResult )
  3270. return FALSE;
  3271. if( dwTrackFlags & TPMX_SELECT_ANY )
  3272. {
  3273. int nItem = _GetNextItem(__NI_ANY);
  3274. if( nItem >= 0 )
  3275. {
  3276. HWND hWndOwn = m_hWnd;
  3277. _ItemFocusSet(
  3278. nItem,
  3279. FALSE,
  3280. FALSE
  3281. );
  3282. if( ! ::IsWindow( hWndOwn ) )
  3283. return FALSE;
  3284. }
  3285. }
  3286. HWND hWndOwn = m_hWnd;
  3287. if( (dwTrackFlags&TPMX_FORCE_NO_ANIMATION) != 0
  3288. || _FindCustomizeMode()
  3289. )
  3290. m_AnimationType = __AT_NONE;
  3291. else
  3292. {
  3293. m_AnimationType = g_DefAnimationType;
  3294. if( CExtToolControlBar::g_bMenuTracking )
  3295. m_AnimationType = __AT_NONE;
  3296. m_ePlaySoundOnAnimationFinished =
  3297. CExtSoundPlayer::__ON_MENU_POPUP_DISPLAYED;
  3298. _StartAnimation();
  3299. if( ! ::IsWindow( hWndOwn ) )
  3300. return FALSE;
  3301. } // if( _FindCustomizeMode() )
  3302. if( m_AnimationType == __AT_NONE )
  3303. {
  3304. m_AnimationType = __AT_CONTENT_DISPLAY;
  3305. m_ePlaySoundOnAnimationFinished =
  3306. CExtSoundPlayer::__ON_MENU_POPUP_DISPLAYED;
  3307. _StartAnimation();
  3308. if( ! ::IsWindow( hWndOwn ) )
  3309. return FALSE;
  3310. ASSERT( m_AnimationType == __AT_CONTENT_DISPLAY );
  3311. }
  3312. if( m_rgnWnd.GetSafeHandle() != NULL )
  3313. {
  3314. ASSERT( m_bExcludeAreaSpec );
  3315. ASSERT( m_bCombineWithEA );
  3316. ASSERT( m_eCombineAlign != __CMBA_NONE );
  3317. CRgn rgnTmp;
  3318. VERIFY( rgnTmp.CreateRectRgn(0,0,0,0) );
  3319. rgnTmp.CopyRgn( &m_rgnWnd );
  3320. ASSERT( rgnTmp.GetSafeHandle() != NULL );
  3321. VERIFY(
  3322. SetWindowRgn(
  3323. (HRGN)rgnTmp.Detach(),
  3324. FALSE
  3325. )
  3326. );
  3327. } // if( m_rgnWnd.GetSafeHandle() != NULL )
  3328. if( ! g_PaintManager.m_bIsWin2000orLater )
  3329. CExtPaintManager::stat_PassPaintMessages();
  3330. bool bFadeOut = _IsFadeOutAnimation();
  3331. bool bForceLayered = false;
  3332. if( (! bFadeOut)
  3333. && g_PaintManager.m_bIsWin2000orLater
  3334. && g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL
  3335. && ( m_AnimationType == __AT_NONE || m_AnimationType == __AT_CONTENT_DISPLAY )
  3336. //&& ( TrackFlagsGet() & TPMX_RIBBON_RESIZING ) == 0
  3337. )
  3338. bForceLayered = true;
  3339. if( bFadeOut || bForceLayered )
  3340. {
  3341. ASSERT( g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL );
  3342. g_PaintManager.m_pfnSetLayeredWindowAttributes( m_hWnd, 0, 1, __EXT_MFC_LWA_ALPHA );
  3343. } // if( bFadeOut )
  3344. if( g_PaintManager.m_bIsWinVistaOrLater
  3345. && g_PaintManager.m_DWM.IsCompositionEnabled()
  3346. )
  3347. {
  3348. CRect rcCapture;
  3349. GetWindowRect( &rcCapture );
  3350. HBITMAP hBmpScreenSrcAlt = CExtPaintManager::stat_GetScreenSurfacePart( rcCapture );
  3351. if( hBmpScreenSrcAlt != NULL )
  3352. {
  3353. if( m_bmpScreenSrcAlt.GetSafeHandle() != NULL )
  3354. m_bmpScreenSrcAlt.DeleteObject();
  3355. m_bmpScreenSrcAlt.Attach( hBmpScreenSrcAlt );
  3356. }
  3357. }
  3358. SetWindowPos(
  3359. &CWnd::wndTopMost, 0, 0, 0, 0,
  3360. SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE
  3361. |SWP_SHOWWINDOW|SWP_NOZORDER
  3362. );
  3363. if( bFadeOut || bForceLayered )
  3364. {
  3365. ASSERT( g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL );
  3366. CExtPaintManager::stat_PassPaintMessages();
  3367. g_PaintManager.m_pfnSetLayeredWindowAttributes( m_hWnd,  0, 255, __EXT_MFC_LWA_ALPHA );
  3368. } // if( bFadeOut )
  3369. else if( ! g_PaintManager.m_bIsWin2000orLater )
  3370. CExtPaintManager::stat_PassPaintMessages();
  3371. ASSERT( IsWindowVisible() );
  3372. if( ! _FindCustomizeMode() )
  3373. {
  3374. _SetCapture();
  3375. }
  3376. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  3377. else
  3378. {
  3379. CExtCustomizeSite * pSite = _FindCustomizeSite();
  3380. ASSERT( pSite != NULL );
  3381. pSite->RegisterCommandDropTarget( this, this );
  3382. }
  3383. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  3384. if( m_bTopLevel && (! m_bExpandWasPressed ) && m_bExpandAvailable && g_nAutoExpandTime > 0 )
  3385. SetTimer( ID_TIMER_AUTO_EXPAND, g_nAutoExpandTime, NULL );
  3386. return TRUE;
  3387. }
  3388. CExtPopupMenuTipWnd & CExtPopupMenuWnd::GetTip()
  3389. {
  3390. return m_wndToolTip;
  3391. }
  3392. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  3393. CExtPopupScreenTipWnd & CExtPopupMenuWnd::GetScreenTip()
  3394. {
  3395. return m_wndScreenTip;
  3396. }
  3397. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  3398. bool CExtPopupMenuWnd::_CreateHelper(
  3399. CWnd * pWndCmdReceiver
  3400. )
  3401. {
  3402. ASSERT_VALID( this );
  3403. bool bHasInplaceItems = false;
  3404. int nCount = ItemGetCount();
  3405. for( int i = 0; i < nCount; i++ )
  3406. {
  3407. MENUITEMDATA & mi = ItemGetInfo( i );
  3408. if( !mi.IsInplaceEdit() )
  3409. continue;
  3410. //ASSERT( mi.GetInplaceEditPtr() == NULL );
  3411. mi.ResetActiveInplaceEditPtr();
  3412. bHasInplaceItems = true;
  3413. break;
  3414. } // for( int i = 0; i < nCount; i++ )
  3415. if( bHasInplaceItems || _IsPalette() )
  3416. _SyncItems();
  3417. CRect wr = _CalcTrackRect();
  3418. if( wr.IsRectEmpty() )
  3419. return false;
  3420. UINT nClassStyle = __POPUP_WNDCLASS_STYLES__;
  3421. // if( (TrackFlagsGet()&TPMX_FORCE_NO_ANIMATION) != 0 )
  3422. // nClassStyle &= ~(CS_SAVEBITS);
  3423. HCURSOR hCursor = ::LoadCursor( NULL, IDC_ARROW );
  3424. ASSERT( hCursor != NULL );
  3425. CExtSafeString strMenuClassName =
  3426. ::AfxRegisterWndClass(
  3427. nClassStyle,
  3428. hCursor,
  3429. (HBRUSH)(COLOR_BTNFACE + 1),
  3430. NULL
  3431. );
  3432. ASSERT( !strMenuClassName.IsEmpty() );
  3433. pWndCmdReceiver->SendMessage(
  3434. g_nMsgPrepareDesktopBk,
  3435. WPARAM( this )
  3436. );
  3437. bool bFadeOut = _IsFadeOutAnimation(), bForceLayered = false;
  3438. if( (! bFadeOut)
  3439. && g_PaintManager.m_bIsWin2000orLater
  3440. && g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL
  3441. && ( m_AnimationType == __AT_NONE || m_AnimationType == __AT_CONTENT_DISPLAY )
  3442. //&& ( TrackFlagsGet() & TPMX_RIBBON_RESIZING ) == 0
  3443. )
  3444. bForceLayered = true;
  3445. BOOL bCreateResult =
  3446. __BaseClassOfCExtPopupBaseWnd::CreateEx(
  3447. _FindCustomizeMode() 
  3448. ? 0 
  3449. : WS_EX_TOPMOST
  3450. | ( g_PaintManager.m_bIsWin2000orLater ? (WS_EX_NOINHERITLAYOUT) : 0 )
  3451. | ( ( bFadeOut || bForceLayered ) ? (__EXT_MFC_WS_EX_LAYERED) : 0 )
  3452. ,
  3453. strMenuClassName,
  3454. NULL,
  3455. WS_POPUP|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
  3456. wr,
  3457. pWndCmdReceiver,
  3458. 0 // IDC_STATIC
  3459. );
  3460. if( ! bCreateResult )
  3461. {
  3462. ASSERT( FALSE );
  3463. return false;
  3464. }
  3465. if( bFadeOut || bForceLayered )
  3466. g_PaintManager.m_pfnSetLayeredWindowAttributes( m_hWnd, 0, 0, __EXT_MFC_LWA_ALPHA );
  3467. if( IsSyncFullRowItems() )
  3468. _SyncItems();
  3469. _RecalcLayoutImpl();
  3470. if( !_FindHelpMode() )
  3471. ::SetCursor( hCursor );
  3472. if( bHasInplaceItems )
  3473. {
  3474. bool bRTL = OnQueryLayoutRTL();
  3475. nCount = ItemGetCount();
  3476. for( int i = 0; i < nCount; i++ )
  3477. {
  3478. MENUITEMDATA & mi = ItemGetInfo( i );
  3479. if( !mi.IsInplaceEdit() )
  3480. continue;
  3481. //ASSERT( mi.GetInplaceEditPtr() == NULL );
  3482. mi.ResetActiveInplaceEditPtr();
  3483. CRect rc( 0, 0, 0, 0 );
  3484. if( mi.IsDisplayed() )
  3485. {
  3486. CRect rcItem;
  3487. _GetItemRect( i, rcItem );
  3488. rc = mi.AdjustInplaceEditRect( rcItem, bRTL );
  3489. } // if( mi.IsDisplayed() )
  3490. mi.CreateInplaceEdit( this, rc );
  3491. } // for( i = 0; i < nCount; i++ )
  3492. } // if( bHasInplaceItems )
  3493. //  if( _IsPopupWithShadowsDynamic() )
  3494. //  m_ctrlShadow.Create( m_hWnd, PmBridge_GetPM()->GetMenuShadowSize() );
  3495. return true;
  3496. }
  3497. bool CExtPopupMenuWnd::IsNoHighlightIconArea()
  3498. {
  3499. ASSERT_VALID( this );
  3500. if( _IsTopLevelPopup()
  3501. && (TrackFlagsGet()&TPMX_RIBBON_FILE_MENU) != 0
  3502. )
  3503. return true;
  3504. CExtPopupMenuWnd * pParent = GetParentMenuWnd();
  3505. if( pParent != NULL
  3506. && pParent->_IsTopLevelPopup()
  3507. && (pParent->TrackFlagsGet()&TPMX_RIBBON_FILE_MENU) != 0
  3508. )
  3509. return true;
  3510. return false;
  3511. }
  3512. bool CExtPopupMenuWnd::IsSyncFullRowItems()
  3513. {
  3514. ASSERT_VALID( this );
  3515. if( (TrackFlagsGet()&(TPMX_RIBBON_RESIZING)) != 0 )
  3516. return true;
  3517. CExtPopupMenuWnd * pParent = GetParentMenuWnd();
  3518. if( pParent != NULL
  3519. && pParent->_IsTopLevelPopup()
  3520. && (pParent->TrackFlagsGet()&TPMX_RIBBON_FILE_MENU) != 0
  3521. )
  3522. return true;
  3523. return false;
  3524. }
  3525. BOOL CExtPopupMenuWnd::DestroyWindow()
  3526. {
  3527. __PROF_UIS_MANAGE_STATE;
  3528. ASSERT_VALID( this );
  3529. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  3530. _KeyTipsShow( false );
  3531. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  3532. int nCount = ItemGetCount();
  3533. for( int i = 0; i < nCount; i++ )
  3534. {
  3535. MENUITEMDATA & mi = ItemGetInfo( i );
  3536. if( mi.IsInplaceEdit() )
  3537. {
  3538. if( mi.GetInplaceEditPtr() != NULL )
  3539. {
  3540. ASSERT_VALID( mi.GetInplaceEditPtr() );
  3541. ASSERT( mi.GetInplaceEditPtr()->GetSafeHwnd() != NULL && (::IsWindow(mi.GetInplaceEditPtr()->GetSafeHwnd())) );
  3542. mi.GetInplaceEditPtr()->DestroyWindow();
  3543. } // if( mi.GetInplaceEditPtr() != NULL )
  3544. mi.ResetActiveInplaceEditPtr();
  3545. }
  3546. } // for( int i = 0; i < nCount; i++ )
  3547. bool bAutoDestroy = false;
  3548. if( _IsFadeOutAnimation() )
  3549. {
  3550. CExtPopupMenuSite & _site = GetSite();
  3551. DWORD dwTrackFlags = TrackFlagsGet();
  3552. if( m_bTopLevel )
  3553. {
  3554. bAutoDestroy = true;
  3555. _site.SetCapture( NULL );
  3556. ASSERT( m_hWndCmdReceiver != NULL );
  3557. if( ::IsWindow(m_hWndCmdReceiver) )
  3558. ::SendMessage(
  3559. m_hWndCmdReceiver,
  3560. g_nMsgNotifyMenuClosed,
  3561. 0,
  3562. LPARAM( this )
  3563. );
  3564. if( m_hWndNotifyMenuClosed != NULL
  3565. && ::IsWindow( m_hWndNotifyMenuClosed )
  3566. )
  3567. ::SendMessage(
  3568. m_hWndNotifyMenuClosed,
  3569. g_nMsgNotifyMenuClosed,
  3570. 0,
  3571. LPARAM( this )
  3572. );
  3573. CExtControlBar::stat_SetMessageString(
  3574. GetOwner()
  3575. );
  3576. } // if( m_bTopLevel )
  3577. CExtToolControlBar::_CloseCustomMenusAll();
  3578. if( CExtToolControlBar::g_bMenuTracking )
  3579. CExtToolControlBar::_CloseTrackingMenus();
  3580. bool bAnimateSequence = false;
  3581. if( ! m_bHelperAnimationControllerDetected )
  3582. {
  3583. if( m_nCurIndex < 0 )
  3584. bAnimateSequence = true;
  3585. else if(
  3586. ( ! ItemGetInfo( m_nCurIndex ).IsPopup() )
  3587. || ItemGetInfo( m_nCurIndex ).GetPopup()->GetSafeHwnd() == NULL
  3588. )
  3589. bAnimateSequence = true;
  3590. }
  3591. if( bAnimateSequence )
  3592. {
  3593. if( (! _site.IsEmpty() )
  3594. // && (! _site.IsShutdownMode() )
  3595. && (dwTrackFlags&TPMX_NO_SITE) == 0
  3596. )
  3597. {
  3598. if( _site.GetInstance() == this )
  3599. _site.DoneInstance();
  3600. //ASSERT( _site.IsEmpty() );
  3601. //ASSERT( !_site.IsShutdownMode() );
  3602. }
  3603. CExtPopupMenuWnd * pPopup = this;
  3604. for( ; pPopup != NULL; )
  3605. {
  3606. CExtPopupMenuWnd * pParent = pPopup->m_pWndParentMenu;
  3607. pPopup->m_bHelperAnimationControllerDetected = true;
  3608. if( pParent == NULL )
  3609. CExtPopupMenuSite::g_DefPopupMenuSite.FadeOutInstanceAdd( pPopup );
  3610. pPopup = pParent;
  3611. }
  3612. m_nFadeOutAnimationStepIndex = 0;
  3613. SetTimer(
  3614. ID_TIMER_FADE_OUT_ANIMATION,
  3615. UINT(m_nFadeOutAnimationEllapse),
  3616. NULL
  3617. );
  3618. }
  3619. return TRUE;
  3620. } // if( _IsFadeOutAnimation() )
  3621. if( m_ctrlShadow.GetSafeHwnd() != NULL )
  3622. m_ctrlShadow.DestroyWindow();
  3623. if( GetSafeHwnd() == NULL )
  3624. {
  3625. ASSERT( ! bAutoDestroy );
  3626. return TRUE;
  3627. }
  3628. #if (!defined __EXT_MFC_NO_CUSTOMIZE)
  3629. if( _FindCustomizeMode() )
  3630. {
  3631. CExtCustomizeSite * pSite = _FindCustomizeSite();
  3632. ASSERT( pSite != NULL );
  3633. pSite->UnRegisterCommandDropTarget( this );
  3634. } // if( _FindCustomizeMode() )
  3635. #endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
  3636. return CExtPopupBaseWnd::DestroyWindow();
  3637. }
  3638. void CExtPopupMenuWnd::_GetItemRect(
  3639. int nIndex,
  3640. RECT & rectItem,
  3641. bool bIncludeIndents // = true
  3642. )
  3643. {
  3644. ASSERT_VALID( this );
  3645. int nCountOfItems = (int)m_items_all.GetSize();
  3646. if( 0 <= nIndex && nIndex < nCountOfItems )
  3647. {
  3648. if( _IsPalette() )
  3649. {
  3650. _GetItemRectPalette(
  3651. nIndex,
  3652. rectItem,
  3653. bIncludeIndents
  3654. );
  3655. return;
  3656. }
  3657. }
  3658. if( nIndex == IDX_RIBBON_FILE_MENU_OPTIONS_BUTTON )
  3659. {
  3660. rectItem = m_rcRibbonBtnOptions;
  3661. return;
  3662. }
  3663. if( nIndex == IDX_RIBBON_FILE_MENU_EXIT_BUTTON )
  3664. {
  3665. rectItem = m_rcRibbonBtnExit;
  3666. return;
  3667. }
  3668. CRect rcClient;
  3669. _GetClientRect( &rcClient );
  3670. rcClient.left += m_nLeftAreaWidth;
  3671. if( m_bScrollingAvailable )
  3672. {
  3673. ASSERT( ! m_rcScrollTop.IsRectEmpty() );
  3674. ASSERT( ! m_rcScrollBottom.IsRectEmpty() );
  3675. if( nIndex == IDX_SCROLL_TOP )
  3676. {
  3677. rectItem = m_rcScrollTop;
  3678. return;
  3679. }