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

对话框与窗口

开发平台:

Visual C++

  1. // XTPOffice2007FrameHook.cpp : implementation file
  2. //
  3. // This file is a part of the XTREME RIBBON 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 "XTPCommandBars.h"
  22. #include "XTPControlButton.h"
  23. #include "XTPOffice2007Theme.h"
  24. #include "XTPOffice2007FrameHook.h"
  25. #ifdef _XTP_INCLUDE_RIBBON
  26. #include "Ribbon/XTPRibbonBar.h"
  27. #endif
  28. #define XTP_TID_MOUSELEAVE  0xACB1
  29. #define XTP_TID_REFRESHFRAME 0xACD1
  30. #ifndef WM_NCMOUSELEAVE
  31. #define WM_NCMOUSELEAVE     0x02A2
  32. #endif
  33. #ifdef _DEBUG
  34. #define new DEBUG_NEW
  35. #undef THIS_FILE
  36. static char THIS_FILE[] = __FILE__;
  37. #endif
  38. class CXTPOffice2007FrameHook::CControlCaptionButton : public CXTPControl
  39. {
  40. public:
  41. CControlCaptionButton(CXTPOffice2007FrameHook* pFrame)
  42. {
  43. m_pFrame = pFrame;
  44. }
  45. public:
  46. virtual int GetSelected() const
  47. {
  48. return m_pFrame->m_pSelected == (CXTPControl*)this;
  49. }
  50. virtual BOOL GetPressed() const
  51. {
  52. return m_pFrame->m_pSelected == (CXTPControl*)this && m_pFrame->m_bButtonPressed;
  53. }
  54. protected:
  55. CXTPOffice2007FrameHook* m_pFrame;
  56. };
  57. void CXTPOffice2007FrameHook::AddCaptionButton(int nId, int nHit)
  58. {
  59. CXTPControl* pButton = new CControlCaptionButton(this);
  60. pButton->SetID(nId);
  61. pButton->SetHelpId(nHit);
  62. m_pCaptionButtons->Add(pButton);
  63. }
  64. class CXTPOffice2007FrameHook::CWinEventHook
  65. {
  66. DECLARE_HANDLE(HWINEVENTHOOK);
  67. public:
  68. CWinEventHook();
  69. ~CWinEventHook();
  70. public:
  71. void SetEventHook();
  72. void RemoveEventHook();
  73. protected:
  74. typedef void (CALLBACK* WINEVENTPROC) ( HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD idEventThread, DWORD dwmsEventTime);
  75. typedef HWINEVENTHOOK (WINAPI* LPFNSETWINEVENTHOOK)(UINT eventMin, UINT eventMax, HMODULE hmodWinEventProc,
  76. WINEVENTPROC lpfnWinEventProc, DWORD idProcess, DWORD idThread, UINT dwflags);
  77. typedef BOOL (WINAPI* LPFNUNHOOKWINEVENT)(HWINEVENTHOOK hWinEventHook);
  78. static void CALLBACK WinEventProc(HWINEVENTHOOK /*hWinEventHook*/,
  79. DWORD event, HWND hWnd, LONG idObject, LONG /*idChild*/, DWORD /*dwEventThread*/, DWORD /*dwmsEventTime*/);
  80. protected:
  81. HWINEVENTHOOK m_hWinEventHook;      // HWINEVENTHOOK value that identifies event hook instance
  82. LPFNSETWINEVENTHOOK m_pSetWinEventHook;
  83. LPFNUNHOOKWINEVENT m_pUnhookWinEvent;
  84. public:
  85. int m_nCount;
  86. };
  87. UINT CXTPOffice2007FrameHook::m_nMsgQueryFrameHook = 0;
  88. CXTPOffice2007FrameHook::CWinEventHook::CWinEventHook()
  89. {
  90. m_pSetWinEventHook = NULL;
  91. m_pUnhookWinEvent = NULL;
  92. m_hWinEventHook = NULL;
  93. m_nCount = 0;
  94. }
  95. CXTPOffice2007FrameHook::CWinEventHook::~CWinEventHook()
  96. {
  97. }
  98. #define EVENT_OBJECT_REORDER 0x8004
  99. void CXTPOffice2007FrameHook::CWinEventHook::SetEventHook()
  100. {
  101. if (m_nCount > 0)
  102. {
  103. m_nCount++;
  104. return;
  105. }
  106. HMODULE hLib = GetModuleHandle(_T("USER32"));
  107. if (hLib)
  108. {
  109. m_pSetWinEventHook = (LPFNSETWINEVENTHOOK)GetProcAddress(hLib, "SetWinEventHook");
  110. m_pUnhookWinEvent = (LPFNUNHOOKWINEVENT)GetProcAddress(hLib, "UnhookWinEvent");
  111. if (m_pSetWinEventHook && m_pUnhookWinEvent)
  112. {
  113. m_hWinEventHook = m_pSetWinEventHook(EVENT_OBJECT_REORDER, EVENT_OBJECT_REORDER, NULL,
  114. &CXTPOffice2007FrameHook::CWinEventHook::WinEventProc, GetCurrentProcessId(), 0, 0);
  115. }
  116. }
  117. m_nCount++;
  118. }
  119. void CXTPOffice2007FrameHook::CWinEventHook::RemoveEventHook()
  120. {
  121. m_nCount--;
  122. if (m_nCount > 0)
  123. return;
  124. HMODULE hLib = GetModuleHandle(_T("USER32"));
  125. if (m_hWinEventHook && hLib && m_pUnhookWinEvent)
  126. {
  127. m_pUnhookWinEvent(m_hWinEventHook);
  128. }
  129. m_hWinEventHook = NULL;
  130. }
  131. void CALLBACK CXTPOffice2007FrameHook::CWinEventHook::WinEventProc(HWINEVENTHOOK /*hWinEventHook*/,
  132. DWORD event, HWND hWnd, LONG idObject, LONG /*idChild*/, DWORD /*dwEventThread*/, DWORD /*dwmsEventTime*/)
  133. {
  134. if (event == EVENT_OBJECT_REORDER && idObject == OBJID_WINDOW)
  135. {
  136. if (!XTPHookManager()->Lookup(hWnd))
  137. return;
  138. CXTPOffice2007FrameHook* pFrame = (CXTPOffice2007FrameHook*)::SendMessage(hWnd, CXTPOffice2007FrameHook::m_nMsgQueryFrameHook, 0, 0);
  139. if (pFrame && !pFrame->IsDwmEnabled())
  140. {
  141. DWORD dwStyle = pFrame->GetSiteStyle();
  142. DWORD dwStyleRemove = (WS_CAPTION | WS_VSCROLL | WS_HSCROLL);
  143. if (dwStyle & dwStyleRemove)
  144. {
  145. pFrame->GetSite()->SetTimer(XTP_TID_REFRESHFRAME, 100, NULL);
  146. }
  147. }
  148. }
  149. }
  150. CXTPOffice2007FrameHook::CXTPOffice2007FrameHook()
  151. {
  152. m_pCommandBars = NULL;
  153. m_pRibbonBar = NULL;
  154. m_pPaintManager = NULL;
  155. m_bActive = TRUE;
  156. m_szFrameRegion = CSize(0, 0);
  157. m_hwndSite = NULL;
  158. m_pSelected = NULL;
  159. m_bDelayReclalcLayout = FALSE;
  160. m_bButtonPressed = FALSE;
  161. m_bOffice2007FrameEnabled = FALSE;
  162. m_nSkipNCPaint = 0;
  163. m_nFrameBorder = 0;
  164. m_bInUpdateFrame = FALSE;
  165. m_bLockNCPaint = FALSE;
  166. m_nMsgUpdateSkinState = RegisterWindowMessage(_T("WM_SKINFRAMEWORK_UPDATESTATE"));
  167. m_nMsgQuerySkinState = RegisterWindowMessage(_T("WM_SKINFRAMEWORK_QUERYSTATE"));
  168. if (m_nMsgQueryFrameHook == 0) m_nMsgQueryFrameHook = RegisterWindowMessage(_T("WM_GETFRAMEHOOK"));
  169. m_bDwmEnabled = FALSE;
  170. m_pCaptionButtons = new CXTPControls();
  171. AddCaptionButton(SC_CLOSE, HTCLOSE);
  172. AddCaptionButton(SC_MAXIMIZE, HTMAXBUTTON);
  173. AddCaptionButton(SC_RESTORE, HTMAXBUTTON);
  174. AddCaptionButton(SC_MINIMIZE, HTMINBUTTON);
  175. }
  176. void CXTPOffice2007FrameHook::EnableOffice2007Frame(CWnd* pSite, CXTPPaintManager* pPaintManager)
  177. {
  178. ASSERT(pSite);
  179. ASSERT(pPaintManager);
  180. if (!pSite || !pPaintManager)
  181. return;
  182. m_pCommandBars = NULL;
  183. m_pRibbonBar = NULL;
  184. m_pPaintManager = pPaintManager;
  185. m_hwndSite = pSite->GetSafeHwnd();
  186. m_bActive = TRUE;
  187. m_szFrameRegion = CSize(0, 0);
  188. m_pSelected = NULL;
  189. m_bDelayReclalcLayout = FALSE;
  190. m_bButtonPressed = FALSE;
  191. m_bOffice2007FrameEnabled = TRUE;
  192. m_bDwmEnabled = pSite->GetStyle() & WS_CHILD ? FALSE : CXTPWinDwmWrapper().IsCompositionEnabled();
  193. XTPHookManager()->SetHook(m_hwndSite, this);
  194. SendMessage(m_hwndSite, m_nMsgUpdateSkinState, 0, 0);
  195. if (!m_bDwmEnabled)
  196. {
  197. RefreshFrameStyle();
  198. }
  199. ::SetWindowPos(m_hwndSite, 0, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
  200. SetWinHook();
  201. }
  202. CXTPOffice2007FrameHook::~CXTPOffice2007FrameHook()
  203. {
  204. CMDTARGET_RELEASE(m_pCaptionButtons);
  205. if (m_bOffice2007FrameEnabled)
  206. {
  207. EnableOffice2007Frame(NULL);
  208. }
  209. }
  210. DWORD CXTPOffice2007FrameHook::GetSiteStyle(BOOL bExStyle) const
  211. {
  212. return m_hwndSite ? (DWORD)GetWindowLong(m_hwndSite, bExStyle ? GWL_EXSTYLE : GWL_STYLE) : 0;
  213. }
  214. void CXTPOffice2007FrameHook::EnableOffice2007Frame(CXTPCommandBars* pCommandBars)
  215. {
  216. BOOL bEnabled = pCommandBars != NULL;
  217. if (m_bOffice2007FrameEnabled == bEnabled)
  218. return;
  219. m_pCommandBars = pCommandBars;
  220. m_pRibbonBar = NULL;
  221. m_pPaintManager = NULL;
  222. if (pCommandBars)
  223. {
  224. #ifdef _XTP_INCLUDE_RIBBON
  225. m_pRibbonBar = DYNAMIC_DOWNCAST(CXTPRibbonBar, pCommandBars->GetMenuBar());
  226. #endif
  227. m_hwndSite = pCommandBars->GetSite()->GetSafeHwnd();
  228. }
  229. m_bActive = TRUE;
  230. m_szFrameRegion = CSize(0, 0);
  231. m_pSelected = NULL;
  232. m_bDelayReclalcLayout = FALSE;
  233. m_bButtonPressed = FALSE;
  234. m_bOffice2007FrameEnabled = bEnabled;
  235. if (pCommandBars)
  236. {
  237. XTPHookManager()->SetHook(m_hwndSite, this);
  238. SendMessage(m_hwndSite, m_nMsgUpdateSkinState, 0, 0);
  239. m_bDwmEnabled = GetSiteStyle() & WS_CHILD ? FALSE : CXTPWinDwmWrapper().IsCompositionEnabled();
  240. if (!m_bDwmEnabled)
  241. {
  242. RefreshFrameStyle();
  243. }
  244. else
  245. {
  246. SetWindowRgn(m_hwndSite, NULL, TRUE);
  247. }
  248. UpdateFrameRegion();
  249. ::SetWindowPos(m_hwndSite, 0, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
  250. }
  251. else
  252. {
  253. XTPHookManager()->RemoveAll(this);
  254. if (m_hwndSite)
  255. {
  256. if (m_bDwmEnabled)
  257. {
  258. CXTPWinDwmWrapper().ExtendFrameIntoClientArea(m_hwndSite, 0, 0, 0, 0);
  259. }
  260. SendMessage(m_hwndSite, m_nMsgUpdateSkinState, 0, 0);
  261. SetWindowRgn(m_hwndSite, (HRGN)NULL, TRUE);
  262. ::SetWindowPos(m_hwndSite, 0, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
  263. }
  264. m_hwndSite = NULL;
  265. m_bDwmEnabled = FALSE;
  266. }
  267. SetWinHook();
  268. }
  269. void CXTPOffice2007FrameHook::SetWinHook()
  270. {
  271. static CWinEventHook hook;
  272. if (m_hwndSite)
  273. {
  274. hook.SetEventHook();
  275. }
  276. else
  277. {
  278. hook.RemoveEventHook();
  279. }
  280. };
  281. CXTPOffice2007Theme* CXTPOffice2007FrameHook::GetPaintManager() const
  282. {
  283. return m_pCommandBars ? (CXTPOffice2007Theme*)m_pCommandBars->GetPaintManager() : (CXTPOffice2007Theme*)m_pPaintManager;
  284. }
  285. void CXTPOffice2007FrameHook::UpdateFrameRegion()
  286. {
  287. if (!IsWindow(m_hwndSite))
  288. return;
  289. CXTPWindowRect rc(m_hwndSite);
  290. UpdateFrameRegion(rc.Size(), TRUE);
  291. }
  292. void CXTPOffice2007FrameHook::UpdateFrameRegion(CSize szFrameRegion, BOOL bUpdate)
  293. {
  294. if (m_bInUpdateFrame)
  295. return;
  296. m_bInUpdateFrame = TRUE;
  297. if (m_szFrameRegion != szFrameRegion || bUpdate)
  298. {
  299. CRect rc(0, 0, szFrameRegion.cx, szFrameRegion.cy);
  300. AdjustWindowRectEx(rc, GetSiteStyle(FALSE), FALSE, GetSiteStyle(TRUE));
  301. m_nFrameBorder = -rc.left;
  302. if (!m_bDwmEnabled)
  303. {
  304. HRGN hRgn = 0;
  305. if (!IsMDIMaximized())
  306. {
  307. if (GetSiteStyle() & WS_MAXIMIZE)
  308. {
  309. int nFrameRegion = m_nFrameBorder - (GetSiteStyle(TRUE) & WS_EX_CLIENTEDGE ? 2 : 0);
  310. hRgn = CreateRectRgn(nFrameRegion, nFrameRegion, szFrameRegion.cx - nFrameRegion, szFrameRegion.cy - nFrameRegion);
  311. }
  312. else
  313. hRgn = GetPaintManager()->CalcRibbonFrameRegion(this, szFrameRegion);
  314. }
  315. ::SetWindowRgn(m_hwndSite, hRgn, TRUE);
  316. }
  317. else
  318. {
  319. if (!(GetSiteStyle() & WS_MAXIMIZE))
  320. {
  321. m_nFrameBorder = 4;
  322. }
  323. int cyTopHeight = IsCaptionVisible() ? 0 : GetCaptionHeight();
  324. CXTPWinDwmWrapper().ExtendFrameIntoClientArea(m_hwndSite, 0, cyTopHeight, 0, 0);
  325. }
  326. m_szFrameRegion = szFrameRegion;
  327. }
  328. m_bInUpdateFrame = FALSE;
  329. }
  330. BOOL CXTPOffice2007FrameHook::IsMDIMaximized() const
  331. {
  332. if ((GetSiteStyle() & WS_MAXIMIZE) && (GetSiteStyle(TRUE) & WS_EX_MDICHILD))
  333. return TRUE;
  334. return FALSE;
  335. }
  336. BOOL CXTPOffice2007FrameHook::IsCaptionVisible() const
  337. {
  338. if (!m_pRibbonBar)
  339. return TRUE;
  340. #ifdef _XTP_INCLUDE_RIBBON
  341. if (!(m_pRibbonBar->IsRibbonBarVisible() && m_pRibbonBar->GetPosition() == xtpBarTop))
  342. return TRUE;
  343. #endif
  344. if ((GetSiteStyle() & (WS_CHILD | WS_MINIMIZE)) == (WS_CHILD | WS_MINIMIZE))
  345. return TRUE;
  346. return FALSE;
  347. }
  348. BOOL CXTPOffice2007FrameHook::IsFrameHasStatusBar(int* pnStatusHeight /*= NULL*/) const
  349. {
  350. if (!GetPaintManager()->m_bFrameStatusBar)
  351. return FALSE;
  352. CWnd* pStatusBar = CWnd::FromHandle(::GetDlgItem(m_hwndSite, AFX_IDW_STATUS_BAR));
  353. if (!pStatusBar)
  354. return FALSE;
  355. if ((GetWindowLong(pStatusBar->m_hWnd, GWL_STYLE) & WS_VISIBLE) == 0)
  356. return FALSE;
  357. if (!GetPaintManager()->m_bThemedStatusBar)
  358. return FALSE;
  359. if (pnStatusHeight)
  360. {
  361. *pnStatusHeight = CXTPWindowRect(pStatusBar).Height();
  362. }
  363. return TRUE;
  364. }
  365. void CXTPOffice2007FrameHook::RedrawFrame()
  366. {
  367. if (!m_bDwmEnabled)
  368. {
  369. CWindowDC dc(GetSite());
  370. GetPaintManager()->DrawRibbonFrame(&dc, this);
  371. }
  372. }
  373. void CXTPOffice2007FrameHook::RedrawRibbonBar()
  374. {
  375. #ifdef _XTP_INCLUDE_RIBBON
  376. if (m_pRibbonBar)
  377. {
  378. m_pRibbonBar->Redraw();
  379. m_pRibbonBar->UpdateWindow();
  380. }
  381. #endif
  382. }
  383. void CXTPOffice2007FrameHook::DelayRecalcFrameLayout()
  384. {
  385. m_bDelayReclalcLayout = TRUE;
  386. ::PostMessage(m_hwndSite, WM_IDLEUPDATECMDUI, 0, 0);
  387. }
  388. void CXTPOffice2007FrameHook::RecalcFrameLayout()
  389. {
  390. m_bDelayReclalcLayout = FALSE;
  391. m_szFrameRegion = CSize(0);
  392. ::SetWindowPos(m_hwndSite, 0, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
  393. CWnd* pSite = GetSite();
  394. CFrameWnd* pFrame = pSite->IsFrameWnd() ? (CFrameWnd*)pSite : NULL;
  395. if (pFrame)
  396. {
  397. pFrame->RecalcLayout(FALSE);
  398. }
  399. else
  400. {
  401. CXTPClientRect rc(pSite);
  402. pSite->SendMessage(WM_SIZE, 0, MAKELPARAM(rc.Width(), rc.Height()));
  403. }
  404. #ifdef _XTP_INCLUDE_RIBBON
  405. if (m_pRibbonBar)
  406. {
  407. m_pRibbonBar->Redraw();
  408. }
  409. #endif
  410. }
  411. AFX_INLINE void SetVisibleAndEnabled(CXTPControl* pControl, BOOL bVisible, BOOL bEnabled)
  412. {
  413. pControl->SetHideFlag(xtpHideGeneric, !bVisible);
  414. pControl->SetEnabled(bEnabled);
  415. }
  416. void CXTPOffice2007FrameHook::RepositionCaptionButtons()
  417. {
  418. CXTPWindowRect rc(m_hwndSite);
  419. rc.OffsetRect(-rc.TopLeft());
  420. DWORD dwStyle = GetSiteStyle(FALSE);
  421. DWORD dwExStyle = GetSiteStyle(TRUE);
  422. BOOL bToolWindow = (dwExStyle & WS_EX_TOOLWINDOW) == WS_EX_TOOLWINDOW;
  423. BOOL bMinimized = dwStyle & WS_MINIMIZE;
  424. BOOL bEnableClose = TRUE;
  425. BOOL bMaximized = (dwStyle & WS_MAXIMIZE) == WS_MAXIMIZE;
  426. BOOL bSysMenu = (dwStyle & WS_SYSMENU);
  427. BOOL bEnabledMaximize = ((dwStyle & WS_MAXIMIZEBOX) == WS_MAXIMIZEBOX);
  428. BOOL bEnabledMinimize = ((dwStyle & WS_MINIMIZEBOX) == WS_MINIMIZEBOX);
  429. BOOL bShowMinMaxButtons = !bToolWindow && bSysMenu && (bEnabledMaximize || bEnabledMinimize);
  430. if (bSysMenu && !bToolWindow)
  431. {
  432. CMenu* pMenu = CMenu::FromHandle(::GetSystemMenu(m_hwndSite, FALSE));
  433. if (pMenu && pMenu->GetMenuState(SC_CLOSE, MF_BYCOMMAND) & (MF_DISABLED | MF_GRAYED)) bEnableClose = FALSE;
  434. }
  435. CRect rcCaption(rc.left, rc.top + m_nFrameBorder, rc.right - 4, rc.top + GetCaptionHeight() - 3);
  436. for (int i = 0; i < m_pCaptionButtons->GetCount(); i++)
  437. {
  438. CXTPControl* pControl = m_pCaptionButtons->GetAt(i);
  439. if (pControl->GetID() == SC_CLOSE)
  440. {
  441. SetVisibleAndEnabled(pControl, bSysMenu, bEnableClose);
  442. }
  443. if (pControl->GetID() == SC_MAXIMIZE)
  444. {
  445. SetVisibleAndEnabled(pControl, !bMaximized && bShowMinMaxButtons, bEnabledMaximize);
  446. }
  447. if (pControl->GetID() == SC_RESTORE)
  448. {
  449. pControl->SetHelpId(bMinimized? HTMINBUTTON : HTMAXBUTTON);
  450. if (bMinimized)
  451. SetVisibleAndEnabled(pControl, bShowMinMaxButtons, bEnabledMinimize);
  452. else
  453. SetVisibleAndEnabled(pControl, bMaximized && bShowMinMaxButtons, bEnabledMaximize);
  454. }
  455. if (pControl->GetID() == SC_MINIMIZE)
  456. {
  457. SetVisibleAndEnabled(pControl, !bMinimized && bShowMinMaxButtons, bEnabledMinimize);
  458. }
  459. if (!pControl->IsVisible())
  460. continue;
  461. CRect rcButton(rcCaption.right - rcCaption.Height(), rcCaption.top, rcCaption.right, rcCaption.bottom);
  462. pControl->SetRect(rcButton);
  463. rcCaption.right -= rcButton.Width();
  464. }
  465. }
  466. void CXTPOffice2007FrameHook::ScreenToFrame(LPPOINT lpPoint)
  467. {
  468. CXTPDrawHelpers::ScreenToWindow(GetSite(), lpPoint);
  469. }
  470. void CXTPOffice2007FrameHook::TrackCaptionButton(CXTPControl* pSelected)
  471. {
  472. CWnd* pSite = GetSite();
  473. if (!pSite)
  474. return;
  475. pSite->SetCapture();
  476. BOOL bAccept = FALSE;
  477. m_bButtonPressed = TRUE;
  478. ASSERT(pSelected);
  479. if (!pSelected)
  480. return;
  481. RedrawFrame();
  482. while (::GetCapture() == m_hwndSite)
  483. {
  484. MSG msg;
  485. if (!::GetMessage(&msg, NULL, 0, 0))
  486. {
  487. AfxPostQuitMessage((int)msg.wParam);
  488. break;
  489. }
  490. if (msg.message == WM_LBUTTONUP)
  491. {
  492. bAccept = m_bButtonPressed;
  493. break;
  494. }
  495. else if (msg.message == WM_MOUSEMOVE)
  496. {
  497. POINT point = msg.pt;
  498. ScreenToFrame(&point);
  499. BOOL bButtonPressed = pSelected->GetRect().PtInRect(point);
  500. if (bButtonPressed != m_bButtonPressed)
  501. {
  502. m_bButtonPressed = bButtonPressed;
  503. RedrawFrame();
  504. }
  505. }
  506. else
  507. {
  508. TranslateMessage(&msg);
  509. DispatchMessage(&msg);
  510. }
  511. }
  512. m_bButtonPressed = NULL;
  513. m_pSelected = NULL;
  514. ReleaseCapture();
  515. RedrawFrame();
  516. if (bAccept)
  517. {
  518. pSite->SendMessage(WM_SYSCOMMAND, pSelected->GetID());
  519. }
  520. }
  521. int CXTPOffice2007FrameHook::GetCaptionHeight() const
  522. {
  523. #ifdef _XTP_INCLUDE_RIBBON
  524. if (IsCaptionVisible() || !m_pRibbonBar)
  525. return GetPaintManager()->GetFrameCaptionHeight() + m_nFrameBorder;
  526. return m_pRibbonBar->GetCaptionHeight() + m_nFrameBorder;
  527. #else
  528. return GetPaintManager()->GetFrameCaptionHeight() + m_nFrameBorder;
  529. #endif
  530. }
  531. #ifndef WM_DWMCOMPOSITIONCHANGED
  532. #define WM_DWMCOMPOSITIONCHANGED  0x031E
  533. #endif
  534. CXTPControl* CXTPOffice2007FrameHook::HitTestCaptionButton(CPoint point)
  535. {
  536. CXTPControl* pCaptionButton = m_pCaptionButtons->HitTest(point);
  537. if (pCaptionButton && !pCaptionButton->GetEnabled()) pCaptionButton = NULL;
  538. return pCaptionButton;
  539. }
  540. void CXTPOffice2007FrameHook::RefreshFrameStyle()
  541. {
  542. if (m_bDwmEnabled)
  543. return;
  544. DWORD dwStyle = GetSiteStyle();
  545. DWORD dwStyleRemove = (WS_DLGFRAME | WS_VSCROLL | WS_HSCROLL);
  546. if (dwStyle & dwStyleRemove)
  547. {
  548. m_bLockNCPaint++;
  549. SetWindowLong(m_hwndSite, GWL_STYLE, dwStyle & ~dwStyleRemove);
  550. RECT rc = CXTPWindowRect(m_hwndSite);
  551. ::SendMessage(m_hwndSite, WM_NCCALCSIZE, FALSE, (LPARAM)&rc);
  552. SetWindowLong(m_hwndSite, GWL_STYLE, dwStyle);
  553. m_bLockNCPaint--;
  554. RedrawFrame();
  555. }
  556. }
  557. BOOL CXTPOffice2007FrameHook::GetAutoHideBar() const
  558. {
  559. APPBARDATA abd;
  560. ZeroMemory(&abd, sizeof(APPBARDATA));
  561. abd.cbSize = sizeof(APPBARDATA);
  562. abd.uEdge = ABE_BOTTOM;
  563. if (SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd))
  564. return TRUE;
  565. abd.uEdge = ABE_TOP;
  566. if (SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd))
  567. return TRUE;
  568. abd.uEdge = ABE_LEFT;
  569. if (SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd))
  570. return TRUE;
  571. abd.uEdge = ABE_RIGHT;
  572. if (SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd))
  573. return TRUE;
  574. return FALSE;
  575. }
  576. int CXTPOffice2007FrameHook::OnHookMessage(HWND /*hWnd*/, UINT nMessage, WPARAM& wParam, LPARAM& lParam, LRESULT& lResult)
  577. {
  578. if (!m_bOffice2007FrameEnabled)
  579. {
  580. return FALSE;
  581. }
  582. if (!m_bDwmEnabled && m_bLockNCPaint && (nMessage == WM_STYLECHANGING || nMessage == WM_STYLECHANGED
  583. || nMessage == WM_WINDOWPOSCHANGED || nMessage == WM_WINDOWPOSCHANGING || nMessage == WM_NCPAINT))
  584. {
  585. if (nMessage == WM_WINDOWPOSCHANGING)
  586. ((WINDOWPOS*)lParam)->flags &= ~SWP_FRAMECHANGED;
  587. return TRUE;
  588. }
  589. if (nMessage == WM_WINDOWPOSCHANGING)
  590. {
  591. WINDOWPOS* lpwndpos = (WINDOWPOS*)lParam;
  592. CSize szFrameRegion(lpwndpos->cx, lpwndpos->cy);
  593. if (((lpwndpos->flags & SWP_NOSIZE) ==  0) && (m_szFrameRegion != szFrameRegion) &&
  594. ((GetSiteStyle() & WS_CHILD) == 0))
  595. {
  596. m_nSkipNCPaint = 1;
  597. }
  598. return FALSE;
  599. }
  600. if (nMessage == CXTPOffice2007FrameHook::m_nMsgQueryFrameHook)
  601. {
  602. lResult = (LRESULT)this;
  603. return TRUE;
  604. }
  605. if (nMessage == WM_WINDOWPOSCHANGED)
  606. {
  607. WINDOWPOS* lpwndpos = (WINDOWPOS*)lParam;
  608. if (lpwndpos->flags & SWP_FRAMECHANGED && !m_bInUpdateFrame)
  609. {
  610. UpdateFrameRegion();
  611. }
  612. return FALSE;
  613. }
  614. if (nMessage == WM_SIZE || nMessage == WM_STYLECHANGED)
  615. {
  616. CXTPWindowRect rc(m_hwndSite);
  617. CSize szFrameRegion(rc.Width(), rc.Height());
  618. if ((m_szFrameRegion != szFrameRegion) || (nMessage == WM_STYLECHANGED))
  619. {
  620. UpdateFrameRegion(szFrameRegion, (nMessage == WM_STYLECHANGED));
  621. RepositionCaptionButtons();
  622. RedrawFrame();
  623. }
  624. return FALSE;
  625. }
  626. if (nMessage == WM_NCRBUTTONUP && IsCaptionVisible()&& !m_bDwmEnabled)
  627. {
  628. if (m_pSelected)
  629. {
  630. m_pSelected = NULL;
  631. RedrawFrame();
  632. }
  633. CPoint point((DWORD)lParam);
  634. ::SendMessage(m_hwndSite, 0x0313, (WPARAM)m_hwndSite, MAKELPARAM(point.x, point.y));
  635. return TRUE;
  636. }
  637. if (nMessage == WM_NCLBUTTONDOWN && IsCaptionVisible() && !m_bDwmEnabled)
  638. {
  639. CPoint point((DWORD)lParam);
  640. ScreenToFrame(&point);
  641. CXTPControl* pCaptionButton = HitTestCaptionButton(point);
  642. if (pCaptionButton)
  643. {
  644. TrackCaptionButton(pCaptionButton);
  645. return TRUE;
  646. }
  647. }
  648. if (nMessage == WM_NCMOUSEMOVE && IsCaptionVisible() && !m_bDwmEnabled)
  649. {
  650. CPoint point((DWORD)lParam);
  651. ScreenToFrame(&point);
  652. CXTPControl* pCaptionButton = HitTestCaptionButton(point);
  653. if (pCaptionButton != m_pSelected)
  654. {
  655. m_pSelected = pCaptionButton;
  656. RedrawFrame();
  657. if (m_pSelected)
  658. {
  659. ::SetTimer (m_hwndSite, XTP_TID_MOUSELEAVE, 50, NULL);
  660. }
  661. else
  662. {
  663. KillTimer(m_hwndSite, XTP_TID_MOUSELEAVE);
  664. }
  665. }
  666. }
  667. if (nMessage == WM_TIMER && wParam == XTP_TID_REFRESHFRAME)
  668. {
  669. RefreshFrameStyle();
  670. ::KillTimer(m_hwndSite, XTP_TID_REFRESHFRAME);
  671. return  TRUE;
  672. }
  673. if (nMessage == WM_TIMER && wParam == XTP_TID_MOUSELEAVE && !m_bDwmEnabled)
  674. {
  675. if (::GetCapture() != NULL)
  676. return TRUE;
  677. CPoint pt;
  678. ::GetCursorPos (&pt);
  679. ScreenToFrame(&pt);
  680. if (!HitTestCaptionButton(pt))
  681. {
  682. if (m_pSelected)
  683. {
  684. m_pSelected = NULL;
  685. RedrawFrame();
  686. }
  687. KillTimer(m_hwndSite, XTP_TID_MOUSELEAVE);
  688. }
  689. return TRUE;
  690. }
  691. if (nMessage == WM_NCHITTEST  && !IsCaptionVisible() && !m_bDwmEnabled)
  692. {
  693. CPoint point((DWORD)lParam);
  694. ScreenToFrame(&point);
  695. lResult = XTPHookManager()->Default();
  696. if ((GetSiteStyle(TRUE) & WS_EX_CLIENTEDGE) && (GetSiteStyle() & WS_SIZEBOX)
  697. && !(GetSiteStyle() & WS_MINIMIZE))
  698. {
  699. if (point.y == m_szFrameRegion.cy - 1 && lResult == HTBORDER)
  700. {
  701. lResult = HTBOTTOM;
  702. }
  703. }
  704. return TRUE;
  705. }
  706. if (nMessage == WM_NCHITTEST  && !IsCaptionVisible() && m_bDwmEnabled)
  707. {
  708. CPoint point((DWORD)lParam);
  709. ScreenToFrame(&point);
  710. lResult = XTPHookManager()->Default();
  711. if (point.y < GetCaptionHeight())
  712. {
  713. CXTPWinDwmWrapper().DefWindowProc(m_hwndSite, nMessage, wParam, lParam, &lResult);
  714. }
  715. return TRUE;
  716. }
  717. if (nMessage == WM_NCHITTEST && IsCaptionVisible() && !m_bDwmEnabled)
  718. {
  719. CPoint point((DWORD)lParam);
  720. ScreenToFrame(&point);
  721. lResult = XTPHookManager()->Default();
  722. if (lResult == HTCLOSE || lResult == HTMINBUTTON || lResult == HTMAXBUTTON || lResult == HTHELP)
  723. lResult = HTCAPTION;
  724. CXTPControl* pCaptionButton = m_pCaptionButtons->HitTest(point);
  725. if (pCaptionButton)
  726. {
  727. lResult = pCaptionButton->GetHelpId();
  728. return TRUE;
  729. }
  730. if (lResult == HTNOWHERE &&  point.y < GetCaptionHeight())
  731. {
  732. if ((point.x < 7 + GetSystemMetrics(SM_CXSMICON)) && (GetSiteStyle() & WS_SYSMENU))
  733. lResult = HTSYSMENU;
  734. else
  735. lResult = HTCAPTION;
  736. }
  737. return TRUE;
  738. }
  739. if (nMessage == WM_SETTEXT)
  740. {
  741. lResult = XTPHookManager()->Default();
  742. if (IsCaptionVisible())
  743. {
  744. RedrawFrame();
  745. }
  746. else
  747. {
  748. if (m_pRibbonBar)
  749. RecalcFrameLayout();
  750. }
  751. return TRUE;
  752. }
  753. if (nMessage == WM_NCACTIVATE && !m_bDwmEnabled)
  754. {
  755. BOOL bActive = (BOOL)wParam;
  756. CWnd* pSite = GetSite();
  757. // stay active if WF_STAYACTIVE bit is on
  758. if (pSite->m_nFlags & WF_STAYACTIVE)
  759. bActive = TRUE;
  760. // but do not stay active if the window is disabled
  761. if (!pSite->IsWindowEnabled())
  762. bActive = FALSE;
  763. DWORD dwStyle = GetSiteStyle();
  764. if (dwStyle & WS_VISIBLE)
  765. {
  766. m_bLockNCPaint = TRUE;
  767. if (dwStyle & WS_SIZEBOX)
  768. {
  769. CWnd::ModifyStyle(m_hwndSite, WS_SIZEBOX, 0, 0);
  770. }
  771. lResult = XTPHookManager()->Default(bActive, 0);
  772. if (dwStyle & WS_SIZEBOX)
  773. {
  774. CWnd::ModifyStyle(m_hwndSite, 0, WS_SIZEBOX, 0);
  775. }
  776. m_bLockNCPaint = FALSE;
  777. if (m_bActive != bActive)
  778. {
  779. m_bActive = bActive;
  780. RepositionCaptionButtons();
  781. RedrawFrame();
  782. RedrawRibbonBar();
  783. }
  784. }
  785. else
  786. {
  787. m_bActive = bActive;
  788. return FALSE;
  789. }
  790. return TRUE;
  791. }
  792. if (nMessage == WM_DWMCOMPOSITIONCHANGED)
  793. {
  794. BOOL bDwmEnabled = GetSiteStyle() & WS_CHILD ? FALSE : CXTPWinDwmWrapper().IsCompositionEnabled();
  795. if (bDwmEnabled != m_bDwmEnabled)
  796. {
  797. m_bDwmEnabled = bDwmEnabled;
  798. ::SetWindowRgn(m_hwndSite, 0, TRUE);
  799. if (!m_bDwmEnabled)
  800. {
  801. RefreshFrameStyle();
  802. }
  803. ::SetWindowPos(m_hwndSite, 0, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
  804. }
  805. return FALSE;
  806. }
  807. if (nMessage == WM_NCCALCSIZE && !m_bLockNCPaint)
  808. {
  809. NCCALCSIZE_PARAMS FAR* lpncsp = (NCCALCSIZE_PARAMS FAR*)lParam;
  810. CRect rc(lpncsp->rgrc[0]);
  811. if (m_bDwmEnabled)
  812. {
  813. lResult = XTPHookManager()->Default();
  814. }
  815. else
  816. {
  817. lpncsp->rgrc[0].left += m_nFrameBorder;
  818. lpncsp->rgrc[0].top += m_nFrameBorder;
  819. lpncsp->rgrc[0].right -= m_nFrameBorder;
  820. lpncsp->rgrc[0].bottom -= m_nFrameBorder;
  821. }
  822. DWORD dwStyle = GetSiteStyle();
  823. if (m_bDwmEnabled)
  824. {
  825. if (!IsCaptionVisible())
  826. lpncsp->rgrc[0].top = rc.top;
  827. }
  828. else
  829. {
  830. lpncsp->rgrc[0].top += (IsCaptionVisible() ? GetCaptionHeight() - m_nFrameBorder :  0);
  831. if (IsFrameHasStatusBar() && ((dwStyle & WS_MAXIMIZE) == 0))
  832. {
  833. int nBorderSize = max(rc.bottom - lpncsp->rgrc[0].bottom - 3, 1);
  834. lpncsp->rgrc[0].bottom = rc.bottom - nBorderSize;
  835. }
  836. }
  837. if (((dwStyle & (WS_MAXIMIZE | WS_CHILD)) == WS_MAXIMIZE) && GetAutoHideBar())
  838. {
  839. lpncsp->rgrc[0].bottom -= 1;
  840. }
  841. return TRUE;
  842. }
  843. if (nMessage == m_nMsgQuerySkinState)
  844. {
  845. lResult = TRUE;
  846. return TRUE;
  847. }
  848. if (nMessage == WM_NCPAINT && !m_bDwmEnabled)
  849. {
  850. if (m_nSkipNCPaint)
  851. {
  852. m_nSkipNCPaint--;
  853. return TRUE;
  854. }
  855. if (!IsMDIMaximized())
  856. {
  857. RepositionCaptionButtons();
  858. CWindowDC dc(GetSite());
  859. GetPaintManager()->DrawRibbonFrame(&dc, this);
  860. }
  861. return TRUE;
  862. }
  863. if (nMessage == WM_PRINT && !m_bDwmEnabled)
  864. {
  865. lResult = XTPHookManager()->Default();
  866. if (lParam & PRF_NONCLIENT)
  867. {
  868. CDC* pDC = CDC::FromHandle((HDC)wParam);
  869. GetPaintManager()->DrawRibbonFrame(pDC, this);
  870. }
  871. }
  872. if (nMessage == WM_IDLEUPDATECMDUI)
  873. {
  874. if (m_bDelayReclalcLayout)
  875. {
  876. RecalcFrameLayout();
  877. }
  878. }
  879. return FALSE;
  880. }