XTPShortcutManager.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:34k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPShortcutManager.cpp : implementation of the CXTPShortcutManager class.
  2. //
  3. // This file is a part of the XTREME COMMANDBARS MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Resource.h"
  22. #include "Common/XTPPropExchange.h"
  23. #include "Common/XTPVC80Helpers.h"
  24. #include "Common/XTPResourceManager.h"
  25. #include "XTPShortcutManager.h"
  26. #include "XTPCommandBars.h"
  27. #ifdef _DEBUG
  28. #define new DEBUG_NEW
  29. #undef THIS_FILE
  30. static char THIS_FILE[] = __FILE__;
  31. #endif
  32. //////////////////////////////////////////////////////////////////////////
  33. // CXTPShortcutManagerAccel
  34. CXTPShortcutManagerAccel::CXTPShortcutManagerAccel()
  35. {
  36. cmd = 0;
  37. key[0].fVirt = 0;
  38. key[0].key = 0;
  39. key[1].fVirt = 0;
  40. key[1].key = 0;
  41. }
  42. CXTPShortcutManagerAccel::CXTPShortcutManagerAccel(ACCEL* pAccel)
  43. {
  44. cmd = pAccel->cmd;
  45. key[0].fVirt = pAccel->fVirt;
  46. key[0].key = pAccel->key;
  47. key[1].fVirt = 0;
  48. key[1].key = 0;
  49. }
  50. CXTPShortcutManagerAccel::CXTPShortcutManagerAccel(const CXTPShortcutManagerAccel& accel)
  51. {
  52. cmd = accel.cmd;
  53. key[0] = accel.key[0];
  54. key[1] = accel.key[1];
  55. }
  56. //////////////////////////////////////////////////////////////////////////
  57. // CXTPShortcutManagerAccelTable
  58. CXTPShortcutManagerAccelTable::CXTPShortcutManagerAccelTable()
  59. {
  60. }
  61. CXTPShortcutManagerAccelTable::~CXTPShortcutManagerAccelTable()
  62. {
  63. RemoveAll();
  64. }
  65. void CXTPShortcutManagerAccelTable::RemoveAll()
  66. {
  67. for (int i = 0; i < GetCount(); i++)
  68. {
  69. delete m_arrAccels[i];
  70. }
  71. m_arrAccels.RemoveAll();
  72. }
  73. void CXTPShortcutManagerAccelTable::RemoveAt(int nIndex)
  74. {
  75. delete m_arrAccels[nIndex];
  76. m_arrAccels.RemoveAt(nIndex);
  77. }
  78. void CXTPShortcutManagerAccelTable::Add(CXTPShortcutManagerAccel accel)
  79. {
  80. m_arrAccels.Add(new CXTPShortcutManagerAccel(accel));
  81. }
  82. void CXTPShortcutManagerAccelTable::CopyAccelTable(LPACCEL lpAccel, int nSize)
  83. {
  84. RemoveAll();
  85. for (int i = 0; i < nSize; i++)
  86. {
  87. m_arrAccels.Add(new CXTPShortcutManagerAccel(&lpAccel[i]));
  88. }
  89. }
  90. CXTPShortcutManagerAccel* CXTPShortcutManagerAccelTable::CopyAccels() const
  91. {
  92. CXTPShortcutManagerAccel* pAccels = new CXTPShortcutManagerAccel[GetCount()];
  93. for (int i = 0; i < GetCount(); i++)
  94. {
  95. pAccels[i] = *m_arrAccels[i];
  96. }
  97. return pAccels;
  98. }
  99. void CXTPShortcutManagerAccelTable::CopyAccelTable(HACCEL hAccelTable)
  100. {
  101. RemoveAll();
  102. if (hAccelTable == NULL)
  103. return;
  104. int nAccelSize = ::CopyAcceleratorTable (hAccelTable, NULL, 0);
  105. if (nAccelSize == 0)
  106. return;
  107. LPACCEL lpAccel = new ACCEL[nAccelSize];
  108. ::CopyAcceleratorTable (hAccelTable, lpAccel, nAccelSize);
  109. CopyAccelTable(lpAccel, nAccelSize);
  110. delete[] lpAccel;
  111. }
  112. int CXTPShortcutManagerAccelTable::GetCount() const
  113. {
  114. return (int)m_arrAccels.GetSize();
  115. }
  116. CXTPShortcutManagerAccel* CXTPShortcutManagerAccelTable::GetAt(int nIndex) const
  117. {
  118. return m_arrAccels.GetAt(nIndex);
  119. }
  120. void CXTPShortcutManagerAccelTable::CopyAccelTable(CXTPShortcutManagerAccelTable* pAccelTable)
  121. {
  122. RemoveAll();
  123. int nAccelSize = pAccelTable->GetCount();
  124. for (int i = 0; i < nAccelSize; i++)
  125. {
  126. m_arrAccels.Add(new CXTPShortcutManagerAccel(*pAccelTable->GetAt(i)));
  127. }
  128. }
  129. //////////////////////////////////////////////////////////////////////////
  130. // CXTPShortcutManagerKeyNameText::CXTPShortcutManagerKeyNameText
  131. CXTPShortcutManager::CKeyNameText::CKeyNameText()
  132. {
  133. static const struct
  134. {
  135. WORD    wKey;       // Virtual Key Code.
  136. LPCTSTR szKeyName;  // Display Name (i.e "CTRL").
  137. }
  138. virtKeys[] =
  139. {
  140. { _T('0'), _T("0") },
  141. { _T('1'), _T("1") },
  142. { _T('2'), _T("2") },
  143. { _T('3'), _T("3") },
  144. { _T('4'), _T("4") },
  145. { _T('5'), _T("5") },
  146. { _T('6'), _T("6") },
  147. { _T('7'), _T("7") },
  148. { _T('8'), _T("8") },
  149. { _T('9'), _T("9") },
  150. { _T('A'), _T("A") },
  151. { _T('B'), _T("B") },
  152. { _T('C'), _T("C") },
  153. { _T('D'), _T("D") },
  154. { _T('E'), _T("E") },
  155. { _T('F'), _T("F") },
  156. { _T('G'), _T("G") },
  157. { _T('H'), _T("H") },
  158. { _T('I'), _T("I") },
  159. { _T('J'), _T("J") },
  160. { _T('K'), _T("K") },
  161. { _T('L'), _T("L") },
  162. { _T('M'), _T("M") },
  163. { _T('N'), _T("N") },
  164. { _T('O'), _T("O") },
  165. { _T('P'), _T("P") },
  166. { _T('Q'), _T("Q") },
  167. { _T('R'), _T("R") },
  168. { _T('S'), _T("S") },
  169. { _T('T'), _T("T") },
  170. { _T('U'), _T("U") },
  171. { _T('V'), _T("V") },
  172. { _T('W'), _T("W") },
  173. { _T('X'), _T("X") },
  174. { _T('Y'), _T("Y") },
  175. { _T('Z'), _T("Z") },
  176. { VK_LBUTTON, _T("Left Button") },
  177. { VK_RBUTTON, _T("Right Button") },
  178. { VK_CANCEL, _T("Ctrl+Break") },
  179. { VK_MBUTTON, _T("Middle Button") },
  180. { VK_BACK, _T("Backspace") },
  181. { VK_TAB, _T("Tab") },
  182. { VK_CLEAR, _T("Clear") },
  183. { VK_RETURN, _T("Enter") },
  184. { VK_SHIFT, _T("Shift") },
  185. { VK_CONTROL, _T("Ctrl") },
  186. { VK_MENU, _T("Alt") },
  187. { VK_PAUSE, _T("Pause") },
  188. { VK_CAPITAL, _T("Caps Lock") },
  189. { VK_ESCAPE, _T("Esc") },
  190. { VK_SPACE, _T("Space") },
  191. { VK_PRIOR, _T("Page Up") },
  192. { VK_NEXT, _T("Page Down") },
  193. { VK_END, _T("End") },
  194. { VK_HOME, _T("Home") },
  195. { VK_LEFT, _T("Left Arrow") },
  196. { VK_UP, _T("Up Arrow") },
  197. { VK_RIGHT, _T("Right Arrow") },
  198. { VK_DOWN, _T("Down Arrow") },
  199. { VK_SELECT, _T("Select") },
  200. { VK_PRINT, _T("Print") },
  201. { VK_EXECUTE, _T("Execute") },
  202. { VK_SNAPSHOT, _T("Snapshot") },
  203. { VK_INSERT, _T("Ins") },
  204. { VK_DELETE, _T("Del") },
  205. { VK_HELP, _T("Help") },
  206. { VK_LWIN , _T("Win") },
  207. { VK_RWIN, _T("Win") },
  208. { VK_APPS, _T("Application") },
  209. { VK_MULTIPLY, _T("Num *") },
  210. { VK_ADD, _T("Num +") },
  211. { VK_SEPARATOR, _T("Separator") },
  212. { VK_SUBTRACT, _T("Num -") },
  213. { VK_DECIMAL, _T("Num .") },
  214. { VK_DIVIDE, _T("Num /") },
  215. { VK_F1, _T("F1") },
  216. { VK_F2, _T("F2") },
  217. { VK_F3, _T("F3") },
  218. { VK_F4, _T("F4") },
  219. { VK_F5, _T("F5") },
  220. { VK_F6, _T("F6") },
  221. { VK_F7, _T("F7") },
  222. { VK_F8, _T("F8") },
  223. { VK_F9, _T("F9") },
  224. { VK_F10, _T("F10") },
  225. { VK_F11, _T("F11") },
  226. { VK_F12, _T("F12") },
  227. { VK_NUMPAD0, _T("Num 0") },
  228. { VK_NUMPAD1, _T("Num 1") },
  229. { VK_NUMPAD2, _T("Num 2") },
  230. { VK_NUMPAD3, _T("Num 3") },
  231. { VK_NUMPAD4, _T("Num 4") },
  232. { VK_NUMPAD5, _T("Num 5") },
  233. { VK_NUMPAD6, _T("Num 6") },
  234. { VK_NUMPAD7, _T("Num 7") },
  235. { VK_NUMPAD8, _T("Num 8") },
  236. { VK_NUMPAD9, _T("Num 9") },
  237. { VK_NUMLOCK, _T("Num Lock") },
  238. { VK_SCROLL, _T("Scrl Lock") },
  239. { VK_ATTN, _T("Attn") },
  240. { VK_CRSEL, _T("Crsel") },
  241. { VK_EXSEL, _T("Exsel") },
  242. { VK_EREOF, _T("Ereof") },
  243. { VK_PLAY, _T("Play") },
  244. { VK_ZOOM, _T("Zoom") },
  245. { VK_NONAME, _T("No Name") },
  246. { VK_PA1, _T("Pa1") },
  247. { VK_OEM_CLEAR, _T("Oem Clear") },
  248. };
  249. for (int i = 0; i < _countof(virtKeys); i++)
  250. {
  251. SetAt(virtKeys[i].wKey, virtKeys[i].szKeyName);
  252. }
  253. }
  254. WORD CXTPShortcutManager::CKeyNameText::Parse(LPCTSTR lpszKey)
  255. {
  256. POSITION pos = m_mapVirtualKeys.GetStartPosition();
  257. while (pos)
  258. {
  259. WORD rKey;
  260. CString strKey;
  261. m_mapVirtualKeys.GetNextAssoc(pos, rKey, strKey);
  262. if (strKey.CompareNoCase(lpszKey) == 0)
  263. return rKey;
  264. }
  265. return 0;
  266. }
  267. CString CXTPShortcutManager::CKeyNameText::Translate(UINT nKey)
  268. {
  269. CString strKeyNameText;
  270. if (m_mapVirtualKeys.Lookup((WORD)nKey, strKeyNameText))
  271. {
  272. return strKeyNameText;
  273. }
  274. return _T("");
  275. }
  276. void CXTPShortcutManager::CKeyNameText::SetAt(UINT uiVirtKey, LPCTSTR strKeyNameText)
  277. {
  278. m_mapVirtualKeys.SetAt((WORD)uiVirtKey, strKeyNameText);
  279. }
  280. #define SAFE_DESTROY_ACCELTABLE(hAccelTable) if (hAccelTable) {::DestroyAcceleratorTable (hAccelTable); hAccelTable = NULL;}
  281. CXTPShortcutManager::CXTPShortcutManager(CXTPCommandBars* pCommandBars)
  282. {
  283. m_pCommandBars = pCommandBars;
  284. m_pAccelTable = new CXTPShortcutManagerAccelTable();
  285. m_pOriginalAccelTable = NULL;
  286. m_bAllowEscapeShortcut = FALSE;
  287. m_bUseSystemKeyNameText = FALSE;
  288. m_pKeyNameText = new CKeyNameText();
  289. m_nDisableShortcuts = 0;
  290. }
  291. CXTPShortcutManager::~CXTPShortcutManager()
  292. {
  293. SAFE_DELETE(m_pAccelTable);
  294. SAFE_DELETE(m_pOriginalAccelTable);
  295. SAFE_DELETE(m_pKeyNameText);
  296. }
  297. void CXTPShortcutManager::SetAccelerators(UINT nIDResource)
  298. {
  299. m_pAccelTable->RemoveAll();
  300. LPCTSTR lpszResourceName = MAKEINTRESOURCE(nIDResource);
  301. HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_ACCELERATOR);
  302. if (hInst)
  303. {
  304. HACCEL hAccel = ::LoadAccelerators(hInst, lpszResourceName);
  305. m_pAccelTable->CopyAccelTable(hAccel);
  306. CreateOriginalAccelTable();
  307. }
  308. }
  309. void CXTPShortcutManager::SetDefaultAccelerator(HACCEL hAccelTable)
  310. {
  311. m_pAccelTable->CopyAccelTable(hAccelTable);
  312. CreateOriginalAccelTable();
  313. }
  314. void CXTPShortcutManager::CreateOriginalAccelTable()
  315. {
  316. if (m_pOriginalAccelTable == NULL)
  317. m_pOriginalAccelTable = new CXTPShortcutManagerAccelTable();
  318. m_pOriginalAccelTable->CopyAccelTable(m_pAccelTable);
  319. }
  320. void CXTPShortcutManager::Reset()
  321. {
  322. ASSERT(m_pOriginalAccelTable);
  323. if (m_pOriginalAccelTable)
  324. {
  325. m_pAccelTable->CopyAccelTable(m_pOriginalAccelTable);
  326. }
  327. }
  328. CString CXTPShortcutManager::Format(CXTPShortcutManagerAccel* lpAccel, int* pPriority)
  329. {
  330. CString str;
  331. CKeyHelper helper (lpAccel, this);
  332. helper.Format (str);
  333. if (pPriority)
  334. {
  335. *pPriority = helper.Priority();
  336. }
  337. return str;
  338. }
  339. BOOL CXTPShortcutManager::OnPreviewEditKey(CXTPShortcutManagerAccel* pAccel)
  340. {
  341. if ((pAccel->key[0].fVirt & FCONTROL) == 0
  342. && (pAccel->key[0].fVirt & FSHIFT) == 0
  343. && (pAccel->key[0].fVirt & FALT) == 0
  344. && (pAccel->key[0].fVirt & FVIRTKEY)
  345. && (pAccel->key[0].key == VK_ESCAPE) && !m_bAllowEscapeShortcut)
  346. return FALSE;
  347. return TRUE;
  348. }
  349. void CXTPShortcutManager::DisableShortcuts(BOOL bDisable)
  350. {
  351. m_nDisableShortcuts += bDisable ? +1 : -1;
  352. }
  353. BOOL CXTPShortcutManager::IsAccelMessage(CXTPShortcutManagerAccel::SHORTCUTACCEL& accel, int nKeyState, LPMSG lpMsg) const
  354. {
  355. BOOL fVirt = lpMsg->message == WM_KEYDOWN || lpMsg->message == WM_SYSKEYDOWN;
  356. WORD flags = accel.fVirt;
  357. if ( (DWORD)accel.key != lpMsg->wParam ||
  358. ((fVirt != 0) != ((flags & FVIRTKEY) != 0)))
  359. {
  360. return FALSE;
  361. }
  362. if (fVirt && ((nKeyState & (FSHIFT | FCONTROL)) != (flags & (FSHIFT | FCONTROL))))
  363. {
  364. return FALSE;
  365. }
  366. if ((nKeyState & FALT) != (flags & FALT))
  367. {
  368. return FALSE;
  369. }
  370. return TRUE;
  371. }
  372. int CXTPShortcutManager::GetAccelKeyState() const
  373. {
  374. int vkCtrl = VK_CONTROL;
  375. int vkAlt = VK_MENU;
  376. if ((GetKeyState(VK_RMENU) & 0x8000) && (GetKeyState(VK_LCONTROL) & 0x8000))
  377. {
  378. vkCtrl = VK_RCONTROL;
  379. vkAlt = VK_LMENU;
  380. }
  381. int nKeyState = 0;
  382. if (GetKeyState(vkCtrl) & 0x8000) nKeyState |= FCONTROL;
  383. if (GetKeyState(vkAlt) & 0x8000) nKeyState |= FALT;
  384. if (GetKeyState(VK_SHIFT) & 0x8000) nKeyState |= FSHIFT;
  385. return nKeyState;
  386. }
  387. BOOL CXTPShortcutManager::TranslateAccelerator(LPMSG lpMsg)
  388. {
  389. if (!m_pCommandBars || m_pCommandBars->IsCustomizeMode())
  390. return FALSE;
  391. HWND hWnd = m_pCommandBars->GetSite()->GetSafeHwnd();
  392. if (m_nDisableShortcuts > 0)
  393. return FALSE;
  394. CXTPShortcutManagerAccelTable* pAccelTable = GetDefaultAccelerator();
  395. if (pAccelTable == NULL || pAccelTable->GetCount() == 0)
  396. return FALSE;
  397. if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN && lpMsg->message != WM_CHAR && lpMsg->message != WM_SYSCHAR)
  398. return FALSE;
  399. int nKeyState = GetAccelKeyState();
  400. BOOL bFound = FALSE;
  401. int nAccelSize = pAccelTable->GetCount();
  402. for (int i = 0; i < nAccelSize; i++)
  403. {
  404. CXTPShortcutManagerAccel* accel = pAccelTable->GetAt(i);
  405. if (!IsAccelMessage(accel->key[0], nKeyState, lpMsg))
  406. continue;
  407. bFound = TRUE;
  408. if (IsWindowEnabled(hWnd) && ::GetCapture() == NULL && !IsIconic(hWnd) && accel->cmd != 0)
  409. {
  410. if (accel->key[1].key != 0)
  411. {
  412. if (m_pCommandBars->GetSite()->IsFrameWnd())
  413. {
  414. CKeyHelper key(accel, this);
  415. CString strMessage, strFormat;
  416. VERIFY(XTPResourceManager()->LoadString(&strFormat, XTP_IDS_SHORTCUT_SECONDKEY));
  417. strMessage.Format(strFormat, (LPCTSTR)key.Format(&accel->key[0]));
  418. ((CFrameWnd*)m_pCommandBars->GetSite())->SetMessageText(strMessage);
  419. }
  420. BOOL bAccept = FALSE;
  421. m_nDisableShortcuts++;
  422. ::SetCapture(hWnd);
  423. while (::GetCapture() == hWnd)
  424. {
  425. MSG msg;
  426. VERIFY(::GetMessage(&msg, NULL, 0, 0));
  427. if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN)
  428. {
  429. if (msg.wParam == VK_SHIFT || msg.wParam == VK_CONTROL || msg.wParam == VK_MENU)
  430. continue;
  431. nKeyState = GetAccelKeyState();
  432. for (int j = 0; j < nAccelSize; j++)
  433. {
  434. CXTPShortcutManagerAccel* secondAccel = pAccelTable->GetAt(j);
  435. if (secondAccel->key[0].fVirt == accel->key[0].fVirt && secondAccel->key[0].key == accel->key[0].key)
  436. {
  437. if (!IsAccelMessage(secondAccel->key[1], nKeyState, &msg))
  438. continue;
  439. bAccept = TRUE;
  440. accel = secondAccel;
  441. break;
  442. }
  443. }
  444. if (!bAccept)
  445. {
  446. MessageBeep(MB_ICONEXCLAMATION);
  447. }
  448. break;
  449. }
  450. DispatchMessage (&msg);
  451. if (msg.message == WM_COMMAND || msg.message == WM_ACTIVATE || msg.message == WM_LBUTTONDOWN ||
  452. msg.message == WM_NCACTIVATE || msg.message == WM_CLOSE || msg.message == WM_SYSCOMMAND)
  453. break;
  454. }
  455. ::ReleaseCapture();
  456. m_nDisableShortcuts--;
  457. if (IsWindow(hWnd) && m_pCommandBars->GetSite()->IsFrameWnd())
  458. {
  459. ((CFrameWnd*)m_pCommandBars->GetSite())->SetMessageText((UINT)0);
  460. }
  461. if (!bAccept)
  462. return TRUE;
  463. }
  464. SendMessage(hWnd, WM_COMMAND, accel->cmd, 0);
  465. }
  466. break;
  467. }
  468. return bFound;
  469. }
  470. BOOL CXTPShortcutManager::FindDefaultFrameAccelerator(int nCmd, CString& strShortcut)
  471. {
  472. CFrameWnd* pFrame = DYNAMIC_DOWNCAST(CFrameWnd, m_pCommandBars->GetSite());
  473. HACCEL hAccelTable = pFrame ? pFrame->m_hAccelTable : NULL;
  474. if (!hAccelTable)
  475. return FALSE;
  476. ASSERT(hAccelTable);
  477. int nAccelSize = ::CopyAcceleratorTable (hAccelTable, NULL, 0);
  478. LPACCEL lpAccel = new ACCEL[nAccelSize];
  479. ::CopyAcceleratorTable (hAccelTable, lpAccel, nAccelSize);
  480. BOOL bFound = FALSE;
  481. BOOL bEqual = FALSE;
  482. CString strFirst = _T("");
  483. int nFirstPriorety = 0;
  484. for (int i = 0; i < nAccelSize; i++)
  485. {
  486. if (lpAccel[i].cmd == nCmd)
  487. {
  488. int nPriority = 0;
  489. CXTPShortcutManagerAccel accel(&lpAccel[i]);
  490. CString str = Format(&accel, &nPriority);
  491. if (str == strShortcut)
  492. bEqual = TRUE;
  493. if (strFirst.IsEmpty() || (nFirstPriorety < nPriority))
  494. {
  495. strFirst = str;
  496. nFirstPriorety = nPriority;
  497. }
  498. bFound = TRUE;
  499. }
  500. }
  501. delete[] lpAccel;
  502. if (!bFound)
  503. strShortcut = "";
  504. else if (!bEqual)
  505. strShortcut = strFirst;
  506. return bFound;
  507. }
  508. BOOL CXTPShortcutManager::FindDefaultAccelerator(int nCmd, CString& strShortcut)
  509. {
  510. if (m_pOriginalAccelTable == NULL)
  511. return FindDefaultFrameAccelerator(nCmd, strShortcut);
  512. CXTPShortcutManagerAccelTable* pAccelTable = GetDefaultAccelerator();
  513. if (!pAccelTable || pAccelTable->GetCount() == 0)
  514. return FALSE;
  515. int nAccelSize = pAccelTable->GetCount();
  516. BOOL bFound = FALSE;
  517. BOOL bEqual = FALSE;
  518. CString strFirst = _T("");
  519. int nFirstPriorety = 0;
  520. for (int i = 0; i < nAccelSize; i++)
  521. {
  522. CXTPShortcutManagerAccel* accel = pAccelTable->GetAt(i);
  523. if (accel->cmd == (int)nCmd)
  524. {
  525. int nPriority = 0;
  526. CString str = Format(accel, &nPriority);
  527. if (str == strShortcut)
  528. bEqual = TRUE;
  529. if (strFirst.IsEmpty() || (nFirstPriorety < nPriority))
  530. {
  531. strFirst = str;
  532. nFirstPriorety = nPriority;
  533. }
  534. bFound = TRUE;
  535. }
  536. }
  537. if (!bFound)
  538. strShortcut = "";
  539. else if (!bEqual)
  540. strShortcut = strFirst;
  541. return bFound;
  542. }
  543. CXTPShortcutManager::CKeyHelper::CKeyHelper(const CXTPShortcutManagerAccel* lpAccel, CXTPShortcutManager* pManager/*= NULL*/) :
  544. m_pManager(pManager), m_lpAccel (lpAccel)
  545. {
  546. m_bAllowLocaleKey = TRUE;
  547. }
  548. CXTPShortcutManager::CKeyHelper::~CKeyHelper()
  549. {
  550. }
  551. int CXTPShortcutManager::CKeyHelper::Priority()
  552. {
  553. if (m_lpAccel == NULL)
  554. return 0;
  555. if (m_lpAccel->key[0].fVirt & FCONTROL)
  556. return 3;
  557. if (m_lpAccel->key[0].fVirt & FALT)
  558. return 2;
  559. if (m_lpAccel->key[0].fVirt & FSHIFT)
  560. return 1;
  561. return 4;
  562. }
  563. void CXTPShortcutManager::CKeyHelper::Format(CString& str) const
  564. {
  565. str.Empty ();
  566. if (m_lpAccel == NULL)
  567. {
  568. ASSERT (FALSE);
  569. return;
  570. }
  571. str = Format(&m_lpAccel->key[0]);
  572. if (m_lpAccel->key[1].key != 0)
  573. {
  574. CString str2 = Format(&m_lpAccel->key[1]);
  575. if (!str2.IsEmpty())
  576. {
  577. str += _T(", ") + str2;
  578. }
  579. }
  580. }
  581. CString CXTPShortcutManager::CKeyHelper::Format(const CXTPShortcutManagerAccel::SHORTCUTACCEL* pAccel) const
  582. {
  583. CString str;
  584. if (pAccel->key != VK_CANCEL)
  585. {
  586. if (pAccel->fVirt & FCONTROL)
  587. {
  588. AddVirtKeyStr(str, VK_CONTROL);
  589. }
  590. if (pAccel->fVirt & FSHIFT)
  591. {
  592. AddVirtKeyStr(str, VK_SHIFT);
  593. }
  594. if (pAccel->fVirt & FALT)
  595. {
  596. AddVirtKeyStr(str, VK_MENU);
  597. }
  598. if (pAccel->fVirt & 0x20)
  599. {
  600. AddVirtKeyStr (str, VK_LWIN);
  601. }
  602. }
  603. if (pAccel->key)
  604. {
  605. if (pAccel->fVirt & FVIRTKEY)
  606. {
  607. AddVirtKeyStr(str, pAccel->key, TRUE);
  608. }
  609. else if ((pAccel->key >= 1 && pAccel->key <= 26) && (pAccel->fVirt == FNOINVERT))
  610. {
  611. AddVirtKeyStr(str, VK_CONTROL);
  612. str += (char) ('A' + pAccel->key - 1);
  613. }
  614. else if (pAccel->key != VK_ESCAPE && pAccel->key != VK_TAB)
  615. {
  616. str += (char) pAccel->key;
  617. }
  618. }
  619. else if (str.GetLength() > 0)
  620. {
  621. str = str.Left(str.GetLength() - 1);
  622. }
  623. return str;
  624. }
  625. void CXTPShortcutManager::CKeyHelper::AddVirtKeyStr(CString& str, UINT uiVirtKey, BOOL bLast) const
  626. {
  627. ASSERT(m_pManager);
  628. if (!m_pManager)
  629. return;
  630. CString strKey;
  631. if (m_bAllowLocaleKey)
  632. {
  633. strKey = m_pManager->GetKeyNameText(uiVirtKey);
  634. }
  635. else
  636. {
  637. strKey = m_pManager->m_pKeyNameText->Translate(uiVirtKey);
  638. if (strKey.IsEmpty())
  639. {
  640. strKey.Format(_T("0x%x"), uiVirtKey);
  641. }
  642. }
  643. if (!strKey.IsEmpty())
  644. {
  645. str += strKey;
  646. if (!bLast)
  647. {
  648. str += '+';
  649. }
  650. }
  651. }
  652. CString CXTPShortcutManager::CKeyHelper::GetLocalKeyNameText(UINT uiVirtKey)
  653. {
  654. #define BUFFER_LEN 50
  655. TCHAR szBuffer[BUFFER_LEN + 1];
  656. ZeroMemory(szBuffer, BUFFER_LEN);
  657. if (uiVirtKey == VK_CANCEL)
  658. return _T("");
  659. UINT nScanCode = ::MapVirtualKeyEx (uiVirtKey, 0,
  660. ::GetKeyboardLayout (0)) << 16 | 0x1;
  661. if (uiVirtKey >= VK_PRIOR && uiVirtKey <= VK_HELP)
  662. {
  663. nScanCode |= 0x01000000;
  664. }
  665. ::GetKeyNameText(nScanCode, szBuffer, BUFFER_LEN);
  666. CString strKey = szBuffer;
  667. if (!strKey.IsEmpty())
  668. {
  669. strKey.MakeLower();
  670. for (int i = 0; i < strKey.GetLength(); i++)
  671. {
  672. TCHAR c = strKey[i];
  673. if (IsCharLower(c))
  674. {
  675. strKey.SetAt (i, CXTPShortcutManager::ToUpper(c));
  676. break;
  677. }
  678. }
  679. }
  680. return strKey;
  681. }
  682. BOOL CXTPShortcutManager::CompareAccelKey(TCHAR chAccel, UINT wParam)
  683. {
  684. if (wParam >= VK_NUMPAD0 && wParam <= VK_NUMPAD9)
  685. return (UINT)chAccel == (wParam + '0' - VK_NUMPAD0);
  686. TCHAR tchVirtualKey = (TCHAR)MapVirtualKey(wParam, 2);
  687. if (tchVirtualKey == NULL)
  688. return FALSE;
  689. TCHAR chAccelUpper = ToUpper(chAccel);
  690. if ((chAccel == (TCHAR)wParam) || (chAccelUpper == (TCHAR)wParam))
  691. return TRUE;
  692. UINT nLayoutCount = GetKeyboardLayoutList(0, 0);
  693. if (nLayoutCount > 1)
  694. {
  695. CArray<HKL, HKL&> arrLayoutList;
  696. arrLayoutList.SetSize(nLayoutCount);
  697. GetKeyboardLayoutList(nLayoutCount, arrLayoutList.GetData());
  698. BYTE keyState[256];
  699. if (!GetKeyboardState (keyState))
  700. return FALSE;
  701. for (UINT i = 0; i < nLayoutCount; i++)
  702. {
  703. WORD chKey = 0;
  704. #ifdef _UNICODE
  705. if (ToUnicodeEx((UINT)wParam, 0, keyState, (LPWSTR)&chKey, 1, 0, arrLayoutList[i]) == 1)
  706. #else
  707. if (ToAsciiEx((UINT)wParam, 0, keyState, &chKey, 0, arrLayoutList[i]) == 1)
  708. #endif
  709. {
  710. if ((chAccel == (TCHAR)chKey) || (chAccelUpper == ToUpper((TCHAR)chKey)))
  711. return TRUE;
  712. }
  713. BYTE ksShift = keyState[VK_SHIFT];
  714. keyState[VK_SHIFT]= 0x81;
  715. #ifdef _UNICODE
  716. if (ToUnicodeEx((UINT)wParam, 0, keyState, (LPWSTR)&chKey, 1, 0, arrLayoutList[i]) == 1)
  717. #else
  718. if (ToAsciiEx((UINT)wParam, 0, keyState, &chKey, 0, arrLayoutList[i]) == 1)
  719. #endif
  720. {
  721. if ((chAccel == (TCHAR)chKey) || (chAccelUpper == ToUpper((TCHAR)chKey)))
  722. return TRUE;
  723. }
  724. keyState[VK_SHIFT] = ksShift;
  725. }
  726. }
  727. return FALSE;
  728. }
  729. void CXTPShortcutManager::SetKeyNameText(UINT uiVirtKey, LPCTSTR strKeyNameText)
  730. {
  731. m_pKeyNameText->SetAt(uiVirtKey, strKeyNameText);
  732. }
  733. CString CXTPShortcutManager::GetKeyNameText(UINT uiVirtKey)
  734. {
  735. CString strKey;
  736. if (m_bUseSystemKeyNameText)
  737. {
  738. strKey = CKeyHelper::GetLocalKeyNameText(uiVirtKey);
  739. }
  740. if (strKey.IsEmpty())
  741. {
  742. strKey = m_pKeyNameText->Translate(uiVirtKey);
  743. }
  744. if (strKey.IsEmpty() && !m_bUseSystemKeyNameText)
  745. {
  746. strKey = CKeyHelper::GetLocalKeyNameText(uiVirtKey);
  747. }
  748. return strKey;
  749. }
  750. TCHAR CXTPShortcutManager::ToUpper(TCHAR vkTCHAR)
  751. {
  752. TCHAR szChar[2] = {vkTCHAR, _T('') };
  753. CharUpper(szChar);
  754. return szChar[0];
  755. }
  756. /////////////////////////////////////////////////////////////////////////////
  757. // CKeyAssign
  758. CXTPShortcutManager::CKeyAssign::CKeyAssign(CXTPShortcutManager* pManager/*= NULL*/)
  759. : m_keyHelper(&m_accel, pManager)
  760. {
  761. m_nKeyDefined = 0;
  762. m_bExtendedOnly = FALSE;
  763. m_bAllowDoubleKeyShortcuts = pManager ? pManager->m_bAllowDoubleKeyShortcuts : FALSE;
  764. ResetKey();
  765. }
  766. CXTPShortcutManager::CKeyAssign::~CKeyAssign()
  767. {
  768. }
  769. BOOL CXTPShortcutManager::CKeyAssign::PreTranslateMessage(MSG* pMsg)
  770. {
  771. if (pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_MBUTTONDOWN || pMsg->message == WM_RBUTTONDOWN)
  772. {
  773. SetFocus ();
  774. return TRUE;
  775. }
  776. if (pMsg->message != WM_KEYDOWN && pMsg->message != WM_SYSKEYDOWN && pMsg->message != WM_KEYUP && pMsg->message != WM_SYSKEYUP)
  777. return CEdit::PreTranslateMessage(pMsg);
  778. if (m_bAllowDoubleKeyShortcuts)
  779. return TranslateDoubleKeyShortcutsMessage(pMsg);
  780. return TranslateSingleKeyShortcutsMessage(pMsg);
  781. }
  782. BOOL CXTPShortcutManager::CKeyAssign::TranslateDoubleKeyShortcutsMessage(MSG* pMsg)
  783. {
  784. BOOL bPressed = pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN;
  785. if (!bPressed)
  786. return FALSE;
  787. BOOL bControlPressed = ::GetKeyState(VK_CONTROL) & 0x8000;
  788. BOOL bAltPressed = ::GetKeyState(VK_MENU) & 0x8000;
  789. if (!bControlPressed && !bAltPressed && (pMsg->wParam == VK_TAB))
  790. {
  791. return FALSE;
  792. }
  793. if (pMsg->wParam == VK_SHIFT || pMsg->wParam == VK_CONTROL || pMsg->wParam == VK_MENU)
  794. return FALSE;
  795. if (pMsg->wParam == VK_BACK)
  796. {
  797. if (m_nKeyDefined == 2)
  798. {
  799. m_accel.key[1].fVirt = 0;
  800. m_accel.key[1].key = 0;
  801. m_nKeyDefined = 1;
  802. }
  803. else
  804. {
  805. ResetKey();
  806. }
  807. }
  808. else
  809. {
  810. if (m_nKeyDefined > 1)
  811. ResetKey();
  812. // read in the actual state because we were not tracking releases if there was a
  813. // definition
  814. SetAccelFlag(m_nKeyDefined, FSHIFT, ::GetKeyState(VK_SHIFT) & 0x8000);
  815. SetAccelFlag(m_nKeyDefined, FCONTROL, bControlPressed);
  816. SetAccelFlag(m_nKeyDefined, FALT, bAltPressed);
  817. m_accel.key[m_nKeyDefined].key = (WORD)pMsg->wParam;
  818. SetAccelFlag(m_nKeyDefined, FVIRTKEY, TRUE);
  819. m_nKeyDefined++;
  820. }
  821. if (m_keyHelper.GetShortcutManager() && !m_keyHelper.GetShortcutManager()->OnPreviewEditKey(&m_accel))
  822. {
  823. ResetKey();
  824. return TRUE;
  825. }
  826. CString str;
  827. m_keyHelper.Format(str);
  828. SetWindowText(str);
  829. SetSel(str.GetLength(), str.GetLength());
  830. return TRUE;
  831. }
  832. BOOL CXTPShortcutManager::CKeyAssign::TranslateSingleKeyShortcutsMessage(MSG* pMsg)
  833. {
  834. BOOL bPressed = pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN;
  835. BOOL bControlPressed = ::GetKeyState(VK_CONTROL) & 0x8000;
  836. BOOL bAltPressed = ::GetKeyState(VK_MENU) & 0x8000;
  837. BOOL bWinPressed = (::GetKeyState(VK_LWIN) & 0x8000) || (::GetKeyState(VK_RWIN) & 0x8000);
  838. if (!bControlPressed && !bAltPressed && (pMsg->wParam == VK_TAB))
  839. {
  840. if (m_nKeyDefined == 0)
  841. ResetKey();
  842. return FALSE;
  843. }
  844. if (bPressed && !((1 << 30) & pMsg->lParam))
  845. {
  846. ResetKey();
  847. }
  848. if (m_bExtendedOnly)
  849. {
  850. if (bPressed)
  851. {
  852. SetAccelFlag(0, FSHIFT, GetKeyState(VK_SHIFT) < 0);
  853. SetAccelFlag(0, FCONTROL, GetKeyState(VK_CONTROL) < 0);
  854. SetAccelFlag(0, FALT, GetKeyState(VK_MENU) < 0);
  855. SetAccelFlag(0, 0x20, bWinPressed);
  856. }
  857. }
  858. else if (m_nKeyDefined == 0)
  859. {
  860. // read in the actual state because we were not tracking releases if there was a
  861. // definition
  862. SetAccelFlag(0, FSHIFT, ::GetKeyState(VK_SHIFT) & 0x8000);
  863. SetAccelFlag(0, FCONTROL, bControlPressed);
  864. SetAccelFlag(0, FALT, bAltPressed);
  865. SetAccelFlag(0, 0x20, bWinPressed);
  866. if (pMsg->wParam == VK_SHIFT
  867. || pMsg->wParam == VK_CONTROL
  868. || pMsg->wParam == VK_MENU
  869. || pMsg->wParam == VK_LWIN
  870. || pMsg->wParam == VK_RWIN
  871. )
  872. {
  873. // all work is already done
  874. }
  875. else if (bPressed)
  876. {
  877. m_accel.key[0].key = (WORD)pMsg->wParam;
  878. SetAccelFlag(0, FVIRTKEY, TRUE);
  879. m_nKeyDefined = 1;
  880. }
  881. }
  882. if (m_keyHelper.GetShortcutManager() && !m_keyHelper.GetShortcutManager()->OnPreviewEditKey(&m_accel))
  883. {
  884. ResetKey();
  885. return TRUE;
  886. }
  887. CString str;
  888. m_keyHelper.Format (str);
  889. SetWindowText(str);
  890. return TRUE;
  891. }
  892. void CXTPShortcutManager::CKeyAssign::ResetKey()
  893. {
  894. memset(&m_accel, 0, sizeof(CXTPShortcutManagerAccel));
  895. m_nKeyDefined = 0;
  896. if (m_hWnd != NULL)
  897. {
  898. SetWindowText (_T(""));
  899. }
  900. }
  901. void CXTPShortcutManager::CKeyAssign::SetAccelFlag(int nKey, BYTE bFlag, BOOL bSet)
  902. {
  903. ASSERT(nKey == 0 || nKey == 1);
  904. if (bSet) m_accel.key[nKey].fVirt |= bFlag;
  905. else m_accel.key[nKey].fVirt &= ~bFlag;
  906. }
  907. BOOL CXTPShortcutManager::CKeyAssign::IsKeyDefined () const
  908. {
  909. return m_nKeyDefined != 0;
  910. }
  911. CXTPShortcutManagerAccel* CXTPShortcutManager::CKeyAssign::GetAccel()
  912. {
  913. return &m_accel;
  914. }
  915. void CXTPShortcutManager::CKeyAssign::SetAccel(CXTPShortcutManagerAccel* pAccel)
  916. {
  917. m_accel = *pAccel;
  918. m_nKeyDefined = (m_accel.key[0].key != 0 ? 1 : 0) + (m_accel.key[1].key != 0 ? 1 : 0);
  919. if (m_hWnd != NULL)
  920. {
  921. CString str;
  922. m_keyHelper.Format (str);
  923. SetWindowText (str);
  924. }
  925. }
  926. void CXTPShortcutManager::UpdateAcellTable(LPACCEL lpAccel, int nSize)
  927. {
  928. m_pAccelTable->CopyAccelTable(lpAccel, nSize);
  929. }
  930. void CXTPShortcutManager::UpdateAcellTable(CXTPShortcutManagerAccel* lpAccel, int nSize)
  931. {
  932. m_pAccelTable->RemoveAll();
  933. for (int i = 0; i < nSize; i++)
  934. {
  935. m_pAccelTable->Add(lpAccel[i]);
  936. }
  937. }
  938. BOOL CXTPShortcutManager::GetShortcut(int ID, CXTPShortcutManagerAccel* pAccel)
  939. {
  940. CXTPShortcutManagerAccelTable* pAccelTable = GetDefaultAccelerator();
  941. if (!pAccelTable)
  942. return FALSE;
  943. for (int i = 0; i < pAccelTable->GetCount(); i++)
  944. {
  945. CXTPShortcutManagerAccel* accel = pAccelTable->GetAt(i);
  946. if (accel->cmd == ID)
  947. {
  948. *pAccel = *accel;
  949. return TRUE;
  950. }
  951. }
  952. return FALSE;
  953. }
  954. void CXTPShortcutManager::AddShortcut(long cmd, LPCTSTR strKey)
  955. {
  956. CXTPShortcutManagerAccel accel;
  957. if (!ParseShortcut(strKey, &accel))
  958. return;
  959. accel.cmd = cmd;
  960. m_pAccelTable->Add(accel);
  961. }
  962. void CXTPShortcutManager::AddShortcut(long fVirt, long key, long cmd)
  963. {
  964. CXTPShortcutManagerAccel accel;
  965. accel.key[0].fVirt = (BYTE)(fVirt | FVIRTKEY);
  966. accel.key[0].key = (WORD)key;
  967. accel.cmd = cmd;
  968. int nAccelSize = m_pAccelTable->GetCount();
  969. for (int i = 0; i < nAccelSize; i++)
  970. {
  971. CXTPShortcutManagerAccel* accelOld = m_pAccelTable->GetAt(i);
  972. if (CKeyHelper::EqualAccels(&accel, accelOld))
  973. {
  974. accelOld->cmd = cmd;
  975. return;
  976. }
  977. }
  978. m_pAccelTable->Add(accel);
  979. }
  980. void CXTPShortcutManager::SerializeShortcuts(CArchive& ar)
  981. {
  982. CXTPPropExchangeArchive px(ar);
  983. DoPropExchange(&px);
  984. }
  985. void CXTPShortcutManager::SaveShortcuts(LPCTSTR lpszProfileName)
  986. {
  987. if (m_pOriginalAccelTable == NULL)
  988. return;
  989. CXTPShortcutManagerAccel* lpAccel = m_pAccelTable->CopyAccels();
  990. AfxGetApp()->WriteProfileBinary(lpszProfileName,  _T("Accelerators"), (LPBYTE)lpAccel, m_pAccelTable->GetCount() * sizeof(CXTPShortcutManagerAccel));
  991. AfxGetApp()->WriteProfileInt(lpszProfileName, _T("AcceleratorsVersion"), 1);
  992. delete[] lpAccel;
  993. }
  994. void CXTPShortcutManager::LoadShortcuts(LPCTSTR lpszProfileName)
  995. {
  996. if (m_pOriginalAccelTable == NULL)
  997. return;
  998. int nVersion = AfxGetApp()->GetProfileInt(lpszProfileName, _T("AcceleratorsVersion"), 0);
  999. if (nVersion == 0)
  1000. {
  1001. UINT uiSize;
  1002. LPACCEL lpAccel = 0;
  1003. if (AfxGetApp()->GetProfileBinary(lpszProfileName,  _T("Accelerators"), (LPBYTE*) &lpAccel, &uiSize))
  1004. {
  1005. int nAccelSize = uiSize / sizeof(ACCEL);
  1006. ASSERT (lpAccel != NULL);
  1007. UpdateAcellTable(lpAccel, nAccelSize);
  1008. delete[] lpAccel;
  1009. }
  1010. }
  1011. else if (nVersion == 1)
  1012. {
  1013. UINT uiSize;
  1014. CXTPShortcutManagerAccel* lpAccel = 0;
  1015. if (AfxGetApp()->GetProfileBinary(lpszProfileName,  _T("Accelerators"), (LPBYTE*) &lpAccel, &uiSize))
  1016. {
  1017. int nAccelSize = uiSize / sizeof(CXTPShortcutManagerAccel);
  1018. ASSERT (lpAccel != NULL);
  1019. UpdateAcellTable(lpAccel, nAccelSize);
  1020. delete[] lpAccel;
  1021. }
  1022. }
  1023. }
  1024. BOOL CXTPShortcutManager::ParseShortcutVirtKey(CString& strShortcutKey, int nAccel) const
  1025. {
  1026. CString str = m_pKeyNameText->Translate(nAccel) + _T('+');
  1027. int nIndex = strShortcutKey.Find(str);
  1028. if (nIndex != -1)
  1029. {
  1030. strShortcutKey = strShortcutKey.Left(nIndex) + strShortcutKey.Mid(nIndex + str.GetLength());
  1031. return TRUE;
  1032. }
  1033. return FALSE;
  1034. }
  1035. BOOL CXTPShortcutManager::ParseShortcut(CString strShortcutKey, BYTE& fVirt, WORD& key) const
  1036. {
  1037. fVirt = FVIRTKEY;
  1038. key = 0;
  1039. if (ParseShortcutVirtKey(strShortcutKey, VK_CONTROL))
  1040. {
  1041. fVirt |= FCONTROL;
  1042. }
  1043. if (ParseShortcutVirtKey(strShortcutKey, VK_MENU))
  1044. {
  1045. fVirt |= FALT;
  1046. }
  1047. if (ParseShortcutVirtKey(strShortcutKey, VK_SHIFT))
  1048. {
  1049. fVirt |= FSHIFT;
  1050. }
  1051. key = m_pKeyNameText->Parse(strShortcutKey);
  1052. if (key != 0)
  1053. return TRUE;
  1054. if (strShortcutKey.GetLength() > 3 && strShortcutKey[0] == _T('0') && strShortcutKey[1] == _T('x'))
  1055. {
  1056. SCANF_S(strShortcutKey, _T("0x%hx"), &key);
  1057. }
  1058. return key != 0;
  1059. }
  1060. BOOL CXTPShortcutManager::ParseShortcut(CString strShortcut, CXTPShortcutManagerAccel* accel)
  1061. {
  1062. int nIndex = strShortcut.Find(_T(", "));
  1063. if (nIndex == -1)
  1064. {
  1065. if (!ParseShortcut(strShortcut, accel->key[0].fVirt, accel->key[0].key))
  1066. return FALSE;
  1067. accel->key[1].fVirt = 0;
  1068. accel->key[1].key = 0;
  1069. }
  1070. else
  1071. {
  1072. if (!ParseShortcut(strShortcut.Left(nIndex), accel->key[0].fVirt, accel->key[0].key))
  1073. return FALSE;
  1074. if (!ParseShortcut(strShortcut.Mid(nIndex + 2), accel->key[1].fVirt, accel->key[1].key))
  1075. return FALSE;
  1076. }
  1077. return TRUE;
  1078. }
  1079. void CXTPShortcutManager::DoPropExchange(CXTPPropExchange* pPX)
  1080. {
  1081. pPX->ExchangeSchemaSafe();
  1082. if (pPX->IsStoring())
  1083. {
  1084. int nAccelSize = m_pAccelTable->GetCount();
  1085. if (pPX->IsAllowBlobValues())
  1086. {
  1087. CXTPShortcutManagerAccel* lpAccel = m_pAccelTable->CopyAccels();
  1088. pPX->WriteCount(nAccelSize);
  1089. pPX->Write(_T("Data"), lpAccel, nAccelSize * sizeof(CXTPShortcutManagerAccel));
  1090. delete[] lpAccel;
  1091. }
  1092. else
  1093. {
  1094. CXTPPropExchangeEnumeratorPtr pEnumerator(pPX->GetEnumerator(_T("Shortcut")));
  1095. POSITION posEnum = pEnumerator->GetPosition(nAccelSize);
  1096. for (int i = 0; i < nAccelSize; i++)
  1097. {
  1098. CXTPPropExchangeSection secItem(pEnumerator->GetNext(posEnum));
  1099. CXTPShortcutManagerAccel* pAccel = m_pAccelTable->GetAt(i);
  1100. CString strShortcut;
  1101. CKeyHelper keyHelper(pAccel, this);
  1102. keyHelper.m_bAllowLocaleKey = FALSE;
  1103. keyHelper.Format(strShortcut);
  1104. PX_Int(&secItem, _T("Id"), pAccel->cmd, 0);
  1105. PX_String(&secItem, _T("Key"), strShortcut);
  1106. }
  1107. }
  1108. }
  1109. else
  1110. {
  1111. m_pAccelTable->RemoveAll();
  1112. if (pPX->GetSchema() < _XTP_SCHEMA_1200)
  1113. {
  1114. if (pPX->IsAllowBlobValues())
  1115. {
  1116. int nAccelSize = (int)pPX->ReadCount();
  1117. LPACCEL lpAccel = new ACCEL[nAccelSize];
  1118. pPX->Read(_T("Data"), lpAccel, nAccelSize* sizeof(ACCEL));
  1119. UpdateAcellTable(lpAccel, nAccelSize);
  1120. delete[] lpAccel;
  1121. }
  1122. else
  1123. {
  1124. CArray<ACCEL, ACCEL&> accels;
  1125. CXTPPropExchangeEnumeratorPtr pEnumerator(pPX->GetEnumerator(_T("Accel")));
  1126. POSITION posEnum = pEnumerator->GetPosition(0);
  1127. while (posEnum)
  1128. {
  1129. ACCEL accel;
  1130. CXTPPropExchangeSection secItem(pEnumerator->GetNext(posEnum));
  1131. PX_UShort(&secItem, _T("Id"), (USHORT&)(accel.cmd), 0);
  1132. PX_Byte(&secItem, _T("virt"), (accel.fVirt), 0);
  1133. PX_UShort(&secItem, _T("key"), (USHORT&)(accel.key), 0);
  1134. accels.Add(accel);
  1135. }
  1136. UpdateAcellTable(accels.GetData(), (int)accels.GetSize());
  1137. }
  1138. }
  1139. else
  1140. {
  1141. if (pPX->IsAllowBlobValues())
  1142. {
  1143. int nAccelSize = (int)pPX->ReadCount();
  1144. CXTPShortcutManagerAccel* lpAccel = new CXTPShortcutManagerAccel[nAccelSize];
  1145. pPX->Read(_T("Data"), lpAccel, nAccelSize * sizeof(CXTPShortcutManagerAccel));
  1146. UpdateAcellTable(lpAccel, nAccelSize);
  1147. delete[] lpAccel;
  1148. }
  1149. else
  1150. {
  1151. CXTPPropExchangeEnumeratorPtr pEnumerator(pPX->GetEnumerator(_T("Shortcut")));
  1152. POSITION posEnum = pEnumerator->GetPosition(0);
  1153. while (posEnum)
  1154. {
  1155. CXTPShortcutManagerAccel accel;
  1156. CXTPPropExchangeSection secItem(pEnumerator->GetNext(posEnum));
  1157. PX_Int(&secItem, _T("Id"), accel.cmd, 0);
  1158. CString strShortcut;
  1159. // TODO: Add Parse Here
  1160. PX_String(&secItem, _T("Key"), strShortcut, _T(""));
  1161. if (ParseShortcut(strShortcut, &accel))
  1162. {
  1163. m_pAccelTable->Add(accel);
  1164. }
  1165. }
  1166. }
  1167. }
  1168. }
  1169. }
  1170. BOOL CXTPShortcutManager::OnBeforeAdd(CXTPShortcutManagerAccel* accel)
  1171. {
  1172. UNREFERENCED_PARAMETER(accel);
  1173. return FALSE;
  1174. }
  1175. BOOL CXTPShortcutManager::OnBeforeRemove(CXTPShortcutManagerAccel* accel)
  1176. {
  1177. UNREFERENCED_PARAMETER(accel);
  1178. return FALSE;
  1179. }