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

对话框与窗口

开发平台:

Visual C++

  1. // XTPDockingPaneKeyboardHook.cpp : implementation of the CXTPDockingPaneKeyboardHook class.
  2. //
  3. // This file is a part of the XTREME DOCKINGPANE 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 "Common/XTPResourceManager.h"
  22. #include "Common/XTPDrawHelpers.h"
  23. #include "Common/Resource.h"
  24. #include "Resource.h"
  25. #include "TabManager/XTPTabPaintManager.h"
  26. #include "TabManager/XTPTabManager.h"
  27. #include "XTPDockingPaneKeyboardHook.h"
  28. #include "XTPDockingPane.h"
  29. #include "XTPDockingPanePaintManager.h"
  30. #include "XTPDockingPaneManager.h"
  31. #include "XTPDockingPaneMiniWnd.h"
  32. #ifdef _DEBUG
  33. #define new DEBUG_NEW
  34. #undef THIS_FILE
  35. static char THIS_FILE[] = __FILE__;
  36. #endif
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CXTPDockingPaneWindowSelect
  39. IMPLEMENT_DYNCREATE(CXTPDockingPaneWindowSelect, CMiniFrameWnd)
  40. CXTPDockingPaneWindowSelect::CXTPDockingPaneWindowSelect()
  41. {
  42. LOGFONT lfIcon;
  43. VERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIcon), &lfIcon, 0));
  44. lfIcon.lfWeight = FW_NORMAL;
  45. m_fnt.CreateFontIndirect(&lfIcon);
  46. lfIcon.lfWeight = FW_BOLD;
  47. m_fntBold.CreateFontIndirect(&lfIcon);
  48. XTPResourceManager()->LoadString(&m_strActiveTools, XTP_IDS_DOCKINGPANE_SELECTWINDOW_ACTIVETOOLS);
  49. XTPResourceManager()->LoadString(&m_strActiveFiles, XTP_IDS_DOCKINGPANE_SELECTWINDOW_ACTIVEFILES);
  50. m_pSelected = NULL;
  51. m_pManager = NULL;
  52. m_bActivatePanes = FALSE;
  53. m_nPaneCount = 0;
  54. m_nFirstFile = 0;
  55. m_hHandCursor = AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(32649));
  56. if (m_hHandCursor == 0)
  57. m_hHandCursor = XTPResourceManager()->LoadCursor(XTP_IDC_HAND);
  58. m_hArrowCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
  59. }
  60. CXTPDockingPaneWindowSelect::~CXTPDockingPaneWindowSelect()
  61. {
  62. for (int i = 0; i < (int)m_arrItems.GetSize(); i++)
  63. {
  64. delete m_arrItems[i];
  65. }
  66. m_arrItems.RemoveAll();
  67. }
  68. int CXTPDockingPaneWindowSelect::CalcItemHeight(CDC* pDC)
  69. {
  70. CXTPFontDC font(pDC, &m_fnt);
  71. CSize szFont = pDC->GetTextExtent(_T(" "), 1);
  72. CSize szIcon = m_pManager->GetPaintManager()->GetTabPaintManager()->m_szIcon;
  73. return max(szIcon.cy + 4, szFont.cy + 4);
  74. }
  75. CXTPDockingPaneWindowSelect::CItem* CXTPDockingPaneWindowSelect::HitTest(CPoint point) const
  76. {
  77. for (int i = 0; i < (int)m_arrItems.GetSize(); i++)
  78. {
  79. CItem* pItem = m_arrItems[i];
  80. if (pItem->rc.PtInRect(point))
  81. {
  82. return pItem;
  83. }
  84. }
  85. return 0;
  86. }
  87. CString CXTPDockingPaneWindowSelect::GetItemCaption(CItem* pItem) const
  88. {
  89. if (pItem->type == itemPane)
  90. {
  91. return pItem->pPane->GetTitle();
  92. }
  93. else
  94. {
  95. CString strCaption;
  96. CFrameWnd* pChild = DYNAMIC_DOWNCAST(CFrameWnd, CWnd::FromHandle(pItem->hWndFrame));
  97. if (pChild && pChild->GetActiveDocument())
  98. {
  99. strCaption = pChild->GetActiveDocument()->GetTitle();
  100. }
  101. else
  102. {
  103. CXTPDrawHelpers::GetWindowCaption(pItem->hWndFrame, strCaption);
  104. }
  105. return strCaption;
  106. }
  107. }
  108. CString CXTPDockingPaneWindowSelect::GetItemDescription(CItem* pItem) const
  109. {
  110. if (pItem->type == itemPane)
  111. return _T("");
  112. CFrameWnd* pChild = DYNAMIC_DOWNCAST(CFrameWnd, CWnd::FromHandle(pItem->hWndFrame));
  113. if (!pChild)
  114. return _T("");
  115. CDocument* pDocument = pChild->GetActiveDocument();
  116. if (!pDocument)
  117. return _T("");
  118. CString strTypeName;
  119. if (pDocument->GetDocTemplate() != NULL) pDocument->GetDocTemplate()->GetDocString(strTypeName, CDocTemplate::regFileTypeName);
  120. return strTypeName;
  121. }
  122. CString CXTPDockingPaneWindowSelect::GetItemPath(CItem* pItem) const
  123. {
  124. if (pItem->type == itemPane)
  125. return _T("");
  126. CFrameWnd* pChild = DYNAMIC_DOWNCAST(CFrameWnd, CWnd::FromHandle(pItem->hWndFrame));
  127. if (!pChild)
  128. return _T("");
  129. CDocument* pDocument = pChild->GetActiveDocument();
  130. if (!pDocument)
  131. return  _T("");
  132. return pDocument->GetPathName();
  133. }
  134. HWND CXTPDockingPaneWindowSelect::GetMDIClient() const
  135. {
  136. CMDIFrameWnd* pFrame = DYNAMIC_DOWNCAST(CMDIFrameWnd, m_pManager->GetSite());
  137. HWND hWndClient = pFrame ? pFrame->m_hWndMDIClient : NULL;
  138. return hWndClient;
  139. }
  140. BOOL CXTPDockingPaneWindowSelect::Reposition()
  141. {
  142. CClientDC dc(this);
  143. int nItemHeight = CalcItemHeight(&dc);
  144. int nItemWidth = 163;
  145. int y = nItemHeight + 13;
  146. int x = 9;
  147. int nRow = 0;
  148. int nColumn = 0;
  149. m_pSelected = 0;
  150. CXTPDockingPaneInfoList& paneList = m_pManager->GetPaneList();
  151. POSITION pos = paneList.GetHeadPosition();
  152. while (pos)
  153. {
  154. CXTPDockingPane* pPane = paneList.GetNext(pos);
  155. if ((pPane->GetEnabled() & xtpPaneEnableClient) == 0)
  156. continue;
  157. CItem* pItem = new CItem;
  158. pItem->pPane = pPane;
  159. pItem->type = itemPane;
  160. pItem->rc = CRect(x, y, x + nItemWidth, y + nItemHeight);
  161. y += nItemHeight + 1;
  162. pItem->nIndex = (int)m_arrItems.Add(pItem);
  163. pItem->nColumn = nColumn;
  164. pItem->nRow = nRow;
  165. if (m_pManager->GetActivePane() == pPane)
  166. m_pSelected = pItem;
  167. nRow++;
  168. }
  169. m_nPaneCount = nRow;
  170. if (m_bActivatePanes && m_nPaneCount > 0)
  171. {
  172. if (m_pSelected == 0)
  173. {
  174. m_pSelected = m_arrItems[GetKeyState(VK_SHIFT) >= 0 ? 0 : nRow - 1];
  175. }
  176. else
  177. {
  178. if (GetKeyState(VK_SHIFT) >= 0)
  179. {
  180. m_pSelected = m_arrItems[m_pSelected->nIndex >= nRow - 1 ? 0 : m_pSelected->nIndex + 1];
  181. }
  182. else
  183. {
  184. m_pSelected = m_arrItems[m_pSelected->nIndex > 0 ? m_pSelected->nIndex - 1 : nRow - 1];
  185. }
  186. }
  187. }
  188. int nTotalRow = nRow;
  189. if (m_nPaneCount > 0)
  190. {
  191. CColumn col;
  192. col.nFirst = 0;
  193. col.nLast = nRow - 1;
  194. m_arrColumns.Add(col);
  195. }
  196. else
  197. {
  198. m_bActivatePanes = FALSE;
  199. }
  200. m_nFirstFile = (int)m_arrItems.GetSize();
  201. int nFirstColumn = m_nFirstFile;
  202. nRow = 0;
  203. if (m_nPaneCount > 0)
  204. {
  205. nColumn++;
  206. x += nItemWidth + 12;
  207. y = nItemHeight + 13;
  208. }
  209. HWND hWndClient = GetMDIClient();
  210. HWND hWndActive = hWndClient ? (HWND)::SendMessage(hWndClient, WM_MDIGETACTIVE, 0, 0) : 0;
  211. if (hWndActive)
  212. {
  213. HWND hWndFrame = hWndActive;
  214. while (hWndFrame)
  215. {
  216. DWORD dwStyle = GetWindowLong(hWndFrame, GWL_STYLE);
  217. if (((dwStyle & WS_VISIBLE) != 0) && ((dwStyle & WS_DISABLED) == 0))
  218. {
  219. if (nRow > 14)
  220. {
  221. CColumn colNext;
  222. colNext.nFirst = nFirstColumn;
  223. colNext.nLast = (int)m_arrItems.GetSize() - 1;
  224. m_arrColumns.Add(colNext);
  225. nTotalRow = max(nRow, nTotalRow);
  226. nFirstColumn = (int)m_arrItems.GetSize();
  227. nRow = 0;
  228. nColumn++;
  229. y = nItemHeight + 13;
  230. x += nItemWidth + 12;
  231. }
  232. CItem* pItem = new CItem;
  233. pItem->hWndFrame = hWndFrame;
  234. pItem->type = itemMDIFrame;
  235. pItem->rc = CRect(x, y, x + nItemWidth, y + nItemHeight);
  236. y += nItemHeight + 1;
  237. pItem->nIndex = (int)m_arrItems.Add(pItem);
  238. pItem->nColumn = nColumn;
  239. pItem->nRow = nRow;
  240. if (hWndActive == hWndFrame && !m_bActivatePanes)
  241. m_pSelected = pItem;
  242. nRow++;
  243. }
  244. hWndFrame = ::GetWindow(hWndFrame, GW_HWNDNEXT);
  245. }
  246. }
  247. else if (!hWndClient)
  248. {
  249. CItem* pItem = new CItem;
  250. pItem->hWndFrame = m_pManager->GetSite()->GetSafeHwnd();
  251. pItem->type = itemSDIFrame;
  252. pItem->rc = CRect(x, y, x + nItemWidth, y + nItemHeight);
  253. pItem->nIndex = (int)m_arrItems.Add(pItem);
  254. pItem->nColumn = nColumn;
  255. pItem->nRow = nRow;
  256. if (m_pSelected == NULL)
  257. m_pSelected = pItem;
  258. m_nFirstFile++;
  259. }
  260. if (nFirstColumn < m_arrItems.GetSize())
  261. {
  262. CColumn colNext;
  263. colNext.nFirst = nFirstColumn;
  264. colNext.nLast = (int)m_arrItems.GetSize() - 1;
  265. m_arrColumns.Add(colNext);
  266. }
  267. if (m_nFirstFile < m_arrItems.GetSize() - 1 && !m_bActivatePanes)
  268. {
  269. if (GetKeyState(VK_SHIFT) >= 0)
  270. m_pSelected = m_arrItems[m_nFirstFile + 1];
  271. else
  272. m_pSelected = m_arrItems[ m_arrItems.GetSize() - 1];
  273. }
  274. nTotalRow = max(nRow, nTotalRow);
  275. int nTotalColumns = max(2, (int)m_arrColumns.GetSize());
  276. CSize sz(4 + (nItemWidth + 12) * nTotalColumns,
  277. nItemHeight + 13 + nTotalRow * (nItemHeight + 1) + 110);
  278. CXTPWindowRect rcWindow(m_pManager->GetSite());
  279. CPoint ptCenter = rcWindow.CenterPoint();
  280. CRect rect(CPoint(ptCenter.x - sz.cx / 2, ptCenter.y - sz.cy /2), sz);
  281. SetWindowPos(&CWnd::wndTopMost, rect.left, rect.top, rect.Width(), rect.Height(),
  282. SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
  283. return TRUE;
  284. }
  285. BEGIN_MESSAGE_MAP(CXTPDockingPaneWindowSelect, CMiniFrameWnd)
  286. //{{AFX_MSG_MAP(CXTPDockingPaneWindowSelect)
  287. ON_WM_KILLFOCUS()
  288. ON_WM_CAPTURECHANGED()
  289. ON_WM_PAINT()
  290. ON_WM_KEYDOWN()
  291. ON_WM_SYSKEYDOWN()
  292. ON_WM_KEYUP()
  293. ON_WM_LBUTTONDOWN()
  294. ON_WM_LBUTTONUP()
  295. ON_WM_MOUSEMOVE()
  296. ON_WM_CHAR()
  297. //}}AFX_MSG_MAP
  298. END_MESSAGE_MAP()
  299. #define CS_DROPSHADOW       0x00020000
  300. /////////////////////////////////////////////////////////////////////////////
  301. // CXTPDockingPaneWindowSelect message handlers
  302. BOOL CXTPDockingPaneWindowSelect::DoModal()
  303. {
  304. CWnd* pSite = m_pManager->GetSite();
  305. HWND hWndParent = pSite->GetSafeHwnd();
  306. HWND hwndFocus = ::GetFocus();
  307. BOOL bLayoutRTL = m_pManager->IsLayoutRTL();
  308. UINT nClassStyle = bLayoutRTL ? 0 : CS_SAVEBITS | CS_OWNDC;
  309. if (XTPSystemVersion()->IsWinXPOrGreater()) // Windows XP only
  310. {
  311. nClassStyle |= CS_DROPSHADOW;
  312. }
  313. if (!CreateEx(WS_EX_TOOLWINDOW | (bLayoutRTL ? WS_EX_LAYOUTRTL : 0),
  314. AfxRegisterWndClass(nClassStyle, m_hArrowCursor), 0,
  315. WS_POPUP | MFS_SYNCACTIVE, CRect(0, 0, 0, 0), pSite, 0))
  316. return FALSE;
  317. if (!Reposition())
  318. {
  319. DestroyWindow();
  320. return FALSE;
  321. }
  322. SetFocus();
  323. SetCapture();
  324. BOOL bEnableParent = FALSE;
  325. if (hWndParent != NULL && ::IsWindowEnabled(hWndParent))
  326. {
  327. CWnd::ModifyStyle(hWndParent, 0, WS_DISABLED, 0);
  328. bEnableParent = TRUE;
  329. }
  330. m_nFlags |= WF_CONTINUEMODAL;
  331. if (m_nFlags & WF_CONTINUEMODAL)
  332. {
  333. // enter modal loop
  334. DWORD dwFlags = MLF_SHOWONIDLE;
  335. VERIFY(RunModalLoop(dwFlags) == m_nModalResult);
  336. }
  337. // hide the window before enabling the parent, etc.
  338. if (m_hWnd != NULL)
  339. SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW|
  340. SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
  341. if (bEnableParent)
  342. CWnd::ModifyStyle(hWndParent, WS_DISABLED, 0, 0);
  343. if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)
  344. ::SetActiveWindow(hWndParent);
  345. if (m_nModalResult == IDOK && m_pSelected)
  346. {
  347. if (m_pSelected->type == itemPane)
  348. {
  349. m_pManager->ShowPane(m_pSelected->pPane);
  350. }
  351. else if (m_pSelected->type == itemMDIFrame)
  352. {
  353. HWND hWndClient = GetMDIClient();
  354. ::SendMessage(hWndClient, WM_MDIACTIVATE, (WPARAM)m_pSelected->hWndFrame, 0);
  355. CWnd* pWnd = CWnd::FromHandle(m_pSelected->hWndFrame);
  356. CWnd* pFocus = GetFocus();
  357. BOOL bHasFocus = pFocus->GetSafeHwnd() &&
  358. (pFocus == pWnd || pWnd->IsChild(pFocus) || (pFocus->GetOwner()->GetSafeHwnd() && pWnd->IsChild(pFocus->GetOwner())));
  359. if (!bHasFocus)
  360. pWnd->SetFocus();
  361. }
  362. }
  363. else
  364. {
  365. ::SetFocus(hwndFocus);
  366. }
  367. DestroyWindow();
  368. return TRUE;
  369. }
  370. void CXTPDockingPaneWindowSelect::OnKillFocus(CWnd* pNewWnd)
  371. {
  372. CWnd::OnKillFocus(pNewWnd);
  373. if (m_nFlags & WF_CONTINUEMODAL) EndModalLoop(IDCANCEL);
  374. }
  375. void CXTPDockingPaneWindowSelect::OnCaptureChanged(CWnd *pWnd)
  376. {
  377. if (m_nFlags & WF_CONTINUEMODAL) EndModalLoop(IDCANCEL);
  378. CWnd::OnCaptureChanged(pWnd);
  379. }
  380. void CXTPDockingPaneWindowSelect::OnPaint()
  381. {
  382. CPaintDC dcPaint(this); // device context for painting
  383. CXTPClientRect rc(this);
  384. CXTPBufferDC dc(dcPaint);
  385. dc.FillSolidRect(rc, GetSysColor(COLOR_3DFACE));
  386. dc.Draw3dRect(rc, GetXtremeColor(XPCOLOR_HIGHLIGHT_BORDER), GetXtremeColor(XPCOLOR_HIGHLIGHT_BORDER));
  387. int nItemHeight = CalcItemHeight(&dc);
  388. CXTPFontDC font(&dc, &m_fntBold);
  389. dc.SetBkMode(TRANSPARENT);
  390. dc.SetTextColor(COLOR_BTNTEXT);
  391. if (m_nPaneCount > 0)
  392. {
  393. CRect rcActiveTools(9, 0, 9 + 163, nItemHeight + 12);
  394. dc.DrawText(m_strActiveTools, rcActiveTools, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
  395. CRect rcActiveFiles( 9 + 13 + 163, 0, 9 + 13 + 2 * 163, nItemHeight + 12);
  396. dc.DrawText(m_strActiveFiles, rcActiveFiles, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
  397. }
  398. else
  399. {
  400. CRect rcActiveFiles( 9, 0, 9 + 2 * 163, nItemHeight + 12);
  401. dc.DrawText(m_strActiveFiles, rcActiveFiles, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
  402. }
  403. font.SetFont(&m_fnt);
  404. CSize szIcon = m_pManager->GetPaintManager()->GetTabPaintManager()->m_szIcon;
  405. for (int i = 0; i < (int)m_arrItems.GetSize(); i++)
  406. {
  407. CItem* pItem = m_arrItems[i];
  408. if (m_pSelected == pItem)
  409. {
  410. dc.FillSolidRect(pItem->rc, GetXtremeColor(XPCOLOR_HIGHLIGHT));
  411. dc.Draw3dRect(pItem->rc, GetXtremeColor(XPCOLOR_HIGHLIGHT_BORDER), GetXtremeColor(XPCOLOR_HIGHLIGHT_BORDER));
  412. }
  413. if (pItem->type == itemPane)
  414. {
  415. CPoint ptIcon(pItem->rc.left + 2, pItem->rc.CenterPoint().y - szIcon.cy/2);
  416. CXTPImageManagerIcon* pImage = pItem->pPane->GetIcon(szIcon.cx);
  417. if (pImage) pImage->Draw(&dc, ptIcon, szIcon);
  418. }
  419. else
  420. {
  421. CPoint ptIcon(pItem->rc.left + 2, pItem->rc.CenterPoint().y - szIcon.cy/2);
  422. HICON hIcon = (HICON)::SendMessage(pItem->hWndFrame, WM_GETICON, ICON_SMALL, 0);
  423. if (hIcon == NULL) hIcon = (HICON)::SendMessage(pItem->hWndFrame, WM_GETICON, ICON_BIG, 0);
  424. if (hIcon == NULL) hIcon = (HICON)(ULONG_PTR)::GetClassLongPtr(pItem->hWndFrame, GCLP_HICONSM);
  425. if (hIcon)
  426. {
  427. if (GetExStyle() & WS_EX_LAYOUTRTL)
  428. ::DrawIconEx(dc, ptIcon.x + szIcon.cx, ptIcon.y, hIcon, -szIcon.cx, szIcon.cy, 0, 0, DI_NORMAL);
  429. else
  430. ::DrawIconEx(dc, ptIcon.x, ptIcon.y, hIcon, szIcon.cx, szIcon.cy, 0, 0, DI_NORMAL);
  431. }
  432. }
  433. CRect rcText(pItem->rc);
  434. rcText.left += 5 + szIcon.cx;
  435. dc.DrawText(GetItemCaption(pItem), rcText, DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
  436. }
  437. CRect rcInfoPane(11, rc.bottom - 100, rc.right - 11, rc.bottom - 10);
  438. dc.Draw3dRect(rcInfoPane, GetXtremeColor(XPCOLOR_HIGHLIGHT_BORDER), GetXtremeColor(XPCOLOR_HIGHLIGHT_BORDER));
  439. if (!m_pSelected)
  440. return;
  441. rcInfoPane.DeflateRect(15, 13, 15, 13);
  442. font.SetFont(&m_fntBold);
  443. CRect rcCaption(rcInfoPane.left, rcInfoPane.top, rcInfoPane.right, rcInfoPane.top + rcInfoPane.Height() / 3);
  444. dc.DrawText(GetItemCaption(m_pSelected), rcCaption, DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
  445. font.SetFont(&m_fnt);
  446. CRect rcTypeName(rcInfoPane.left, rcCaption.bottom, rcInfoPane.right, rcCaption.bottom + rcInfoPane.Height() / 3);
  447. dc.DrawText(GetItemDescription(m_pSelected), rcTypeName, DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
  448. CRect rcPathName(rcInfoPane.left, rcTypeName.bottom, rcInfoPane.right, rcInfoPane.bottom);
  449. dc.DrawText(GetItemPath(m_pSelected), rcPathName, DT_SINGLELINE | DT_VCENTER | DT_PATH_ELLIPSIS | DT_NOPREFIX);
  450. }
  451. void CXTPDockingPaneWindowSelect::Select(int nItem)
  452. {
  453. Select(nItem >= 0 && nItem < m_arrItems.GetSize() ? m_arrItems[nItem] : NULL);
  454. }
  455. void CXTPDockingPaneWindowSelect::Select(CItem* pItem)
  456. {
  457. if (m_pSelected != pItem)
  458. {
  459. m_pSelected = pItem;
  460. Invalidate(FALSE);
  461. }
  462. }
  463. void CXTPDockingPaneWindowSelect::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  464. {
  465. CMiniFrameWnd::OnChar(nChar, nRepCnt, nFlags);
  466. }
  467. void CXTPDockingPaneWindowSelect::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  468. {
  469. OnKeyDown(nChar, nRepCnt, nFlags);
  470. }
  471. void CXTPDockingPaneWindowSelect::OnKeyDown(UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/)
  472. {
  473. XTPDrawHelpers()->KeyToLayout(this, nChar);
  474. if (nChar == VK_TAB)
  475. {
  476. if (GetKeyState(VK_SHIFT) >= 0)
  477. {
  478. int nSelected = m_pSelected ? m_pSelected->nIndex + 1: 0;
  479. if (nSelected >= m_arrItems.GetSize())
  480. nSelected = m_nFirstFile == m_arrItems.GetSize() ? 0 : m_nFirstFile;
  481. else if (nSelected == m_nFirstFile)
  482. nSelected = 0;
  483. Select(nSelected);
  484. }
  485. else
  486. {
  487. int nSelected = m_pSelected ? m_pSelected->nIndex - 1: (int)m_arrItems.GetSize() - 1;
  488. if (nSelected < 0)
  489. nSelected = m_nFirstFile == 0 ? (int)m_arrItems.GetSize() - 1 : m_nFirstFile - 1;
  490. else if (nSelected == m_nFirstFile - 1)
  491. nSelected = (int)m_arrItems.GetSize() - 1;
  492. Select(nSelected);
  493. }
  494. }
  495. else if (nChar == VK_LEFT)
  496. {
  497. if (m_arrColumns.GetSize() > 1 && m_pSelected)
  498. {
  499. int nColumn = m_pSelected->nColumn;
  500. int nRow = m_pSelected->nRow;
  501. CColumn& col = m_arrColumns[nColumn > 0 ? nColumn - 1 : m_arrColumns.GetSize() - 1];
  502. int nItem = col.nFirst + nRow > col.nLast ? col.nLast : col.nFirst + nRow;
  503. Select(nItem);
  504. }
  505. }
  506. else if (nChar == VK_RIGHT)
  507. {
  508. if (m_arrColumns.GetSize() > 1 && m_pSelected)
  509. {
  510. int nColumn = m_pSelected->nColumn;
  511. int nRow = m_pSelected->nRow;
  512. CColumn& col = m_arrColumns[nColumn < m_arrColumns.GetSize() - 1 ? nColumn + 1 : 0];
  513. int nItem = col.nFirst + nRow > col.nLast ? col.nLast : col.nFirst + nRow;
  514. Select(nItem);
  515. }
  516. }
  517. else if (nChar == VK_DOWN)
  518. {
  519. int nSelected = m_pSelected ? m_pSelected->nIndex + 1 : 0;
  520. Select(nSelected < m_arrItems.GetSize() ? nSelected : 0);
  521. }
  522. else if (nChar == VK_UP)
  523. {
  524. int nSelected = m_pSelected ? m_pSelected->nIndex - 1 : -1;
  525. Select(nSelected >= 0 ? nSelected : (int)m_arrItems.GetSize() - 1);
  526. }
  527. else if (nChar == VK_SHIFT)
  528. {
  529. }
  530. else
  531. {
  532. EndModalLoop(IDOK);
  533. }
  534. }
  535. void CXTPDockingPaneWindowSelect::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
  536. {
  537. if (::GetKeyState(VK_CONTROL) >= 0)
  538. {
  539. EndModalLoop(IDOK);
  540. }
  541. CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
  542. }
  543. void CXTPDockingPaneWindowSelect::OnLButtonDown(UINT nFlags, CPoint point)
  544. {
  545. CXTPClientRect rc(this);
  546. if (!rc.PtInRect(point))
  547. EndModalLoop(IDCANCEL);
  548. CItem* pItem = HitTest(point);
  549. if (pItem)
  550. {
  551. Select(pItem);
  552. }
  553. CWnd::OnLButtonDown(nFlags, point);
  554. }
  555. void CXTPDockingPaneWindowSelect::OnLButtonUp(UINT nFlags, CPoint point)
  556. {
  557. CItem* pItem = HitTest(point);
  558. if (pItem)
  559. {
  560. m_pSelected = pItem;
  561. EndModalLoop(IDOK);
  562. }
  563. CWnd::OnLButtonUp(nFlags, point);
  564. }
  565. void CXTPDockingPaneWindowSelect::OnMouseMove(UINT /*nFlags*/, CPoint point)
  566. {
  567. CItem* pItem = HitTest(point);
  568. ::SetCursor(pItem ? m_hHandCursor : m_hArrowCursor);
  569. }
  570. void CXTPDockingPaneWindowSelect::PostNcDestroy()
  571. {
  572. }
  573. //////////////////////////////////////////////////////////////////////////
  574. // CXTPDockingPaneKeyboardHook
  575. CThreadLocal<CXTPDockingPaneKeyboardHook> CXTPDockingPaneKeyboardHook::_xtpKeyboardThreadState;
  576. CXTPDockingPaneKeyboardHook::CXTPDockingPaneKeyboardHook()
  577. {
  578. m_pWindowSelect = 0;
  579. m_hHookKeyboard = 0;
  580. #ifdef _AFXDLL
  581. m_pModuleState = 0;
  582. #endif
  583. }
  584. CXTPDockingPaneKeyboardHook::~CXTPDockingPaneKeyboardHook()
  585. {
  586. ASSERT(m_mapSites.IsEmpty());
  587. ASSERT(m_hHookKeyboard == 0);
  588. }
  589. CXTPDockingPaneManager* CXTPDockingPaneKeyboardHook::FindFocusedManager()
  590. {
  591. HWND hWnd = GetFocus();
  592. while (hWnd)
  593. {
  594. CXTPDockingPaneManager* pManager = Lookup(hWnd);
  595. if (pManager)
  596. {
  597. if (!pManager->GetSite()->IsWindowEnabled())
  598. return FALSE;
  599. return pManager;
  600. }
  601. LONG dwStyle = ::GetWindowLong(hWnd, GWL_STYLE);
  602. if (dwStyle & WS_CHILD)
  603. {
  604. hWnd = ::GetParent(hWnd);
  605. }
  606. else if (::GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)
  607. {
  608. CXTPDockingPaneMiniWnd* pMinWnd = DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd,
  609. CWnd::FromHandle(hWnd));
  610. if (pMinWnd != NULL)
  611. return pMinWnd->GetDockingPaneManager();
  612. return NULL;
  613. }
  614. else return NULL;
  615. }
  616. return NULL;
  617. }
  618. LRESULT CALLBACK CXTPDockingPaneKeyboardHook::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
  619. {
  620. CXTPDockingPaneKeyboardHook* pKeyboardManager = GetThreadState();
  621. if (code != HC_ACTION)
  622. return CallNextHookEx(pKeyboardManager->m_hHookKeyboard, code, wParam, lParam);
  623. if ((!(HIWORD(lParam) & KF_UP)))
  624. {
  625. if (wParam == VK_TAB && GetKeyState(VK_CONTROL) < 0 && !(HIWORD(lParam) & KF_ALTDOWN))
  626. {
  627. SAFE_MANAGE_STATE(pKeyboardManager->m_pModuleState);
  628. CXTPDockingPaneWindowSelect*& pWindowSelect = pKeyboardManager->m_pWindowSelect;
  629. if (pWindowSelect)
  630. {
  631. pWindowSelect->OnKeyDown(VK_TAB, 0, 0);
  632. return TRUE;
  633. }
  634. CXTPDockingPaneManager* pManager = pKeyboardManager->FindFocusedManager();
  635. if (pManager && (pManager->IsKeyboardNavigateEnabled() & xtpPaneKeyboardUseCtrlTab))
  636. {
  637. pWindowSelect = (CXTPDockingPaneWindowSelect*)pManager->GetKeyboardWindowSelectClass()->CreateObject();
  638. pWindowSelect->m_pManager = pManager;
  639. pWindowSelect->m_bActivatePanes = FALSE;
  640. BOOL bResult = pWindowSelect->DoModal();
  641. delete pWindowSelect;
  642. pWindowSelect = 0;
  643. if (bResult)
  644. return TRUE;
  645. }
  646. }
  647. if ((HIWORD(lParam) & KF_ALTDOWN) && (wParam == VK_F7) && GetKeyState(VK_CONTROL) >= 0)
  648. {
  649. SAFE_MANAGE_STATE(pKeyboardManager->m_pModuleState);
  650. CXTPDockingPaneWindowSelect*& pWindowSelect = pKeyboardManager->m_pWindowSelect;
  651. if (pWindowSelect)
  652. {
  653. pWindowSelect->OnKeyDown(VK_TAB, 0, 0);
  654. return TRUE;
  655. }
  656. CXTPDockingPaneManager* pManager = pKeyboardManager->FindFocusedManager();
  657. if (pManager && (pManager->IsKeyboardNavigateEnabled() & xtpPaneKeyboardUseAltF7))
  658. {
  659. pWindowSelect = (CXTPDockingPaneWindowSelect*)pManager->GetKeyboardWindowSelectClass()->CreateObject();
  660. pWindowSelect->m_pManager = pManager;
  661. pWindowSelect->m_bActivatePanes = TRUE;
  662. BOOL bResult = pWindowSelect->DoModal();
  663. delete pWindowSelect;
  664. pWindowSelect = 0;
  665. if (bResult)
  666. return TRUE;
  667. }
  668. }
  669. if ((HIWORD(lParam) & KF_ALTDOWN) && (wParam == VK_F6) && GetKeyState(VK_CONTROL) >= 0) // Alt + F6
  670. {
  671. SAFE_MANAGE_STATE(pKeyboardManager->m_pModuleState);
  672. CXTPDockingPaneManager* pManager = pKeyboardManager->FindFocusedManager();
  673. if (pManager && (pManager->IsKeyboardNavigateEnabled() & xtpPaneKeyboardUseAltF6))
  674. {
  675. pManager->PostMessage(WM_SYSCOMMAND,
  676. (UINT)(GetKeyState(VK_SHIFT) >= 0 ? SC_NEXTWINDOW : SC_PREVWINDOW), 0);
  677. return TRUE;
  678. }
  679. }
  680. if ((HIWORD(lParam) & KF_ALTDOWN) && ((wParam == 0xBD || wParam == VK_SUBTRACT)) &&
  681. GetKeyState(VK_CONTROL) >= 0 && GetKeyState(VK_SHIFT) >= 0) //  Alt + '-'
  682. {
  683. SAFE_MANAGE_STATE(pKeyboardManager->m_pModuleState);
  684. CXTPDockingPaneManager* pManager = pKeyboardManager->FindFocusedManager();
  685. if (pManager && (pManager->IsKeyboardNavigateEnabled() & xtpPaneKeyboardUseAltMinus))
  686. {
  687. CXTPDockingPane* pPane = pManager->GetActivePane();
  688. if (pPane)
  689. {
  690. if (!pPane->IsClosed() && !pPane->IsHidden())
  691. pManager->PostMessage(WM_SYSCOMMAND, SC_KEYMENU, MAKELONG(TEXT('-'), 0));
  692. return TRUE;
  693. }
  694. }
  695. }
  696. }
  697. return CallNextHookEx(pKeyboardManager->m_hHookKeyboard, code, wParam, lParam);
  698. }
  699. CXTPDockingPaneManager* CXTPDockingPaneKeyboardHook::Lookup(HWND hSite) const
  700. {
  701. CXTPDockingPaneManager* pManager = NULL;
  702. if (m_mapSites.Lookup(hSite, pManager))
  703. return pManager;
  704. return NULL;
  705. }
  706. void CXTPDockingPaneKeyboardHook::SetupKeyboardHook(CXTPDockingPaneManager* pManager, BOOL bSetup)
  707. {
  708. if (!pManager->GetSite())
  709. return;
  710. if (bSetup)
  711. {
  712. if (Lookup(pManager->GetSite()->GetSafeHwnd()))
  713. return;
  714. if (m_hHookKeyboard == 0)
  715. {
  716. m_hHookKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
  717. }
  718. #ifdef _AFXDLL
  719. m_pModuleState = AfxGetModuleState();
  720. #endif
  721. m_mapSites.SetAt(pManager->GetSite()->GetSafeHwnd(), pManager);
  722. }
  723. else
  724. {
  725. if (Lookup(pManager->GetSite()->GetSafeHwnd()))
  726. {
  727. m_mapSites.RemoveKey(pManager->GetSite()->GetSafeHwnd());
  728. }
  729. if (m_hHookKeyboard && m_mapSites.IsEmpty())
  730. {
  731. UnhookWindowsHookEx(m_hHookKeyboard);
  732. m_hHookKeyboard = 0;
  733. }
  734. }
  735. }