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

对话框与窗口

开发平台:

Visual C++

  1. // XTPDrawHelpers.cpp: implementation of the CXTPDrawHelpers 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 "resource.h"
  22. #include "XTPSystemHelpers.h"
  23. #include "XTPColorManager.h"
  24. #include "XTPDrawHelpers.h"
  25. #include "XTPVC50Helpers.h"
  26. #include "XTPResourceManager.h"
  27. #ifdef _DEBUG
  28. #undef THIS_FILE
  29. static char THIS_FILE[] = __FILE__;
  30. #define new DEBUG_NEW
  31. #endif
  32. HHOOK CXTPMouseMonitor::m_hHookMouse = 0;
  33. CWnd* CXTPMouseMonitor::m_pWndMonitor = 0;
  34. //////////////////////////////////////////////////////////////////////////
  35. // CXTPMouseMonitor
  36. //////////////////////////////////////////////////////////////////////////
  37. void CXTPMouseMonitor::SetupHook(CWnd* pWndMonitor)
  38. {
  39. if (pWndMonitor && m_hHookMouse == 0)
  40. {
  41. m_hHookMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, 0, GetCurrentThreadId ());
  42. }
  43. if (!pWndMonitor && m_hHookMouse)
  44. {
  45. UnhookWindowsHookEx(m_hHookMouse);
  46. m_hHookMouse = 0;
  47. }
  48. m_pWndMonitor = pWndMonitor;
  49. }
  50. BOOL CXTPMouseMonitor::IsMouseHooked()
  51. {
  52. return m_pWndMonitor != NULL;
  53. }
  54. LRESULT CALLBACK CXTPMouseMonitor::MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
  55. {
  56. if (nCode != HC_ACTION || !m_pWndMonitor)
  57. return CallNextHookEx(m_hHookMouse, nCode, wParam, lParam);
  58. CXTPWindowRect rc(m_pWndMonitor);
  59. if (!rc.PtInRect(((PMOUSEHOOKSTRUCT)lParam)->pt))
  60. {
  61. switch (wParam)
  62. {
  63. case WM_LBUTTONDOWN:
  64. case WM_NCLBUTTONDOWN:
  65. case WM_RBUTTONDOWN:
  66. case WM_NCRBUTTONDOWN:
  67. case WM_MBUTTONDOWN:
  68. case WM_NCMBUTTONDOWN:
  69. m_pWndMonitor->GetOwner()->SetFocus();
  70. return TRUE;
  71. }
  72. }
  73. return CallNextHookEx(m_hHookMouse, nCode, wParam, lParam);
  74. }
  75. //===========================================================================
  76. // CXTPClientCursorPos class
  77. //===========================================================================
  78. CXTPTransparentBitmap::CXTPTransparentBitmap(HBITMAP hBitmap)
  79. : m_hBitmap(hBitmap)
  80. {
  81. }
  82. // Not foolproof, but works 99% of the time :).  Assumes the top
  83. // left pixel is the transparent color.
  84. COLORREF CXTPTransparentBitmap::GetTransparentColor() const
  85. {
  86. CBitmap* pBitmap = CBitmap::FromHandle(m_hBitmap);
  87. if (pBitmap != NULL)
  88. {
  89. CXTPCompatibleDC dc(NULL, pBitmap);
  90. return dc.GetPixel(0, 0);
  91. }
  92. return (COLORREF)-1;
  93. }
  94. HICON CXTPTransparentBitmap::ConvertToIcon() const
  95. {
  96. if (m_hBitmap == NULL)
  97. return NULL;
  98. COLORREF crTransparent = GetTransparentColor();
  99. BITMAP bmp;
  100. if (!::GetObject(m_hBitmap, sizeof(BITMAP), &bmp))
  101. return NULL;
  102. if (bmp.bmHeight == 0 || bmp.bmWidth == 0)
  103. return NULL;
  104. CImageList il;
  105. il.Create(bmp.bmWidth, bmp.bmHeight, ILC_COLOR24 | ILC_MASK, 0, 1);
  106. il.Add(CBitmap::FromHandle(m_hBitmap), crTransparent);
  107. ASSERT(il.GetImageCount() == 1);
  108. return il.ExtractIcon(0);
  109. }
  110. //===========================================================================
  111. // CXTPClientCursorPos class
  112. //===========================================================================
  113. CXTPClientCursorPos::CXTPClientCursorPos(CWnd* pWnd)
  114. {
  115. GetCursorPos(this);
  116. pWnd->ScreenToClient(this);
  117. }
  118. //===========================================================================
  119. // CXTPEmptySize class
  120. //===========================================================================
  121. CXTPEmptySize::CXTPEmptySize()
  122. {
  123. SetSizeEmpty();
  124. }
  125. void CXTPEmptySize::SetSizeEmpty()
  126. {
  127. cx = 0;
  128. cy = 0;
  129. }
  130. const SIZE& CXTPEmptySize::operator=(const SIZE& srcSize)
  131. {
  132. cx = srcSize.cx;
  133. cy = srcSize.cy;
  134. return *this;
  135. }
  136. //===========================================================================
  137. // CXTPEmptyRect class
  138. //===========================================================================
  139. CXTPEmptyRect::CXTPEmptyRect()
  140. {
  141. SetRectEmpty();
  142. }
  143. //===========================================================================
  144. // CXTPWindowRect class
  145. //===========================================================================
  146. CXTPWindowRect::CXTPWindowRect(HWND hWnd)
  147. {
  148. if (::IsWindow(hWnd))
  149. ::GetWindowRect(hWnd, this);
  150. else
  151. SetRectEmpty();
  152. }
  153. CXTPWindowRect::CXTPWindowRect(const CWnd* pWnd)
  154. {
  155. if (::IsWindow(pWnd->GetSafeHwnd()))
  156. ::GetWindowRect(pWnd->GetSafeHwnd(), this);
  157. else
  158. SetRectEmpty();
  159. }
  160. //===========================================================================
  161. // CXTPClientRect class
  162. //===========================================================================
  163. CXTPClientRect::CXTPClientRect(HWND hWnd)
  164. {
  165. if (::IsWindow(hWnd))
  166. ::GetClientRect(hWnd, this);
  167. else
  168. SetRectEmpty();
  169. }
  170. CXTPClientRect::CXTPClientRect(const CWnd* pWnd)
  171. {
  172. if (::IsWindow(pWnd->GetSafeHwnd()))
  173. ::GetClientRect(pWnd->GetSafeHwnd(), this);
  174. else
  175. SetRectEmpty();
  176. }
  177. //===========================================================================
  178. // CXTPBufferDC class
  179. //===========================================================================
  180. CXTPBufferDC::CXTPBufferDC(HDC hDestDC, const CRect& rcPaint) : m_hDestDC (hDestDC)
  181. {
  182. m_rect = rcPaint;
  183. Attach (::CreateCompatibleDC (m_hDestDC));
  184. if (!m_hDC)
  185. return;
  186. m_bitmap.Attach (::CreateCompatibleBitmap(
  187. m_hDestDC, m_rect.right, m_rect.bottom));
  188. m_hOldBitmap = ::SelectObject (m_hDC, m_bitmap);
  189. }
  190. CXTPBufferDC::CXTPBufferDC(CPaintDC& paintDC)
  191. {
  192. m_hDestDC = paintDC.GetSafeHdc();
  193. m_rect = paintDC.m_ps.rcPaint;
  194. Attach (::CreateCompatibleDC (m_hDestDC));
  195. if (!m_hDC)
  196. return;
  197. m_bitmap.Attach (::CreateCompatibleBitmap(
  198. m_hDestDC, max(1, m_rect.right), max(1, m_rect.bottom)));
  199. m_hOldBitmap = ::SelectObject (m_hDC, m_bitmap);
  200. CRgn rgn;
  201. rgn.CreateRectRgnIndirect(&m_rect);
  202. SelectClipRgn(&rgn);
  203. }
  204. CXTPBufferDC::~CXTPBufferDC()
  205. {
  206. if (!m_hDC)
  207. return;
  208. if (m_hDestDC)
  209. {
  210. ::BitBlt (m_hDestDC, m_rect.left, m_rect.top, m_rect.Width(),
  211. m_rect.Height(), m_hDC, m_rect.left, m_rect.top, SRCCOPY);
  212. }
  213. ::SelectObject (m_hDC, m_hOldBitmap);
  214. }
  215. void CXTPBufferDC::Discard()
  216. {
  217. m_hDestDC = 0;
  218. }
  219. CDC* CXTPBufferDC::GetDestDC()
  220. {
  221. return CDC::FromHandle(m_hDestDC);
  222. }
  223. //===========================================================================
  224. // CXTPBufferDC class
  225. //===========================================================================
  226. CXTPBufferDCEx::CXTPBufferDCEx(HDC hDestDC, const CRect rcPaint) : m_hDestDC (hDestDC)
  227. {
  228. m_rect = rcPaint;
  229. Attach (::CreateCompatibleDC (m_hDestDC));
  230. m_bitmap = ::CreateCompatibleBitmap(
  231. m_hDestDC, m_rect.Width(), m_rect.Height());
  232. m_hOldBitmap = ::SelectObject (m_hDC, m_bitmap);
  233. SetViewportOrg(-rcPaint.left, -rcPaint.top);
  234. }
  235. CXTPBufferDCEx::~CXTPBufferDCEx()
  236. {
  237. SetViewportOrg(0, 0);
  238. ::BitBlt (m_hDestDC, m_rect.left, m_rect.top, m_rect.Width(),
  239. m_rect.Height(), m_hDC, 0, 0, SRCCOPY);
  240. ::SelectObject (m_hDC, m_hOldBitmap);
  241. ::DeleteObject(m_bitmap);
  242. }
  243. //===========================================================================
  244. // CXTPBitmapDC class
  245. //===========================================================================
  246. CXTPBitmapDC::CXTPBitmapDC(CDC* pDC, CBitmap* pBitmap)
  247. : m_hDC(pDC->GetSafeHdc())
  248. {
  249. m_hOldBitmap = SelectObject(m_hDC, pBitmap->GetSafeHandle());
  250. }
  251. CXTPBitmapDC::CXTPBitmapDC(CDC* pDC, HBITMAP hBitmap)
  252. : m_hDC(pDC->GetSafeHdc())
  253. {
  254. m_hOldBitmap = SelectObject(m_hDC, hBitmap);
  255. }
  256. CXTPBitmapDC::~CXTPBitmapDC()
  257. {
  258. ::SelectObject(m_hDC, m_hOldBitmap);
  259. }
  260. void CXTPBitmapDC::SetBitmap(CBitmap* pBitmap)
  261. {
  262. ::SelectObject(m_hDC, m_hOldBitmap);
  263. m_hOldBitmap = SelectObject(m_hDC, pBitmap->GetSafeHandle());
  264. }
  265. //===========================================================================
  266. // CXTPFontDC class
  267. //===========================================================================
  268. CXTPFontDC::CXTPFontDC(CDC* pDC, CFont* pFont)
  269. {
  270. ASSERT(pDC);
  271. m_pDC = pDC;
  272. m_pOldFont = NULL;
  273. m_clrOldTextColor = COLORREF_NULL;
  274. if (pFont)
  275. {
  276. SetFont(pFont);
  277. }
  278. }
  279. CXTPFontDC::CXTPFontDC(CDC* pDC, CFont* pFont, COLORREF clrTextColor)
  280. {
  281. ASSERT(pDC);
  282. ASSERT(clrTextColor != COLORREF_NULL);
  283. m_pDC = pDC;
  284. m_pOldFont = NULL;
  285. m_clrOldTextColor = COLORREF_NULL;
  286. if (pFont)
  287. {
  288. SetFont(pFont);
  289. }
  290. SetColor(clrTextColor);
  291. }
  292. CXTPFontDC::~CXTPFontDC()
  293. {
  294. ReleaseFont();
  295. ReleaseColor();
  296. }
  297. void CXTPFontDC::SetFont(CFont* pFont)
  298. {
  299. if (m_pDC && pFont)
  300. {
  301. CFont* pFontPrev = m_pDC->SelectObject(pFont);
  302. if (!m_pOldFont && pFontPrev)
  303. {
  304. m_pOldFont = pFontPrev;
  305. }
  306. }
  307. }
  308. void CXTPFontDC::SetColor(COLORREF clrTextColor)
  309. {
  310. ASSERT(clrTextColor != COLORREF_NULL);
  311. ASSERT(m_pDC);
  312. if (m_pDC && clrTextColor != COLORREF_NULL)
  313. {
  314. COLORREF clrTextColorPrev= m_pDC->SetTextColor(clrTextColor);
  315. if (m_clrOldTextColor == COLORREF_NULL)
  316. {
  317. m_clrOldTextColor = clrTextColorPrev;
  318. }
  319. }
  320. }
  321. void CXTPFontDC::SetFontColor(CFont* pFont, COLORREF clrTextColor)
  322. {
  323. SetFont(pFont);
  324. SetColor(clrTextColor);
  325. }
  326. void CXTPFontDC::ReleaseFont()
  327. {
  328. ASSERT(m_pDC);
  329. if (m_pDC && m_pOldFont)
  330. {
  331. m_pDC->SelectObject(m_pOldFont);
  332. m_pOldFont = NULL;
  333. }
  334. }
  335. void CXTPFontDC::ReleaseColor()
  336. {
  337. ASSERT(m_pDC);
  338. if (m_pDC && m_clrOldTextColor != COLORREF_NULL)
  339. {
  340. m_pDC->SetTextColor(m_clrOldTextColor);
  341. m_clrOldTextColor = COLORREF_NULL;
  342. }
  343. }
  344. //===========================================================================
  345. // CXTPPenDC class
  346. //===========================================================================
  347. CXTPPenDC::CXTPPenDC(CDC* pDC, CPen* pPen)
  348. : m_hDC(pDC->GetSafeHdc())
  349. {
  350. m_hOldPen = (HPEN)::SelectObject(m_hDC, pPen->GetSafeHandle());
  351. }
  352. CXTPPenDC::CXTPPenDC(HDC hDC, COLORREF crColor)
  353. : m_hDC (hDC)
  354. {
  355. VERIFY(m_pen.CreatePen (PS_SOLID, 1, crColor));
  356. m_hOldPen = (HPEN)::SelectObject (m_hDC, m_pen);
  357. }
  358. CXTPPenDC::~CXTPPenDC ()
  359. {
  360. ::SelectObject (m_hDC, m_hOldPen);
  361. }
  362. void CXTPPenDC::Color(COLORREF crColor)
  363. {
  364. ::SelectObject (m_hDC, m_hOldPen);
  365. VERIFY(m_pen.DeleteObject());
  366. VERIFY(m_pen.CreatePen (PS_SOLID, 1, crColor));
  367. m_hOldPen = (HPEN)::SelectObject (m_hDC, m_pen);
  368. }
  369. COLORREF CXTPPenDC::Color()
  370. {
  371. LOGPEN logPen;
  372. m_pen.GetLogPen(&logPen);
  373. return logPen.lopnColor;
  374. }
  375. //===========================================================================
  376. // CXTPBrushDC class
  377. //===========================================================================
  378. CXTPBrushDC::CXTPBrushDC(HDC hDC, COLORREF crColor)
  379. : m_hDC (hDC)
  380. {
  381. VERIFY(m_brush.CreateSolidBrush (crColor));
  382. m_hOldBrush = (HBRUSH)::SelectObject (m_hDC, m_brush);
  383. }
  384. CXTPBrushDC::~CXTPBrushDC()
  385. {
  386. ::SelectObject(m_hDC, m_hOldBrush);
  387. }
  388. void CXTPBrushDC::Color(COLORREF crColor)
  389. {
  390. ::SelectObject(m_hDC, m_hOldBrush);
  391. VERIFY(m_brush.DeleteObject());
  392. VERIFY(m_brush.CreateSolidBrush(crColor));
  393. m_hOldBrush = (HBRUSH)::SelectObject (m_hDC, m_brush);
  394. }
  395. //===========================================================================
  396. // CXTPCompatibleDC class
  397. //===========================================================================
  398. CXTPCompatibleDC::CXTPCompatibleDC(CDC* pDC, CBitmap* pBitmap)
  399. {
  400. CreateCompatibleDC(pDC);
  401. m_hOldBitmap = (HBITMAP)::SelectObject(GetSafeHdc(), pBitmap->GetSafeHandle());
  402. }
  403. CXTPCompatibleDC::CXTPCompatibleDC(CDC* pDC, HBITMAP hBitmap)
  404. {
  405. CreateCompatibleDC(pDC);
  406. m_hOldBitmap = (HBITMAP)::SelectObject(GetSafeHdc(), hBitmap);
  407. }
  408. CXTPCompatibleDC::~CXTPCompatibleDC()
  409. {
  410. ::SelectObject(GetSafeHdc(), m_hOldBitmap);
  411. DeleteDC();
  412. }
  413. //===========================================================================
  414. // CXTPSplitterTracker class
  415. //===========================================================================
  416. CXTPSplitterTracker::CXTPSplitterTracker(BOOL bSolid /*= FALSE*/)
  417. {
  418. m_bSolid = bSolid;
  419. m_rcBoundRect.SetRectEmpty();
  420. m_pDC = 0;
  421. }
  422. void CXTPSplitterTracker::OnInvertTracker(CRect rect)
  423. {
  424. ASSERT(!rect.IsRectEmpty());
  425. if (m_bSolid)
  426. {
  427. m_pDC->InvertRect(rect);
  428. }
  429. else
  430. {
  431. CBrush* pDitherBrush = CDC::GetHalftoneBrush();
  432. CBrush* pBrush = (CBrush*)m_pDC->SelectObject(pDitherBrush);
  433. m_pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT);
  434. m_pDC->SelectObject(pBrush);
  435. }
  436. }
  437. BOOL CXTPSplitterTracker::Track(CWnd* pTrackWnd, CRect rcAvail, CRect& rectTracker, CPoint point, BOOL bHoriz)
  438. {
  439. pTrackWnd->SetCapture();
  440. m_pDC = 0;
  441. CWnd* pWnd = CWnd::GetDesktopWindow();
  442. if (pWnd->LockWindowUpdate())
  443. m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
  444. else
  445. m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE);
  446. ASSERT(m_pDC != NULL);
  447. CPoint ptOffset = bHoriz ? CPoint(rectTracker.left - point.x, 0) :
  448. CPoint(0, rectTracker.top - point.y);
  449. OnInvertTracker(rectTracker);
  450. if (!m_rcBoundRect.IsRectEmpty())
  451. OnInvertTracker(m_rcBoundRect);
  452. BOOL bAccept = FALSE;
  453. while (CWnd::GetCapture() == pTrackWnd)
  454. {
  455. MSG msg;
  456. if (!GetMessage(&msg, NULL, 0, 0))
  457. break;
  458. if (msg.message == WM_MOUSEMOVE)
  459. {
  460. point = CPoint(msg.lParam);
  461. pTrackWnd->ClientToScreen(&point);
  462. point += ptOffset;
  463. point.x = max(min(point.x, rcAvail.right), rcAvail.left);
  464. point.y = max(min(point.y, rcAvail.bottom), rcAvail.top);
  465. if (bHoriz)
  466. {
  467. if (rectTracker.left != point.x)
  468. {
  469. OnInvertTracker(rectTracker);
  470. rectTracker.OffsetRect(point.x - rectTracker.left, 0);
  471. OnInvertTracker(rectTracker);
  472. }
  473. }
  474. else
  475. {
  476. if (rectTracker.top != point.y)
  477. {
  478. OnInvertTracker(rectTracker);
  479. rectTracker.OffsetRect(0, point.y - rectTracker.top);
  480. OnInvertTracker(rectTracker);
  481. }
  482. }
  483. }
  484. else if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) break;
  485. else if (msg.message == WM_LBUTTONUP)
  486. {
  487. bAccept = TRUE;
  488. break;
  489. }
  490. else  ::DispatchMessage(&msg);
  491. }
  492. if (!m_rcBoundRect.IsRectEmpty())
  493. OnInvertTracker(m_rcBoundRect);
  494. OnInvertTracker(rectTracker);
  495. if (CWnd::GetCapture() == pTrackWnd) ReleaseCapture();
  496. pWnd = CWnd::GetDesktopWindow();
  497. pWnd->UnlockWindowUpdate();
  498. if (m_pDC != NULL)
  499. {
  500. pWnd->ReleaseDC(m_pDC);
  501. m_pDC = NULL;
  502. }
  503. return bAccept;
  504. }
  505. //===========================================================================
  506. // CXTPDrawHelpers class
  507. //===========================================================================
  508. CXTPDrawHelpers::CXTPDrawHelpers()
  509. {
  510. m_pfnFastGradientFill = 0;
  511. m_pfnAlphaBlend = 0;
  512. m_pfnTransparentBlt = 0;
  513. // Don't use CXTPModuleHandle to reduce dependence between common source
  514. m_hMsImgDll = ::LoadLibrary(_T("msimg32.dll"));
  515. if (m_hMsImgDll)
  516. {
  517. m_pfnFastGradientFill = (PFNGRADIENTFILL)GetProcAddress(m_hMsImgDll, "GradientFill");
  518. m_pfnAlphaBlend = (PFNALPHABLEND)::GetProcAddress(m_hMsImgDll, "AlphaBlend");
  519. m_pfnTransparentBlt = (PFNTRANSPARENTBLT)::GetProcAddress(m_hMsImgDll, "TransparentBlt");
  520. }
  521. }
  522. CXTPDrawHelpers* AFX_CDECL XTPDrawHelpers()
  523. {
  524. static CXTPDrawHelpers s_instance; // singleton
  525. return &s_instance;
  526. }
  527. CXTPDrawHelpers::~CXTPDrawHelpers()
  528. {
  529. if (m_hMsImgDll != NULL)
  530. {
  531. //::FreeLibrary(m_hMsImgDll); Dangerous to call FreeLibrary in destructor of static object.
  532. }
  533. }
  534. BOOL CXTPDrawHelpers::GradientFill(HDC hdc, PTRIVERTEX pVertex, ULONG dwNumVertex, PVOID pMesh, ULONG dwNumMesh, ULONG dwMode)
  535. {
  536. if (m_pfnFastGradientFill)
  537. {
  538. return (*m_pfnFastGradientFill)(hdc, pVertex, dwNumVertex, pMesh, dwNumMesh, dwMode);
  539. }
  540. return FALSE;
  541. }
  542. void CXTPDrawHelpers::GradientFillSlow(CDC* pDC, LPCRECT lpRect, COLORREF crFrom, COLORREF crTo, BOOL bHorz)
  543. {
  544. int cx = max(1, lpRect->right - lpRect->left);
  545. int cy = max(1, lpRect->bottom - lpRect->top);
  546. CRect rc;
  547. pDC->GetClipBox(&rc);
  548. if (rc.IsRectEmpty())
  549. rc = *lpRect;
  550. else
  551. rc.IntersectRect(rc, lpRect);
  552. if (bHorz)
  553. {
  554. for (int nX = rc.left; nX < rc.right; nX++)
  555. {
  556. pDC->FillSolidRect(nX, rc.top, 1, rc.Height(), BlendColors(
  557. crFrom, crTo, (double)(1.0 - ((nX - lpRect->left) / (double)cx))));
  558. }
  559. }
  560. else
  561. {
  562. for (int nY = rc.top; nY < rc.bottom; nY++)
  563. {
  564. pDC->FillSolidRect(rc.left, nY, rc.Width(), 1, BlendColors(
  565. crFrom, crTo, (double)(1.0 - ((nY - lpRect->top)) / (double)cy)));
  566. }
  567. }
  568. }
  569. void CXTPDrawHelpers::GradientFillFast(CDC* pDC, LPCRECT lpRect, COLORREF crFrom, COLORREF crTo, BOOL bHorz)
  570. {
  571. TRIVERTEX vert[2];
  572. vert[0].x = lpRect->left;
  573. vert[0].y = lpRect->top;
  574. vert[0].Red = (COLOR16)(GetRValue(crFrom) << 8);
  575. vert[0].Green = (COLOR16)(GetGValue(crFrom) << 8);
  576. vert[0].Blue = (COLOR16)(GetBValue(crFrom) << 8);
  577. vert[0].Alpha = 0x0000;
  578. vert[1].x = lpRect->right;
  579. vert[1].y = lpRect->bottom;
  580. vert[1].Red = (COLOR16)(GetRValue(crTo) << 8);
  581. vert[1].Green = (COLOR16)(GetGValue(crTo) << 8);
  582. vert[1].Blue = (COLOR16)(GetBValue(crTo) << 8);
  583. vert[1].Alpha = 0x0000;
  584. GRADIENT_RECT gRect = { 0, 1 };
  585. GradientFill(*pDC, vert, 2, &gRect, 1, bHorz ? GRADIENT_FILL_RECT_H : GRADIENT_FILL_RECT_V);
  586. }
  587. void CXTPDrawHelpers::GradientFill(CDC* pDC, LPCRECT lpRect, COLORREF crFrom, COLORREF crTo, BOOL bHorz)
  588. {
  589. if (!lpRect)
  590. return;
  591. if (::IsRectEmpty(lpRect))
  592. return;
  593. if (IsLowResolution(pDC->GetSafeHdc()))
  594. {
  595. pDC->FillSolidRect(lpRect, crFrom);
  596. }
  597. else if (crFrom == crTo)
  598. {
  599. pDC->FillSolidRect(lpRect, crFrom);
  600. }
  601. else if ((m_pfnFastGradientFill == NULL) || (IsContextRTL(pDC) && XTPSystemVersion()->IsWin9x()))
  602. {
  603. GradientFillSlow(pDC, lpRect, crFrom, crTo, bHorz);
  604. }
  605. else
  606. {
  607. GradientFillFast(pDC, lpRect, crFrom, crTo, bHorz);
  608. }
  609. }
  610. void CXTPDrawHelpers::GradientFill(CDC* pDC, LPCRECT lpRect, COLORREF crFrom, COLORREF crTo, BOOL bHorz, LPCRECT lpRectClip)
  611. {
  612. CRect rc(lpRect);
  613. if (lpRectClip == NULL)
  614. {
  615. GradientFill(pDC, lpRect, crFrom, crTo, bHorz);
  616. return;
  617. }
  618. COLORREF crFrom1 = crFrom;
  619. if (bHorz)
  620. {
  621. if (rc.top < lpRectClip->top)
  622. {
  623. rc.top = lpRectClip->top;
  624. }
  625. if (rc.bottom > lpRectClip->bottom)
  626. {
  627. rc.bottom = lpRectClip->bottom;
  628. }
  629. if ((rc.left > lpRectClip->right) || (rc.right < lpRectClip->left))
  630. return;
  631. if (rc.left < lpRectClip->left)
  632. {
  633. rc.left = lpRectClip->left;
  634. crFrom = BlendColors(crFrom, crTo,
  635. (float)(lpRect->right - lpRectClip->left) / (float)(lpRect->right - lpRect->left));
  636. }
  637. if (rc.right > lpRectClip->right)
  638. {
  639. rc.right = lpRectClip->right;
  640. crTo = BlendColors(crFrom1, crTo,
  641. (float)(lpRect->right - lpRectClip->right) / (float)(lpRect->right - lpRect->left));
  642. }
  643. GradientFill(pDC, rc, crFrom, crTo, bHorz);
  644. }
  645. else
  646. {
  647. if (rc.left < lpRectClip->left)
  648. {
  649. rc.left = lpRectClip->left;
  650. }
  651. if (rc.right > lpRectClip->right)
  652. {
  653. rc.right = lpRectClip->right;
  654. }
  655. if ((rc.top > lpRectClip->bottom) || (rc.bottom < lpRectClip->top))
  656. return;
  657. if (rc.top < lpRectClip->top)
  658. {
  659. rc.top = lpRectClip->top;
  660. crFrom = BlendColors(crFrom, crTo,
  661. (float)(lpRect->bottom - lpRectClip->top) / (float)(lpRect->bottom - lpRect->top));
  662. }
  663. if (rc.bottom > lpRectClip->bottom)
  664. {
  665. rc.bottom = lpRectClip->bottom;
  666. crTo = BlendColors(crFrom1, crTo,
  667. (float)(lpRect->bottom - lpRectClip->bottom) / (float)(lpRect->bottom - lpRect->top));
  668. }
  669. GradientFill(pDC, rc, crFrom, crTo, bHorz);
  670. }
  671. }
  672. void CXTPDrawHelpers::GradientFill(CDC* pDC, LPCRECT lpRect, const CXTPPaintManagerColorGradient& grc, BOOL bHorz, LPCRECT lpRectClip)
  673. {
  674. // using gradient factor color gradient fill
  675. if (grc.fGradientFactor != 0.5f)
  676. {
  677. COLORREF clrMid = BlendColors(grc.clrLight, grc.clrDark, grc.fGradientFactor);
  678. if (bHorz)
  679. {
  680. CRect rcLeft(lpRect);
  681. rcLeft.right -= rcLeft.Width()/2;
  682. GradientFill(pDC, &rcLeft, grc.clrLight, clrMid, bHorz, lpRectClip);
  683. CRect rcRight(lpRect);
  684. rcRight.left = rcLeft.right;
  685. GradientFill(pDC, &rcRight, clrMid, grc.clrDark, bHorz, lpRectClip);
  686. }
  687. else
  688. {
  689. CRect rcTop(lpRect);
  690. rcTop.bottom -= rcTop.Height()/2;
  691. GradientFill(pDC, &rcTop, grc.clrLight, clrMid, bHorz, lpRectClip);
  692. CRect rcBottom(lpRect);
  693. rcBottom.top = rcTop.bottom;
  694. GradientFill(pDC, &rcBottom, clrMid, grc.clrDark, bHorz, lpRectClip);
  695. }
  696. }
  697. // using 2 color gradient fill
  698. else
  699. {
  700. GradientFill(pDC, lpRect, grc.clrLight, grc.clrDark, bHorz, lpRectClip);
  701. }
  702. }
  703. void CXTPDrawHelpers::ExcludeCorners(CDC* pDC, CRect rc)
  704. {
  705. pDC->ExcludeClipRect(rc.left, rc.top, rc.left + 1, rc.top + 1);
  706. pDC->ExcludeClipRect(rc.right - 1, rc.top, rc.right, rc.top + 1);
  707. pDC->ExcludeClipRect(rc.left, rc.bottom - 1, rc.left + 1, rc.bottom);
  708. pDC->ExcludeClipRect(rc.right - 1, rc.bottom - 1, rc.right, rc.bottom);
  709. }
  710. void CXTPDrawHelpers::StripMnemonics(CString& strClear)
  711. {
  712. for (int i = 0; i < strClear.GetLength(); i++)
  713. {
  714. if (strClear[i] == _T('&') && (i == strClear.GetLength() - 1 || strClear[i + 1] != _T('&')))
  715. {
  716. DELETE_S(strClear, i);
  717. }
  718. }
  719. }
  720. void CXTPDrawHelpers::StripMnemonics(LPTSTR lpszClear)
  721. {
  722. if (lpszClear == NULL || lpszClear == LPSTR_TEXTCALLBACK)
  723. return;
  724. LPTSTR lpszResult = lpszClear;
  725. while (*lpszClear)
  726. {
  727. if (*lpszClear == _T('&') && *(lpszClear + 1) != _T('&'))
  728. {
  729. lpszClear++;
  730. continue;
  731. }
  732. *lpszResult++ = *lpszClear++;
  733. }
  734. *lpszResult = 0;
  735. }
  736. void CXTPDrawHelpers::BlurPoints(CDC* pDC, LPPOINT pts, int nCount)
  737. {
  738. for (int i = 0; i < nCount; i += 2)
  739. {
  740. CPoint ptBlur = pts[i];
  741. CPoint ptDirection(pts[i].x + pts[i + 1].x, pts[i].y + pts[i + 1].y);
  742. COLORREF clrBlur = pDC->GetPixel(ptDirection);
  743. COLORREF clrDirection = pDC->GetPixel(ptBlur);
  744. pDC->SetPixel(ptBlur, RGB(
  745. (GetRValue(clrBlur) + GetRValue(clrDirection)) / 2,
  746. (GetGValue(clrBlur) + GetGValue(clrDirection)) / 2,
  747. (GetBValue(clrBlur) + GetBValue(clrDirection)) / 2));
  748. }
  749. }
  750. COLORREF CXTPDrawHelpers::BlendColors(COLORREF crA, COLORREF crB, double fAmountA)
  751. {
  752. double fAmountB = (1.0 - fAmountA);
  753. int btR = (int)(GetRValue(crA) * fAmountA + GetRValue(crB) * fAmountB);
  754. int btG = (int)(GetGValue(crA) * fAmountA + GetGValue(crB) * fAmountB);
  755. int btB = (int)(GetBValue(crA) * fAmountA + GetBValue(crB) * fAmountB);
  756. return RGB(min(255, btR), (BYTE)min(255, btG), (BYTE)min(255, btB));
  757. }
  758. COLORREF CXTPDrawHelpers::DarkenColor(long lScale, COLORREF lColor)
  759. {
  760. long red   = MulDiv(GetRValue(lColor), (255 - lScale), 255);
  761. long green = MulDiv(GetGValue(lColor), (255 - lScale), 255);
  762. long blue  = MulDiv(GetBValue(lColor), (255 - lScale), 255);
  763. return RGB(red, green, blue);
  764. }
  765. COLORREF CXTPDrawHelpers::LightenColor(long lScale, COLORREF lColor)
  766. {
  767. long R = MulDiv(255 - GetRValue(lColor), lScale, 255) + GetRValue(lColor);
  768. long G = MulDiv(255 - GetGValue(lColor), lScale, 255) + GetGValue(lColor);
  769. long B = MulDiv(255 - GetBValue(lColor), lScale, 255) + GetBValue(lColor);
  770. return RGB(R, G, B);
  771. }
  772. CPoint CXTPDrawHelpers::Dlu2Pix(int dluX, int dluY)
  773. {
  774. CPoint baseXY(::GetDialogBaseUnits());
  775. CPoint pixXY(0,0);
  776. pixXY.x = ::MulDiv(dluX, baseXY.x, 4);
  777. pixXY.y = ::MulDiv(dluY, baseXY.y, 8);
  778. return pixXY;
  779. }
  780. COLORREF CXTPDrawHelpers::RGBtoHSL(COLORREF rgb)
  781. {
  782. int delta, sum;
  783. int nH, nS, nL;
  784. int r = GetRValue(rgb);
  785. int g = GetGValue(rgb);
  786. int b = GetBValue(rgb);
  787. int cmax = ((r) >= (g) ? ((r) >= (b) ? (r) : (b)) : (g) >= (b) ? (g) : (b));
  788. int cmin = ((r) <= (g) ? ((r) <= (b) ? (r) : (b)) : (g) <= (b) ? (g) : (b));
  789. nL = (cmax + cmin + 1) / 2;
  790. if(cmax == cmin)
  791. {
  792. nH = 255; // H is really undefined
  793. nS = 0;
  794. }
  795. else
  796. {
  797. delta = cmax - cmin;
  798. sum = cmax + cmin;
  799. if(nL < 127)
  800. nS = ((delta + 1) * 256) / sum;
  801. else
  802. nS = (delta * 256) / ((2 * 256) - sum);
  803. if(r == cmax)
  804. nH = ((g - b) * 256) / delta;
  805. else if(g == cmax)
  806. nH = (2 * 256) + ((b - r) * 256) / delta;
  807. else
  808. nH = (4 * 256) + ((r - g) * 256) / delta;
  809. nH /= 6;
  810. if(nH < 0)
  811. nH += 256;
  812. }
  813. nH = nH * 239 / 255;
  814. nS = nS * 240 / 255;
  815. nL = nL * 240 / 255;
  816. return RGB((BYTE)min(nH, 239), (BYTE)min(nS, 240), (BYTE)min(nL, 240));
  817. }
  818. void CXTPDrawHelpers::RGBtoHSL(COLORREF clr, double& h, double& s, double& l)
  819. {
  820. double r = (double)GetRValue(clr)/255.0;
  821. double g = (double)GetGValue(clr)/255.0;
  822. double b = (double)GetBValue(clr)/255.0;
  823. double maxcolor = __max(r, __max(g, b));
  824. double mincolor = __min(r, __min(g, b));
  825. l = (maxcolor + mincolor)/2;
  826. if (maxcolor == mincolor)
  827. {
  828. h = 0;
  829. s = 0;
  830. }
  831. else
  832. {
  833. if (l < 0.5)
  834. s = (maxcolor-mincolor)/(maxcolor + mincolor);
  835. else
  836. s = (maxcolor-mincolor)/(2.0-maxcolor-mincolor);
  837. if (r == maxcolor)
  838. h = (g-b)/(maxcolor-mincolor);
  839. else if (g == maxcolor)
  840. h = 2.0+(b-r)/(maxcolor-mincolor);
  841. else
  842. h = 4.0+(r-g)/(maxcolor-mincolor);
  843. h /= 6.0;
  844. if (h < 0.0) h += 1;
  845. }
  846. }
  847. double CXTPDrawHelpers::HueToRGB(double temp1, double temp2, double temp3)
  848. {
  849. if (temp3 < 0)
  850. temp3 = temp3 + 1.0;
  851. if (temp3 > 1)
  852. temp3 = temp3-1.0;
  853. if (6.0*temp3 < 1)
  854. return (temp1+(temp2-temp1)*temp3 * 6.0);
  855. else if (2.0*temp3 < 1)
  856. return temp2;
  857. else if (3.0*temp3 < 2.0)
  858. return (temp1+(temp2-temp1)*((2.0/3.0)-temp3)*6.0);
  859. return temp1;
  860. }
  861. int CXTPDrawHelpers::HueToRGB(int m1, int m2, int h)
  862. {
  863. if(h < 0)
  864. h += 255;
  865. if(h > 255)
  866. h -= 255;
  867. if((6 * h) < 255)
  868. return ((m1 + ((m2 - m1) / 255 * h * 6)) / 255);
  869. if((2 * h) < 255)
  870. return m2 / 255;
  871. if((3 * h) < (2 * 255))
  872. return ((m1 + (m2 - m1) / 255 * ((255 * 2 / 3) - h) * 6) / 255);
  873. return (m1 / 255);
  874. }
  875. COLORREF CXTPDrawHelpers::HSLtoRGB(COLORREF hsl)
  876. {
  877. int r, g, b;
  878. int m1, m2;
  879. int nH = GetRValue(hsl) * 255 / 239;
  880. int nS = GetGValue(hsl) * 255 / 240;
  881. int nL = GetBValue(hsl) * 255 / 240;
  882. if(nS == 0)
  883. r = g = b = nL;
  884. else
  885. {
  886. if(nL <= 127)
  887. m2 = nL * (255 + nS);
  888. else
  889. m2 = (nL + nS - ((nL * nS) / 255)) * 255;
  890. m1 = (2 * 255 * nL) - m2;
  891. r = HueToRGB(m1, m2, nH + (255 / 3));
  892. g = HueToRGB(m1, m2, nH);
  893. b = HueToRGB(m1, m2, nH - (255 / 3));
  894. }
  895. return RGB((BYTE)min(r, 255), (BYTE)min(g, 255), (BYTE)min(b, 255));
  896. }
  897. COLORREF CXTPDrawHelpers::HSLtoRGB(double h, double s, double l)
  898. {
  899. double r, g, b;
  900. double temp1, temp2;
  901. if (s == 0)
  902. {
  903. r = g = b = l;
  904. }
  905. else
  906. {
  907. if (l < 0.5)
  908. temp2 = l*(1.0 + s);
  909. else
  910. temp2 = l + s-l*s;
  911. temp1 = 2.0 * l-temp2;
  912. r = HueToRGB(temp1, temp2, h + 1.0/3.0);
  913. g = HueToRGB(temp1, temp2, h);
  914. b = HueToRGB(temp1, temp2, h - 1.0/3.0);
  915. }
  916. return RGB((BYTE)(r * 255), (BYTE)(g * 255), (BYTE)(b * 255));
  917. }
  918. static int CALLBACK XTPEnumFontFamExProc(ENUMLOGFONTEX* pelf, NEWTEXTMETRICEX* /*lpntm*/, int /*FontType*/, LPVOID pThis)
  919. {
  920. LPCTSTR strFontName = (LPCTSTR)pThis;
  921. CString strFaceName = pelf->elfLogFont.lfFaceName;
  922. if (strFaceName.CompareNoCase(strFontName) == 0)
  923. return 0;
  924. return 1;
  925. }
  926. BOOL CXTPDrawHelpers::FontExists(LPCTSTR strFaceName)
  927. {
  928. // Enumerate all styles and charsets of all fonts:
  929. LOGFONT lfEnum;
  930. ::ZeroMemory(&lfEnum, sizeof(LOGFONT));
  931. lfEnum.lfFaceName[ 0 ] = 0;
  932. lfEnum.lfCharSet = DEFAULT_CHARSET;
  933. CWindowDC dc(NULL);
  934. return  ::EnumFontFamiliesEx(dc.m_hDC, &lfEnum, (FONTENUMPROC)
  935. XTPEnumFontFamExProc, (LPARAM)strFaceName, 0) == 0;
  936. }
  937. CString CXTPDrawHelpers::GetDefaultFontName()
  938. {
  939. LOGFONT lfFont;
  940. ZeroMemory(&lfFont, sizeof(LOGFONT));
  941. ::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lfFont);
  942. return CString(lfFont.lfFaceName);
  943. }
  944. CString AFX_CDECL CXTPDrawHelpers::GetVerticalFontName(BOOL bUseOfficeFont)
  945. {
  946. LOGFONT lfFont;
  947. ZeroMemory(&lfFont, sizeof(LOGFONT));
  948. ::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lfFont);
  949. bool bUseSystemFont = lfFont.lfCharSet > SYMBOL_CHARSET;
  950. if (bUseSystemFont && !XTPSystemVersion()->IsWin2KOrGreater())
  951. bUseSystemFont = FALSE;
  952. if (bUseSystemFont && (_tcsicmp(lfFont.lfFaceName, _T("MS Shell Dlg")) == 0))
  953. bUseSystemFont = FALSE; // Can draw it vertically in Windows 2000.
  954. CString strVerticalFaceName = _T("Arial");
  955. LPCTSTR strOfficeFont = _T("Tahoma");
  956. if (bUseSystemFont || !FontExists(strVerticalFaceName))
  957. {
  958. strVerticalFaceName = lfFont.lfFaceName;
  959. }
  960. else if (bUseOfficeFont && !bUseSystemFont && FontExists(strOfficeFont))
  961. {
  962. strVerticalFaceName = strOfficeFont;
  963. }
  964. return strVerticalFaceName;
  965. }
  966. BOOL CXTPDrawHelpers::IsContextRTL(CDC* pDC)
  967. {
  968. return pDC && IsContextRTL(pDC->GetSafeHdc());
  969. }
  970. BOOL CXTPDrawHelpers::IsContextRTL(HDC hDC)
  971. {
  972. typedef DWORD (CALLBACK* PFNGDIGETLAYOUTPROC)(HDC);
  973. static PFNGDIGETLAYOUTPROC s_pfn = (PFNGDIGETLAYOUTPROC)-1;
  974. if (s_pfn == (PFNGDIGETLAYOUTPROC)-1)
  975. {
  976. HINSTANCE hInst = ::GetModuleHandleA("GDI32.DLL");
  977. s_pfn = hInst ? (PFNGDIGETLAYOUTPROC)GetProcAddress(hInst, "GetLayout") : NULL;
  978. }
  979. return s_pfn ? (*s_pfn)(hDC) : FALSE;
  980. }
  981. void CXTPDrawHelpers::SetContextRTL(CDC* pDC, BOOL bLayoutRTL)
  982. {
  983. if (pDC) SetContextRTL(pDC->GetSafeHdc(), bLayoutRTL);
  984. }
  985. void CXTPDrawHelpers::SetContextRTL(HDC hDC, BOOL bLayoutRTL)
  986. {
  987. typedef DWORD (CALLBACK* PFNGDISETLAYOUTPROC)(HDC, DWORD);
  988. static PFNGDISETLAYOUTPROC s_pfn = (PFNGDISETLAYOUTPROC)-1;
  989. if (s_pfn == (PFNGDISETLAYOUTPROC)-1)
  990. {
  991. HINSTANCE hInst = ::GetModuleHandleA("GDI32.DLL");
  992. s_pfn = hInst ? (PFNGDISETLAYOUTPROC)GetProcAddress(hInst, "SetLayout") : NULL;
  993. }
  994. if (s_pfn != NULL)
  995. {
  996. (*s_pfn)(hDC, bLayoutRTL);
  997. }
  998. }
  999. void CXTPDrawHelpers::KeyToLayout(CWnd* pWnd, UINT& nChar)
  1000. {
  1001. ASSERT(pWnd);
  1002. if (!pWnd || !pWnd->GetSafeHwnd())
  1003. return;
  1004. if (nChar == VK_LEFT && pWnd->GetExStyle() & WS_EX_LAYOUTRTL)
  1005. nChar = VK_RIGHT;
  1006. else if (nChar == VK_RIGHT && pWnd->GetExStyle() & WS_EX_LAYOUTRTL)
  1007. nChar = VK_LEFT;
  1008. }
  1009. void CXTPDrawHelpers::Triangle(CDC* pDC, CPoint pt0, CPoint pt1, CPoint pt2, COLORREF clr)
  1010. {
  1011. CXTPPenDC pen (*pDC, clr);
  1012. CXTPBrushDC brush (*pDC, clr);
  1013. Triangle(pDC, pt0, pt1, pt2);
  1014. }
  1015. BOOL CXTPDrawHelpers::DrawLine(CDC* pDC, int x, int y, int nLength, int nHeight, COLORREF crLine)
  1016. {
  1017. if (pDC->GetSafeHdc())
  1018. {
  1019. CXTPPenDC penDC(*pDC, crLine);
  1020. pDC->MoveTo(x, y);
  1021. pDC->LineTo(x + nLength, y + nHeight);
  1022. return TRUE;
  1023. }
  1024. return FALSE;
  1025. }
  1026. DWORD CXTPDrawHelpers::GetComCtlVersion()
  1027. {
  1028. return XTPSystemVersion()->GetComCtlVersion();
  1029. }
  1030. BOOL CXTPDrawHelpers::IsLowResolution(HDC hDC/* = 0*/)
  1031. {
  1032. return XTPColorManager()->IsLowResolution(hDC);
  1033. }
  1034. CRect CXTPDrawHelpers::GetWorkArea(LPCRECT rect)
  1035. {
  1036. return XTPMultiMonitor()->GetWorkArea(rect);
  1037. }
  1038. CRect CXTPDrawHelpers::GetWorkArea(const CWnd* pWnd)
  1039. {
  1040. return XTPMultiMonitor()->GetWorkArea(pWnd);
  1041. }
  1042. CRect CXTPDrawHelpers::GetScreenArea(const CWnd* pWnd)
  1043. {
  1044. return XTPMultiMonitor()->GetScreenArea(pWnd);
  1045. }
  1046. CRect CXTPDrawHelpers::GetWorkArea(const POINT& point)
  1047. {
  1048. return XTPMultiMonitor()->GetWorkArea(point);
  1049. }
  1050. CRect CXTPDrawHelpers::GetWorkArea()
  1051. {
  1052. return XTPMultiMonitor()->GetWorkArea();
  1053. }
  1054. BOOL CXTPDrawHelpers::IsTopParentActive(HWND hWnd)
  1055. {
  1056. HWND hwndForeground = ::GetForegroundWindow();
  1057. HWND hWndT;
  1058. while ((hWndT = AfxGetParentOwner(hWnd)) != NULL)
  1059. {
  1060. hWnd = hWndT;
  1061. }
  1062. HWND hwndActivePopup = ::GetLastActivePopup(hWnd);
  1063. if (hwndForeground == hwndActivePopup)
  1064. return TRUE;
  1065. return FALSE;
  1066. }
  1067. void CXTPDrawHelpers::ScreenToWindow(CWnd* pWnd, LPPOINT lpPoint)
  1068. {
  1069. RECT rc;
  1070. ::GetWindowRect(pWnd->GetSafeHwnd(), &rc);
  1071. lpPoint->y -= rc.top;
  1072. if (GetWindowLong(pWnd->GetSafeHwnd(), GWL_EXSTYLE) & WS_EX_LAYOUTRTL )
  1073. {
  1074. lpPoint->x = rc.right - lpPoint->x;
  1075. }
  1076. else
  1077. {
  1078. lpPoint->x -= rc.left;
  1079. }
  1080. }
  1081. BOOL AFX_CDECL CXTPDrawHelpers::RegisterWndClass(HINSTANCE hInstance, LPCTSTR lpszClassName, UINT style, HICON hIcon)
  1082. {
  1083. WNDCLASS wndcls;
  1084. ZeroMemory(&wndcls, sizeof(wndcls));
  1085. wndcls.style = style;
  1086. wndcls.lpfnWndProc = ::DefWindowProc;
  1087. wndcls.hInstance = hInstance ? hInstance : AfxGetInstanceHandle();
  1088. wndcls.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
  1089. wndcls.lpszClassName = lpszClassName;
  1090. wndcls.hIcon = hIcon;
  1091. return AfxRegisterClass(&wndcls);
  1092. }
  1093. void CXTPDrawHelpers::GetWindowCaption(HWND hWnd, CString& strWindowText)
  1094. {
  1095. #ifdef _UNICODE
  1096. int nLen = (int)::DefWindowProc(hWnd, WM_GETTEXTLENGTH, 0, 0);
  1097. ::DefWindowProc(hWnd, WM_GETTEXT, nLen + 1, (WPARAM)(LPCTSTR)strWindowText.GetBuffer(nLen));
  1098. strWindowText.ReleaseBuffer();
  1099. #else
  1100. int nLen = ::GetWindowTextLength(hWnd);
  1101. ::GetWindowText(hWnd, strWindowText.GetBufferSetLength(nLen), nLen + 1);
  1102. strWindowText.ReleaseBuffer();
  1103. #endif
  1104. }
  1105. BOOL AFX_CDECL XTPGetPrinterDeviceDefaults(HGLOBAL& ref_hDevMode, HGLOBAL& ref_hDevNames)
  1106. {
  1107. CWinApp* pApp = AfxGetApp();
  1108. if (pApp)
  1109. {
  1110. PRINTDLG _pd;
  1111. ::ZeroMemory(&_pd, sizeof(_pd));
  1112. if (pApp->GetPrinterDeviceDefaults(&_pd))
  1113. {
  1114. ref_hDevMode = _pd.hDevMode;
  1115. ref_hDevNames = _pd.hDevNames;
  1116. return TRUE;
  1117. }
  1118. }
  1119. return FALSE;
  1120. }
  1121. //////////////////////////////////////////////////////////////////////////
  1122. IMPLEMENT_DYNAMIC(CXTPPrinterInfo, CCmdTarget)
  1123. CXTPPrinterInfo::CXTPPrinterInfo()
  1124. {
  1125. }
  1126. CXTPPrinterInfo::~CXTPPrinterInfo()
  1127. {
  1128. }
  1129. CString CXTPPrinterInfo::GetName(XTPEnumDeviceName eNameID)
  1130. {
  1131. CString strName;
  1132. HGLOBAL hDevMode = NULL, hDevNames = NULL;
  1133. if (XTPGetPrinterDeviceDefaults(hDevMode, hDevNames) && hDevNames != NULL)
  1134. {
  1135. LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(hDevNames);
  1136. if (lpDev)
  1137. {
  1138. strName = (LPCTSTR)lpDev + _GetNameOffset(lpDev, eNameID);
  1139. }
  1140. ::GlobalUnlock(hDevNames);
  1141. }
  1142. return strName;
  1143. }
  1144. WORD CXTPPrinterInfo::_GetNameOffset(LPDEVNAMES pDevNames, XTPEnumDeviceName eNameID)
  1145. {
  1146. ASSERT(pDevNames);
  1147. if (!pDevNames)
  1148. return 0;
  1149. switch(eNameID)
  1150. {
  1151. case xtpDevName_Driver:
  1152. return pDevNames->wDriverOffset;
  1153. case xtpDevName_Device:
  1154. return pDevNames->wDeviceOffset;
  1155. case xtpDevName_Port:
  1156. return pDevNames->wOutputOffset;
  1157. };
  1158. ASSERT(FALSE);
  1159. return 0;
  1160. }
  1161. /////////////////////////////////////////////////////////////////////////////
  1162. IMPLEMENT_DYNAMIC(CXTPPrintPageHeaderFooter, CCmdTarget)
  1163. CXTPPrintPageHeaderFooter::CXTPPrintPageHeaderFooter(CXTPPrintOptions* pOwner, BOOL bHeader)
  1164. {
  1165. ASSERT(pOwner);
  1166. m_bHeader = bHeader;
  1167. m_pOwner = pOwner;
  1168. VERIFY( ::SystemParametersInfo( SPI_GETICONTITLELOGFONT, sizeof(m_lfFont), &m_lfFont, 0 ) );
  1169. m_clrColor = RGB(0, 0, 0);
  1170. }
  1171. CXTPPrintPageHeaderFooter::~CXTPPrintPageHeaderFooter()
  1172. {
  1173. }
  1174. void CXTPPrintPageHeaderFooter::Set(const CXTPPrintPageHeaderFooter* pSrc)
  1175. {
  1176. ASSERT(pSrc);
  1177. if (!pSrc)
  1178. return;
  1179. m_lfFont = pSrc->m_lfFont;
  1180. m_clrColor = pSrc->m_clrColor;
  1181. m_strFormatString = pSrc->m_strFormatString;
  1182. m_strLeft = pSrc->m_strLeft;
  1183. m_strCenter = pSrc->m_strCenter;
  1184. m_strRight = pSrc->m_strRight;
  1185. }
  1186. void CXTPPrintPageHeaderFooter::Clear()
  1187. {
  1188. VERIFY( ::SystemParametersInfo( SPI_GETICONTITLELOGFONT, sizeof(m_lfFont), &m_lfFont, 0 ) );
  1189. m_clrColor = RGB(0, 0, 0);
  1190. m_strFormatString.Empty();
  1191. m_strLeft.Empty();
  1192. m_strCenter.Empty();
  1193. m_strRight.Empty();
  1194. }
  1195. BOOL CXTPPrintPageHeaderFooter::IsEmpty()
  1196. {
  1197. return m_strLeft.IsEmpty() && m_strCenter.IsEmpty() && m_strRight.IsEmpty();
  1198. }
  1199. //===========================================================================
  1200. //  &w      Window title
  1201. //
  1202. //  &d      Date in short format (as specified by Regional Settings in Control Panel)
  1203. //  &D      Date in long format (as specified by Regional Settings in Control Panel)
  1204. //
  1205. //  &t      Time in the format specified by Regional Settings in Control Panel
  1206. //  &T      Time in 24-hour format
  1207. //
  1208. //  &p      Current page number
  1209. //  &P      Total number of pages
  1210. //
  1211. //  &b      The text immediately following these characters as centered.
  1212. //  &b&b    The text immediately following the first "&b" as centered, and the text following the second "&b" as right-justified.
  1213. //
  1214. //  &&      A single ampersand (&)
  1215. //===========================================================================
  1216. void CXTPPrintPageHeaderFooter::FormatTexts(CPrintInfo* pInfo, LPCTSTR pcszWndTitle)
  1217. {
  1218. ASSERT(pInfo);
  1219. if (m_strFormatString.IsEmpty() || !pInfo)
  1220. return;
  1221. LCID lcidLocale = m_pOwner ? m_pOwner->GetActiveLCID() : LOCALE_USER_DEFAULT;
  1222. CString strFormat = m_strFormatString;
  1223. REPLACE_S(strFormat, _T("&&"), _T("1"));
  1224. CString str_p, str_P = _T("*");
  1225. str_p.Format(_T("%d"), pInfo->m_nCurPage);
  1226. if (pInfo->GetMaxPage() != 65535)
  1227. str_P.Format(_T("%d"), pInfo->GetMaxPage());
  1228. REPLACE_S(strFormat, _T("&p"), str_p);
  1229. REPLACE_S(strFormat, _T("&P"), str_P);
  1230. REPLACE_S(strFormat, _T("\n"), _T("n"));
  1231. _SplitFormatLCR(strFormat);
  1232. _FormatDateTime(m_strLeft, lcidLocale);
  1233. _FormatDateTime(m_strCenter, lcidLocale);
  1234. _FormatDateTime(m_strRight, lcidLocale);
  1235. if (pcszWndTitle)
  1236. {
  1237. REPLACE_S(m_strLeft, _T("&w"), pcszWndTitle);
  1238. REPLACE_S(m_strCenter, _T("&w"), pcszWndTitle);
  1239. REPLACE_S(m_strRight, _T("&w"), pcszWndTitle);
  1240. }
  1241. REPLACE_S(m_strLeft,  _T("1"), _T("&"));
  1242. REPLACE_S(m_strCenter, _T("1"), _T("&"));
  1243. REPLACE_S(m_strRight, _T("1"), _T("&"));
  1244. }
  1245. CString CXTPPrintPageHeaderFooter::GetParentFrameTitle(CWnd* pWnd)
  1246. {
  1247. CString strTitle;
  1248. ASSERT(pWnd);
  1249. if (!pWnd)
  1250. return strTitle;
  1251. pWnd->GetWindowText(strTitle);
  1252. if (strTitle.IsEmpty() || !pWnd->IsFrameWnd())
  1253. {
  1254. if (pWnd->GetParentFrame())
  1255. pWnd->GetParentFrame()->GetWindowText(strTitle);
  1256. if (strTitle.IsEmpty())
  1257. {
  1258. if (pWnd->GetParentOwner())
  1259. pWnd->GetParentOwner()->GetWindowText(strTitle);
  1260. }
  1261. }
  1262. return strTitle;
  1263. }
  1264. void CXTPPrintPageHeaderFooter::_FormatDateTime(CString& strFormat, LCID lcidLocale)
  1265. {
  1266. SYSTEMTIME stNow;
  1267. ::GetLocalTime(&stNow);
  1268. const int cnBufferSize = 200;
  1269. TCHAR szDateFormatShort[cnBufferSize] = {0};
  1270. TCHAR szDateFormatLong[cnBufferSize] = {0};
  1271. TCHAR szTimeFormat[cnBufferSize] = {0};
  1272. TCHAR szTimeFormat24[cnBufferSize] = {0};
  1273. ::GetDateFormat(lcidLocale, DATE_SHORTDATE, &stNow, NULL, szDateFormatShort, cnBufferSize);
  1274. ::GetDateFormat(lcidLocale, DATE_LONGDATE, &stNow, NULL, szDateFormatLong, cnBufferSize);
  1275. ::GetTimeFormat(lcidLocale, 0, &stNow, NULL, szTimeFormat, cnBufferSize);
  1276. DWORD dwFlags24h = TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER;
  1277. ::GetTimeFormat(lcidLocale, dwFlags24h, &stNow, NULL, szTimeFormat24, cnBufferSize);
  1278. REPLACE_S(strFormat, _T("&d"), szDateFormatShort); // &d   Date in short format (as specified by Regional Settings in Control Panel)
  1279. REPLACE_S(strFormat, _T("&D"), szDateFormatLong);  // &D   Date in long format (as specified by Regional Settings in Control Panel)
  1280. REPLACE_S(strFormat, _T("&t"), szTimeFormat);   // &t  Time in the format specified by Regional Settings in Control Panel
  1281. REPLACE_S(strFormat, _T("&T"), szTimeFormat24); // &T  Time in 24-hour format
  1282. }
  1283. void CXTPPrintPageHeaderFooter::_SplitFormatLCR(CString strFormat)
  1284. {
  1285. m_strLeft.Empty();
  1286. m_strCenter.Empty();
  1287. m_strRight.Empty();
  1288. int nAmpBidx = strFormat.Find(_T("&b"));
  1289. if (nAmpBidx < 0)
  1290. {
  1291. m_strLeft = strFormat;
  1292. }
  1293. else if (nAmpBidx >= 0)
  1294. {
  1295. if (nAmpBidx > 0)
  1296. m_strLeft = strFormat.Left(nAmpBidx);
  1297. DELETE_S(strFormat, 0, nAmpBidx + 2);
  1298. nAmpBidx = strFormat.Find(_T("&b"));
  1299. if (nAmpBidx < 0)
  1300. {
  1301. m_strCenter = strFormat;
  1302. }
  1303. else if (nAmpBidx >= 0)
  1304. {
  1305. if (nAmpBidx > 0)
  1306. m_strCenter = strFormat.Left(nAmpBidx);
  1307. DELETE_S(strFormat, 0, nAmpBidx + 2);
  1308. m_strRight = strFormat;
  1309. }
  1310. }
  1311. }
  1312. int CXTPPrintPageHeaderFooter::fnYi(int Xi, int Wi)
  1313. {
  1314. int nYi = Wi / Xi;
  1315. int nYi_ = Wi % Xi;
  1316. return nYi + (nYi_ ? 1 : 0);
  1317. }
  1318. int CXTPPrintPageHeaderFooter::_Calc3ColSizesIfSingleCol(CDC* pDC, int nW,
  1319.   const CString& str1, const CString& str2, const CString& str3,
  1320.   CSize& rsz1, CSize& rsz2, CSize& rsz3)
  1321. {
  1322. CString str1trim = str1;
  1323. CString str2trim = str2;
  1324. CString str3trim = str3;
  1325. str1trim.TrimLeft();
  1326. str2trim.TrimLeft();
  1327. str3trim.TrimLeft();
  1328. UINT uFlags = DT_TOP | DT_WORDBREAK | DT_CALCRECT;
  1329. rsz1 = rsz2 = rsz3 = CSize(0, 0);
  1330. if (!str1trim.IsEmpty() && str2trim.IsEmpty() && str3trim.IsEmpty())
  1331. {
  1332. CRect rcText1(0, 0, nW, 32000);
  1333. rsz1.cx = nW;
  1334. return rsz1.cy = pDC->DrawText(str1, &rcText1, uFlags | DT_LEFT);
  1335. }
  1336. if (str1trim.IsEmpty() && !str2trim.IsEmpty() && str3trim.IsEmpty())
  1337. {
  1338. CRect rcText2(0, 0, nW, 32000);
  1339. rsz2.cx = nW;
  1340. return rsz2.cy = pDC->DrawText(str2, &rcText2, uFlags | DT_CENTER);
  1341. }
  1342. if (str1trim.IsEmpty() && str2trim.IsEmpty() && !str3trim.IsEmpty())
  1343. {
  1344. CRect rcText3(0, 0, nW, 32000);
  1345. rsz3.cx = nW;
  1346. return rsz3.cy = pDC->DrawText(str3, &rcText3, uFlags | DT_RIGHT);
  1347. }
  1348. return -1;
  1349. }
  1350. int CXTPPrintPageHeaderFooter::Calc3ColSizes(CDC* pDC, int nW,
  1351.   const CString& str1, const CString& str2, const CString& str3,
  1352.   CSize& rsz1, CSize& rsz2, CSize& rsz3)
  1353. {
  1354. ASSERT(pDC);
  1355. if (!pDC)
  1356. return 0;
  1357. int nIfSingleCol = _Calc3ColSizesIfSingleCol(pDC, nW, str1, str2, str3, rsz1, rsz2, rsz3);
  1358. if (nIfSingleCol >= 0)
  1359. return nIfSingleCol;
  1360. int nW1 = pDC->GetTextExtent(str1).cx;
  1361. int nW2 = pDC->GetTextExtent(str2).cx;
  1362. int nW3 = pDC->GetTextExtent(str3).cx;
  1363. if (!nW || !nW1 && !nW2 && !nW3)
  1364. return 0;
  1365. nW1 = max(nW1, 1);
  1366. nW2 = max(nW2, 1);
  1367. nW3 = max(nW3, 1);
  1368. int nYmin = INT_MAX;
  1369. int nYminMetric = INT_MAX;
  1370. int nXforYmin[4] = {0, 1, 1, 1};
  1371. int nX[4] = {0, 0, 0, 0};
  1372. int nX_step = 15; //nW/50;
  1373. int nX_start = nW/9;
  1374. int nX_stop = nW/2 - nW/9;
  1375. for (nX[1] = nX_start; nX[1] <= nX_stop; nX[1] += nX_step)
  1376. {
  1377. int nY[4];
  1378. //************************
  1379. nY[1] = fnYi(nX[1], nW1);
  1380. int nX2_stop = nW - nX[1] - nW/9;
  1381. for (nX[2] = nX_start; nX[2] <= nX2_stop; nX[2] += nX_step)
  1382. {
  1383. nX[3] = nW - nX[1] - nX[2];
  1384. //************************
  1385. nY[2] = fnYi(nX[2], nW2);
  1386. if (nY[2] > nYmin)
  1387. continue;
  1388. nY[3] = fnYi(nX[3], nW3);
  1389. if (nY[3] > nYmin)
  1390. break;
  1391. int nY123 = max( max(nY[1], nY[2]), max(nY[1], nY[3]) );
  1392. int nM = nW / 3;
  1393. int nY123Metric = abs(nM - nX[1]) + abs(nM - nX[2]) + abs(nM - nX[3]);
  1394. if (nY123 < nYmin || nY123 == nYmin && nY123Metric < nYminMetric)
  1395. {
  1396. //TRACE(_T("-- =*=   %d <= %d, metrics(cur: %d, min: %d) n"), nY123, nYmin, nY123Metric, nYminMetric);
  1397. //TRACE(_T("-- prev (%d, %d, %d) n"), nXforYmin[1], nXforYmin[2], nXforYmin[3]);
  1398. //TRACE(_T("-- new  (%d, %d, %d) n"), nX[1], nX[2], nX[3]);
  1399. nYmin = nY123;
  1400. nYminMetric = nY123Metric;
  1401. nXforYmin[1] = nX[1];
  1402. nXforYmin[2] = nX[2];
  1403. nXforYmin[3] = nX[3];
  1404. }
  1405. }
  1406. }
  1407. ASSERT(nXforYmin[1] + nXforYmin[2] + nXforYmin[3] <= nW);
  1408. UINT uFlags = DT_TOP | DT_WORDBREAK | DT_CALCRECT;
  1409. CRect rcText1(0, 0, nXforYmin[1], 32000);
  1410. rsz1.cx = nXforYmin[1];
  1411. rsz1.cy = pDC->DrawText(str1, &rcText1, uFlags | DT_LEFT);
  1412. CRect rcText2(0, 0, nXforYmin[2], 32000);
  1413. rsz2.cx = nXforYmin[2];
  1414. rsz2.cy = pDC->DrawText(str2, &rcText2, uFlags | DT_CENTER);
  1415. CRect rcText3(0, 0, nXforYmin[3], 32000);
  1416. rsz3.cx = nXforYmin[3];
  1417. rsz3.cy = pDC->DrawText(str3, &rcText3, uFlags | DT_RIGHT);
  1418. return max( max(rsz1.cy, rsz2.cy), max(rsz1.cy, rsz3.cy) );
  1419. }
  1420. void CXTPPrintPageHeaderFooter::Draw(CDC* pDC, CRect& rcRect, BOOL bCalculateOnly)
  1421. {
  1422. CFont fntHF;
  1423. VERIFY(fntHF.CreateFontIndirect(&m_lfFont));
  1424. CXTPFontDC autoFont(pDC, &fntHF, m_clrColor);
  1425. int nWidth = rcRect.Width();
  1426. CSize szLeft2, szCenter2, szRight2;
  1427. int nHeight = Calc3ColSizes(pDC, nWidth, m_strLeft, m_strCenter, m_strRight,
  1428. szLeft2, szCenter2, szRight2);
  1429. int nBorderH = nHeight ? 3 : 0;
  1430. if (m_bHeader)
  1431. {
  1432. rcRect.bottom = rcRect.top + nHeight + nBorderH;
  1433. }
  1434. else
  1435. {
  1436. rcRect.top = rcRect.bottom - nHeight - nBorderH;
  1437. }
  1438. if (bCalculateOnly)
  1439. {
  1440. return;
  1441. }
  1442. int nBkModePrev = pDC->SetBkMode(TRANSPARENT);
  1443. UINT uFlags = DT_TOP | DT_WORDBREAK | DT_NOPREFIX;
  1444. CRect rcLeft = rcRect;
  1445. rcLeft.right = rcLeft.left + szLeft2.cx;
  1446. pDC->DrawText(m_strLeft, &rcLeft, uFlags | DT_LEFT);
  1447. CRect rcCenter = rcRect;
  1448. rcCenter.left = rcLeft.right;
  1449. rcCenter.right = rcCenter.left + szCenter2.cx;
  1450. pDC->DrawText(m_strCenter, &rcCenter, uFlags | DT_CENTER);
  1451. CRect rcRight = rcRect;
  1452. rcRight.left = rcRight.right - szRight2.cx;
  1453. pDC->DrawText(m_strRight, &rcRight, uFlags | DT_RIGHT);
  1454. pDC->SetBkMode(nBkModePrev);
  1455. }
  1456. //*************************************************************
  1457. IMPLEMENT_DYNAMIC(CXTPPrintOptions, CCmdTarget)
  1458. LCID CXTPPrintOptions::GetActiveLCID()
  1459. {
  1460. return LOCALE_USER_DEFAULT;
  1461. }
  1462. BOOL CXTPPrintOptions::IsMarginsMeasureInches()
  1463. {
  1464. TCHAR szResult[5];
  1465. int nResult = ::GetLocaleInfo(GetActiveLCID(), LOCALE_IMEASURE, szResult, 4);
  1466. ASSERT(nResult == 2);
  1467. long nIsInches = _ttoi(szResult);
  1468. return nIsInches != 0;
  1469. }
  1470. CXTPPrintOptions::CXTPPrintOptions()
  1471. {
  1472. BOOL bIsInches = IsMarginsMeasureInches();
  1473. int nMargin = bIsInches ? (1000 * 1/2  ) : (10 * 100);
  1474. m_rcMargins.SetRect(nMargin, nMargin, nMargin, nMargin);
  1475. m_pPageHeader = new CXTPPrintPageHeaderFooter(this, TRUE);
  1476. m_pPageFooter = new CXTPPrintPageHeaderFooter(this, FALSE);
  1477. m_bBlackWhitePrinting = FALSE;
  1478. m_nBlackWhiteContrast = 0;
  1479. //#ifdef _XTP_ACTIVEX
  1480. //  EnableAutomation();
  1481. //  EnableTypeLib();
  1482. //#endif
  1483. }
  1484. CXTPPrintOptions::~CXTPPrintOptions()
  1485. {
  1486. CMDTARGET_RELEASE(m_pPageHeader);
  1487. CMDTARGET_RELEASE(m_pPageFooter);
  1488. }
  1489. void CXTPPrintOptions::Set(const CXTPPrintOptions* pSrc)
  1490. {
  1491. ASSERT(pSrc);
  1492. if (!pSrc)
  1493. return;
  1494. m_rcMargins = pSrc->m_rcMargins;
  1495. if (m_pPageHeader)
  1496. m_pPageHeader->Set(pSrc->m_pPageHeader);
  1497. if (m_pPageFooter)
  1498. m_pPageFooter->Set(pSrc->m_pPageFooter);
  1499. m_bBlackWhitePrinting = pSrc->m_bBlackWhitePrinting;
  1500. m_nBlackWhiteContrast = pSrc->m_nBlackWhiteContrast;
  1501. }
  1502. CRect CXTPPrintOptions::GetMarginsHimetric()
  1503. {
  1504. BOOL bIsInches = IsMarginsMeasureInches();
  1505. if (!bIsInches)
  1506. {
  1507. return m_rcMargins;
  1508. }
  1509. int nMul_i2m = 254;
  1510. int nDiv_i2m = 100;
  1511. CRect rcMarginsHimetric;
  1512. rcMarginsHimetric.left = m_rcMargins.left * nMul_i2m / nDiv_i2m;
  1513. rcMarginsHimetric.top = m_rcMargins.top * nMul_i2m / nDiv_i2m;
  1514. rcMarginsHimetric.right = m_rcMargins.right * nMul_i2m / nDiv_i2m;
  1515. rcMarginsHimetric.bottom = m_rcMargins.bottom * nMul_i2m / nDiv_i2m;
  1516. return rcMarginsHimetric;
  1517. }
  1518. CRect CXTPPrintOptions::GetMarginsLP(CDC* pDC)
  1519. {
  1520. ASSERT(pDC);
  1521. if (!pDC)
  1522. return CRect(0, 0, 0, 0);
  1523. CRect rcMarginsHI = GetMarginsHimetric();
  1524. CSize szLT(rcMarginsHI.left, rcMarginsHI.top);
  1525. CSize szRB(rcMarginsHI.right, rcMarginsHI.bottom);
  1526. pDC->HIMETRICtoLP(&szLT);
  1527. pDC->HIMETRICtoLP(&szRB);
  1528. CRect rcLP(szLT.cx, szLT.cy, szRB.cx, szRB.cy);
  1529. return rcLP;
  1530. }
  1531. CXTPPrintPageHeaderFooter* CXTPPrintOptions::GetPageHeader()
  1532. {
  1533. return m_pPageHeader;
  1534. }
  1535. CXTPPrintPageHeaderFooter* CXTPPrintOptions::GetPageFooter()
  1536. {
  1537. return m_pPageFooter;
  1538. }
  1539. /////////////////////////////////////////////////////////////////////////////
  1540. // Printing Dialog
  1541. class XTP_PRINT_STATE : public CNoTrackObject
  1542. {
  1543. public:
  1544. // printing abort
  1545. BOOL m_bUserAbort;
  1546. };
  1547. PROCESS_LOCAL(XTP_PRINT_STATE, g_xtpPrintState)
  1548. BOOL CALLBACK _XTPAbortProc(HDC, int)
  1549. {
  1550. XTP_PRINT_STATE* pState = g_xtpPrintState;
  1551. MSG msg;
  1552. while (!pState->m_bUserAbort &&
  1553. ::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
  1554. {
  1555. if (!AfxGetThread()->PumpMessage())
  1556. return FALSE;   // terminate if WM_QUIT received
  1557. }
  1558. return !pState->m_bUserAbort;
  1559. }
  1560. CXTPPrintingDialog::CXTPPrintingDialog(CWnd* pParent)
  1561. {
  1562. Create(CXTPPrintingDialog::IDD, pParent);      // modeless !
  1563. g_xtpPrintState->m_bUserAbort = FALSE;
  1564. }
  1565. BOOL CXTPPrintingDialog::OnInitDialog()
  1566. {
  1567. //SetWindowText(AfxGetAppName());
  1568. CenterWindow();
  1569. return CDialog::OnInitDialog();
  1570. }
  1571. void CXTPPrintingDialog::OnCancel()
  1572. {
  1573. g_xtpPrintState->m_bUserAbort = TRUE;  // flag that user aborted print
  1574. CDialog::OnCancel();
  1575. }
  1576. void CXTPPrintPageHeaderFooter::DoInsertHFFormatSpecifierViaMenu(
  1577. CWnd* pParent, CEdit* pEdit, CButton* pButton)
  1578. {
  1579. CMap<UINT, UINT, CString, CString&> menuData;
  1580. menuData[XTP_ID_HF_FORMAT_D1]   = _T("&d");
  1581. menuData[XTP_ID_HF_FORMAT_D2]   = _T("&D");
  1582. menuData[XTP_ID_HF_FORMAT_T1]   = _T("&t");
  1583. menuData[XTP_ID_HF_FORMAT_T2]   = _T("&T");
  1584. menuData[XTP_ID_HF_FORMAT_P1]   = _T("&p");
  1585. menuData[XTP_ID_HF_FORMAT_P2]   = _T("&P");
  1586. menuData[XTP_ID_HF_FORMAT_B]    = _T("&b");
  1587. menuData[XTP_ID_HF_FORMAT_W]    = _T("&w");
  1588. menuData[XTP_ID_HF_FORMAT_UMP]  = _T("&&");
  1589. menuData[XTP_ID_HF_FORMAT_N]    = _T("\n");
  1590. if (!pParent || !pEdit || !pButton)
  1591. {
  1592. ASSERT(FALSE);
  1593. return;
  1594. }
  1595. CRect rcButton;
  1596. pButton->GetWindowRect(&rcButton);
  1597. CPoint ptMenu(rcButton.left, rcButton.bottom + 1);
  1598. CMenu menu;
  1599. VERIFY(XTPResourceManager()->LoadMenu(&menu, XTP_IDR_MENU_HEADERFOOTER_FORMATS));
  1600. // track menu
  1601. int nMenuResult = menu.GetSubMenu(0)->TrackPopupMenu(
  1602. TPM_RETURNCMD | TPM_LEFTALIGN |TPM_RIGHTBUTTON,
  1603. ptMenu.x, ptMenu.y, pParent, NULL);
  1604. pEdit->SetFocus();
  1605. CString strItem = menuData[nMenuResult];
  1606. if (!strItem.IsEmpty())
  1607. {
  1608. pEdit->ReplaceSel(strItem, TRUE);
  1609. }
  1610. }
  1611. //////////////////////////////////////////////////////////////////////////