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

界面编程

开发平台:

Visual C++

  1. // This is part of the Professional User Interface Suite library.
  2. // Copyright (C) 2001-2009 FOSS Software, Inc.
  3. // All rights reserved.
  4. //
  5. // http://www.prof-uis.com
  6. // mailto:support@prof-uis.com
  7. //
  8. // This source code can be used, modified and redistributed
  9. // under the terms of the license agreement that is included
  10. // in the Professional User Interface Suite package.
  11. //
  12. // Warranties and Disclaimers:
  13. // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND
  14. // INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  16. // IN NO EVENT WILL FOSS SOFTWARE INC. BE LIABLE FOR ANY DIRECT,
  17. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES,
  18. // INCLUDING DAMAGES FOR LOSS OF PROFITS, LOSS OR INACCURACY OF DATA,
  19. // INCURRED BY ANY PERSON FROM SUCH PERSON'S USAGE OF THIS SOFTWARE
  20. // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  21. #include "StdAfx.h"
  22. #if (!defined __ExtCmdManager_H)
  23. #include <ExtCmdManager.h>
  24. #endif
  25. #if (!defined __EXT_REGISTRY_H)
  26. #include <ExtRegistry.h>
  27. #endif
  28. #if (!defined __EXT_EXTINTEGRITYCHECKSUM_H)
  29. #include "ExtIntegrityCheckSum.h"
  30. #endif
  31. #if (!defined __EXT_PAINT_MANAGER_H)
  32. #include <ExtPaintManager.h>
  33. #endif
  34. #if (!defined __EXT_LOCALIZATION_H)
  35. #include <../Src/ExtLocalization.h>
  36. #endif
  37. #if _MFC_VER < 0x700
  38. #include <../src/AfxImpl.h>
  39. #else
  40. #include <../src/mfc/AfxImpl.h>
  41. #endif
  42. #if (!defined __AFXPRIV_H__)
  43. #include <AfxPriv.h>
  44. #endif
  45. #include <Resources/Resource.h>
  46. #include <limits.h>
  47. #if _MFC_VER < 0x700
  48. #include <../Src/occimpl.h>
  49. #else
  50. #include <ocdb.h>
  51. #include <afxocc.h>
  52. #include <../src/mfc/occimpl.h>
  53. #endif
  54. #pragma message("   Prof-UIS is automatically linking with version.lib")
  55. #pragma message("      (Version info support)")
  56. #pragma comment(lib,"version.lib") 
  57. #ifndef _AFX_OLD_EXCEPTIONS
  58. #define DELETE_EXCEPTION(e) do { e->Delete(); } while (0)
  59. #define NO_CPP_EXCEPTION(expr)
  60. #else
  61. #define DELETE_EXCEPTION(e)
  62. #define NO_CPP_EXCEPTION(expr) expr
  63. #endif
  64. #ifdef _DEBUG
  65. #define new DEBUG_NEW
  66. #undef THIS_FILE
  67. static char THIS_FILE[] = __FILE__;
  68. #endif
  69. bool CExtLocalResourceHelper::g_bUseResourceHandle = false;
  70. static CExtSafeString productsection2regkeypath(
  71. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  72. __EXT_MFC_SAFE_LPCTSTR sSectionNameCompany, // under HKEY_CURRENT_USERSoftware
  73. __EXT_MFC_SAFE_LPCTSTR sSectionNameProduct // under HKEY_CURRENT_USERSoftware%sSectionNameCompany%
  74. )
  75. {
  76. return CExtCmdManager::GetSubSystemRegKeyPath(
  77. __PROF_UIS_REG_COMMAND_MANAGER,
  78. sProfileName,
  79. sSectionNameCompany,
  80. sSectionNameProduct
  81. );
  82. }
  83. static bool fileobj_to_registry(
  84. CFile & _file,
  85. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  86. __EXT_MFC_SAFE_LPCTSTR sSectionNameCompany, // under HKEY_CURRENT_USERSoftware
  87. __EXT_MFC_SAFE_LPCTSTR sSectionNameProduct, // under HKEY_CURRENT_USERSoftware%sSectionNameCompany%
  88. HKEY hKeyRoot,
  89. bool bEnableThrowExceptions
  90. )
  91. {
  92. ASSERT( sProfileName != NULL );
  93. ASSERT( sSectionNameCompany != NULL );
  94. ASSERT( sSectionNameProduct != NULL );
  95. CExtSafeString sRegKeyPath =
  96. productsection2regkeypath(
  97. sProfileName,
  98. sSectionNameCompany,
  99. sSectionNameProduct
  100. );
  101. return
  102. CExtCmdManager::FileObjToRegistry(
  103. _file,
  104. sRegKeyPath,
  105. hKeyRoot,
  106. bEnableThrowExceptions
  107. );
  108. }
  109. static bool fileobj_from_registry(
  110. CFile & _file,
  111. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  112. __EXT_MFC_SAFE_LPCTSTR sSectionNameCompany, // under HKEY_CURRENT_USERSoftware
  113. __EXT_MFC_SAFE_LPCTSTR sSectionNameProduct, // under HKEY_CURRENT_USERSoftware%sSectionNameCompany%
  114. HKEY hKeyRoot,
  115. bool bEnableThrowExceptions
  116. )
  117. {
  118. ASSERT( sProfileName != NULL );
  119. ASSERT( sSectionNameCompany != NULL );
  120. ASSERT( sSectionNameProduct != NULL );
  121. ASSERT( _file.GetLength() == 0 );
  122. CExtSafeString sRegKeyPath =
  123. productsection2regkeypath(
  124. sProfileName,
  125. sSectionNameCompany,
  126. sSectionNameProduct
  127. );
  128. return
  129. CExtCmdManager::FileObjFromRegistry(
  130. _file,
  131. sRegKeyPath,
  132. hKeyRoot,
  133. bEnableThrowExceptions
  134. );
  135. }
  136. /////////////////////////////////////////////////////////////////////////////
  137. // CExtCmdItem
  138. // command item class
  139. #define __MAX_TOTAL_TICK_COUNT (UINT_MAX-1)
  140. #define __DECREASE_TICK_COUNT_BY_REF(_REF_) (_REF_) /= 2
  141. CExtCmdItem::CExtCmdItem(
  142. UINT nCmdID // = IDC_STATIC
  143. )
  144. : m_pProfile( NULL )
  145. , m_nCmdID( nCmdID )
  146. , m_dwStateFlags( STATE_ENABLED )
  147. , m_dwExStateFlags( 0 )
  148. , m_nIconIdx( -1 )
  149. , m_sMenuText( _T("") )
  150. , m_sToolbarText( _T("") )
  151. , m_sTipTool( _T("") )
  152. , m_sTipStatus( _T("") )
  153. , m_sAccelText( _T("") )
  154. , m_nUsageTickCount( 0 )
  155. , m_nLParamUserData( 0L )
  156. #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD)
  157. , m_nTextFieldWidth( 100 ) // __EXT_MENU_DEF_INPLACE_EDIT_WIDTH
  158. , m_nDropDownWidth( -2 ) // (-1) - auto calc, (-2) - same as button area
  159. , m_nDropDownHeightMax( 250 )
  160. #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD)
  161. {
  162. }
  163. CExtCmdItem::CExtCmdItem( const CExtCmdItem & other )
  164. : m_pProfile( NULL )
  165. , m_nCmdID( (UINT)IDC_STATIC )
  166. , m_dwStateFlags( STATE_ENABLED )
  167. , m_dwExStateFlags( 0 )
  168. , m_nIconIdx( -1 )
  169. , m_sMenuText( _T("") )
  170. , m_sToolbarText( _T("") )
  171. , m_sTipTool( _T("") )
  172. , m_sTipStatus( _T("") )
  173. , m_sAccelText( _T("") )
  174. , m_nUsageTickCount( 0 )
  175. , m_nLParamUserData( 0L )
  176. #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD)
  177. , m_nTextFieldWidth( 100 ) // __EXT_MENU_DEF_INPLACE_EDIT_WIDTH
  178. , m_nDropDownWidth( -2 ) // (-1) - auto calc, (-2) - same as button area
  179. , m_nDropDownHeightMax( 250 )
  180. #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD)
  181. {
  182. CExtCmdItem::AssignFromOther(other);
  183. }
  184. CExtCmdItem::~CExtCmdItem()
  185. {
  186. }
  187. CExtCmdItem & CExtCmdItem::operator = ( const CExtCmdItem & other )
  188. {
  189. AssignFromOther(other);
  190. return *this;
  191. }
  192. void CExtCmdItem::AssignFromOther( const CExtCmdItem & other )
  193. {
  194. LPVOID lpvThis = (LPVOID)this;
  195. LPVOID lpvOther = (LPVOID)(&other);
  196. if( lpvThis == lpvOther )
  197. return;
  198. m_pProfile = other.m_pProfile;
  199. m_nCmdID = other.m_nCmdID;
  200. m_dwStateFlags = other.m_dwStateFlags;
  201. m_dwExStateFlags = other.m_dwExStateFlags;
  202. m_nIconIdx = other.m_nIconIdx;
  203. m_sMenuText = other.m_sMenuText,
  204. m_sToolbarText = other.m_sToolbarText,
  205. m_sTipTool = other.m_sTipTool;
  206. m_sTipStatus = other.m_sTipStatus;
  207. m_sAccelText = other.m_sAccelText;
  208. m_nUsageTickCount = other.m_nUsageTickCount;
  209. m_nLParamUserData = other.m_nLParamUserData;
  210. #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD)
  211. m_nTextFieldWidth = other.m_nTextFieldWidth;
  212. m_nDropDownWidth = other.m_nDropDownWidth; // (-1) - auto calc, (-2) - same as button area
  213. m_nDropDownHeightMax = other.m_nDropDownHeightMax;
  214. #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD)
  215. }
  216. void CExtCmdItem::ReplaceFromOtherNonEmpty( const CExtCmdItem & other )
  217. {
  218. LPVOID lpvThis = (LPVOID)this;
  219. LPVOID lpvOther = (LPVOID)(&other);
  220. if( lpvThis == lpvOther )
  221. return;
  222. // ASSERT( m_pProfile == other.m_pProfile );
  223. // ASSERT( m_nCmdID == other.m_nCmdID );
  224. // m_dwStateFlags = other.m_dwStateFlags;
  225. // m_dwExStateFlags = other.m_dwExStateFlags;
  226. if( other.m_nIconIdx >= 0 )
  227. m_nIconIdx = other.m_nIconIdx;
  228. if( !other.m_sMenuText.IsEmpty() )
  229. m_sMenuText = other.m_sMenuText;
  230. if( !other.m_sToolbarText.IsEmpty() )
  231. m_sToolbarText = other.m_sToolbarText;
  232. if( !other.m_sTipTool.IsEmpty() )
  233. m_sTipTool = other.m_sTipTool;
  234. if( !other.m_sTipStatus.IsEmpty() )
  235. m_sTipStatus = other.m_sTipStatus;
  236. if( !other.m_sAccelText.IsEmpty() )
  237. m_sAccelText = other.m_sAccelText;
  238. // m_nUsageTickCount = other.m_nUsageTickCount;
  239. // m_nLParamUserData = other.m_nLParamUserData;
  240. }
  241. void CExtCmdItem::UpdateMoreExact( const CExtCmdItem & other )
  242. {
  243. LPVOID lpvThis = (LPVOID)this;
  244. LPVOID lpvOther = (LPVOID)(&other);
  245. if( lpvThis == lpvOther )
  246. return;
  247. // ASSERT( m_pProfile == other.m_pProfile );
  248. // ASSERT( m_nCmdID == other.m_nCmdID );
  249. // m_dwStateFlags = other.m_dwStateFlags;
  250. // m_dwExStateFlags = other.m_dwExStateFlags;
  251. if( m_nIconIdx < 0 )
  252. m_nIconIdx = other.m_nIconIdx;
  253. if( m_sMenuText.IsEmpty() )
  254. m_sMenuText = other.m_sMenuText;
  255. if( m_sTipTool.IsEmpty() )
  256. m_sTipTool = other.m_sTipTool;
  257. if( m_sTipStatus.IsEmpty() )
  258. m_sTipStatus = other.m_sTipStatus;
  259. if( m_sAccelText.IsEmpty() )
  260. m_sAccelText = other.m_sAccelText;
  261. // m_nUsageTickCount = other.m_nUsageTickCount;
  262. // m_nLParamUserData = other.m_nLParamUserData;
  263. }
  264. bool CExtCmdItem::StateIsBasic() const
  265. {
  266. if( CExtCmdManager::IsForceBasicCommand(m_nCmdID) )
  267. return true;
  268. if( CExtCmdManager::IsForceRarelyCommand(m_nCmdID) )
  269. return false;
  270. bool bBasic =
  271. (m_dwStateFlags&STATE_BASICCMDPROP) ? true : false;
  272. return bBasic;
  273. }
  274. bool CExtCmdItem::StateIsRarelyUsed() const
  275. {
  276. if( StateIsBasic() )
  277. return false;
  278. UINT nUsagePercent = GetUsagePercent();
  279. ASSERT( m_pProfile != NULL );
  280. return
  281. (nUsagePercent < m_pProfile->m_nRarelyPercent) ?
  282. true : false;
  283. }
  284. bool CExtCmdItem::StateIsForceRarely() const
  285. {
  286. if( CExtCmdManager::IsForceRarelyCommand(m_nCmdID) )
  287. return true;
  288. if( CExtCmdManager::IsForceBasicCommand(m_nCmdID) )
  289. return false;
  290. bool bForceRarely =
  291. (m_dwStateFlags&STATE_FORCE_RARELY) ? true : false;
  292. return bForceRarely;
  293. }
  294. void CExtCmdItem::TipsClean()
  295. {
  296. m_sTipTool = _T("");
  297. m_sTipStatus = _T("");
  298. }
  299. bool CExtCmdItem::TipsLoad()
  300. {
  301. TipsClean();
  302. if( !CExtCmdManager::IsCommand(m_nCmdID) )
  303. {
  304. ASSERT( FALSE );
  305. return false;
  306. }
  307. CExtSafeString sText;
  308. if( ! g_ResourceManager->LoadString( sText, m_nCmdID ) )
  309. return false;
  310. sText.Replace( _T("t"), _T(" ") );
  311. sText.Replace( _T("r"), _T("") );
  312. sText.TrimLeft();
  313. sText.TrimRight();
  314. if( sText.IsEmpty() )
  315. return false;
  316. int nSep = sText.ReverseFind('n');
  317. if( nSep < 0 )
  318. {
  319. //m_sTipTool = sText; // (- v.2.24)
  320. m_sTipStatus = sText; // (+ v.2.24)
  321. return true;
  322. }
  323. int nLen = sText.GetLength();
  324. m_sTipTool = sText.Right( nLen - nSep );
  325. m_sTipTool.TrimLeft();
  326. m_sTipTool.TrimRight();
  327. m_sTipStatus = sText.Left( nSep );
  328. m_sTipStatus.TrimLeft();
  329. m_sTipStatus.TrimRight();
  330. return true;
  331. }
  332. bool CExtCmdItem::DoUpdateCmdUI(
  333. CCmdTarget * pCmdTarget,
  334. UINT nIndex // = 0
  335. )
  336. {
  337. ASSERT( pCmdTarget != NULL );
  338. CExtCmdItemUI cmd_ui( this );
  339. if( CExtCmdManager::IsCommandNeedsSpecUpdate(m_nCmdID) )
  340. {
  341. cmd_ui.Enable(TRUE);
  342. return true;
  343. } // if( CExtCmdManager::IsCommandNeedsSpecUpdate(m_nCmdID) )
  344. else
  345. {
  346. cmd_ui.m_nIndex = nIndex;
  347. BOOL bRetVal =
  348. cmd_ui.DoUpdate(
  349. pCmdTarget,
  350. CExtCmdManager::g_bDisableCmdIfNoHandler ?
  351. TRUE : FALSE
  352. );
  353. return bRetVal ? true : false;
  354. } // else from if( CExtCmdManager::IsCommandNeedsSpecUpdate(m_nCmdID) )
  355. }
  356. bool CExtCmdItem::Deliver(
  357. HWND hWndCmdTarget,
  358. bool bSend // = false
  359. )
  360. {
  361. if( hWndCmdTarget == NULL )
  362. return false;
  363. IncrementUsageCount();
  364. ASSERT( ::IsWindow( hWndCmdTarget ) );
  365. ASSERT( CExtCmdManager::IsCommand(m_nCmdID) );
  366. UINT nMsg = WM_COMMAND;
  367. LPARAM lParam = 0;
  368. if( CExtCmdManager::IsSystemCommand(m_nCmdID) )
  369. { // if we need WM_SYSCOMMAND
  370. nMsg = WM_SYSCOMMAND;
  371. POINT point = { 0, 0 };
  372. ::GetCursorPos( &point );
  373. lParam =
  374. MAKELONG(
  375. point.x,
  376. point.y
  377. );
  378. } // if we need WM_SYSCOMMAND
  379. if( bSend )
  380. {
  381. if( !::SendMessage(
  382. hWndCmdTarget,
  383. nMsg,
  384. m_nCmdID,
  385. lParam
  386. )
  387. )
  388. {
  389. //ASSERT( FALSE );
  390. return false;
  391. }
  392. } // if( bSend )
  393. else
  394. {
  395. if( !::PostMessage(
  396. hWndCmdTarget,
  397. nMsg,
  398. m_nCmdID,
  399. lParam
  400. )
  401. )
  402. {
  403. ASSERT( FALSE );
  404. return false;
  405. }
  406. } // else from  if( bSend )
  407. return true;
  408. }
  409. bool CExtCmdItem::Deliver(
  410. CWnd * pWndCmdTarget,
  411. bool bSend // = false
  412. )
  413. {
  414. ASSERT_VALID( pWndCmdTarget );
  415. return
  416. Deliver(
  417. pWndCmdTarget->GetSafeHwnd(),
  418. bSend
  419. );
  420. }
  421. bool CExtCmdItem::Deliver(
  422. CControlBar * pWndCmdSource,
  423. bool bSend // = false
  424. )
  425. {
  426. if( pWndCmdSource == NULL
  427. || pWndCmdSource->GetSafeHwnd() == NULL
  428. )
  429. {
  430. ASSERT( FALSE );
  431. return FALSE;
  432. }
  433. ASSERT_VALID( pWndCmdSource );
  434. CWnd * pOwner = pWndCmdSource->GetOwner();
  435. if( pOwner == NULL )
  436. {
  437. ASSERT( FALSE );
  438. return FALSE;
  439. }
  440. ASSERT_VALID( pOwner );
  441. ASSERT( ! pOwner->IsKindOf(RUNTIME_CLASS(CControlBar)) );
  442. return
  443. Deliver(
  444. pOwner->GetSafeHwnd(),
  445. bSend
  446. );
  447. }
  448. UINT CExtCmdItem::GetUsageTickCount() const
  449. {
  450. return m_nUsageTickCount;
  451. }
  452. UINT CExtCmdItem::GetUsagePercent() const
  453. {
  454. ASSERT( m_pProfile != NULL );
  455. if( m_pProfile->m_nTotalTickCount == 0 )
  456. return 0;
  457. return
  458. (m_nUsageTickCount * 100)
  459. /
  460. m_pProfile->m_nTotalTickCount
  461. ;
  462. }
  463. void CExtCmdItem::IncrementUsageCount()
  464. {
  465. if( StateIsBasic()
  466. || StateIsForceRarely()
  467. )
  468. return;
  469. ASSERT( m_pProfile != NULL );
  470. m_nUsageTickCount++;
  471. m_pProfile->m_nTotalTickCount++;
  472. AnalyzeGlobalUsageOverflow();
  473. }
  474. void CExtCmdItem::ResetUsageStatistics()
  475. {
  476. if( StateIsBasic()
  477. || StateIsForceRarely()
  478. )
  479. return;
  480. ASSERT( m_pProfile != NULL );
  481. m_nUsageTickCount = 0;
  482. }
  483. UINT CExtCmdItem::GetProfileTickCount() const
  484. {
  485. ASSERT( m_pProfile != NULL );
  486. return m_pProfile->m_nTotalTickCount;
  487. }
  488. UINT CExtCmdItem::GetProfileRarelyPercent() const
  489. {
  490. ASSERT( m_pProfile != NULL );
  491. return m_pProfile->m_nRarelyPercent;
  492. }
  493. void CExtCmdItem::SetProfileRarelyPercent(
  494. UINT nRarelyPercent
  495. )
  496. {
  497. ASSERT( nRarelyPercent <= 100 );
  498. if( nRarelyPercent > 100 )
  499. nRarelyPercent = 100;
  500. ASSERT( m_pProfile != NULL );
  501. m_pProfile->m_nRarelyPercent = nRarelyPercent;
  502. }
  503. void CExtCmdItem::AnalyzeGlobalUsageOverflow()
  504. {
  505. ASSERT( m_pProfile != NULL );
  506. if( m_pProfile->m_nTotalTickCount < __MAX_TOTAL_TICK_COUNT )
  507. return;
  508. __DECREASE_TICK_COUNT_BY_REF( m_pProfile->m_nTotalTickCount );
  509. POSITION pos = m_pProfile->m_cmds.GetStartPosition();
  510. for( ; pos != NULL; )
  511. {
  512. UINT nCmdID;
  513. CExtCmdItem * pCmdItem = NULL;
  514. m_pProfile->m_cmds.GetNextAssoc( pos, nCmdID, pCmdItem );
  515. ASSERT( pCmdItem != NULL );
  516. __DECREASE_TICK_COUNT_BY_REF( pCmdItem->m_nUsageTickCount );
  517. }
  518. }
  519. bool CExtCmdItem::OnQueryStateSerializationNecessity() const
  520. {
  521. if( StateIsBasic()
  522. || StateIsForceRarely()
  523. || StateIsMenubarTemp()
  524. || CExtCmdManager::IsSystemCommand( m_nCmdID )
  525. || m_nUsageTickCount == 0
  526. )
  527. return false;
  528. return true;
  529. }
  530. void CExtCmdItem::OnGlobalPaintManagerChanged()
  531. {
  532. CExtCmdIcon * pIcon = m_pProfile->CmdGetIconPtr( m_nCmdID );
  533. if( pIcon != NULL )
  534. pIcon->OnGlobalPaintManagerChanged();
  535. }
  536. void CExtCmdItem::OnSysColorChange(
  537. CExtPaintManager * pPM
  538. )
  539. {
  540. ASSERT( m_pProfile != NULL );
  541. CExtCmdIcon * pIcon = m_pProfile->CmdGetIconPtr( m_nCmdID );
  542. if( pIcon != NULL )
  543. pIcon->SyncSysColors( pPM );
  544. }
  545. void CExtCmdItem::OnSettingChange(
  546. CExtPaintManager * pPM,
  547. UINT uFlags,
  548. __EXT_MFC_SAFE_LPCTSTR lpszSection
  549. )
  550. {
  551. ASSERT( m_pProfile != NULL );
  552. CExtCmdIcon * pIcon = m_pProfile->CmdGetIconPtr( m_nCmdID );
  553. if( pIcon != NULL )
  554. pIcon->OnSettingChange( pPM, uFlags, lpszSection );
  555. }
  556. void CExtCmdItem::OnDisplayChange(
  557. CExtPaintManager * pPM,
  558. INT nDepthBPP,
  559. CPoint ptSizes
  560. )
  561. {
  562. ASSERT( m_pProfile != NULL );
  563. CExtCmdIcon * pIcon = m_pProfile->CmdGetIconPtr( m_nCmdID );
  564. if( pIcon != NULL )
  565. pIcon->OnDisplayChange( pPM, nDepthBPP, ptSizes );
  566. }
  567. void CExtCmdItem::OnThemeChanged(
  568. CExtPaintManager * pPM,
  569. WPARAM wParam,
  570. LPARAM lParam
  571. )
  572. {
  573. ASSERT( m_pProfile != NULL );
  574. CExtCmdIcon * pIcon = m_pProfile->CmdGetIconPtr( m_nCmdID );
  575. if( pIcon != NULL )
  576. pIcon->OnThemeChanged( pPM, wParam, lParam );
  577. }
  578. CExtSafeString CExtCmdItem::OnGetToolBarCustomizeName()
  579. {
  580. return OnGetCustomizeScriptName();
  581. }
  582. CExtSafeString CExtCmdItem::OnGetCustomizeScriptName()
  583. {
  584. if( ! m_sMenuText.IsEmpty() )
  585. return m_sMenuText;
  586. if( ! m_sTipTool.IsEmpty() )
  587. return m_sTipTool;
  588. if( ! m_sToolbarText.IsEmpty() )
  589. return m_sToolbarText;
  590. return CExtSafeString( _T("") );
  591. }
  592. CExtSafeString CExtCmdItem::OnGetCustomizeCommandDescription()
  593. {
  594. if( !m_sTipStatus.IsEmpty() )
  595. return m_sTipStatus;
  596. return CExtSafeString( _T("") );
  597. }
  598. /////////////////////////////////////////////////////////////////////////////
  599. // CExtCmdItemUI
  600. // command UI update class
  601. CExtCmdItemUI::CExtCmdItemUI(
  602. CExtCmdItem * pCmd,
  603. int nIndexMax // = 0
  604. )
  605. {
  606. ASSERT( pCmd != NULL );
  607. m_pCmd = pCmd;
  608. m_nIndexMax = nIndexMax;
  609. m_nID = pCmd->m_nCmdID;
  610. m_pOther = NULL;
  611. }
  612. void CExtCmdItemUI::Enable(
  613. BOOL bOn // = TRUE
  614. )
  615. {
  616. ASSERT( m_pCmd != NULL );
  617. CCmdUI::m_bEnableChanged = TRUE;
  618. m_pCmd->StateEnable( bOn ? true : false );
  619. }
  620. void CExtCmdItemUI::SetCheck(
  621. int nCheck // = 1 // 0, 1 or 2 (indeterminate)
  622. )
  623. {
  624. ASSERT( m_pCmd != NULL );
  625. if( nCheck == 0 || nCheck == 1 )
  626. m_pCmd->StateSetCheck(
  627. (nCheck == 0) ? false : true
  628. );
  629. else
  630. {
  631. ASSERT( nCheck == 2 );
  632. m_pCmd->StateSetIndeterminate(
  633. true
  634. );
  635. }
  636. }
  637. void CExtCmdItemUI::SetRadio(
  638. BOOL bOn // = TRUE
  639. )
  640. {
  641. ASSERT( m_pCmd != NULL );
  642. m_pCmd->StateSetRadio( bOn ? true : false );
  643. }
  644. void CExtCmdItemUI::SetText(
  645. __EXT_MFC_SAFE_LPCTSTR lpszText
  646. )
  647. {
  648. ASSERT( m_pCmd != NULL );
  649. m_pCmd->m_sMenuText = lpszText;
  650. }
  651. /////////////////////////////////////////////////////////////////////////////
  652. // CExtCmdProfile
  653. // command profile class
  654. CExtCmdProfile::CExtCmdProfile(
  655. __EXT_MFC_SAFE_LPCTSTR sName // = NULL
  656. )
  657. : m_sName( (sName == NULL) ? _T("") : sName )
  658. , m_nRarelyPercent( __MFCEXT_DEF_RARELY_USED_PERCENT )
  659. , m_nTotalTickCount( 0 )
  660. , m_nLParamUserData( 0L )
  661. {
  662. }
  663. CExtCmdProfile::CExtCmdProfile(
  664. const CExtCmdProfile & other
  665. )
  666. : m_sName( _T("") )
  667. , m_nRarelyPercent( __MFCEXT_DEF_RARELY_USED_PERCENT )
  668. , m_nTotalTickCount( 0 )
  669. , m_nLParamUserData( 0L )
  670. {
  671. AssignFromOther( other );
  672. }
  673. CExtCmdProfile::~CExtCmdProfile()
  674. {
  675. _RemoveAllIconsImpl();
  676. _RemoveAllCmdsImpl();
  677. }
  678. CExtCmdProfile & CExtCmdProfile::operator = (
  679. const CExtCmdProfile & other
  680. )
  681. {
  682. AssignFromOther( other );
  683. return *this;
  684. }
  685. void CExtCmdProfile::AssignFromOther(
  686. const CExtCmdProfile & other
  687. )
  688. {
  689. LPVOID lpvThis = (LPVOID)this;
  690. LPVOID lpvOther = (LPVOID)(&other);
  691. if( lpvThis == lpvOther )
  692. return;
  693. m_sName = other.m_sName;
  694. m_nRarelyPercent = other.m_nRarelyPercent;
  695. m_nTotalTickCount = other.m_nTotalTickCount;
  696. m_nLParamUserData = other.m_nLParamUserData;
  697. _RemoveAllCmdsImpl();
  698. POSITION pos = other.m_cmds.GetStartPosition();
  699. for( ; pos != NULL; )
  700. {
  701. UINT nCmdID;
  702. CExtCmdItem * pCmdItem = NULL;
  703. other.m_cmds.GetNextAssoc( pos, nCmdID, pCmdItem );
  704. ASSERT( pCmdItem != NULL );
  705. m_cmds[ nCmdID  ] = OnCreateCmdItem( *pCmdItem );
  706. ASSERT( m_cmds[ nCmdID  ] != NULL );
  707. }
  708. _RemoveAllIconsImpl();
  709. for( int iIcon = 0;
  710. iIcon < other.m_icons.GetSize();
  711. iIcon++
  712. )
  713. {
  714. CExtCmdIcon * pIcon = other.m_icons[iIcon];
  715. ASSERT( pIcon != NULL );
  716. m_icons.Add( new CExtCmdIcon( *pIcon ) );
  717. }
  718. }
  719. void CExtCmdProfile::_RemoveAllCmdsImpl()
  720. {
  721. POSITION pos = m_cmds.GetStartPosition();
  722. for( ; pos != NULL; )
  723. {
  724. UINT nCmdID;
  725. CExtCmdItem * pCmdItem = NULL;
  726. m_cmds.GetNextAssoc( pos, nCmdID, pCmdItem );
  727. ASSERT( pCmdItem != NULL );
  728. delete pCmdItem;
  729. }
  730. m_cmds.RemoveAll();
  731. }
  732. void CExtCmdProfile::_RemoveAllIconsImpl()
  733. {
  734. for( INT iIcon = 0; iIcon < m_icons.GetSize(); iIcon++ )
  735. {
  736. CExtCmdIcon * pIcon = m_icons[iIcon];
  737. ASSERT( pIcon != NULL );
  738. delete pIcon;
  739. }
  740. m_icons.RemoveAll();
  741. }
  742. CExtCmdItem * CExtCmdProfile::OnCreateCmdItem( const CExtCmdItem & _cmd )
  743. {
  744. return new CExtCmdItem( _cmd );
  745. }
  746. bool CExtCmdProfile::CmdSetup(
  747. const CExtCmdItem & _cmd,
  748. bool bReplaceOld, // = false // but force set images anywhere if was empty
  749. bool * pbWasAddedNew // = NULL
  750. )
  751. {
  752. if( pbWasAddedNew != NULL )
  753. *pbWasAddedNew = false;
  754. if( !CExtCmdManager::IsCommand(_cmd.m_nCmdID) )
  755. {
  756. ASSERT( FALSE );
  757. return false;
  758. }
  759. CExtCmdItem * pCmdItem = NULL;
  760. BOOL bExist =
  761. m_cmds.Lookup( _cmd.m_nCmdID, pCmdItem );
  762. if( !bExist )
  763. {
  764. pCmdItem = OnCreateCmdItem( _cmd );
  765. ASSERT( pCmdItem != NULL );
  766. pCmdItem->m_pProfile = this;
  767. m_cmds.SetAt( _cmd.m_nCmdID, pCmdItem );
  768. if( pbWasAddedNew != NULL )
  769. *pbWasAddedNew = true;
  770. return true;
  771. } // if( !bExist )
  772. ASSERT( pCmdItem != NULL );
  773. ASSERT( pCmdItem->m_pProfile == this );
  774. if( bReplaceOld )
  775. pCmdItem->ReplaceFromOtherNonEmpty( _cmd ); // (+ v.2.22)
  776. else
  777. pCmdItem->UpdateMoreExact( _cmd );
  778. return true;
  779. }
  780. bool CExtCmdProfile::CmdRemove(
  781. UINT nCmdID,
  782. bool * pbWasRemoved // = NULL
  783. )
  784. {
  785. if( pbWasRemoved != NULL )
  786. *pbWasRemoved = false;
  787. if( ! CExtCmdManager::IsCommand( nCmdID ) )
  788. {
  789. ASSERT( FALSE );
  790. return false;
  791. } // if( ! CExtCmdManager::IsCommand( nCmdID ) )
  792. CExtCmdItem * pCmdItem = NULL;
  793. BOOL bExist =
  794. m_cmds.Lookup( nCmdID, pCmdItem );
  795. if( !bExist )
  796. return true;
  797. int nCmdIconIdx = pCmdItem->m_nIconIdx;
  798. ASSERT( pCmdItem != NULL );
  799. delete pCmdItem;
  800. m_cmds.RemoveKey( nCmdID );
  801. if( pbWasRemoved != NULL )
  802. *pbWasRemoved = true;
  803. if( nCmdIconIdx < 0 )
  804. return true;
  805. CExtCmdIcon * pIcon = m_icons.GetAt( nCmdIconIdx );
  806. ASSERT( pIcon != NULL );
  807. delete pIcon;
  808. m_icons.RemoveAt( nCmdIconIdx, 1 );
  809. POSITION pos = m_cmds.GetStartPosition();
  810. for( ; pos != NULL; )
  811. {
  812. UINT nCmdID;
  813. CExtCmdItem * pCmdItem = NULL;
  814. m_cmds.GetNextAssoc( pos, nCmdID, pCmdItem );
  815. ASSERT( pCmdItem != NULL );
  816. ASSERT( pCmdItem->m_nIconIdx != nCmdIconIdx );
  817. if( pCmdItem->m_nIconIdx < nCmdIconIdx )
  818. continue;
  819. pCmdItem->m_nIconIdx --;
  820. } // for( ; pos != NULL; )
  821. return true;
  822. }
  823. void CExtCmdProfile::CmdRemoveAll()
  824. {
  825. _RemoveAllIconsImpl();
  826. _RemoveAllCmdsImpl();
  827. }
  828. void CExtCmdProfile::CmdRemoveByMask(
  829. DWORD dwMask,
  830. DWORD dwExMask, // = 0
  831. bool bAllBitsOnly, // = false
  832. bool bExAllBitsOnly // = false
  833. )
  834. {
  835. CList < UINT, UINT > _listCmdsToRemove;
  836. POSITION pos = m_cmds.GetStartPosition();
  837. for( ; pos != NULL; )
  838. {
  839. UINT nCmdID;
  840. CExtCmdItem * pCmdItem = NULL;
  841. m_cmds.GetNextAssoc( pos, nCmdID, pCmdItem );
  842. ASSERT( pCmdItem != NULL );
  843. DWORD dwTest =
  844. pCmdItem->m_dwStateFlags & dwMask;
  845. DWORD dwExTest =
  846. pCmdItem->m_dwExStateFlags & dwExMask;
  847. if( dwTest == 0 && dwExTest == 0 )
  848. continue;
  849. if( bAllBitsOnly && dwTest != dwMask )
  850. continue;
  851. if( bExAllBitsOnly && dwExTest != dwExMask )
  852. continue;
  853. _listCmdsToRemove.AddTail( nCmdID );
  854. } // for( ; pos != NULL; )
  855. pos = _listCmdsToRemove.GetHeadPosition();
  856. for( ; pos != NULL; )
  857. {
  858. UINT nCmdID = _listCmdsToRemove.GetNext( pos );
  859. CmdRemove( nCmdID );
  860. } // for( ; pos != NULL; )
  861. }
  862. CExtCmdItem * CExtCmdProfile::CmdAllocPtr(
  863. UINT nCmdID // = 0 // 0 means any free in avail range
  864. )
  865. {
  866. if( nCmdID != 0 && CmdIsRegistered(nCmdID) )
  867. return NULL;
  868. if( nCmdID == 0 )
  869. { // find free ID for new command
  870. nCmdID = 65534;
  871. if( !m_cmds.IsEmpty() )
  872. {
  873. while( true )
  874. {
  875. CExtCmdItem * pCmdItem = NULL;
  876. BOOL bExist =
  877. m_cmds.Lookup( nCmdID, pCmdItem );
  878. if( bExist )
  879. {
  880. ASSERT( pCmdItem != NULL );
  881. nCmdID --;
  882. if( nCmdID == 0 )
  883. {
  884. ASSERT( FALSE );
  885. return NULL;
  886. }
  887. continue;
  888. }
  889. ASSERT( CExtCmdManager::IsCommand(nCmdID) );
  890. break;
  891. } // while( true )
  892. } // if( !m_cmds.IsEmpty() )
  893. } // find free ID for new command
  894. ASSERT( !CmdIsRegistered(nCmdID) );
  895. CExtCmdItem _cmd(nCmdID);
  896. if( !CmdSetup(_cmd) )
  897. return NULL;
  898. CExtCmdItem * pCmdItem = CmdGetPtr(nCmdID);
  899. ASSERT( pCmdItem != NULL );
  900. ASSERT( pCmdItem->m_nCmdID == nCmdID );
  901. return pCmdItem;
  902. }
  903. CExtCmdItem * CExtCmdProfile::CmdGetPtr(
  904. UINT nCmdID
  905. )
  906. {
  907. if( ! CExtCmdManager::IsCommand( nCmdID ) )
  908. return NULL;
  909. CExtCmdItem * pCmdItem = NULL;
  910. BOOL bExist =
  911. m_cmds.Lookup( nCmdID, pCmdItem );
  912. if( !bExist )
  913. return NULL;
  914. ASSERT( pCmdItem != NULL );
  915. return pCmdItem;
  916. }
  917. bool CExtCmdProfile::CmdSetIcon(
  918. UINT nCmdID,
  919. const CExtCmdIcon * pCmdIcon,
  920. bool bUseCmdIconObject
  921. )
  922. {
  923. if( ! CExtCmdManager::IsCommand( nCmdID ) )
  924. {
  925. ASSERT( FALSE );
  926. return false;
  927. }
  928. if( pCmdIcon != NULL
  929. && pCmdIcon->IsEmpty()
  930. )
  931. {
  932. if( bUseCmdIconObject )
  933. delete pCmdIcon;
  934. pCmdIcon = NULL;
  935. }
  936. CExtCmdItem * pCmdItem = NULL;
  937. BOOL bExist =
  938. m_cmds.Lookup( nCmdID, pCmdItem );
  939. if( !bExist )
  940. return NULL;
  941. if( pCmdIcon == NULL )
  942. { // if remove icon query
  943. if( pCmdItem->m_nIconIdx < 0 )
  944. return true;
  945. ASSERT( pCmdItem->m_nIconIdx < m_icons.GetSize() );
  946. CExtCmdIcon * pIcon = m_icons[ pCmdItem->m_nIconIdx ];
  947. ASSERT( pIcon != NULL );
  948. delete pIcon;
  949. m_icons.RemoveAt( pCmdItem->m_nIconIdx, 1 ); // 2.24 fix
  950. POSITION pos = m_cmds.GetStartPosition();
  951. ASSERT( pos != NULL );
  952. for( ; pos != NULL; )
  953. {
  954. CExtCmdItem * pCmdItemWalk = NULL;
  955. UINT nCmdIDWalk = (UINT)IDC_STATIC;
  956. m_cmds.GetNextAssoc( pos, nCmdIDWalk, pCmdItemWalk );
  957. ASSERT( pCmdItemWalk != NULL );
  958. ASSERT( nCmdIDWalk == pCmdItemWalk->m_nCmdID );
  959. if( pCmdItemWalk == pCmdItem )
  960. continue;
  961. if( pCmdItemWalk->m_nIconIdx < 0 )
  962. continue;
  963. ASSERT( pCmdItemWalk->m_nIconIdx <= m_icons.GetSize() );
  964. ASSERT( pCmdItemWalk->m_nIconIdx != pCmdItem->m_nIconIdx );
  965. if( pCmdItemWalk->m_nIconIdx < pCmdItem->m_nIconIdx )
  966. continue;
  967. pCmdItemWalk->m_nIconIdx --;
  968. } // for( ; pos != NULL; )
  969. pCmdItem->m_nIconIdx = -1;
  970. return true;
  971. } // if remove icon query
  972. else
  973. { // if add/set icon query
  974. ASSERT( ! pCmdIcon->IsEmpty() );
  975. if( pCmdItem->m_nIconIdx < 0 )
  976. {
  977. if( ! bUseCmdIconObject )
  978. {
  979. try
  980. {
  981. CExtCmdIcon * pNewCmdIcon =
  982. new CExtCmdIcon( *pCmdIcon );
  983. ASSERT( ! pNewCmdIcon->IsEmpty() );
  984. pCmdIcon = pNewCmdIcon;
  985. }
  986. catch( CException * pXept )
  987. {
  988. ASSERT( FALSE );
  989. pXept->Delete();
  990. return false;
  991. }
  992. catch( ... )
  993. {
  994. ASSERT( FALSE );
  995. return false;
  996. } // catch( ... )
  997. } // if( ! bUseCmdIconObject )
  998. pCmdItem->m_nIconIdx = (INT)m_icons.GetSize();
  999. m_icons.Add(
  1000. const_cast < CExtCmdIcon * > ( pCmdIcon )
  1001. );
  1002. ASSERT( (pCmdItem->m_nIconIdx + 1) == m_icons.GetSize() );
  1003. } // if( pCmdItem->m_nIconIdx < 0 )
  1004. else
  1005. {
  1006. ASSERT( pCmdItem->m_nIconIdx < m_icons.GetSize() );
  1007. CExtCmdIcon * pExistingCmdIcon =
  1008. m_icons[ pCmdItem->m_nIconIdx ];
  1009. ASSERT( pExistingCmdIcon != NULL );
  1010. if( bUseCmdIconObject )
  1011. {
  1012. m_icons.SetAt(pCmdItem->m_nIconIdx, (CExtCmdIcon*)pCmdIcon );
  1013. delete pExistingCmdIcon;
  1014. } // if( bUseCmdIconObject )
  1015. else
  1016. {
  1017. (*pExistingCmdIcon) = (*pCmdIcon);
  1018. ASSERT( ! pExistingCmdIcon->IsEmpty() );
  1019. } // else from if( bUseCmdIconObject )
  1020. } // else from if( pCmdItem->m_nIconIdx < 0 )
  1021. return true;
  1022. } // if add/set icon query
  1023. }
  1024. bool CExtCmdProfile::CmdSetIcon(
  1025. UINT nCmdID,
  1026. const CExtCmdIcon & cmdIcon // if empty - remove
  1027. )
  1028. {
  1029. if( cmdIcon.IsEmpty() )
  1030. return CmdSetIcon( nCmdID, (CExtCmdIcon *)NULL, false );
  1031. return CmdSetIcon( nCmdID, &cmdIcon, false );
  1032. }
  1033. bool CExtCmdProfile::CmdSetIcon(
  1034. UINT nCmdID,
  1035. const CExtBitmap & _bitmap, // if empty - remove
  1036. COLORREF clrTransparent, // = RGB(0,0,0)
  1037. LPCRECT pRectBitmapSrc // = NULL
  1038. )
  1039. {
  1040. if( _bitmap.IsEmpty() )
  1041. return CmdSetIcon( nCmdID, ((CExtCmdIcon *)NULL), false );
  1042. CExtCmdIcon _icon;
  1043. if( ! _icon.m_bmpNormal.FromBitmap( _bitmap, pRectBitmapSrc ) )
  1044. return false;
  1045. if( clrTransparent != COLORREF(-1L) )
  1046. {
  1047. _icon.m_bmpNormal.Make32();
  1048. _icon.m_bmpNormal.AlphaColor( clrTransparent, RGB(0,0,0), 0 );
  1049. }
  1050. return CmdSetIcon( nCmdID, &_icon, false );
  1051. }
  1052. bool CExtCmdProfile::CmdSetIcon(
  1053. UINT nCmdID,
  1054. HICON hIcon, // if NULL - remove
  1055. bool bCopyIcon // = true
  1056. )
  1057. {
  1058. if( hIcon == NULL )
  1059. return CmdSetIcon( nCmdID, ((CExtCmdIcon *)NULL), false );
  1060. CExtCmdIcon _icon;
  1061. _icon.AssignFromHICON( hIcon, bCopyIcon );
  1062. return CmdSetIcon( nCmdID, &_icon, false );
  1063. }
  1064. CExtCmdIcon * CExtCmdProfile::CmdGetIconPtr(
  1065. UINT nCmdID
  1066. )
  1067. {
  1068. if( ! CExtCmdManager::IsCommand( nCmdID ) )
  1069. {
  1070. // ASSERT( FALSE );
  1071. return NULL;
  1072. }
  1073. CExtCmdItem * pCmdItem = NULL;
  1074. BOOL bExist =
  1075. m_cmds.Lookup( nCmdID, pCmdItem );
  1076. if( !bExist )
  1077. return NULL;
  1078. ASSERT( pCmdItem != NULL );
  1079. if( pCmdItem->m_nIconIdx < 0 )
  1080. return NULL;
  1081. ASSERT( pCmdItem->m_nIconIdx < m_icons.GetSize() );
  1082. CExtCmdIcon * pIcon = m_icons[ pCmdItem->m_nIconIdx ];
  1083. ASSERT( pIcon != NULL );
  1084. ASSERT( !(pIcon->IsEmpty()) );
  1085. return pIcon;
  1086. }
  1087. const CExtCmdIcon * CExtCmdProfile::CmdGetIconPtr(
  1088. UINT nCmdID
  1089. ) const
  1090. {
  1091. return
  1092. ( const_cast < CExtCmdProfile * > ( this ) )
  1093. -> CmdGetIconPtr( nCmdID );
  1094. }
  1095. CExtCmdIcon & CExtCmdProfile::CmdGetIcon(
  1096. UINT nCmdID
  1097. )
  1098. {
  1099. CExtCmdIcon * pIcon = CmdGetIconPtr( nCmdID );
  1100. if( pIcon != NULL )
  1101. return (*pIcon);
  1102. static CExtCmdIcon g_EmptyIcon;
  1103. return g_EmptyIcon;
  1104. }
  1105. const CExtCmdIcon & CExtCmdProfile::CmdGetIcon(
  1106. UINT nCmdID
  1107. ) const
  1108. {
  1109. return
  1110. ( const_cast < CExtCmdProfile * > ( this ) )
  1111. -> CmdGetIcon( nCmdID );
  1112. }
  1113. bool CExtCmdProfile::CmdIsRegistered(
  1114. UINT nCmdID
  1115. )
  1116. {
  1117. bool bRegistered =
  1118. (CmdGetPtr(nCmdID) != NULL) ?
  1119. true : false;
  1120. return bRegistered;
  1121. }
  1122. bool CExtCmdProfile::UpdateFromMenu(
  1123. HMENU hMenu,
  1124. bool bReplaceOld, // = false
  1125. bool bRecursive, // = true
  1126. bool bLoadTips // = true
  1127. )
  1128. {
  1129. if( hMenu == NULL )
  1130. {
  1131. ASSERT( FALSE );
  1132. return false;
  1133. }
  1134. if( !(::IsMenu(hMenu)) )
  1135. {
  1136. ASSERT( FALSE );
  1137. return false;
  1138. }
  1139. int nMenuItemCount = ::GetMenuItemCount(hMenu);
  1140. for( int nMenuItemIdx=0;
  1141. nMenuItemIdx < nMenuItemCount;
  1142. nMenuItemIdx++
  1143. )
  1144. { // for all menu level items
  1145. // get the menu item info
  1146. CExtSafeString sMenuText;
  1147. MENUITEMINFO mii;
  1148. ::memset( &mii, 0, sizeof(MENUITEMINFO) );
  1149. mii.cbSize = sizeof(MENUITEMINFO);
  1150. mii.fMask =
  1151. MIIM_CHECKMARKS
  1152. |MIIM_DATA
  1153. |MIIM_ID
  1154. |MIIM_STATE
  1155. |MIIM_SUBMENU
  1156. |MIIM_TYPE
  1157. ;
  1158. mii.cch = __MAX_UI_ITEM_TEXT;
  1159. mii.dwTypeData =
  1160. sMenuText.GetBuffer(__MAX_UI_ITEM_TEXT);
  1161. ASSERT( mii.dwTypeData != NULL );
  1162. if( mii.dwTypeData == NULL )
  1163. {
  1164. ASSERT( FALSE );
  1165. continue;
  1166. }
  1167. if( !::GetMenuItemInfo(
  1168. hMenu,
  1169. nMenuItemIdx,
  1170. TRUE,
  1171. &mii
  1172. )
  1173. )
  1174. {
  1175. sMenuText.ReleaseBuffer();
  1176. ASSERT( FALSE );
  1177. continue;
  1178. }
  1179. sMenuText.ReleaseBuffer();
  1180. if( (mii.fType & MFT_SEPARATOR) != 0 )
  1181. continue;
  1182. // if sub-menu process it
  1183. if( mii.hSubMenu != NULL )
  1184. {
  1185. if( !bRecursive )
  1186. continue;
  1187. VERIFY(
  1188. UpdateFromMenu(
  1189. mii.hSubMenu,
  1190. bReplaceOld,
  1191. true
  1192. )
  1193. );
  1194. continue;
  1195. } // if( mii.hSubMenu != NULL )
  1196. // register command
  1197. if( !CExtCmdManager::IsCommand(mii.wID) )
  1198. continue;
  1199. CExtCmdItem _cmd;
  1200. _cmd.m_nCmdID = mii.wID;
  1201. sMenuText.Replace( _T("n"), _T("") );
  1202. sMenuText.Replace( _T("r"), _T("") );
  1203. sMenuText.TrimLeft();
  1204. sMenuText.TrimRight();
  1205. if( ! sMenuText.IsEmpty() )
  1206. {
  1207. int nSep =
  1208. sMenuText.ReverseFind( _T('t') );
  1209. if( nSep >= 0 )
  1210. {
  1211. int nLen = sMenuText.GetLength();
  1212. _cmd.m_sAccelText = sMenuText.Right( nLen - nSep );
  1213. _cmd.m_sAccelText.TrimLeft();
  1214. _cmd.m_sAccelText.TrimRight();
  1215. _cmd.m_sMenuText = sMenuText.Left( nSep );
  1216. _cmd.m_sMenuText.TrimLeft();
  1217. _cmd.m_sMenuText.TrimRight();
  1218. }
  1219. else
  1220. _cmd.m_sMenuText = sMenuText;
  1221. } // if( ! sMenuText.IsEmpty() )
  1222. if( bLoadTips )
  1223. _cmd.TipsLoad();
  1224. VERIFY( CmdSetup(_cmd,bReplaceOld) );
  1225. } // for all menu level items
  1226. return true;
  1227. }
  1228. bool CExtCmdProfile::UpdateFromMenu(
  1229. UINT nResourceID,
  1230. bool bReplaceOld, // = false
  1231. bool bLoadTips // = true
  1232. )
  1233. {
  1234. __PROF_UIS_MANAGE_STATE;
  1235. CMenu menu;
  1236. if( ! g_ResourceManager->LoadMenu( menu, nResourceID ) )
  1237. {
  1238. ASSERT( FALSE );
  1239. return false;
  1240. }
  1241. return
  1242. UpdateFromMenu(
  1243. menu.GetSafeHmenu(),
  1244. bReplaceOld,
  1245. true, // bRecursive
  1246. bLoadTips
  1247. );
  1248. }
  1249. CExtCmdProfile::MFC_TOOLBAR_LOADER::MFC_TOOLBAR_LOADER(
  1250. HINSTANCE hInstResourceCommands,
  1251. HRSRC hRsrcCommands,
  1252. HINSTANCE hInstResourceBitmap,
  1253. HRSRC hRsrcCommandsBitmap,
  1254. COLORREF clrBmpTransparent // = RGB(192,192,192)
  1255. )
  1256. : m_pCommands( NULL )
  1257. , m_pButtons( NULL )
  1258. , m_nCountCommands( 0 )
  1259. , m_nCountButtons( 0 )
  1260. , m_clrBmpTransparent( clrBmpTransparent )
  1261. , m_sizeButton( 0, 0 )
  1262. , m_nVersion( 0 )
  1263. {
  1264. ASSERT( hInstResourceCommands != NULL );
  1265. ASSERT( hRsrcCommands != NULL );
  1266. ASSERT( hInstResourceBitmap != NULL );
  1267. ASSERT( hRsrcCommandsBitmap != NULL );
  1268. m_bmp.Empty();
  1269. if( ! m_bmp.LoadBMP_Resource(
  1270. hInstResourceBitmap,
  1271. hRsrcCommandsBitmap
  1272. )
  1273. )
  1274. {
  1275. ASSERT( FALSE );
  1276. return;
  1277. }
  1278. if( ! m_bmp.Make32() )
  1279. {
  1280. ASSERT( FALSE );
  1281. return;
  1282. }
  1283. HGLOBAL hGlobalResourceCommands =
  1284. ::LoadResource(
  1285. hInstResourceCommands,
  1286. hRsrcCommands
  1287. );
  1288. ASSERT( hGlobalResourceCommands != NULL );
  1289. if( hGlobalResourceCommands == NULL )
  1290. return;
  1291. LP_MFC_TOOLBAR_RESOURCE_DATA pData =
  1292. (LP_MFC_TOOLBAR_RESOURCE_DATA)
  1293. ::LockResource( hGlobalResourceCommands );
  1294. if( pData == NULL )
  1295. return;
  1296. m_nCountCommands = (INT)pData->wItemCount;
  1297. ASSERT( m_nCountCommands > 0 );
  1298. m_nVersion = pData->wVersion;
  1299. m_pCommands = new UINT[ m_nCountCommands ];
  1300. m_nCountButtons = 0;
  1301. INT nCommandIdx = 0;
  1302. for( nCommandIdx = 0;
  1303. nCommandIdx < m_nCountCommands;
  1304. nCommandIdx++
  1305. )
  1306. {
  1307. m_pCommands[nCommandIdx] = pData->items()[nCommandIdx];
  1308. if( m_pCommands[nCommandIdx] != ID_SEPARATOR )
  1309. m_nCountButtons++;
  1310. }
  1311. ASSERT( m_nCountButtons > 0 );
  1312. m_pButtons =  new UINT[ m_nCountButtons ];
  1313. INT nButtonIdx = 0;
  1314. for( nCommandIdx = 0;
  1315. nCommandIdx < m_nCountCommands;
  1316. nCommandIdx++
  1317. )
  1318. {
  1319. if( m_pCommands[nCommandIdx] == ID_SEPARATOR )
  1320. continue;
  1321. ASSERT( nButtonIdx < m_nCountButtons );
  1322. m_pButtons[ nButtonIdx ] = m_pCommands[nCommandIdx];
  1323. nButtonIdx++;
  1324. if( nButtonIdx == m_nCountButtons )
  1325. break;
  1326. }
  1327. ASSERT( pData->wWidth > 0 && pData->wHeight > 0 );
  1328. m_sizeButton.cx = (INT)pData->wWidth;
  1329. m_sizeButton.cy = (INT)pData->wHeight;
  1330. ::UnlockResource( hGlobalResourceCommands );
  1331. ::FreeResource( hGlobalResourceCommands );
  1332. }
  1333. CExtCmdProfile::MFC_TOOLBAR_LOADER::~MFC_TOOLBAR_LOADER()
  1334. {
  1335. if( m_pCommands != NULL )
  1336. delete [] m_pCommands;
  1337. if( m_pButtons != NULL )
  1338. delete [] m_pButtons;
  1339. }
  1340. WORD CExtCmdProfile::MFC_TOOLBAR_LOADER::GetVersion() const
  1341. {
  1342. return m_nVersion;
  1343. }
  1344. INT CExtCmdProfile::MFC_TOOLBAR_LOADER::IsEmpty() const
  1345. {
  1346. return ( m_pCommands == NULL ) ? true : false;
  1347. }
  1348. INT CExtCmdProfile::MFC_TOOLBAR_LOADER::GetCommandCount() const
  1349. {
  1350. if( m_pCommands == NULL )
  1351. return 0;
  1352. ASSERT( m_nCountCommands > 0 );
  1353. ASSERT( m_nCountButtons > 0 );
  1354. ASSERT( m_pButtons != NULL );
  1355. ASSERT( ! m_bmp.IsEmpty() );
  1356. ASSERT( m_sizeButton.cx > 0 && m_sizeButton.cy > 0 );
  1357. return m_nCountCommands;
  1358. }
  1359. INT CExtCmdProfile::MFC_TOOLBAR_LOADER::GetButtonCount() const
  1360. {
  1361. if( m_pCommands == NULL )
  1362. return 0;
  1363. ASSERT( m_nCountCommands > 0 );
  1364. ASSERT( m_nCountButtons > 0 );
  1365. ASSERT( m_pButtons != NULL );
  1366. ASSERT( ! m_bmp.IsEmpty() );
  1367. ASSERT( m_sizeButton.cx > 0 && m_sizeButton.cy > 0 );
  1368. return m_nCountButtons;
  1369. }
  1370. COLORREF CExtCmdProfile::MFC_TOOLBAR_LOADER::GetTransparentColor() const
  1371. {
  1372. return m_clrBmpTransparent;
  1373. }
  1374. UINT CExtCmdProfile::MFC_TOOLBAR_LOADER::GetCommandIdAt( INT nCommandIdx ) const
  1375. {
  1376. if( IsEmpty() )
  1377. {
  1378. ASSERT( FALSE );
  1379. return 0;
  1380. }
  1381. ASSERT( m_pCommands != NULL );
  1382. ASSERT( m_nCountCommands != NULL );
  1383. if( nCommandIdx < 0 || nCommandIdx >= m_nCountCommands )
  1384. {
  1385. ASSERT( FALSE );
  1386. return 0;
  1387. }
  1388. return m_pCommands[ nCommandIdx ];
  1389. }
  1390. UINT CExtCmdProfile::MFC_TOOLBAR_LOADER::GetButtonIdAt( INT nButtonIdx ) const
  1391. {
  1392. if( IsEmpty() )
  1393. {
  1394. ASSERT( FALSE );
  1395. return 0;
  1396. }
  1397. ASSERT( m_pButtons != NULL );
  1398. ASSERT( m_nCountButtons != NULL );
  1399. if( nButtonIdx < 0 || nButtonIdx >= m_nCountButtons )
  1400. {
  1401. ASSERT( FALSE );
  1402. return 0;
  1403. }
  1404. return m_pButtons[ nButtonIdx ];
  1405. }
  1406. UINT CExtCmdProfile::MFC_TOOLBAR_LOADER::ExtractButtonData(
  1407. INT nButtonIdx,
  1408. CExtCmdIcon & icon
  1409. ) const
  1410. {
  1411. icon.Empty();
  1412. if( IsEmpty() )
  1413. {
  1414. ASSERT( FALSE );
  1415. return 0;
  1416. }
  1417. ASSERT( m_nCountCommands > 0 );
  1418. ASSERT( m_nCountButtons > 0 );
  1419. ASSERT( m_pCommands != NULL );
  1420. ASSERT( m_pButtons != NULL );
  1421. ASSERT( ! m_bmp.IsEmpty() );
  1422. ASSERT( m_sizeButton.cx > 0 && m_sizeButton.cy > 0 );
  1423. if( nButtonIdx < 0 || nButtonIdx >= m_nCountButtons )
  1424. {
  1425. ASSERT( FALSE );
  1426. return 0;
  1427. }
  1428. CPoint ptItem( m_sizeButton.cx * nButtonIdx, 0 );
  1429. CRect rcItem( ptItem, m_sizeButton );
  1430. icon.Empty();
  1431. icon.m_bmpNormal.FromBitmap(
  1432. m_bmp,
  1433. &rcItem
  1434. );
  1435. if( m_clrBmpTransparent != COLORREF(-1L) )
  1436. icon.m_bmpNormal.AlphaColor( m_clrBmpTransparent, RGB(0,0,0), 0 );
  1437. if( icon.IsEmpty() )
  1438. {
  1439. ASSERT( FALSE );
  1440. return 0;
  1441. }
  1442. return m_pButtons[ nButtonIdx ];
  1443. }
  1444. void CExtCmdProfile::MFC_TOOLBAR_LOADER::GetCmdArray(
  1445. LPUINT * ppCmdArray,
  1446. LPINT pCmdCount // = NULL
  1447. ) const
  1448. {
  1449. if( ppCmdArray != NULL )
  1450. (*ppCmdArray) = NULL;
  1451. if( pCmdCount != NULL )
  1452. (*pCmdCount) = m_nCountCommands;
  1453. if( IsEmpty() || ppCmdArray == NULL )
  1454. return;
  1455. ASSERT( m_nCountCommands > 0 );
  1456. ASSERT( m_nCountButtons > 0 );
  1457. ASSERT( m_pCommands != NULL );
  1458. ASSERT( m_pButtons != NULL );
  1459. (*ppCmdArray) = new UINT[ m_nCountCommands ];
  1460. UINT nSizeInBytes = 
  1461. m_nCountCommands * sizeof(UINT);
  1462. __EXT_MFC_MEMCPY(
  1463. (LPVOID)(*ppCmdArray),
  1464. nSizeInBytes,
  1465. (LPCVOID)m_pCommands,
  1466. nSizeInBytes
  1467. );
  1468. }
  1469. bool CExtCmdProfile::UpdateFromToolBar(
  1470. CToolBar & bar,
  1471. bool bReplaceOld, // = false // but force set images anywhere if was empty
  1472. bool bLoadTips // = true
  1473. )
  1474. {
  1475. if( bar.GetSafeHwnd() == NULL
  1476. || (! ::IsWindow(bar.GetSafeHwnd()))
  1477. )
  1478. {
  1479. ASSERT( FALSE );
  1480. return false;
  1481. }
  1482. CImageList * pImageList =
  1483. bar.GetToolBarCtrl().GetImageList();
  1484. if( pImageList == NULL
  1485. || pImageList->GetSafeHandle() == NULL
  1486. )
  1487. {
  1488. ASSERT( FALSE );
  1489. return false;
  1490. }
  1491. int nButtonCount = bar.GetCount();
  1492.     for( int nButtonIdx = 0; nButtonIdx < nButtonCount; nButtonIdx++ )
  1493. {
  1494. // get button info
  1495. UINT nCmdID = bar.GetItemID( nButtonIdx ); 
  1496. if( nCmdID == ID_SEPARATOR )
  1497. continue;
  1498. ASSERT( CExtCmdManager::IsCommand( nCmdID ) );
  1499. TBBUTTONINFO tbi;
  1500. ::memset( &tbi, 0, sizeof(TBBUTTONINFO) );
  1501. tbi.cbSize = sizeof(TBBUTTONINFO);
  1502. tbi.idCommand = nCmdID;
  1503. tbi.dwMask = TBIF_IMAGE|TBIF_TEXT;
  1504. tbi.cchText = __MAX_UI_ITEM_TEXT;
  1505. CExtSafeString sToolbarText;
  1506. tbi.pszText =
  1507. sToolbarText.GetBuffer(__MAX_UI_ITEM_TEXT);
  1508. ASSERT( tbi.pszText != NULL );
  1509. if( tbi.pszText == NULL )
  1510. {
  1511. ASSERT( FALSE );
  1512. continue;
  1513. }
  1514. if( !bar.GetToolBarCtrl().GetButtonInfo(nCmdID,&tbi) )
  1515. {
  1516. UINT nDummyID,nDummyStyle;
  1517. bar.GetButtonInfo(
  1518. nButtonIdx,
  1519. nDummyID,
  1520. nDummyStyle,
  1521. tbi.iImage
  1522. );
  1523. }
  1524. sToolbarText.ReleaseBuffer();
  1525. // register command
  1526. CExtCmdItem _cmd;
  1527. _cmd.m_nCmdID = nCmdID;
  1528. _cmd.m_sToolbarText = sToolbarText;
  1529. if( bLoadTips )
  1530. _cmd.TipsLoad();
  1531. if( !CmdSetup(_cmd,bReplaceOld) )
  1532. {
  1533. ASSERT( FALSE );
  1534. continue;
  1535. }
  1536. if( tbi.iImage < 0 )
  1537. continue;
  1538. ASSERT( tbi.iImage < pImageList->GetImageCount() );
  1539. CExtCmdItem * pCmdItem = CmdGetPtr(nCmdID);
  1540. ASSERT( pCmdItem != NULL );
  1541. if( pCmdItem->m_nIconIdx >= 0 )
  1542. {
  1543. ASSERT( pCmdItem->m_nIconIdx < m_icons.GetSize() );
  1544. continue;
  1545. }
  1546. HICON hIcon = pImageList->ExtractIcon( tbi.iImage );
  1547. if( hIcon == NULL )
  1548. {
  1549. ASSERT( FALSE );
  1550. continue;
  1551. }
  1552. CExtCmdIcon * pIcon = new CExtCmdIcon;
  1553. pIcon->AssignFromHICON( hIcon, false );
  1554. int nIconIndex = (int)m_icons.Add( pIcon );
  1555. ASSERT( nIconIndex >= 0 );
  1556. pCmdItem->m_nIconIdx = nIconIndex;
  1557. } // for( int nButtonIdx = 0; nButtonIdx < nButtonCount; nButtonIdx++ )
  1558. return true;
  1559. }
  1560. bool CExtCmdProfile::UpdateFromToolBar(
  1561. __EXT_MFC_SAFE_LPCTSTR strResourceID,
  1562. LPUINT * ppCmdArray, // = NULL
  1563. LPINT pCmdCount, // = NULL
  1564. bool bReplaceOld, // = false // but force set images anywhere if was empty
  1565. bool bLoadTips, // = true
  1566. COLORREF clrBmpTransparent // = RGB(192,192,192)
  1567. )
  1568. {
  1569. ASSERT( strResourceID != NULL );
  1570. if( strResourceID == NULL )
  1571. return false;
  1572. //HINSTANCE hInstResourceCommands =
  1573. // ::AfxFindResourceHandle(
  1574. // strResourceID,
  1575. // RT_TOOLBAR
  1576. // );
  1577. // if( hInstResourceCommands == NULL )
  1578. // return false;
  1579. //HRSRC hRsrcCommands =
  1580. // ::FindResource(
  1581. // hInstResourceCommands,
  1582. // strResourceID,
  1583. // RT_TOOLBAR
  1584. // );
  1585. // if( hRsrcCommands == NULL )
  1586. // return false;
  1587. //HINSTANCE hInstResourceBitmap =
  1588. // ::AfxFindResourceHandle(
  1589. // strResourceID,
  1590. // RT_BITMAP
  1591. // );
  1592. // if( hInstResourceBitmap == NULL )
  1593. // return false;
  1594. //HRSRC hRsrcBitmap =
  1595. // ::FindResource(
  1596. // hInstResourceBitmap,
  1597. // strResourceID,
  1598. // RT_BITMAP
  1599. // );
  1600. // if( hRsrcBitmap == NULL )
  1601. // return false;
  1602. HRSRC hRsrcCommands = NULL;
  1603. HINSTANCE hInstResourceCommands =
  1604. g_ResourceManager->FindResourceHandle(
  1605. RT_TOOLBAR,
  1606. UINT(__EXT_MFC_UINT_PTR(LPCTSTR(strResourceID))),
  1607. NULL,
  1608. &hRsrcCommands
  1609. );
  1610. if( hInstResourceCommands == NULL )
  1611. return false;
  1612. HRSRC hRsrcBitmap = NULL;
  1613. HINSTANCE hInstResourceBitmap =
  1614. g_ResourceManager->FindResourceHandle(
  1615. RT_BITMAP,
  1616. UINT(__EXT_MFC_UINT_PTR(LPCTSTR(strResourceID))),
  1617. NULL,
  1618. &hRsrcBitmap
  1619. );
  1620. if( hInstResourceBitmap == NULL )
  1621. return false;
  1622. ASSERT( hRsrcBitmap != NULL );
  1623. MFC_TOOLBAR_LOADER _loader(
  1624. hInstResourceCommands,
  1625. hRsrcCommands,
  1626. hInstResourceBitmap,
  1627. hRsrcBitmap,
  1628. clrBmpTransparent
  1629. );
  1630. if( _loader.IsEmpty() )
  1631. return false;
  1632. int nButtonCount = _loader.GetButtonCount();
  1633. ASSERT( nButtonCount > 0 );
  1634.     for( int nButtonIdx = 0; nButtonIdx < nButtonCount; nButtonIdx++ )
  1635. {
  1636. CExtCmdIcon * pIcon = new CExtCmdIcon;
  1637. CExtCmdItem _cmd;
  1638. _cmd.m_nCmdID =
  1639. _loader.ExtractButtonData( nButtonIdx, *pIcon );
  1640. if( _cmd.m_nCmdID == ID_SEPARATOR || pIcon->IsEmpty() )
  1641. {
  1642. ASSERT( FALSE );
  1643. delete pIcon;
  1644. continue;
  1645. }
  1646. ASSERT( CExtCmdManager::IsCommand( _cmd.m_nCmdID ) );
  1647. if( bLoadTips )
  1648. _cmd.TipsLoad();
  1649. if( !CmdSetup( _cmd, bReplaceOld ) )
  1650. {
  1651. ASSERT( FALSE );
  1652. delete pIcon;
  1653. continue;
  1654. } // if( !CmdSetup( _cmd, bReplaceOld ) )
  1655. // CExtCmdItem * pCmdItem = CmdGetPtr( _cmd.m_nCmdID );
  1656. // ASSERT( pCmdItem != NULL );
  1657. // if( pCmdItem->m_nIconIdx >= 0 )
  1658. // {
  1659. // ASSERT( pCmdItem->m_nIconIdx < m_icons.GetSize() );
  1660. // delete pIcon;
  1661. // continue;
  1662. // } // if( pCmdItem->m_nIconIdx >= 0 )
  1663. // int nIconIndex = m_icons.Add( pIcon );
  1664. // ASSERT( nIconIndex >= 0 );
  1665. // pCmdItem->m_nIconIdx = nIconIndex;
  1666. CmdSetIcon( _cmd.m_nCmdID, pIcon, true );
  1667. } // for( int nButtonIdx = 0; nButtonIdx < nButtonCount; nButtonIdx++ )
  1668. _loader.GetCmdArray( ppCmdArray, pCmdCount );
  1669. return true;
  1670. }
  1671. bool CExtCmdProfile::SerializeState(
  1672. CArchive & ar,
  1673. bool bEnableThrowExceptions // = false
  1674. )
  1675. {
  1676. bool bRetVal = false;
  1677. try
  1678. {
  1679. //CExtSafeString sFriendlyVer;
  1680. //DWORD dwApiVer0 = g_CmdManager.GetVersionDWORD( false );
  1681. //DWORD dwApiVer1 = g_CmdManager.GetVersionDWORD( true );
  1682. DWORD dwGeneralFlags = 0;
  1683. DWORD dwReserved = 0L;
  1684. if( ar.IsStoring() )
  1685. { // store state
  1686. //CExtSafeString sTmpBuffer;
  1687. // store version info
  1688. //sFriendlyVer.Format(
  1689. // _T("Prof-UIS (v. %s) command profile"),
  1690. // g_CmdManager.GetVersionString( sTmpBuffer )
  1691. // );
  1692. //ar << sFriendlyVer;
  1693. //ar << dwApiVer0;
  1694. //ar << dwApiVer1;
  1695. ar << dwGeneralFlags;
  1696. ar << dwReserved;
  1697. ar << dwReserved;
  1698. ar << dwReserved;
  1699. ar << dwReserved;
  1700. // store command usage information
  1701. ar << DWORD(m_nTotalTickCount);
  1702. POSITION pos = m_cmds.GetStartPosition();
  1703. for( ; pos != NULL; )
  1704. {
  1705. UINT nCmdID;
  1706. CExtCmdItem * pCmdItem = NULL;
  1707. m_cmds.GetNextAssoc( pos, nCmdID, pCmdItem);
  1708. ASSERT( pCmdItem != NULL );
  1709. if( !pCmdItem->OnQueryStateSerializationNecessity() )
  1710. continue;
  1711. ar << DWORD(pCmdItem->m_nCmdID);
  1712. ar << DWORD(pCmdItem->m_nUsageTickCount);
  1713. }
  1714. ar << DWORD(0);
  1715. } // store state
  1716. else
  1717. { // load state
  1718. // load version info
  1719. //DWORD dwApiVer0a = 0, dwApiVer1a = 0;
  1720. DWORD dwTmp;
  1721. //ar >> sFriendlyVer;
  1722. //ar >> dwApiVer0a;
  1723. //ar >> dwApiVer1a;
  1724. ar >> dwGeneralFlags;
  1725. ar >> dwReserved;
  1726. ar >> dwReserved;
  1727. ar >> dwReserved;
  1728. ar >> dwReserved;
  1729. //if( dwApiVer1 != dwApiVer1a )
  1730. // return false;
  1731. // load command usage information
  1732. ar >> dwTmp;
  1733. m_nTotalTickCount = UINT(dwTmp);
  1734. for( ; true; )
  1735. {
  1736. UINT nCmdId, nUsageTickCount;
  1737. ar >> dwTmp;
  1738. nCmdId = UINT(dwTmp);
  1739. if( nCmdId == 0 )
  1740. break;
  1741. ar >> dwTmp;
  1742. nUsageTickCount = UINT(dwTmp);
  1743. CExtCmdItem * pCmdItem = CmdGetPtr( nCmdId );
  1744. ASSERT( pCmdItem != NULL );
  1745. if( pCmdItem == NULL )
  1746. continue;
  1747. if( pCmdItem->StateIsBasic()
  1748. || pCmdItem->StateIsForceRarely()
  1749. || CExtCmdManager::IsSystemCommand(pCmdItem->m_nCmdID)
  1750. )
  1751. continue;
  1752. pCmdItem->m_nUsageTickCount = nUsageTickCount;
  1753. }
  1754. } // load state
  1755. dwGeneralFlags;
  1756. dwReserved;
  1757. bRetVal = true;
  1758. } // try
  1759. catch( CException * pXept )
  1760. {
  1761. if( bEnableThrowExceptions )
  1762. throw;
  1763. pXept->Delete();
  1764. //ASSERT( FALSE );
  1765. } // catch( CException * pXept )
  1766. catch( ... )
  1767. {
  1768. if( bEnableThrowExceptions )
  1769. throw;
  1770. //ASSERT( FALSE );
  1771. } // catch( ... )
  1772. return bRetVal;
  1773. }
  1774. bool CExtCmdProfile::SetBasicCommands(
  1775. UINT * pCommands,
  1776. bool bOn // = true
  1777. )
  1778. {
  1779. if( pCommands == NULL )
  1780. {
  1781. ASSERT( FALSE );
  1782. return false;
  1783. }
  1784. bool bRetVal = true;
  1785. for(; *pCommands != 0; pCommands++ )
  1786. {
  1787. if( CExtCmdManager::IsSystemCommand( *pCommands ) )
  1788. {
  1789. ASSERT( FALSE );
  1790. bRetVal = false; // we find some error
  1791. continue;
  1792. }
  1793. CExtCmdItem * pCmdItem = CmdGetPtr( *pCommands );
  1794. if( pCmdItem == NULL )
  1795. {
  1796. ASSERT( FALSE );
  1797. bRetVal = false; // we find some error
  1798. continue;
  1799. }
  1800. pCmdItem->StateSetBasic( bOn );
  1801. } // for(; *pCommands != 0; pCommands++ )
  1802. return bRetVal;
  1803. }
  1804. bool CExtCmdProfile::SerializeState(
  1805. __EXT_MFC_SAFE_LPCTSTR sSectionNameCompany, // under HKEY_CURRENT_USERSoftware
  1806. __EXT_MFC_SAFE_LPCTSTR sSectionNameProduct, // under HKEY_CURRENT_USERSoftware%sSectionNameCompany%
  1807. bool bSave,
  1808. HKEY hKeyRoot, //  = HKEY_CURRENT_USER
  1809. bool bEnableThrowExceptions // = false
  1810. )
  1811. {
  1812. ASSERT( sSectionNameCompany != NULL );
  1813. ASSERT( sSectionNameProduct != NULL );
  1814. bool bRetVal = false;
  1815. try
  1816. {
  1817. CMemFile _file;
  1818. if( bSave )
  1819. {
  1820. { // BLOCK: CArchive usage
  1821. CArchive ar(
  1822. &_file,
  1823. CArchive::store
  1824. );
  1825. if( ! SerializeState( ar, bEnableThrowExceptions ) )
  1826. return false;
  1827. ar.Flush();
  1828. } // BLOCK: CArchive usage
  1829. // ... write _file to registry
  1830. _file.Seek(0,CFile::begin);
  1831. if( ! fileobj_to_registry(
  1832. _file,
  1833. m_sName,
  1834. sSectionNameCompany,
  1835. sSectionNameProduct,
  1836. hKeyRoot,
  1837. bEnableThrowExceptions
  1838. )
  1839. )
  1840. return false;
  1841. } // if( bSave )
  1842. else
  1843. {
  1844. // ... read _file from registry
  1845. if( ! fileobj_from_registry(
  1846. _file,
  1847. m_sName,
  1848. sSectionNameCompany,
  1849. sSectionNameProduct,
  1850. hKeyRoot,
  1851. bEnableThrowExceptions
  1852. )
  1853. )
  1854. return false;
  1855. _file.Seek(0,CFile::begin);
  1856. CArchive ar(
  1857. &_file,
  1858. CArchive::load
  1859. );
  1860. if( ! SerializeState( ar, bEnableThrowExceptions ) )
  1861. return false;
  1862. } // else from if( bSave )
  1863. bRetVal = true;
  1864. } // try
  1865. catch( CException * pXept )
  1866. {
  1867. pXept->Delete();
  1868. ASSERT( FALSE );
  1869. } // catch( CException * pXept )
  1870. catch( ... )
  1871. {
  1872. ASSERT( FALSE );
  1873. } // catch( ... )
  1874. return bRetVal;
  1875. }
  1876. void CExtCmdProfile::OnGlobalPaintManagerChanged()
  1877. {
  1878. POSITION pos = m_cmds.GetStartPosition();
  1879. for( ; pos != NULL; )
  1880. {
  1881. UINT nCmdID = 0;
  1882. CExtCmdItem * pCmdItem = NULL;
  1883. m_cmds.GetNextAssoc( pos, nCmdID, pCmdItem);
  1884. ASSERT( pCmdItem != NULL );
  1885. pCmdItem->OnGlobalPaintManagerChanged();
  1886. } // for( ; pos != NULL; )
  1887. }
  1888. void CExtCmdProfile::OnSysColorChange(
  1889. class CExtPaintManager * pPM
  1890. )
  1891. {
  1892. POSITION pos = m_cmds.GetStartPosition();
  1893. for( ; pos != NULL; )
  1894. {
  1895. UINT nCmdID = 0;
  1896. CExtCmdItem * pCmdItem = NULL;
  1897. m_cmds.GetNextAssoc( pos, nCmdID, pCmdItem);
  1898. ASSERT( pCmdItem != NULL );
  1899. pCmdItem->OnSysColorChange( pPM );
  1900. } // for( ; pos != NULL; )
  1901. }
  1902. void CExtCmdProfile::OnSettingChange(
  1903. class CExtPaintManager * pPM,
  1904. UINT uFlags,
  1905. __EXT_MFC_SAFE_LPCTSTR lpszSection
  1906. )
  1907. {
  1908. POSITION pos = m_cmds.GetStartPosition();
  1909. for( ; pos != NULL; )
  1910. {
  1911. UINT nCmdID = 0;
  1912. CExtCmdItem * pCmdItem = NULL;
  1913. m_cmds.GetNextAssoc( pos, nCmdID, pCmdItem);
  1914. ASSERT( pCmdItem != NULL );
  1915. pCmdItem->OnSettingChange( pPM, uFlags, lpszSection );
  1916. } // for( ; pos != NULL; )
  1917. }
  1918. void CExtCmdProfile::OnDisplayChange(
  1919. class CExtPaintManager * pPM,
  1920. INT nDepthBPP,
  1921. CPoint ptSizes
  1922. )
  1923. {
  1924. POSITION pos = m_cmds.GetStartPosition();
  1925. for( ; pos != NULL; )
  1926. {
  1927. UINT nCmdID = 0;
  1928. CExtCmdItem * pCmdItem = NULL;
  1929. m_cmds.GetNextAssoc( pos, nCmdID, pCmdItem);
  1930. ASSERT( pCmdItem != NULL );
  1931. pCmdItem->OnDisplayChange( pPM, nDepthBPP, ptSizes );
  1932. } // for( ; pos != NULL; )
  1933. }
  1934. void CExtCmdProfile::OnThemeChanged(
  1935. class CExtPaintManager * pPM,
  1936. WPARAM wParam,
  1937. LPARAM lParam
  1938. )
  1939. {
  1940. POSITION pos = m_cmds.GetStartPosition();
  1941. for( ; pos != NULL; )
  1942. {
  1943. UINT nCmdID = 0;
  1944. CExtCmdItem * pCmdItem = NULL;
  1945. m_cmds.GetNextAssoc( pos, nCmdID, pCmdItem);
  1946. ASSERT( pCmdItem != NULL );
  1947. pCmdItem->OnThemeChanged( pPM, wParam, lParam );
  1948. } // for( ; pos != NULL; )
  1949. }
  1950. void CExtCmdProfile::ResetUsageStatistics()
  1951. {
  1952. POSITION pos = m_cmds.GetStartPosition();
  1953. for( ; pos != NULL; )
  1954. {
  1955. UINT nCmdID = 0;
  1956. CExtCmdItem * pCmdItem = NULL;
  1957. m_cmds.GetNextAssoc( pos, nCmdID, pCmdItem);
  1958. ASSERT( pCmdItem != NULL );
  1959. pCmdItem->ResetUsageStatistics();
  1960. }
  1961. m_nTotalTickCount = 0;
  1962. }
  1963. /////////////////////////////////////////////////////////////////////////////
  1964. // CExtCmdManager
  1965. // command manager class
  1966. CExtCmdManager::CExtCmdManagerAutoPtr g_CmdManager;
  1967. volatile DWORD CExtCmdManager::CExtCmdManagerAutoPtr::g_dwVersion = 0;
  1968. DWORD CExtCmdManager::CExtCmdManagerAutoPtr::GetVersionDWORD(
  1969. bool bForSerialization // = false
  1970. )
  1971. {
  1972. #if (!defined __EXT_PROFUIS_STATIC_LINK)
  1973. DWORD dwVersion = 0;
  1974. static CCriticalSection scs;
  1975. CSingleLock sl( &scs );
  1976. BYTE * pByteVerInfo = NULL;
  1977. sl.Lock();
  1978. try
  1979. {
  1980. if( g_dwVersion == 0 )
  1981. {
  1982. HANDLE hModule =
  1983. ::GetModuleHandle( __PROF_UIS_MODULE_NAME );
  1984. ASSERT( hModule != NULL );
  1985. TCHAR szFileName[MAX_PATH];
  1986. VERIFY(
  1987. ::GetModuleFileName(
  1988. HINSTANCE(hModule),
  1989. szFileName,
  1990. MAX_PATH
  1991. )
  1992. );
  1993. DWORD dwFVIS =
  1994. ::GetFileVersionInfoSize(
  1995. szFileName,
  1996. &dwFVIS
  1997. );
  1998. pByteVerInfo = new BYTE[4096];
  1999. ::memset( pByteVerInfo, 0, 4096 );
  2000. VERIFY(
  2001. ::GetFileVersionInfo(
  2002. szFileName,
  2003. NULL,
  2004. dwFVIS,
  2005. pByteVerInfo
  2006. )
  2007. );
  2008. UINT uNum = 0;
  2009. VS_FIXEDFILEINFO * lpv = NULL;
  2010. VERIFY(
  2011. ::VerQueryValue(
  2012. pByteVerInfo,
  2013. _T("\"),
  2014. ((LPVOID*)&lpv),
  2015. &uNum
  2016. )
  2017. );
  2018. ASSERT( lpv != NULL );
  2019. g_dwVersion = 
  2020.  (DWORD(HIWORD(lpv->dwFileVersionMS)&0x0FF)<<24)
  2021. |(DWORD(LOWORD(lpv->dwFileVersionMS)&0x0FF)<<16)
  2022. |(DWORD(HIWORD(lpv->dwFileVersionLS)&0x0FF)<<8)
  2023. |(DWORD(LOWORD(lpv->dwFileVersionLS)&0x0FF))
  2024. ;
  2025. if( pByteVerInfo != NULL )
  2026. {
  2027. delete [] pByteVerInfo;
  2028. pByteVerInfo = NULL;
  2029. }
  2030. } // if( g_dwVersion == 0 )
  2031. dwVersion = g_dwVersion;
  2032. if( bForSerialization )
  2033. dwVersion >>= 16;
  2034. } // try
  2035. catch( CException * pXept )
  2036. {
  2037. pXept->Delete();
  2038. ASSERT( FALSE );
  2039. } // catch( CException * pXept )
  2040. catch( ... )
  2041. {
  2042. ASSERT( FALSE );
  2043. } // catch( ... )
  2044. sl.Unlock();
  2045. if( pByteVerInfo != NULL )
  2046. delete [] pByteVerInfo;
  2047. return dwVersion;
  2048. #else // #if (!defined __EXT_PROFUIS_STATIC_LINK)
  2049. DWORD dwVersion = __PROF_UIS_VERSION_DWORD;
  2050. if( g_dwVersion == 0 )
  2051. {
  2052. static CCriticalSection scs;
  2053. CSingleLock sl( &scs );
  2054. sl.Lock();
  2055. g_dwVersion = dwVersion;
  2056. sl.Unlock();
  2057. }
  2058. if( bForSerialization )
  2059. dwVersion >>= 16;
  2060. return dwVersion;
  2061. #endif // else from #if (!defined __EXT_PROFUIS_STATIC_LINK)
  2062. }
  2063. __EXT_MFC_SAFE_LPCTSTR CExtCmdManager::CExtCmdManagerAutoPtr::GetVersionString(
  2064. CExtSafeString & strBuff,
  2065. __EXT_MFC_SAFE_TCHAR tchrSeparator
  2066. )
  2067. {
  2068. DWORD dwVersion = GetVersionDWORD( false );
  2069. ASSERT( dwVersion != 0 );
  2070. strBuff.Format(
  2071. _T("%d%c%d%c%d%c%d"),
  2072. INT( (dwVersion>>24)&0x0FF ),
  2073. tchrSeparator,
  2074. INT( (dwVersion>>16)&0x0FF ),
  2075. tchrSeparator,
  2076. INT( (dwVersion>>8)&0x0FF ),
  2077. tchrSeparator,
  2078. INT( dwVersion&0x0FF )
  2079. );
  2080. return strBuff;
  2081. }
  2082. __EXT_MFC_SAFE_LPCTSTR CExtCmdManager::CExtCmdManagerAutoPtr::GetVersionString(
  2083. CExtSafeString & strBuff
  2084. )
  2085. {
  2086. return GetVersionString( strBuff, _T('.') );
  2087. }
  2088. CExtCmdManager::CExtCmdManagerAutoPtr::CExtCmdManagerAutoPtr()
  2089. {
  2090. m_pCmdManager = new CExtCmdManager;
  2091. }
  2092. CExtCmdManager::CExtCmdManagerAutoPtr::~CExtCmdManagerAutoPtr()
  2093. {
  2094. ASSERT( m_pCmdManager != NULL );
  2095. if( m_pCmdManager != NULL )
  2096. {
  2097. delete m_pCmdManager;
  2098. m_pCmdManager = NULL;
  2099. }
  2100. }
  2101. CExtCmdManager * CExtCmdManager::CExtCmdManagerAutoPtr::operator -> ()
  2102. {
  2103. ASSERT( m_pCmdManager != NULL );
  2104. return m_pCmdManager;
  2105. }
  2106. void CExtCmdManager::CExtCmdManagerAutoPtr::OnGlobalPaintManagerChanged()
  2107. {
  2108. ASSERT( m_pCmdManager != NULL );
  2109. m_pCmdManager->OnGlobalPaintManagerChanged();
  2110. }
  2111. void CExtCmdManager::CExtCmdManagerAutoPtr::OnSysColorChange(
  2112. CExtPaintManager * pPM,
  2113. CWnd * pWndNotifySrc
  2114. )
  2115. {
  2116. ASSERT_VALID( pWndNotifySrc );
  2117. ASSERT( pWndNotifySrc->GetSafeHwnd() != NULL && ::IsWindow(pWndNotifySrc->GetSafeHwnd()) );
  2118. ASSERT( m_pCmdManager != NULL );
  2119. if( ! g_PaintManager.IsWndUpdateSource(pWndNotifySrc) )
  2120. return;
  2121. m_pCmdManager->OnSysColorChange( pPM );
  2122. }
  2123. void CExtCmdManager::CExtCmdManagerAutoPtr::OnSettingChange(
  2124. CExtPaintManager * pPM,
  2125. CWnd * pWndNotifySrc,
  2126. UINT uFlags,
  2127. __EXT_MFC_SAFE_LPCTSTR lpszSection
  2128. )
  2129. {
  2130. ASSERT_VALID( pWndNotifySrc );
  2131. ASSERT( pWndNotifySrc->GetSafeHwnd() != NULL && ::IsWindow(pWndNotifySrc->GetSafeHwnd()) );
  2132. ASSERT( m_pCmdManager != NULL );
  2133. if( ! g_PaintManager.IsWndUpdateSource(pWndNotifySrc) )
  2134. return;
  2135. m_pCmdManager->OnSettingChange( pPM, uFlags, lpszSection );
  2136. }
  2137. void CExtCmdManager::CExtCmdManagerAutoPtr::OnDisplayChange(
  2138. CExtPaintManager * pPM,
  2139. CWnd * pWndNotifySrc,
  2140. INT nDepthBPP,
  2141. CPoint ptSizes
  2142. )
  2143. {
  2144. ASSERT_VALID( pWndNotifySrc );
  2145. ASSERT( pWndNotifySrc->GetSafeHwnd() != NULL && ::IsWindow(pWndNotifySrc->GetSafeHwnd()) );
  2146. ASSERT( m_pCmdManager != NULL );
  2147. if( ! g_PaintManager.IsWndUpdateSource(pWndNotifySrc) )
  2148. return;
  2149. m_pCmdManager->OnDisplayChange( pPM, nDepthBPP, ptSizes );
  2150. }
  2151. void CExtCmdManager::CExtCmdManagerAutoPtr::OnThemeChanged(
  2152. CExtPaintManager * pPM,
  2153. CWnd * pWndNotifySrc,
  2154. WPARAM wParam,
  2155. LPARAM lParam
  2156. )
  2157. {
  2158. ASSERT_VALID( pWndNotifySrc );
  2159. ASSERT( pWndNotifySrc->GetSafeHwnd() != NULL && ::IsWindow(pWndNotifySrc->GetSafeHwnd()) );
  2160. ASSERT( m_pCmdManager != NULL );
  2161. if( ! g_PaintManager.IsWndUpdateSource(pWndNotifySrc) )
  2162. return;
  2163. m_pCmdManager->OnThemeChanged( pPM, wParam, lParam );
  2164. }
  2165. bool CExtCmdManager::g_bDisableCmdIfNoHandler = true;
  2166. CExtCmdManager::CExtCmdManager()
  2167. {
  2168. ProfileSetup(
  2169. __EXTMFC_DEF_PROFILE_NAME
  2170. );
  2171. }
  2172. CExtCmdManager::~CExtCmdManager()
  2173. {
  2174. _RemoveAllProfilesImpl();
  2175. }
  2176. void CExtCmdManager::_RemoveAllProfilesImpl()
  2177. {
  2178. POSITION pos = m_profiles.GetStartPosition();
  2179. for( ; pos != NULL; )
  2180. {
  2181. CExtSafeString sProfileName;
  2182. CExtCmdProfile * pProfile = NULL;
  2183. m_profiles.GetNextAssoc( pos, sProfileName, (void *&)pProfile );
  2184. ASSERT( pProfile != NULL );
  2185. delete pProfile;
  2186. } // for( ; pos != NULL; )
  2187. m_profiles.RemoveAll();
  2188. m_profile_wnds.RemoveAll();
  2189. }
  2190. // setup single profile
  2191. bool CExtCmdManager::ProfileSetup(
  2192. __EXT_MFC_SAFE_LPCTSTR sProfileName, //  = NULL
  2193. HWND hProfileWnd, // = NULL
  2194. CExtCmdProfile * pNewProfileInstance // = NULL
  2195. )
  2196. {
  2197. if( sProfileName == NULL
  2198. || _tcslen( sProfileName ) == 0
  2199. )
  2200. sProfileName = __EXTMFC_DEF_PROFILE_NAME;
  2201. // m_cs.Lock();
  2202. CExtCmdProfile * pProfile = NULL;
  2203. BOOL bExist = m_profiles.Lookup( sProfileName, (void *&)pProfile );
  2204. if( !bExist )
  2205. {
  2206. if( pNewProfileInstance != NULL )
  2207. {
  2208. pProfile = pNewProfileInstance;
  2209. // avoid invalid method usage
  2210. ASSERT( pNewProfileInstance->m_sName == LPCTSTR( sProfileName ) );
  2211. } // if( pNewProfileInstance != NULL )
  2212. else
  2213. pProfile = new CExtCmdProfile( sProfileName );
  2214. m_profiles.SetAt( sProfileName, pProfile );
  2215. } // if( !bExist )
  2216. #ifdef _DEBUG
  2217. else
  2218. {
  2219. // avoid leaks when invalid method usage
  2220. ASSERT( pNewProfileInstance == NULL );
  2221. } // else from if( !bExist )
  2222. #endif // _DEBUG
  2223. ASSERT( pProfile != NULL );
  2224. ASSERT( pProfile->m_sName == LPCTSTR(sProfileName) );
  2225. // m_cs.Unlock();
  2226. if( hProfileWnd != NULL )
  2227. return ProfileWndAdd( sProfileName, hProfileWnd );
  2228. else
  2229. return true;
  2230. }
  2231. // setup profile window
  2232. bool CExtCmdManager::ProfileWndAdd(
  2233. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2234. HWND hProfileWnd
  2235. )
  2236. {
  2237. ASSERT( hProfileWnd != NULL );
  2238. if( hProfileWnd == NULL )
  2239. {
  2240. ASSERT( FALSE );
  2241. return false;
  2242. }
  2243. ASSERT( ::IsWindow(hProfileWnd) );
  2244. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2245. if( pProfile == NULL )
  2246. {
  2247. ASSERT( FALSE );
  2248. return false;
  2249. }
  2250. // m_cs.Lock();
  2251. CExtCmdProfile * pProfile2 = NULL;
  2252. BOOL bExist = m_profile_wnds.Lookup( hProfileWnd, pProfile2 );
  2253. if( !bExist )
  2254. m_profile_wnds.SetAt( hProfileWnd, pProfile );
  2255. #ifdef _DEBUG
  2256. else
  2257. {
  2258. ASSERT( pProfile2 != NULL );
  2259. ASSERT( pProfile2 == pProfile );
  2260. }
  2261. #endif // _DEBUG
  2262. // m_cs.Unlock();
  2263. return true;
  2264. }
  2265. // remove profile window
  2266. bool CExtCmdManager::ProfileWndRemove(
  2267. HWND hProfileWnd,
  2268. bool bRemoveProfileIfLastHWND, // = false
  2269. bool * p_bProfileWasRemoved // = NULL
  2270. )
  2271. {
  2272. ASSERT( hProfileWnd != NULL );
  2273. if( p_bProfileWasRemoved  != NULL )
  2274. *p_bProfileWasRemoved = false;
  2275. if( hProfileWnd == NULL )
  2276. return false;
  2277. //ASSERT( ::IsWindow(hProfileWnd) );
  2278. // m_cs.Lock();
  2279. CExtCmdProfile * pProfile = NULL;
  2280. BOOL bExists = m_profile_wnds.Lookup( hProfileWnd, pProfile );
  2281. if( bExists )
  2282. {
  2283. ASSERT( pProfile != NULL );
  2284. VERIFY( m_profile_wnds.RemoveKey(hProfileWnd) );
  2285. if( bRemoveProfileIfLastHWND )
  2286. {
  2287. int nProfileFoundWindowCount = 0;
  2288. for( POSITION pos = m_profile_wnds.GetStartPosition();
  2289. pos != NULL;
  2290. )
  2291. {
  2292. HWND hWndWalk = NULL;
  2293. CExtCmdProfile * pProfileWalk = NULL;
  2294. m_profile_wnds.GetNextAssoc(
  2295. pos,
  2296. hWndWalk,
  2297. pProfileWalk
  2298. );
  2299. ASSERT( hWndWalk != NULL );
  2300. ASSERT( pProfileWalk != NULL );
  2301. if( pProfileWalk == pProfile )
  2302. {
  2303. nProfileFoundWindowCount++;
  2304. break;
  2305. }
  2306. }
  2307. if( nProfileFoundWindowCount == 0 )
  2308. {
  2309. if( p_bProfileWasRemoved  != NULL )
  2310. *p_bProfileWasRemoved = true;
  2311. CExtSafeString sProfileName( pProfile->m_sName );
  2312. delete pProfile;
  2313. VERIFY( m_profiles.RemoveKey(LPCTSTR(sProfileName)) );
  2314. } // if( nProfileFoundWindowCount == 0 )
  2315. } // if( bRemoveProfileIfLastHWND )
  2316. } // if( bExists )
  2317. // m_cs.Unlock();
  2318. return bExists ? true : false;
  2319. }
  2320. // remove all profile windows
  2321. int CExtCmdManager::ProfileWndRemoveAll(
  2322. __EXT_MFC_SAFE_LPCTSTR sProfileName
  2323. )
  2324. {
  2325. if( sProfileName == NULL
  2326. || _tcslen( sProfileName ) == 0
  2327. )
  2328. {
  2329. ASSERT( FALSE );
  2330. return 0;
  2331. }
  2332. // m_cs.Lock();
  2333. int nRemovedCount = 0;
  2334. CExtCmdProfile * pProfile = NULL;
  2335. BOOL bExists = m_profiles.Lookup( sProfileName, (void *&)pProfile );
  2336. if( bExists )
  2337. {
  2338. ASSERT( pProfile != NULL );
  2339. ASSERT( pProfile->m_sName == LPCTSTR(sProfileName) );
  2340. CList < HWND, HWND & > list;
  2341. _ProfileGetWndListImpl( pProfile, list );
  2342. for( POSITION pos = list.GetHeadPosition();
  2343. pos != NULL;
  2344. )
  2345. {
  2346. HWND hWndWalk = list.GetNext( pos );
  2347. ASSERT( hWndWalk != NULL );
  2348. VERIFY( m_profile_wnds.RemoveKey(hWndWalk) );
  2349. nRemovedCount ++;
  2350. }
  2351. ASSERT( nRemovedCount == list.GetCount() );
  2352. } // if( bExists )
  2353. // m_cs.Unlock();
  2354. return nRemovedCount;
  2355. }
  2356. // get profile window list
  2357. void CExtCmdManager::ProfileGetWndList(
  2358. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2359. CList < HWND, HWND & > & list
  2360. )
  2361. {
  2362. // m_cs.Lock();
  2363. _ProfileGetWndListImpl( sProfileName, list );
  2364. // m_cs.Unlock();
  2365. }
  2366. void CExtCmdManager::_ProfileGetWndListImpl(
  2367. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2368. CList < HWND, HWND & > & list
  2369. )
  2370. {
  2371. list.RemoveAll();
  2372. if( sProfileName == NULL
  2373. || _tcslen( sProfileName ) == 0
  2374. )
  2375. {
  2376. ASSERT( FALSE );
  2377. return;
  2378. }
  2379. CExtCmdProfile * pProfile = NULL;
  2380. BOOL bExists = m_profiles.Lookup( sProfileName, (void *&)pProfile );
  2381. if( ! bExists )
  2382. {
  2383. ASSERT( FALSE );
  2384. return;
  2385. }
  2386. ASSERT( pProfile != NULL );
  2387. ASSERT( pProfile->m_sName == LPCTSTR(sProfileName) );
  2388. _ProfileGetWndListImpl( pProfile, list );
  2389. }
  2390. void CExtCmdManager::_ProfileGetWndListImpl(
  2391. CExtCmdProfile * pProfile,
  2392. CList < HWND, HWND & > & list
  2393. )
  2394. {
  2395. ASSERT( pProfile != NULL );
  2396. ASSERT( ! pProfile->m_sName.IsEmpty() );
  2397. ASSERT( list.GetCount() == 0 );
  2398. for( POSITION pos = m_profile_wnds.GetStartPosition();
  2399. pos != NULL;
  2400. )
  2401. {
  2402. HWND hWndWalk = NULL;
  2403. CExtCmdProfile * pProfileWalk = NULL;
  2404. m_profile_wnds.GetNextAssoc(
  2405. pos,
  2406. hWndWalk,
  2407. pProfileWalk
  2408. );
  2409. ASSERT( hWndWalk != NULL );
  2410. ASSERT( pProfileWalk != NULL );
  2411. if( pProfileWalk == pProfile )
  2412. list.AddTail( hWndWalk );
  2413. }
  2414. }
  2415. // remove profile from command manager
  2416. bool CExtCmdManager::ProfileDestroy(
  2417. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2418. bool bDestroyIfHasWindows // = false
  2419. )
  2420. {
  2421. if( sProfileName == NULL
  2422. || _tcslen( sProfileName ) == 0
  2423. )
  2424. {
  2425. ASSERT( FALSE );
  2426. return false;
  2427. }
  2428. // m_cs.Lock();
  2429. CExtCmdProfile * pProfile = NULL;
  2430. bool bProfileDestroyed = false;
  2431. BOOL bExists = m_profiles.Lookup( sProfileName, (void *&)pProfile );
  2432. if( bExists )
  2433. {
  2434. ASSERT( pProfile != NULL );
  2435. ASSERT( pProfile->m_sName == LPCTSTR(sProfileName) );
  2436. CList < HWND, HWND & > list;
  2437. _ProfileGetWndListImpl( pProfile, list );
  2438. int nWndCount = (int)list.GetCount();
  2439. if( nWndCount > 0 && bDestroyIfHasWindows )
  2440. {
  2441. POSITION pos = list.GetHeadPosition();
  2442. ASSERT( pos != NULL );
  2443. for( ; pos != NULL; )
  2444. {
  2445. HWND hWndWalk = list.GetNext( pos );
  2446. ASSERT( hWndWalk != NULL );
  2447. VERIFY( m_profile_wnds.RemoveKey( hWndWalk ) );
  2448. ASSERT( nWndCount > 0 );
  2449. nWndCount--;
  2450. } // for( ; pos != NULL; )
  2451. ASSERT( nWndCount == 0 );
  2452. } // if( nWndCount > 0 && bDestroyIfHasWindows )
  2453. if( nWndCount == 0 )
  2454. {
  2455. bProfileDestroyed = true;
  2456. CExtSafeString sProfileName2( pProfile->m_sName );
  2457. delete pProfile;
  2458. VERIFY( m_profiles.RemoveKey(LPCTSTR(sProfileName2)) );
  2459. } // if( nWndCount == 0 )
  2460. } // if( bExists )
  2461. // m_cs.Unlock();
  2462. return bProfileDestroyed;
  2463. }
  2464. // rename profile
  2465. bool CExtCmdManager::ProfileRename(
  2466. __EXT_MFC_SAFE_LPCTSTR sProfileNameOld,
  2467. __EXT_MFC_SAFE_LPCTSTR sProfileNameNew
  2468. )
  2469. {
  2470. if( sProfileNameOld == NULL
  2471. || sProfileNameNew == NULL
  2472. || _tcslen( sProfileNameOld ) == 0
  2473. || _tcslen( sProfileNameNew ) == 0
  2474. || _tcscmp( sProfileNameOld, __EXTMFC_DEF_PROFILE_NAME ) == 0
  2475. || _tcscmp( sProfileNameNew, __EXTMFC_DEF_PROFILE_NAME ) == 0
  2476. )
  2477. {
  2478. ASSERT( FALSE );
  2479. return false;
  2480. }
  2481. // m_cs.Lock();
  2482. bool bProfileRenamed = false;
  2483. CExtCmdProfile * pProfile = NULL;
  2484. BOOL bExists = m_profiles.Lookup( sProfileNameOld, (void *&)pProfile );
  2485. if( bExists )
  2486. {
  2487. ASSERT( pProfile != NULL );
  2488. ASSERT( pProfile->m_sName == LPCTSTR(sProfileNameOld) );
  2489. if( LPVOID(LPCTSTR(sProfileNameOld)) == LPVOID(LPCTSTR(sProfileNameNew)) )
  2490. bProfileRenamed = true;
  2491. else
  2492. {
  2493. CExtCmdProfile * pProfileOther = NULL;
  2494. BOOL bExistsOther = m_profiles.Lookup( sProfileNameNew, (void *&)pProfileOther );
  2495. if( !bExistsOther )
  2496. {
  2497. bProfileRenamed = true;
  2498. CExtSafeString sProfileName = LPCTSTR(sProfileNameOld);
  2499. VERIFY( m_profiles.RemoveKey(LPCTSTR(sProfileName)) );
  2500. pProfile->m_sName = sProfileNameNew;
  2501. m_profiles.SetAt( sProfileNameNew, pProfile );
  2502. } // if( !bExistsOther )
  2503. #ifdef _DEBUG
  2504. else
  2505. {
  2506. ASSERT( pProfileOther != NULL );
  2507. ASSERT( pProfileOther->m_sName == LPCTSTR(sProfileNameNew) );
  2508. } // else from if( !bExistsOther )
  2509. #endif // _DEBUG
  2510. } // else from if( LPVOID(LPCTSTR(sProfileNameOld)) == LPVOID(LPCTSTR(sProfileNameNew)) )
  2511. } // if( bExists )
  2512. // m_cs.Unlock();
  2513. return bProfileRenamed;
  2514. }
  2515. // get profile
  2516. CExtCmdProfile * CExtCmdManager::ProfileGetPtr(
  2517. __EXT_MFC_SAFE_LPCTSTR sProfileName //  = NULL
  2518. )
  2519. {
  2520. if( sProfileName == NULL )
  2521. sProfileName = __EXTMFC_DEF_PROFILE_NAME;
  2522. // m_cs.Lock();
  2523. CExtCmdProfile * pProfile = NULL;
  2524. BOOL bExists = m_profiles.Lookup( sProfileName, (void *&)pProfile );
  2525. if( bExists )
  2526. {
  2527. ASSERT( pProfile != NULL );
  2528. ASSERT( pProfile->m_sName == LPCTSTR(sProfileName) );
  2529. } // if( bExists )
  2530. else
  2531. pProfile = NULL;
  2532. // m_cs.Unlock();
  2533. return pProfile;
  2534. }
  2535. // get profile name for window
  2536. __EXT_MFC_SAFE_LPCTSTR CExtCmdManager::ProfileNameFromWnd(
  2537. HWND hWnd
  2538. )
  2539. {
  2540. ASSERT( hWnd != NULL );
  2541. if( hWnd == NULL )
  2542. return NULL;
  2543. ASSERT( ::IsWindow(hWnd) );
  2544. __EXT_MFC_SAFE_LPCTSTR sProfileName = NULL;
  2545. // m_cs.Lock();
  2546. for( ; sProfileName == NULL && hWnd != NULL; )
  2547. {
  2548. CExtCmdProfile * pProfile = NULL;
  2549. BOOL bExists = m_profile_wnds.Lookup( hWnd, pProfile );
  2550. if( bExists )
  2551. {
  2552. ASSERT( pProfile != NULL );
  2553. ASSERT( !pProfile->m_sName.IsEmpty() );
  2554. sProfileName = pProfile->m_sName;
  2555. break;
  2556. } // if( bExists )
  2557. hWnd = GetParent( hWnd );
  2558. if( hWnd == NULL )
  2559. break;
  2560. CWnd * pWndPermanent = CWnd::FromHandlePermanent( hWnd );
  2561. if( pWndPermanent
  2562. && pWndPermanent->IsKindOf( RUNTIME_CLASS(CControlBar) )
  2563. && (! (((CControlBar*)pWndPermanent)->IsDockBar()) )
  2564. && ((CControlBar*)pWndPermanent)->m_pDockSite->GetSafeHwnd() != NULL
  2565. )
  2566. hWnd = ((CControlBar*)pWndPermanent)->m_pDockSite->m_hWnd;
  2567. } // for( ; sProfileName == NULL && hWnd != NULL; )
  2568. // m_cs.Unlock();
  2569. return sProfileName;
  2570. }
  2571. // reset the toolbar/menu command statistics
  2572. bool CExtCmdManager::ProfileResetUsageStatistics(
  2573. __EXT_MFC_SAFE_LPCTSTR sProfileName
  2574. )
  2575. {
  2576. // m_cs.Lock();
  2577. bool bRetVal = false;
  2578. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2579. if( pProfile != NULL )
  2580. {
  2581. pProfile->ResetUsageStatistics();
  2582. bRetVal = true;
  2583. } // if( pProfile != NULL )
  2584. // m_cs.Unlock();
  2585. return bRetVal;
  2586. }
  2587. // setup single command
  2588. bool CExtCmdManager::CmdSetup(
  2589. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2590. const CExtCmdItem & _cmd,
  2591. bool bReplaceOld, // = false // but force set images anywhere if was empty
  2592. bool * pbWasAddedNew // = NULL
  2593. )
  2594. {
  2595. if( pbWasAddedNew != NULL )
  2596. *pbWasAddedNew = false;
  2597. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2598. if( pProfile == NULL )
  2599. {
  2600. ASSERT( FALSE );
  2601. return false;
  2602. }
  2603. // m_cs.Lock();
  2604. bool bRetVal = pProfile->CmdSetup(_cmd,bReplaceOld,pbWasAddedNew);
  2605. // m_cs.Unlock();
  2606. return bRetVal;
  2607. }
  2608. // remove single command
  2609. bool CExtCmdManager::CmdRemove(
  2610. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2611. UINT nCmdID,
  2612. bool * pbWasRemoved // = NULL
  2613. )
  2614. {
  2615. if( pbWasRemoved != NULL )
  2616. *pbWasRemoved = false;
  2617. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2618. if( pProfile == NULL )
  2619. {
  2620. ASSERT( FALSE );
  2621. return false;
  2622. }
  2623. // m_cs.Lock();
  2624. bool bRetVal = pProfile->CmdRemove(nCmdID,pbWasRemoved);
  2625. // m_cs.Unlock();
  2626. return bRetVal;
  2627. }
  2628. void CExtCmdManager::CmdRemoveAll(
  2629. __EXT_MFC_SAFE_LPCTSTR sProfileName
  2630. )
  2631. {
  2632. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2633. if( pProfile == NULL )
  2634. {
  2635. ASSERT( FALSE );
  2636. return;
  2637. }
  2638. // m_cs.Lock();
  2639. pProfile->CmdRemoveAll();
  2640. // m_cs.Unlock();
  2641. }
  2642. bool CExtCmdManager::CmdRemoveByMask(
  2643. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2644. DWORD dwMask,
  2645. DWORD dwExMask, // = 0
  2646. bool bAllBitsOnly, // = false
  2647. bool bExAllBitsOnly // = false
  2648. )
  2649. {
  2650. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2651. if( pProfile == NULL )
  2652. {
  2653. ASSERT( FALSE );
  2654. return false;
  2655. }
  2656. // m_cs.Lock();
  2657. pProfile->CmdRemoveByMask(
  2658. dwMask,
  2659. dwExMask,
  2660. bAllBitsOnly,
  2661. bExAllBitsOnly
  2662. );
  2663. // m_cs.Unlock();
  2664. return true;
  2665. }
  2666. // alloc command
  2667. CExtCmdItem * CExtCmdManager::CmdAllocPtr(
  2668. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2669. UINT nCmdID // = 0 // 0 means any free in avail range
  2670. )
  2671. {
  2672. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2673. if( pProfile == NULL )
  2674. {
  2675. ASSERT( FALSE );
  2676. return NULL;
  2677. }
  2678. // m_cs.Lock();
  2679. CExtCmdItem * pCmdItem = pProfile->CmdAllocPtr(nCmdID);
  2680. // m_cs.Unlock();
  2681. return pCmdItem;
  2682. }
  2683. // get command
  2684. CExtCmdItem * CExtCmdManager::CmdGetPtr(
  2685. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2686. UINT nCmdID
  2687. )
  2688. {
  2689. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2690. if( pProfile == NULL )
  2691. {
  2692. ASSERT( FALSE );
  2693. return NULL;
  2694. }
  2695. // m_cs.Lock();
  2696. CExtCmdItem * pCmdItem = pProfile->CmdGetPtr(nCmdID);
  2697. // m_cs.Unlock();
  2698. return pCmdItem;
  2699. }
  2700. // assign icon to command
  2701. bool CExtCmdManager::CmdSetIcon(
  2702. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2703. UINT nCmdID,
  2704. const CExtCmdIcon * pCmdIcon, // if NULL or empty - remove
  2705. bool bUseCmdIconObject
  2706. )
  2707. {
  2708. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2709. if( pProfile == NULL )
  2710. {
  2711. ASSERT( FALSE );
  2712. return false;
  2713. }
  2714. // m_cs.Lock();
  2715. bool bRetVal = pProfile->CmdSetIcon( nCmdID, pCmdIcon, bUseCmdIconObject );
  2716. // m_cs.Unlock();
  2717. return bRetVal;
  2718. }
  2719. bool CExtCmdManager::CmdSetIcon(
  2720. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2721. UINT nCmdID,
  2722. const CExtCmdIcon & cmdIcon // if empty - remove
  2723. )
  2724. {
  2725. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2726. if( pProfile == NULL )
  2727. {
  2728. ASSERT( FALSE );
  2729. return false;
  2730. }
  2731. // m_cs.Lock();
  2732. bool bRetVal =
  2733. pProfile->CmdSetIcon(
  2734. nCmdID,
  2735. cmdIcon
  2736. );
  2737. // m_cs.Unlock();
  2738. return bRetVal;
  2739. }
  2740. bool CExtCmdManager::CmdSetIcon(
  2741. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2742. UINT nCmdID,
  2743. const CExtBitmap & _bitmap, // if empty - remove
  2744. COLORREF clrTransparent, // = RGB(0,0,0)
  2745. LPCRECT pRectBitmapSrc // = NULL
  2746. )
  2747. {
  2748. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2749. if( pProfile == NULL )
  2750. {
  2751. ASSERT( FALSE );
  2752. return false;
  2753. }
  2754. // m_cs.Lock();
  2755. bool bRetVal =
  2756. pProfile->CmdSetIcon(
  2757. nCmdID,
  2758. _bitmap,
  2759. clrTransparent,
  2760. pRectBitmapSrc
  2761. );
  2762. // m_cs.Unlock();
  2763. return bRetVal;
  2764. }
  2765. bool CExtCmdManager::CmdSetIcon(
  2766. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2767. UINT nCmdID,
  2768. HICON hIcon, // if NULL - remove
  2769. bool bCopyIcon // = true
  2770. )
  2771. {
  2772. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2773. if( pProfile == NULL )
  2774. {
  2775. ASSERT( FALSE );
  2776. return false;
  2777. }
  2778. // m_cs.Lock();
  2779. bool bRetVal =
  2780. pProfile->CmdSetIcon(
  2781. nCmdID,
  2782. hIcon,
  2783. bCopyIcon
  2784. );
  2785. // m_cs.Unlock();
  2786. return bRetVal;
  2787. }
  2788. // get command icon (if command and its icon exist)
  2789. CExtCmdIcon * CExtCmdManager::CmdGetIconPtr(
  2790. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2791. UINT nCmdID
  2792. )
  2793. {
  2794. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2795. if( pProfile == NULL )
  2796. {
  2797. ASSERT( FALSE );
  2798. return NULL;
  2799. }
  2800. // m_cs.Lock();
  2801. CExtCmdIcon * pIcon = pProfile->CmdGetIconPtr( nCmdID );
  2802. // m_cs.Unlock();
  2803. return pIcon;
  2804. }
  2805. const CExtCmdIcon * CExtCmdManager::CmdGetIconPtr(
  2806. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2807. UINT nCmdID
  2808. ) const
  2809. {
  2810. return
  2811. ( const_cast < CExtCmdManager * > ( this ) )
  2812. -> CmdGetIconPtr( sProfileName, nCmdID );
  2813. }
  2814. CExtCmdIcon & CExtCmdManager::CmdGetIcon(
  2815. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2816. UINT nCmdID
  2817. )
  2818. {
  2819. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2820. if( pProfile == NULL )
  2821. {
  2822. static CExtCmdIcon g_EmptyIcon;
  2823. return g_EmptyIcon;
  2824. }
  2825. // m_cs.Lock();
  2826. CExtCmdIcon & _icon = pProfile->CmdGetIcon( nCmdID );
  2827. // m_cs.Unlock();
  2828. return _icon;
  2829. }
  2830. const CExtCmdIcon & CExtCmdManager::CmdGetIcon(
  2831. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2832. UINT nCmdID
  2833. ) const
  2834. {
  2835. return
  2836. ( const_cast < CExtCmdManager * > ( this ) )
  2837. -> CmdGetIcon( sProfileName, nCmdID );
  2838. }
  2839. // is command registered
  2840. bool CExtCmdManager::CmdIsRegistered(
  2841. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2842. UINT nCmdID
  2843. )
  2844. {
  2845. bool bRegistered =
  2846. (CmdGetPtr(sProfileName,nCmdID) != NULL) ?
  2847. true : false;
  2848. return bRegistered;
  2849. }
  2850. // update commands collection from menu handle
  2851. bool CExtCmdManager::UpdateFromMenu(
  2852. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2853. HMENU hMenu,
  2854. bool bReplaceOld, // = false
  2855. bool bRecursive, // = true
  2856. bool bLoadTips // = true
  2857. )
  2858. {
  2859. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2860. if( pProfile == NULL )
  2861. {
  2862. ASSERT( FALSE );
  2863. return false;
  2864. }
  2865. // m_cs.Lock();
  2866. bool bRetVal =
  2867. pProfile->UpdateFromMenu(
  2868. hMenu, bReplaceOld, bRecursive, bLoadTips );
  2869. // m_cs.Unlock();
  2870. return bRetVal;
  2871. }
  2872. // update commands collection from menu resurce
  2873. bool CExtCmdManager::UpdateFromMenu(
  2874. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2875. UINT nResourceID,
  2876. bool bReplaceOld, // = false
  2877. bool bLoadTips // = true
  2878. )
  2879. {
  2880. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2881. if( pProfile == NULL )
  2882. {
  2883. ASSERT( FALSE );
  2884. return false;
  2885. }
  2886. // m_cs.Lock();
  2887. bool bRetVal =
  2888. pProfile->UpdateFromMenu(
  2889. nResourceID, bReplaceOld, bLoadTips );
  2890. // m_cs.Unlock();
  2891. return bRetVal;
  2892. }
  2893. bool CExtCmdManager::UpdateFromToolBar(
  2894. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2895. CToolBar & bar,
  2896. bool bReplaceOld, // = false // but force set images anywhere if was empty
  2897. bool bLoadTips // = true
  2898. )
  2899. {
  2900. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2901. if( pProfile == NULL )
  2902. {
  2903. ASSERT( FALSE );
  2904. return false;
  2905. }
  2906. // m_cs.Lock();
  2907. bool bRetVal =
  2908. pProfile->UpdateFromToolBar(
  2909. bar, bReplaceOld, bLoadTips );
  2910. // m_cs.Unlock();
  2911. return bRetVal;
  2912. }
  2913. bool CExtCmdManager::UpdateFromToolBar(
  2914. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2915. UINT nResourceID,
  2916. LPUINT * ppCmdArray, // = NULL
  2917. LPINT pCmdCount, // = NULL
  2918. bool bReplaceOld, // = false // but force set images anywhere if was empty
  2919. bool bLoadTips, // = true
  2920. COLORREF clrBmpTransparent // = RGB(192,192,192)
  2921. )
  2922. {
  2923. return
  2924. UpdateFromToolBar(
  2925. sProfileName,
  2926. MAKEINTRESOURCE( nResourceID ),
  2927. ppCmdArray,
  2928. pCmdCount,
  2929. bReplaceOld,
  2930. bLoadTips,
  2931. clrBmpTransparent
  2932. );
  2933. }
  2934. bool CExtCmdManager::UpdateFromToolBar(
  2935. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2936. __EXT_MFC_SAFE_LPCTSTR strResourceID,
  2937. LPUINT * ppCmdArray, // = NULL
  2938. LPINT pCmdCount, // = NULL
  2939. bool bReplaceOld, // = false // but force set images anywhere if was empty
  2940. bool bLoadTips, // = true
  2941. COLORREF clrBmpTransparent // = RGB(192,192,192)
  2942. )
  2943. {
  2944. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2945. if( pProfile == NULL )
  2946. {
  2947. ASSERT( FALSE );
  2948. return false;
  2949. }
  2950. // m_cs.Lock();
  2951. bool bRetVal =
  2952. pProfile->UpdateFromToolBar(
  2953. strResourceID,
  2954. ppCmdArray,
  2955. pCmdCount,
  2956. bReplaceOld,
  2957. bLoadTips,
  2958. clrBmpTransparent
  2959. );
  2960. // m_cs.Unlock();
  2961. return bRetVal;
  2962. }
  2963. // set list of commands (up to (UINT)0) as basic or non basic
  2964. bool CExtCmdManager::SetBasicCommands(
  2965. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2966. UINT * pCommands,
  2967. bool bOn // = true
  2968. )
  2969. {
  2970. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  2971. if( pProfile == NULL )
  2972. {
  2973. ASSERT( FALSE );
  2974. return false;
  2975. }
  2976. // m_cs.Lock();
  2977. bool bRetVal =
  2978. pProfile->SetBasicCommands( pCommands, bOn );
  2979. // m_cs.Unlock();
  2980. return bRetVal;
  2981. }
  2982. #define __REG_LINES_IN_BLOCK 128
  2983. #define __REG_LINE_SIZE 16
  2984. #define __REG_LINE_FMT _T("data_0x%08lX")
  2985. #define __REG_BLOCK_FMT _T("block_0x%08lX")
  2986. #define __REG_VAR_DATA_SIZE _T("data_size")
  2987. #define __REG_VAR_DATA_CHECK _T("data_integrity")
  2988. #define __REG_VAR_GENERATOR _T("data_generator")
  2989. #define __REG_FMT_GENERATOR _T("Prof-UIS registry archiver rev. %d")
  2990. #define __REG_VAR_LIBRARY_VERSION _T("library_version")
  2991. #define __REG_FMT_LIBRARY_VERSION _T("Prof-UIS v. %s")
  2992. #define __REG_VAR_DATA_LINES_IN_BLOCK _T("data_block_size")
  2993. #define __REG_VAR_DATA_LINE_SIZE _T("data_line_size")
  2994. #define __REG_VAR_DATA_FORMAT_REV _T("data_fmt_rev")
  2995. #define __REG_GENERATOR_REV 0
  2996. CExtSafeString CExtCmdManager::GetSubSystemRegKeyPath(
  2997. __EXT_MFC_SAFE_LPCTSTR sSubSystemName,
  2998. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  2999. __EXT_MFC_SAFE_LPCTSTR sSectionNameCompany, // under HKEY_CURRENT_USERSoftware
  3000. __EXT_MFC_SAFE_LPCTSTR sSectionNameProduct // under HKEY_CURRENT_USERSoftware%sSectionNameCompany%
  3001. )
  3002. {
  3003. ASSERT( sSubSystemName != NULL );
  3004. ASSERT( sProfileName != NULL );
  3005. ASSERT( sSectionNameCompany != NULL );
  3006. ASSERT( sSectionNameProduct != NULL );
  3007. CExtSafeString s;
  3008. s.Format(
  3009. _T("Software\%s\%s\%s\%s\%s\%s"),
  3010. sSectionNameCompany,
  3011. sSectionNameProduct,
  3012. __PROF_UIS_REG_SECTION,
  3013. __PROF_UIS_REG_PROFILES,
  3014. sProfileName,
  3015. sSubSystemName
  3016. );
  3017. // s.Replace(' ','_');
  3018. s.Replace('r','_');
  3019. s.Replace('t','_');
  3020. s.Replace('n','_');
  3021. s.Replace('?','_');
  3022. s.Replace('*','_');
  3023. // s.Replace('.','_'); // (- v.2.23)
  3024. // s.Replace(',','_'); // (- v.2.23)
  3025. return s;
  3026. }
  3027. bool CExtCmdManager::FileObjToRegistry(
  3028. CFile & _file,
  3029. __EXT_MFC_SAFE_LPCTSTR sRegKeyPath,
  3030. HKEY hKeyRoot, // = HKEY_CURRENT_USER
  3031. bool bEnableThrowExceptions // = false
  3032. )
  3033. {
  3034. ASSERT( sRegKeyPath != NULL );
  3035. if( sRegKeyPath == NULL )
  3036. {
  3037. if( bEnableThrowExceptions )
  3038. ::AfxThrowUserException();
  3039. return false;
  3040. }
  3041. CExtRegistry::RegDeleteKey(
  3042. hKeyRoot, // HKEY_CURRENT_USER
  3043. sRegKeyPath,
  3044. NULL
  3045. );
  3046. _file.Seek( 0, CFile::begin );
  3047. DWORD dwLen = (DWORD)_file.GetLength();
  3048. CExtRegistry reg;
  3049. if( ! reg.Create(
  3050. hKeyRoot, // HKEY_CURRENT_USER
  3051. sRegKeyPath,
  3052. KEY_ALL_ACCESS
  3053. )
  3054. )
  3055. return false;
  3056. if( ! reg.SaveNumber(
  3057. __REG_VAR_DATA_SIZE,
  3058. dwLen
  3059. )
  3060. )
  3061. {
  3062. if( bEnableThrowExceptions )
  3063. ::AfxThrowUserException();
  3064. return false;
  3065. }
  3066. BYTE buffer[__REG_LINE_SIZE];
  3067. ULONG nCount, nPortion=0;
  3068. CExtIntegrityCheckSum _ExtIntegrityCheckSum;
  3069. for( ; (nCount=_file.Read(&buffer,__REG_LINE_SIZE)) > 0;  )
  3070. {
  3071. CExtSafeString sBlockSubKey;
  3072. ULONG nBlockNo = nPortion/__REG_LINES_IN_BLOCK;
  3073. sBlockSubKey.Format( __REG_BLOCK_FMT, nBlockNo );
  3074. CExtSafeString sRegKeyPath2( sRegKeyPath );
  3075. sRegKeyPath2 += _T('\');
  3076. sRegKeyPath2 += sBlockSubKey;
  3077. CExtRegistry reg;
  3078. if( ! reg.Create(
  3079. hKeyRoot, // HKEY_CURRENT_USER
  3080. sRegKeyPath2,
  3081. KEY_ALL_ACCESS
  3082. )
  3083. )
  3084. {
  3085. if( bEnableThrowExceptions )
  3086. ::AfxThrowUserException();
  3087. return false;
  3088. }
  3089. CExtSafeString sVarName;
  3090. sVarName.Format(
  3091. __REG_LINE_FMT,
  3092. nPortion++
  3093. );
  3094. if( ! reg.SaveBinary(
  3095. sVarName,
  3096. buffer,
  3097. nCount
  3098. )
  3099. )
  3100. {
  3101. if( bEnableThrowExceptions )
  3102. ::AfxThrowUserException();
  3103. return false;
  3104. }
  3105. _ExtIntegrityCheckSum.Update(
  3106. buffer,
  3107. nCount
  3108. );
  3109. }
  3110. USES_CONVERSION;
  3111. CExtSafeString sExtIntegrityCheckSum = _ExtIntegrityCheckSum.Final();
  3112. ASSERT( !sExtIntegrityCheckSum.IsEmpty() );
  3113. CExtSafeString sTmpBuffer, sGeneratorRev, sLibraryVer;
  3114. sGeneratorRev.Format( __REG_FMT_GENERATOR, __REG_GENERATOR_REV );
  3115. sLibraryVer.Format( __REG_FMT_LIBRARY_VERSION, g_CmdManager.GetVersionString( sTmpBuffer ) );
  3116. if( ( ! reg.SaveString( __REG_VAR_DATA_CHECK,          sExtIntegrityCheckSum ) )
  3117. || ( ! reg.SaveString( __REG_VAR_GENERATOR,           sGeneratorRev ) )
  3118. || ( ! reg.SaveString( __REG_VAR_LIBRARY_VERSION,     sLibraryVer ) )
  3119. || ( ! reg.SaveNumber( __REG_VAR_DATA_LINE_SIZE,      DWORD( __REG_LINE_SIZE ) ) )
  3120. || ( ! reg.SaveNumber( __REG_VAR_DATA_LINES_IN_BLOCK, DWORD( __REG_LINES_IN_BLOCK ) ) )
  3121. || ( ! reg.SaveNumber( __REG_VAR_DATA_FORMAT_REV,     DWORD( __REG_GENERATOR_REV ) ) )
  3122. )
  3123. {
  3124. if( bEnableThrowExceptions )
  3125. ::AfxThrowUserException();
  3126. return false;
  3127. }
  3128. return true;
  3129. }
  3130. bool CExtCmdManager::FileObjFromRegistry(
  3131. CFile & _file,
  3132. __EXT_MFC_SAFE_LPCTSTR sRegKeyPath,
  3133. HKEY hKeyRoot, // = HKEY_CURRENT_USER
  3134. bool bEnableThrowExceptions // = false
  3135. )
  3136. {
  3137. ASSERT( sRegKeyPath != NULL );
  3138. if( sRegKeyPath == NULL )
  3139. {
  3140. if( bEnableThrowExceptions )
  3141. ::AfxThrowUserException();
  3142. return false;
  3143. }
  3144. CExtRegistry reg;
  3145. if( ! reg.Open(
  3146. hKeyRoot, // HKEY_CURRENT_USER
  3147. sRegKeyPath,
  3148. KEY_READ
  3149. )
  3150. )
  3151. {
  3152. if( bEnableThrowExceptions )
  3153. ::AfxThrowUserException();
  3154. return false;
  3155. }
  3156. DWORD dwLen = 0;
  3157. if( ! reg.LoadNumber(
  3158. __REG_VAR_DATA_SIZE,
  3159. &dwLen
  3160. )
  3161. )
  3162. {
  3163. if( bEnableThrowExceptions )
  3164. ::AfxThrowUserException();
  3165. return false;
  3166. }
  3167. if( dwLen == 0 )
  3168. return true;
  3169. BYTE buffer[__REG_LINE_SIZE];
  3170. ULONG nCount = __REG_LINE_SIZE, nPortion = 0;
  3171. DWORD dwLoaded = 0;
  3172. CExtIntegrityCheckSum _ExtIntegrityCheckSum;
  3173. for( ; true;  )
  3174. {
  3175. CExtSafeString sBlockSubKey;
  3176. ULONG nBlockNo = nPortion/__REG_LINES_IN_BLOCK;
  3177. sBlockSubKey.Format( __REG_BLOCK_FMT, nBlockNo );
  3178. CExtSafeString sRegKeyPath2( sRegKeyPath );
  3179. sRegKeyPath2 += _T('\');
  3180. sRegKeyPath2 += sBlockSubKey;
  3181. CExtRegistry reg;
  3182. if( ! reg.Open(
  3183. hKeyRoot, // HKEY_CURRENT_USER
  3184. sRegKeyPath2,
  3185. KEY_READ
  3186. )
  3187. )
  3188. {
  3189. if( bEnableThrowExceptions )
  3190. ::AfxThrowUserException();
  3191. return false;
  3192. }
  3193. CExtSafeString sVarName;
  3194. sVarName.Format(
  3195. __REG_LINE_FMT,
  3196. nPortion++
  3197. );
  3198. if( dwLen-dwLoaded < __REG_LINE_SIZE )
  3199. nCount = dwLen-dwLoaded;
  3200. ASSERT( nCount > 0 && nCount <= __REG_LINE_SIZE );
  3201. if( ! reg.LoadBinary(
  3202. sVarName,
  3203. buffer,
  3204. nCount
  3205. )
  3206. )
  3207. {
  3208. if( bEnableThrowExceptions )
  3209. ::AfxThrowUserException();
  3210. return false;
  3211. }
  3212. dwLoaded += nCount;
  3213. ASSERT( dwLoaded <= dwLen );
  3214. _ExtIntegrityCheckSum.Update(
  3215. buffer,
  3216. nCount
  3217. );
  3218. _file.Write(
  3219. buffer,
  3220. nCount
  3221. );
  3222. if( dwLoaded == dwLen )
  3223. break;
  3224. }
  3225. USES_CONVERSION;
  3226. CExtSafeString sExtIntegrityCheckSum = _ExtIntegrityCheckSum.Final();
  3227. ASSERT( !sExtIntegrityCheckSum.IsEmpty() );
  3228. CExtSafeString sExtIntegrityCheckSumA;
  3229. int nSz = sExtIntegrityCheckSum.GetLength() + 1;
  3230. if( ! reg.LoadString(
  3231. __REG_VAR_DATA_CHECK,
  3232. sExtIntegrityCheckSumA.GetBuffer( nSz ),
  3233. nSz
  3234. )
  3235. )
  3236. {
  3237. sExtIntegrityCheckSumA.ReleaseBuffer();
  3238. if( bEnableThrowExceptions )
  3239. ::AfxThrowUserException();
  3240. return false;
  3241. }
  3242. sExtIntegrityCheckSumA.ReleaseBuffer();
  3243. if( sExtIntegrityCheckSumA != sExtIntegrityCheckSum )
  3244. {
  3245. if( bEnableThrowExceptions )
  3246. ::AfxThrowUserException();
  3247. return false;
  3248. }
  3249. _file.Seek( 0, CFile::begin );
  3250. return true;
  3251. }
  3252. // save/load command manager state
  3253. bool CExtCmdManager::SerializeState(
  3254. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  3255. __EXT_MFC_SAFE_LPCTSTR sSectionNameCompany, // under HKEY_CURRENT_USERSoftware
  3256. __EXT_MFC_SAFE_LPCTSTR sSectionNameProduct, // under HKEY_CURRENT_USERSoftware%sSectionNameCompany%
  3257. bool bSave,
  3258. HKEY hKeyRoot, // = HKEY_CURRENT_USER
  3259. bool bEnableThrowExceptions // = false
  3260. )
  3261. {
  3262. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  3263. if( pProfile == NULL )
  3264. {
  3265. ASSERT( FALSE );
  3266. return false;
  3267. }
  3268. // m_cs.Lock();
  3269. bool bRetVal =
  3270. pProfile->SerializeState(
  3271. sSectionNameCompany,
  3272. sSectionNameProduct,
  3273. bSave,
  3274. hKeyRoot,
  3275. bEnableThrowExceptions
  3276. );
  3277. // m_cs.Unlock();
  3278. return bRetVal;
  3279. }
  3280. bool CExtCmdManager::SerializeState(
  3281. __EXT_MFC_SAFE_LPCTSTR sProfileName,
  3282. CArchive & ar,
  3283. bool bEnableThrowExceptions // = false
  3284. )
  3285. {
  3286. CExtCmdProfile * pProfile = ProfileGetPtr( sProfileName );
  3287. if( pProfile == NULL )
  3288. {
  3289. ASSERT( FALSE );
  3290. return false;
  3291. }
  3292. // m_cs.Lock();
  3293. bool bRetVal =
  3294. pProfile->SerializeState( ar, bEnableThrowExceptions );
  3295. // m_cs.Unlock();
  3296. return bRetVal;
  3297. }
  3298. void CExtCmdManager::OnGlobalPaintManagerChanged()
  3299. {
  3300. // m_cs.Lock();
  3301. POSITION pos = m_profiles.GetStartPosition();
  3302. for( ; pos != NULL; )
  3303. {
  3304. CExtSafeString sProfileName;
  3305. CExtCmdProfile * pProfile = NULL;
  3306. m_profiles.GetNextAssoc( pos, sProfileName, (void *&)pProfile );
  3307. ASSERT( pProfile != NULL );
  3308. pProfile->OnGlobalPaintManagerChanged();
  3309. } // for( ; pos != NULL; )
  3310. // m_cs.Unlock();
  3311. }
  3312. void CExtCmdManager::OnSysColorChange(
  3313. CExtPaintManager * pPM
  3314. )
  3315. {
  3316. // m_cs.Lock();
  3317. POSITION pos = m_profiles.GetStartPosition();
  3318. for( ; pos != NULL; )
  3319. {
  3320. CExtSafeString sProfileName;
  3321. CExtCmdProfile * pProfile = NULL;
  3322. m_profiles.GetNextAssoc( pos, sProfileName, (void *&)pProfile );
  3323. ASSERT( pProfile != NULL );
  3324. pProfile->OnSysColorChange( pPM );
  3325. } // for( ; pos != NULL; )
  3326. // m_cs.Unlock();
  3327. }
  3328. void CExtCmdManager::OnSettingChange(
  3329. CExtPaintManager * pPM,
  3330. UINT uFlags,
  3331. __EXT_MFC_SAFE_LPCTSTR lpszSection
  3332. )
  3333. {
  3334. // m_cs.Lock();
  3335. POSITION pos = m_profiles.GetStartPosition();
  3336. for( ; pos != NULL; )
  3337. {
  3338. CExtSafeString sProfileName;
  3339. CExtCmdProfile * pProfile = NULL;
  3340. m_profiles.GetNextAssoc( pos, sProfileName, (void *&)pProfile );
  3341. ASSERT( pProfile != NULL );
  3342. pProfile->OnSettingChange( pPM, uFlags, lpszSection );
  3343. } // for( ; pos != NULL; )
  3344. // m_cs.Unlock();
  3345. }
  3346. void CExtCmdManager::OnDisplayChange(
  3347. CExtPaintManager * pPM,
  3348. INT nDepthBPP,
  3349. CPoint ptSizes
  3350. )
  3351. {
  3352. // m_cs.Lock();
  3353. POSITION pos = m_profiles.GetStartPosition();
  3354. for( ; pos != NULL; )
  3355. {
  3356. CExtSafeString sProfileName;
  3357. CExtCmdProfile * pProfile = NULL;
  3358. m_profiles.GetNextAssoc( pos, sProfileName, (void *&)pProfile );
  3359. ASSERT( pProfile != NULL );
  3360. pProfile->OnDisplayChange( pPM, nDepthBPP, ptSizes );
  3361. } // for( ; pos != NULL; )
  3362. // m_cs.Unlock();
  3363. }
  3364. void CExtCmdManager::OnThemeChanged(
  3365. CExtPaintManager * pPM,
  3366. WPARAM wParam,
  3367. LPARAM lParam
  3368. )
  3369. {
  3370. // m_cs.Lock();
  3371. POSITION pos = m_profiles.GetStartPosition();
  3372. for( ; pos != NULL; )
  3373. {
  3374. CExtSafeString sProfileName;
  3375. CExtCmdProfile * pProfile = NULL;
  3376. m_profiles.GetNextAssoc( pos, sProfileName, (void *&)pProfile );
  3377. ASSERT( pProfile != NULL );
  3378. pProfile->OnThemeChanged( pPM, wParam, lParam );
  3379. } // for( ; pos != NULL; )
  3380. // m_cs.Unlock();
  3381. }
  3382. /////////////////////////////////////////////////////////////////////////////
  3383. // CExtResourceManager
  3384. // resource manager class
  3385. IMPLEMENT_SERIAL( CExtResourceManager, CObject, VERSIONABLE_SCHEMA|1 );
  3386. CExtResourceManager::CExtResourceManagerAutoPtr g_ResourceManager;
  3387. WORD CExtResourceManager::g_nLangIdNeutral = __EXT_MFC_LANG_ID_DEFAULT_NEUTRAL;
  3388. CExtResourceManager::CExtResourceManagerAutoPtr::CExtResourceManagerAutoPtr()
  3389. : m_pResourceManager( NULL )
  3390. {
  3391. }
  3392. CExtResourceManager::CExtResourceManagerAutoPtr::~CExtResourceManagerAutoPtr()
  3393. {
  3394. if( m_pResourceManager != NULL )
  3395. delete m_pResourceManager;
  3396. }
  3397. // resource manager instance access
  3398. CExtResourceManager * CExtResourceManager::CExtResourceManagerAutoPtr::operator -> ()
  3399. {
  3400. return GetRM();
  3401. }
  3402. CExtResourceManager * CExtResourceManager::CExtResourceManagerAutoPtr::GetRM()
  3403. {
  3404. if( m_pResourceManager != NULL )
  3405. return m_pResourceManager;
  3406. InstallResourceManager();
  3407. return m_pResourceManager;
  3408. }
  3409. void CExtResourceManager::CExtResourceManagerAutoPtr::InstallResourceManager(
  3410. CExtResourceManager * pNewResourceManager // = NULL // NULL means install default resource manager
  3411. )
  3412. {
  3413. if( m_pResourceManager != NULL )
  3414. delete m_pResourceManager;
  3415. if( pNewResourceManager == NULL )
  3416. m_pResourceManager = new CExtResourceManager;
  3417. else
  3418. m_pResourceManager = pNewResourceManager;
  3419. }
  3420. bool CExtResourceManager::CExtResourceManagerAutoPtr::PmSynchronizeSink_PerformSynchronizationWith(
  3421. CExtPmSynchronizeSink * pPmSynchronizeSink,
  3422. bool bRegister, // = true
  3423. bool bSynchronizeItNow // = true
  3424. )
  3425. {
  3426. __PROF_UIS_MANAGE_STATE;
  3427. if( bRegister )
  3428. {
  3429. if( pPmSynchronizeSink == NULL )
  3430. return false;
  3431. if( pPmSynchronizeSink->PmSynchronizeSink_IsEqual( this ) )
  3432. return false;
  3433. DWORD dwOwnThreadID = PmSynchronizeSink_GetThreadID();
  3434. DWORD dwOtherThreadID = PmSynchronizeSink_GetThreadID();
  3435. if( dwOwnThreadID != dwOtherThreadID )
  3436. return false;
  3437. INT nIndex = GetIndexOfPmSynchronizeSink( pPmSynchronizeSink );
  3438. if( nIndex < 0 )
  3439. m_arrPmSynchronizeSink.Add( pPmSynchronizeSink );
  3440. if( bSynchronizeItNow )
  3441. {
  3442. LPSTREAM pStream = PmSynchronizeSink_GetData();
  3443. if( pStream != NULL )
  3444. {
  3445. pPmSynchronizeSink ->
  3446. PmSynchronizeSink_SynchronizeFrom(
  3447. pStream
  3448. );
  3449. pStream->Release();
  3450. } // if( pStream != NULL )
  3451. } // if( bSynchronizeItNow )
  3452. return true;
  3453. } // if( bRegister )
  3454. else
  3455. {
  3456. if( pPmSynchronizeSink == NULL )
  3457. {
  3458. m_arrPmSynchronizeSink.RemoveAll();
  3459. return true;
  3460. }
  3461. INT nIndex = GetIndexOfPmSynchronizeSink( pPmSynchronizeSink );
  3462. if( nIndex < 0 )
  3463. return false;
  3464. m_arrPmSynchronizeSink.RemoveAt( nIndex );
  3465. return true;
  3466. } // else from if( bRegister )
  3467. }
  3468. LPSTREAM CExtResourceManager::CExtResourceManagerAutoPtr::PmSynchronizeSink_GetData(
  3469. HGLOBAL hGlobal // = NULL
  3470. )
  3471. {
  3472. __PROF_UIS_MANAGE_STATE;
  3473. CExtResourceManager * pRM = GetRM();
  3474. if( pRM == NULL )
  3475. return NULL;
  3476. LPSTREAM pStream = NULL;
  3477. SCODE sc =
  3478. ::CreateStreamOnHGlobal(
  3479. hGlobal,
  3480. ( hGlobal != NULL ) ? FALSE : TRUE,
  3481. &pStream
  3482. );
  3483. if( sc != S_OK )
  3484. {
  3485. ASSERT( FALSE );
  3486. return NULL;
  3487. }
  3488. ASSERT( pStream != NULL );
  3489. COleStreamFile _file;
  3490. try