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

对话框与窗口

开发平台:

Visual C++

  1. // XTPHookManager.cpp : implementation of the CXTPHookManager class.
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO 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 "XTPHookManager.h"
  22. #include "XTPColorManager.h"
  23. #include "XTPDrawHelpers.h"
  24. #ifdef _DEBUG
  25. #define new DEBUG_NEW
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #endif
  29. #define FALSE_EXIT 2
  30. CXTPHookManagerHookAble::CXTPHookManagerHookAble()
  31. {
  32. m_bAutoDestroy = FALSE;
  33. }
  34. CXTPHookManagerHookAble::~CXTPHookManagerHookAble()
  35. {
  36. }
  37. class CXTPHookManager::CHookSink : public CArray<CXTPHookManagerHookAble*, CXTPHookManagerHookAble*>
  38. {
  39. friend class CXTPHookManager;
  40. public:
  41. CHookSink(HWND hWnd);
  42. ~CHookSink();
  43. public:
  44. int Find(CXTPHookManagerHookAble* pItem)
  45. {
  46. for (int i = 0; i < GetSize(); i++)
  47. {
  48. if (pItem == GetAt(i))
  49. return  i;
  50. }
  51. return -1;
  52. }
  53. void RemoveHook(CXTPHookManagerHookAble* pHook)
  54. {
  55. int nIndex = Find(pHook);
  56. if (nIndex != -1)
  57. {
  58. RemoveAt(nIndex);
  59. if (pHook->m_bAutoDestroy)
  60. delete pHook;
  61. if (GetSize() == 0)
  62. {
  63. XTPHookManager()->m_mapHooks.RemoveKey(m_hWnd);
  64. delete this;
  65. }
  66. }
  67. }
  68. public:
  69. BOOL OnHookMessage(HWND hWnd, UINT nMessage, WPARAM& wParam, LPARAM& lParam, LRESULT& lResult);
  70. protected:
  71. WNDPROC m_pOldWndProc;
  72. HWND m_hWnd;
  73. BOOL m_bUnicode;
  74. #ifdef _AFXDLL
  75. AFX_MODULE_STATE* m_pModuleState;
  76. #endif
  77. };
  78. #if (_MSC_VER <= 1200) && !defined(_WIN64)
  79. #define GetWindowLongPtrW GetWindowLongW
  80. #define GetWindowLongPtrA GetWindowLongA
  81. #define SetWindowLongPtrW SetWindowLongW
  82. #define SetWindowLongPtrA SetWindowLongA
  83. #endif
  84. CXTPHookManager::CHookSink::CHookSink(HWND hWnd)
  85. {
  86. #ifdef _AFXDLL
  87. m_pModuleState = 0;
  88. #endif
  89. m_bUnicode = IsWindowUnicode(hWnd);
  90. m_hWnd = hWnd;
  91. if (m_bUnicode)
  92. {
  93. m_pOldWndProc = (WNDPROC)GetWindowLongPtrW(hWnd, GWLP_WNDPROC);
  94. SetWindowLongPtrW(hWnd, GWLP_WNDPROC, (LONG_PTR)CXTPHookManager::HookWndProc);
  95. }
  96. else
  97. {
  98. m_pOldWndProc = (WNDPROC)GetWindowLongPtrA(hWnd, GWLP_WNDPROC);
  99. SetWindowLongPtrA(hWnd, GWLP_WNDPROC, (LONG_PTR)CXTPHookManager::HookWndProc);
  100. }
  101. }
  102. CXTPHookManager::CHookSink::~CHookSink()
  103. {
  104. if (m_bUnicode)
  105. SetWindowLongPtrW(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_pOldWndProc);
  106. else
  107. SetWindowLongPtrA(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_pOldWndProc);
  108. for (int i = (int)GetSize() - 1; i >= 0; i--)
  109. {
  110. CXTPHookManagerHookAble* pHookAble = GetAt(i);
  111. if (pHookAble->m_bAutoDestroy)
  112. {
  113. delete pHookAble;
  114. }
  115. }
  116. }
  117. BOOL CXTPHookManager::CHookSink::OnHookMessage(HWND hWnd, UINT nMessage, WPARAM& wParam, LPARAM& lParam, LRESULT& lResult)
  118. {
  119. int nCount = (int)GetSize();
  120. for (int i = nCount - 1; i >= 0; i--)
  121. {
  122. int nResult = GetAt(i)->OnHookMessage(hWnd, nMessage, wParam, lParam, lResult);
  123. if (nResult == TRUE)
  124. return TRUE;
  125. if (nResult == FALSE_EXIT)
  126. return FALSE;
  127. }
  128. return FALSE;
  129. }
  130. CXTPHookManager::CXTPHookManager()
  131. {
  132. }
  133. CXTPHookManager* AFX_CDECL XTPHookManager()
  134. {
  135. static CXTPHookManager s_managerInstance;
  136. return &s_managerInstance;
  137. }
  138. CXTPHookManager::~CXTPHookManager()
  139. {
  140. RemoveAll();
  141. }
  142. LRESULT CXTPHookManager::Default(WPARAM wParam, LPARAM lParam)
  143. {
  144. MSG& curMsg = AfxGetThreadState()->m_lastSentMsg;
  145. CHookSink* pSink = Lookup(curMsg.hwnd);
  146. ASSERT(pSink);
  147. if (!pSink)
  148. return 0;
  149. WNDPROC wndProc = pSink->m_pOldWndProc;
  150. LRESULT lResult = ::CallWindowProc(wndProc, curMsg.hwnd, curMsg.message, wParam, lParam);
  151. return lResult;
  152. }
  153. LRESULT CXTPHookManager::Default()
  154. {
  155. MSG& curMsg = AfxGetThreadState()->m_lastSentMsg;
  156. return Default(curMsg.wParam, curMsg.lParam);;
  157. }
  158. LRESULT CALLBACK CXTPHookManager::HookWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  159. {
  160. MSG& curMsg = AfxGetThreadState()->m_lastSentMsg;
  161. MSG  oldMsg = curMsg;
  162. curMsg.hwnd = hWnd;
  163. curMsg.message = message;
  164. curMsg.wParam = wParam;
  165. curMsg.lParam = lParam;
  166. // Get hook object for this window. Get from hook map
  167. CHookSink* pSink = XTPHookManager()->Lookup(hWnd);
  168. ASSERT(pSink);
  169. if (!pSink)
  170. return 0;
  171. SAFE_MANAGE_STATE(pSink->m_pModuleState);
  172. LRESULT lResult = 0;
  173. WNDPROC wndProc = pSink->m_pOldWndProc;
  174. // Window is being destroyed: unhook all hooks (for this window)
  175. // and pass message to orginal window proc
  176. if (message == WM_NCDESTROY)
  177. {
  178. XTPHookManager()->RemoveAll(hWnd);
  179. }
  180. // pass to message hook
  181. else
  182. {
  183. if (pSink->OnHookMessage(hWnd, message, wParam, lParam, lResult))
  184. {
  185. curMsg = oldMsg;
  186. return lResult;
  187. }
  188. }
  189. lResult = ::CallWindowProc(wndProc, hWnd, message, wParam, lParam);
  190. curMsg = oldMsg;
  191. return lResult;
  192. }
  193. void CXTPHookManager::SetHook(HWND hWnd, CXTPHookManagerHookAble* pHook)
  194. {
  195. CHookSink* pSink = Lookup(hWnd);
  196. if (pSink)
  197. {
  198. if (pSink->Find(pHook) == -1)
  199. {
  200. pSink->Add(pHook);
  201. }
  202. }
  203. else
  204. {
  205. pSink = new CHookSink(hWnd);
  206. pSink->Add(pHook);
  207. m_mapHooks[hWnd] = pSink;
  208. }
  209. #ifdef _AFXDLL
  210. pSink->m_pModuleState = AfxGetModuleState();
  211. #endif
  212. }
  213. void CXTPHookManager::RemoveAll()
  214. {
  215. HWND hWnd;
  216. POSITION pos = m_mapHooks.GetStartPosition();
  217. CHookSink* pSink;
  218. while (pos)
  219. {
  220. m_mapHooks.GetNextAssoc(pos, hWnd, (void*&)pSink);
  221. delete pSink;
  222. }
  223. m_mapHooks.RemoveAll();
  224. }
  225. void CXTPHookManager::RemoveAll(HWND hWnd)
  226. {
  227. CHookSink* pSink = Lookup(hWnd);
  228. if (pSink)
  229. {
  230. m_mapHooks.RemoveKey(hWnd);
  231. delete pSink;
  232. }
  233. }
  234. void CXTPHookManager::RemoveAll(CXTPHookManagerHookAble* pHook)
  235. {
  236. ASSERT(pHook);
  237. HWND hWnd;
  238. CHookSink* pSink = NULL;
  239. POSITION pos = m_mapHooks.GetStartPosition();
  240. while (pos)
  241. {
  242. m_mapHooks.GetNextAssoc(pos, hWnd, (void*&)pSink);
  243. pSink->RemoveHook(pHook);
  244. }
  245. }
  246. CXTPHookManager::CHookSink* CXTPHookManager::Lookup(HWND hWnd)
  247. {
  248. CHookSink* pSink;
  249. if (m_mapHooks.Lookup(hWnd, (void*&)pSink))
  250. return pSink;
  251. return NULL;
  252. }
  253. void CXTPHookManager::RemoveHook(HWND hWnd, CXTPHookManagerHookAble* pHook)
  254. {
  255. ASSERT(hWnd);
  256. CHookSink* pSink = Lookup(hWnd);
  257. if (pSink)
  258. {
  259. pSink->RemoveHook(pHook);
  260. }
  261. }
  262. //////////////////////////////////////////////////////////////////////////
  263. // CXTPShadowManager
  264. class CXTPShadowManager::CShadowWnd : public CWnd, public CXTPHookManagerHookAble
  265. {
  266. public:
  267. //-------------------------------------------------------------------------
  268. // Summary:
  269. //     Constructs a CShadowWnd object.
  270. //-------------------------------------------------------------------------
  271. CShadowWnd(CXTPShadowManager* pShadowManager);
  272. ~CShadowWnd();
  273. public:
  274. BOOL Create(BOOL bHoriz, CRect rcWindow);
  275. void LongShadow(CShadowList* pList);
  276. BOOL ExcludeRect(CRect rcExclude);
  277. private:
  278. DECLARE_MESSAGE_MAP()
  279. afx_msg BOOL OnEraseBkgnd(CDC* pDC);
  280. afx_msg void OnPaint();
  281. afx_msg void OnSize(UINT nType, int cx, int cy);
  282. afx_msg LRESULT OnNcHitTest(CPoint point);
  283. private:
  284. virtual int OnHookMessage(HWND hWnd, UINT nMessage, WPARAM& wParam, LPARAM& lParam, LRESULT& lResult);
  285. UINT Factor(int& nRed, int& nGreen, int& nBlue, double dFactor);
  286. private:
  287. BOOL m_bHoriz;
  288. BOOL m_bExcluded;
  289. CWnd* m_pShadowsOwner;
  290. BOOL m_bControlPopup;
  291. CXTPShadowManager* m_pShadowsManager;
  292. friend class CXTPShadowManager;
  293. };
  294. //===========================================================================
  295. // Summary:
  296. //     Shadow list
  297. //===========================================================================
  298. class CXTPShadowManager::CShadowList : public CList<CShadowWnd*, CShadowWnd*>
  299. {
  300. public:
  301. void AddShadow(CShadowWnd* pShadow)
  302. {
  303. pShadow->LongShadow(this);
  304. AddTail(pShadow);
  305. }
  306. void RemoveShadow(CShadowWnd* pShadow)
  307. {
  308. POSITION pos = Find(pShadow);
  309. ASSERT(pos);
  310. RemoveAt(pos);
  311. }
  312. };
  313. CXTPShadowManager::CXTPShadowManager()
  314. {
  315. m_pfnUpdateLayeredWindow = NULL;
  316. HMODULE hLib = GetModuleHandle(_T("USER32"));
  317. if (hLib)
  318. {
  319. m_pfnUpdateLayeredWindow = (LPFNUPDATELAYEREDWINDOW) GetProcAddress(hLib, "UpdateLayeredWindow");
  320. }
  321. m_bAlphaShadow = IsAlphaShadow();
  322. m_nShadowOptions = 0;
  323. m_clrShadowFactor = 0;
  324. m_bUseSystemSaveBitsStyle = TRUE;
  325. m_pShadows = new CShadowList();
  326. }
  327. CXTPShadowManager::~CXTPShadowManager()
  328. {
  329. ASSERT(m_pShadows->IsEmpty());
  330. SAFE_DELETE(m_pShadows);
  331. }
  332. BOOL CXTPShadowManager::IsAlphaShadow()
  333. {
  334. #ifdef NOALPHASHADOW
  335. return FALSE;
  336. #endif
  337. if (XTPColorManager()->IsLowResolution())
  338. return FALSE;
  339. return (m_pfnUpdateLayeredWindow != NULL);
  340. }
  341. #ifndef SPI_GETDROPSHADOW
  342. #define SPI_GETDROPSHADOW     0x1024
  343. #endif
  344. void CXTPShadowManager::SetShadow(CWnd* pShadowOwner, const CRect& rcExclude)
  345. {
  346. if (!(GetShadowOptions() & xtpShadowOfficeAlpha))
  347. {
  348. if (!m_bAlphaShadow)
  349. return;
  350. BOOL bDropShadow = FALSE;
  351. SystemParametersInfo(SPI_GETDROPSHADOW, 0, &bDropShadow, 0);
  352. if (!bDropShadow)
  353. return;
  354. }
  355. CXTPWindowRect rc(pShadowOwner);
  356. CreateShadow(TRUE, rc, rcExclude, pShadowOwner, FALSE);
  357. CreateShadow(FALSE, rc, rcExclude, pShadowOwner, FALSE);
  358. HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
  359. if (pShadowOwner->GetWindowRgn(hRgn) == COMPLEXREGION)
  360. {
  361. CreateShadow(2, rc, rcExclude, pShadowOwner, FALSE);
  362. }
  363. DeleteObject(hRgn);
  364. }
  365. void CXTPShadowManager::SetShadow(CRect rcWindow, CWnd* pShadowOwner)
  366. {
  367. if ((GetShadowOptions() & (xtpShadowOfficeAlpha | xtpShadowShowPopupControl)) ==
  368. (xtpShadowOfficeAlpha | xtpShadowShowPopupControl))
  369. {
  370. CreateShadow(TRUE, rcWindow, CXTPEmptyRect(), pShadowOwner, TRUE);
  371. CreateShadow(FALSE, rcWindow, CXTPEmptyRect(), pShadowOwner, TRUE);
  372. }
  373. }
  374. POSITION CXTPShadowManager::GetHeadPosition(CWnd* pShadowOwner) const
  375. {
  376. POSITION pos = m_pShadows->GetHeadPosition();
  377. while (pos)
  378. {
  379. CShadowWnd* pShadow = m_pShadows->GetAt(pos);
  380. if (pShadow->m_pShadowsOwner == pShadowOwner)
  381. return pos;
  382. m_pShadows->GetNext(pos);
  383. }
  384. return NULL;
  385. }
  386. CWnd* CXTPShadowManager::GetNext(POSITION& pos) const
  387. {
  388. CShadowWnd* pShadowResult = m_pShadows->GetNext(pos);
  389. while (pos)
  390. {
  391. CShadowWnd* pShadow = m_pShadows->GetAt(pos);
  392. if (pShadow->m_pShadowsOwner == pShadowResult->m_pShadowsOwner)
  393. break;
  394. m_pShadows->GetNext(pos);
  395. }
  396. return pShadowResult;
  397. }
  398. void CXTPShadowManager::RemoveShadow(CWnd* pShadowOwner)
  399. {
  400. POSITION pos = m_pShadows->GetHeadPosition();
  401. while (pos)
  402. {
  403. CShadowWnd* pShadow = m_pShadows->GetNext(pos);
  404. if (pShadowOwner == pShadow->m_pShadowsOwner)
  405. {
  406. XTPHookManager()->RemoveHook(pShadow->m_pShadowsOwner->GetSafeHwnd(), pShadow);
  407. DestroyShadow(pShadow);
  408. }
  409. }
  410. }
  411. void CXTPShadowManager::OffsetShadow(CWnd* pShadowOwner, CSize szOffset)
  412. {
  413. BOOL bLayoutRTL = pShadowOwner->GetExStyle() & WS_EX_LAYOUTRTL;
  414. POSITION pos = m_pShadows->GetHeadPosition();
  415. while (pos)
  416. {
  417. CShadowWnd* pShadow = m_pShadows->GetNext(pos);
  418. if (pShadowOwner == pShadow->m_pShadowsOwner && pShadow->GetSafeHwnd() && !pShadow->m_bControlPopup)
  419. {
  420. if (pShadow->m_bExcluded)
  421. {
  422. pShadow->SetWindowRgn(NULL, FALSE);
  423. pShadow->m_bExcluded = FALSE;
  424. }
  425. CXTPWindowRect rc(pShadow);
  426. if (bLayoutRTL)
  427. {
  428. if (pShadow->m_bHoriz == 1)
  429. {
  430. pShadow->SetWindowPos(0, rc.left - szOffset.cx , rc.top + szOffset.cy,
  431. rc.Width() + szOffset.cx, rc.Height(), SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
  432. }
  433. else if (pShadow->m_bHoriz == 2)
  434. {
  435. pShadow->SetWindowPos(0, rc.left, rc.top + szOffset.cy,
  436. rc.Width(), rc.Height(), SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
  437. }
  438. else
  439. {
  440. pShadow->SetWindowPos(0, rc.left, rc.top,
  441. rc.Width(), rc.Height() + szOffset.cy, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
  442. }
  443. }
  444. else
  445. {
  446. if (pShadow->m_bHoriz == 1)
  447. {
  448. pShadow->SetWindowPos(0, rc.left, rc.top + szOffset.cy,
  449. rc.Width() + szOffset.cx, rc.Height(), SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
  450. }
  451. else if (pShadow->m_bHoriz == 2)
  452. {
  453. pShadow->SetWindowPos(0, rc.left + szOffset.cx , rc.top + szOffset.cy,
  454. rc.Width(), rc.Height(), SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
  455. }
  456. else
  457. {
  458. pShadow->SetWindowPos(0, rc.left + szOffset.cx, rc.top,
  459. rc.Width(), rc.Height() + szOffset.cy, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
  460. }
  461. }
  462. }
  463. }
  464. }
  465. CXTPShadowManager::CShadowWnd* CXTPShadowManager::CreateShadow(BOOL bHoriz, CRect rc, CRect rcExclude, CWnd* pShadowOwner, BOOL bControlPopup)
  466. {
  467. CShadowWnd* pShadow = new CShadowWnd(this);
  468. pShadow->m_pShadowsOwner = pShadowOwner;
  469. pShadow->m_bControlPopup = bControlPopup;
  470. pShadow->Create(bHoriz, rc);
  471. m_pShadows->AddShadow(pShadow);
  472. if (m_nShadowOptions & xtpShadowShowPopupControl)
  473. {
  474. pShadow->ExcludeRect(rcExclude);
  475. }
  476. POSITION pos = m_pShadows->GetHeadPosition();
  477. while (pos)
  478. {
  479. CShadowWnd* pShadowPrev = m_pShadows->GetNext(pos);
  480. if (pShadowPrev->m_pShadowsOwner && (bHoriz != 2 || pShadowPrev->m_pShadowsOwner != pShadowOwner))
  481. {
  482. pShadow->ExcludeRect(CXTPWindowRect(pShadowPrev->m_pShadowsOwner));
  483. }
  484. }
  485. pShadow->SetWindowPos(pShadowOwner->GetExStyle() & WS_EX_TOPMOST ? &CWnd::wndTopMost : &CWnd::wndTop,
  486. 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
  487. XTPHookManager()->SetHook(pShadowOwner->m_hWnd, pShadow);
  488. return pShadow;
  489. }
  490. void CXTPShadowManager::DestroyShadow(CShadowWnd* pWnd)
  491. {
  492. if (pWnd->GetSafeHwnd()) pWnd->ShowWindow(SW_HIDE);
  493. pWnd->m_pShadowsOwner = 0;
  494. m_pShadows->RemoveShadow(pWnd);
  495. pWnd->DestroyWindow();
  496. delete pWnd;
  497. }
  498. CXTPShadowManager::CShadowWnd::CShadowWnd(CXTPShadowManager* pShadowManager)
  499. {
  500. m_pShadowsOwner = 0;
  501. m_bHoriz = FALSE;
  502. m_bExcluded = FALSE;
  503. m_pShadowsManager = pShadowManager;
  504. CMDTARGET_ADDREF(m_pShadowsManager);
  505. }
  506. CXTPShadowManager::CShadowWnd::~CShadowWnd()
  507. {
  508. CMDTARGET_RELEASE(m_pShadowsManager);
  509. }
  510. int CXTPShadowManager::CShadowWnd::OnHookMessage(HWND hWnd, UINT nMessage, WPARAM& wParam, LPARAM& /*lParam*/, LRESULT& /*lResult*/)
  511. {
  512. if (nMessage == WM_SHOWWINDOW && wParam == FALSE)
  513. {
  514. ShowWindow(SW_HIDE);
  515. }
  516. if (nMessage == WM_SHOWWINDOW && wParam == TRUE)
  517. {
  518. ShowWindow(SW_SHOWNA);
  519. }
  520. if (nMessage == WM_DESTROY)
  521. {
  522. XTPHookManager()->RemoveHook(hWnd, this);
  523. m_pShadowsManager->DestroyShadow(this);
  524. }
  525. return 0;
  526. }
  527. BOOL CXTPShadowManager::CShadowWnd::Create(BOOL bHoriz, CRect rcWindow)
  528. {
  529. CWnd* pSite = m_pShadowsOwner->GetParent();
  530. ASSERT(pSite);
  531. if (m_hWnd == 0)
  532. {
  533. int nFlags = WS_EX_TOOLWINDOW;
  534. if (m_pShadowsManager->m_bAlphaShadow) nFlags |= 0x80000;
  535. UINT nClassStyle = m_pShadowsManager->m_bUseSystemSaveBitsStyle ? CS_SAVEBITS | CS_OWNDC : 0;
  536. CString strClass = ::AfxRegisterWndClass(nClassStyle, AfxGetApp()->LoadStandardCursor(IDC_ARROW));
  537. if (!CreateEx(nFlags, strClass, 0, WS_POPUP, CXTPEmptyRect(), pSite, 0))
  538. return FALSE;
  539. }
  540. SetWindowRgn(NULL, FALSE);
  541. int nWidth = m_pShadowsManager->m_bAlphaShadow ? 4 : 2;
  542. m_bHoriz = bHoriz;
  543. CRect rcShadow;
  544. if (bHoriz == 2)
  545. rcShadow.SetRect(rcWindow.right - 1, rcWindow.bottom - 1, rcWindow.right, rcWindow.bottom);
  546. else if (bHoriz == 1)
  547. rcShadow.SetRect(rcWindow.left + nWidth, rcWindow.bottom, rcWindow.right + nWidth, rcWindow.bottom + nWidth);
  548. else
  549. rcShadow.SetRect(rcWindow.right, rcWindow.top + nWidth, rcWindow.right + nWidth, rcWindow.bottom);
  550. MoveWindow(rcShadow, FALSE);
  551. return TRUE;
  552. }
  553. BEGIN_MESSAGE_MAP(CXTPShadowManager::CShadowWnd, CWnd)
  554. { WM_ERASEBKGND, 0, 0, 0, AfxSig_bD, (AFX_PMSG)(AFX_PMSGW) (static_cast< BOOL (AFX_MSG_CALL CWnd::*)(CDC*) > (CXTPShadowManager::CShadowWnd::OnEraseBkgnd)) },
  555. { WM_PAINT, 0, 0, 0, AfxSig_vv, (AFX_PMSG)(AFX_PMSGW) (static_cast< void (AFX_MSG_CALL CWnd::*)(void) > (CXTPShadowManager::CShadowWnd::OnPaint)) },
  556. { WM_SIZE, 0, 0, 0, AfxSig_vwii, (AFX_PMSG)(AFX_PMSGW) (static_cast< void (AFX_MSG_CALL CWnd::*)(UINT, int, int) > (CXTPShadowManager::CShadowWnd::OnSize)) },
  557. { WM_NCHITTEST, 0, 0, 0, AfxSig_wp, (AFX_PMSG)(AFX_PMSGW) (static_cast< LRESULT (AFX_MSG_CALL CWnd::*)(CPoint) > (CXTPShadowManager::CShadowWnd::OnNcHitTest)) },
  558. END_MESSAGE_MAP()
  559. LRESULT CXTPShadowManager::CShadowWnd::OnNcHitTest(CPoint /*point*/)
  560. {
  561. return (LRESULT)HTTRANSPARENT;
  562. }
  563. void CXTPShadowManager::CShadowWnd::OnPaint()
  564. {
  565. CPaintDC dc(this);
  566. CXTPClientRect rcClient(this);
  567. dc.FillSolidRect(rcClient, m_pShadowsManager->m_bAlphaShadow ? 0 : GetXtremeColor(COLOR_3DSHADOW));
  568. }
  569. BOOL CXTPShadowManager::CShadowWnd::OnEraseBkgnd(CDC* /*pDC*/)
  570. {
  571. return TRUE;
  572. }
  573. BOOL CXTPShadowManager::CShadowWnd::ExcludeRect(CRect rcExclude)
  574. {
  575. CXTPWindowRect rcWindow(this);
  576. CRect rcIntersect;
  577. if (rcIntersect.IntersectRect(rcWindow, rcExclude))
  578. {
  579. CXTPClientRect rcClient(this);
  580. HRGN hrgnClip = ::CreateRectRgnIndirect(&rcClient);
  581. rcIntersect.OffsetRect(-rcWindow.TopLeft());
  582. HRGN hrgnIntersect = ::CreateRectRgnIndirect(&rcIntersect);
  583. CombineRgn(hrgnClip, hrgnClip, hrgnIntersect, RGN_DIFF);
  584. DeleteObject(hrgnIntersect);
  585. if (!SetWindowRgn(hrgnClip, FALSE))
  586. DeleteObject(hrgnClip);
  587. m_bExcluded = TRUE;
  588. }
  589. return TRUE;
  590. }
  591. void CXTPShadowManager::CShadowWnd::LongShadow(CShadowList* pList)
  592. {
  593. CXTPWindowRect rcWindow(this);
  594. POSITION pos = pList->GetHeadPosition();
  595. while (pos)
  596. {
  597. CShadowWnd* pWnd = pList->GetNext(pos);
  598. if (m_bHoriz == !pWnd->m_bHoriz)
  599. {
  600. CXTPWindowRect rc(pWnd);
  601. if (m_bHoriz == FALSE)
  602. {
  603. if (rcWindow.top == rc.bottom -1 && rcWindow.right < rc.right && rcWindow.right > rc.left)
  604. {
  605. rcWindow.top -= 2 * rc.Height();
  606. MoveWindow(rcWindow, FALSE);
  607. }
  608. }
  609. else
  610. {
  611. if (rcWindow.left == rc.right - 1 && rcWindow.top > rc.top && rcWindow.bottom < rc.bottom)
  612. {
  613. rcWindow.left -= 2 * rc.Width() + 1;
  614. MoveWindow(rcWindow, FALSE);
  615. }
  616. }
  617. }
  618. }
  619. }
  620. UINT CXTPShadowManager::CShadowWnd::Factor(int& nRed, int& nGreen, int& nBlue, double dFactor)
  621. {
  622. return (int(nRed * dFactor) << 16) + (int(nGreen * dFactor) << 8) + (int(nBlue * dFactor));
  623. }
  624. void CXTPShadowManager::CShadowWnd::OnSize(UINT nType, int cx, int cy)
  625. {
  626. CWnd::OnSize(nType, cx, cy);
  627. if (!cx || !cy || !m_pShadowsManager->m_bAlphaShadow ||
  628. !m_pShadowsManager->m_pfnUpdateLayeredWindow || !m_pShadowsOwner)
  629. return;
  630. BLENDFUNCTION bf;
  631. bf.BlendOp = AC_SRC_OVER;
  632. bf.BlendFlags = 0;
  633. bf.SourceConstantAlpha = 255;
  634. bf.AlphaFormat = 0x01;
  635. POINT pt = {0, 0};
  636. int x, y;
  637. HBITMAP hbitmap;
  638. BITMAPINFO bmi;
  639. CClientDC cDC(this);
  640. CDC dc;
  641. dc.CreateCompatibleDC(&cDC);
  642. // zero the memory for the bitmap info
  643. ZeroMemory(&bmi, sizeof(BITMAPINFO));
  644. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  645. bmi.bmiHeader.biWidth = cx;
  646. bmi.bmiHeader.biHeight = cy;
  647. bmi.bmiHeader.biPlanes = 1;
  648. bmi.bmiHeader.biBitCount = 32;         // four 8-bit components
  649. bmi.bmiHeader.biCompression = BI_RGB;
  650. bmi.bmiHeader.biSizeImage = cx * cy * 4;
  651. UINT* pvBits = NULL;
  652. // create our DIB section and select the bitmap into the dc
  653. hbitmap = CreateDIBSection(cDC, &bmi, DIB_RGB_COLORS, (void**)&pvBits, NULL, 0x0);
  654. if (pvBits == NULL || hbitmap == NULL)
  655. return;
  656. COLORREF clrFactor = m_pShadowsManager->m_clrShadowFactor;
  657. int nRed = GetRValue(clrFactor), nGreen = GetGValue(clrFactor), nBlue = GetBValue(clrFactor);
  658. int nFactor = m_pShadowsManager->m_nShadowOptions & xtpShadowOfficeAlpha ? 1 : 2;
  659. if (m_bHoriz == 2)
  660. {
  661. pvBits[0] = (UINT) 4 * 0x0F000000 * nFactor
  662. + Factor(nRed, nGreen, nBlue, 1);
  663. }
  664. else if (m_bHoriz == 0)
  665. {
  666. ASSERT(cx == 4);
  667. for (x = 0; x < 4; x++) for (y = 0; y < 4; y++)
  668. {
  669. pvBits[3 - x + (cy - 1 - y) * cx] = (UINT) 3 * (x + 1) * (y + 1) * 0x1000000 * nFactor
  670. + Factor(nRed, nGreen, nBlue, double((x + 1) * (y + 1))/20);
  671. }
  672. for (x = 3; x >= 0; x--)
  673. {
  674. UINT nColor = 0x0F000000 * nFactor * (4 - x) + Factor(nRed, nGreen, nBlue, double(4 - x)/4);
  675. for (y = 0; y < cy - 4; y++) pvBits[x + y * cx] = nColor;
  676. }
  677. }
  678. else
  679. {
  680. ASSERT(cy == 4);
  681. for (x = 0; x < 4; x++) for (y = 0; y < 4; y++)
  682. {
  683. pvBits[x + y * cx] = (UINT) 3 * (x + 1) * (y + 1) * 0x1000000 * nFactor
  684. + Factor(nRed, nGreen, nBlue, double((x + 1) * (y + 1))/20);
  685. }
  686. for (y = 0; y < 4; y++)
  687. {
  688. UINT nColor = 0x0F000000 * nFactor * (y + 1) + Factor(nRed, nGreen, nBlue, double(y + 1)/4);
  689. for (x = 4; x < cx - 4; x++) pvBits[x + y * cx] = nColor;
  690. }
  691. for (x = 0; x < 4; x++) for (y = 0; y < 4; y++)
  692. {
  693. pvBits[cx - 1 - x + y * cx] = (UINT)3 * (x + 1) * (y + 1) * 0x1000000 * nFactor
  694. + Factor(nRed, nGreen, nBlue, double((x + 1) * (y + 1))/20);
  695. }
  696. }
  697. HBITMAP hOld = (HBITMAP)SelectObject(dc, hbitmap);
  698. SIZE sz = {cx, cy};
  699. m_pShadowsManager->m_pfnUpdateLayeredWindow((HWND)GetSafeHwnd(), (HDC)0, 0, &sz, dc.GetSafeHdc(), &pt, 0, &bf, 0x02);
  700. SelectObject(dc, hOld);
  701. DeleteObject(hbitmap);
  702. dc.DeleteDC();
  703. }