2193 lines
51 KiB
C++
2193 lines
51 KiB
C++
2 years ago
|
// XTPDrawHelpers.cpp: implementation of the CXTPDrawHelpers class.
|
||
|
//
|
||
|
// This file is a part of the XTREME TOOLKIT PRO MFC class library.
|
||
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
||
|
//
|
||
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
||
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
||
|
// CONSENT OF CODEJOCK SOFTWARE.
|
||
|
//
|
||
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
||
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
||
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
||
|
// SINGLE COMPUTER.
|
||
|
//
|
||
|
// CONTACT INFORMATION:
|
||
|
// support@codejock.com
|
||
|
// http://www.codejock.com
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "resource.h"
|
||
|
|
||
|
#include "XTPSystemHelpers.h"
|
||
|
#include "XTPColorManager.h"
|
||
|
#include "XTPDrawHelpers.h"
|
||
|
|
||
|
#include "XTPResourceManager.h"
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#define new DEBUG_NEW
|
||
|
#endif
|
||
|
|
||
|
HHOOK CXTPMouseMonitor::m_hHookMouse = 0;
|
||
|
CWnd* CXTPMouseMonitor::m_pWndMonitor = 0;
|
||
|
|
||
|
typedef BOOL (WINAPI *PFNSETLAYEREDWINDOWATTRIBUTES) (HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
|
||
|
|
||
|
#ifndef LWA_ALPHA
|
||
|
#define LWA_ALPHA 0x00000002
|
||
|
#endif
|
||
|
|
||
|
#ifndef WS_EX_LAYERED
|
||
|
#define WS_EX_LAYERED 0x00080000
|
||
|
#endif
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
// CXTPMouseMonitor
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void CXTPMouseMonitor::SetupHook(CWnd* pWndMonitor)
|
||
|
{
|
||
|
if (pWndMonitor && m_hHookMouse == 0)
|
||
|
{
|
||
|
m_hHookMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, 0, GetCurrentThreadId ());
|
||
|
}
|
||
|
if (!pWndMonitor && m_hHookMouse)
|
||
|
{
|
||
|
UnhookWindowsHookEx(m_hHookMouse);
|
||
|
m_hHookMouse = 0;
|
||
|
}
|
||
|
m_pWndMonitor = pWndMonitor;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPMouseMonitor::IsMouseHooked()
|
||
|
{
|
||
|
return m_pWndMonitor != NULL;
|
||
|
}
|
||
|
|
||
|
LRESULT CALLBACK CXTPMouseMonitor::MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
if (nCode != HC_ACTION || !m_pWndMonitor)
|
||
|
return CallNextHookEx(m_hHookMouse, nCode, wParam, lParam);
|
||
|
|
||
|
CXTPWindowRect rc(m_pWndMonitor);
|
||
|
|
||
|
if (!rc.PtInRect(((PMOUSEHOOKSTRUCT)lParam)->pt))
|
||
|
{
|
||
|
switch (wParam)
|
||
|
{
|
||
|
case WM_LBUTTONDOWN:
|
||
|
case WM_NCLBUTTONDOWN:
|
||
|
case WM_RBUTTONDOWN:
|
||
|
case WM_NCRBUTTONDOWN:
|
||
|
case WM_MBUTTONDOWN:
|
||
|
case WM_NCMBUTTONDOWN:
|
||
|
m_pWndMonitor->GetOwner()->SetFocus();
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return CallNextHookEx(m_hHookMouse, nCode, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPClientCursorPos class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPTransparentBitmap::CXTPTransparentBitmap(HBITMAP hBitmap)
|
||
|
: m_hBitmap(hBitmap)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
// Not foolproof, but works 99% of the time :). Assumes the top
|
||
|
// left pixel is the transparent color.
|
||
|
|
||
|
COLORREF CXTPTransparentBitmap::GetTransparentColor() const
|
||
|
{
|
||
|
CBitmap* pBitmap = CBitmap::FromHandle(m_hBitmap);
|
||
|
if (pBitmap != NULL)
|
||
|
{
|
||
|
CXTPCompatibleDC dc(NULL, pBitmap);
|
||
|
return dc.GetPixel(0, 0);
|
||
|
}
|
||
|
return (COLORREF)-1;
|
||
|
}
|
||
|
|
||
|
|
||
|
HICON CXTPTransparentBitmap::ConvertToIcon() const
|
||
|
{
|
||
|
if (m_hBitmap == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
COLORREF crTransparent = GetTransparentColor();
|
||
|
|
||
|
BITMAP bmp;
|
||
|
if (!::GetObject(m_hBitmap, sizeof(BITMAP), &bmp))
|
||
|
return NULL;
|
||
|
|
||
|
if (bmp.bmHeight == 0 || bmp.bmWidth == 0)
|
||
|
return NULL;
|
||
|
|
||
|
CImageList il;
|
||
|
il.Create(bmp.bmWidth, bmp.bmHeight, ILC_COLOR24 | ILC_MASK, 0, 1);
|
||
|
il.Add(CBitmap::FromHandle(m_hBitmap), crTransparent);
|
||
|
|
||
|
ASSERT(il.GetImageCount() == 1);
|
||
|
|
||
|
return il.ExtractIcon(0);
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPClientCursorPos class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPClientCursorPos::CXTPClientCursorPos(CWnd* pWnd)
|
||
|
{
|
||
|
GetCursorPos(this);
|
||
|
pWnd->ScreenToClient(this);
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPEmptySize class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPEmptySize::CXTPEmptySize()
|
||
|
{
|
||
|
SetSizeEmpty();
|
||
|
}
|
||
|
|
||
|
void CXTPEmptySize::SetSizeEmpty()
|
||
|
{
|
||
|
cx = 0;
|
||
|
cy = 0;
|
||
|
}
|
||
|
|
||
|
const SIZE& CXTPEmptySize::operator=(const SIZE& srcSize)
|
||
|
{
|
||
|
cx = srcSize.cx;
|
||
|
cy = srcSize.cy;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPEmptyRect class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPEmptyRect::CXTPEmptyRect()
|
||
|
{
|
||
|
SetRectEmpty();
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPWindowRect class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPWindowRect::CXTPWindowRect(HWND hWnd)
|
||
|
{
|
||
|
if (::IsWindow(hWnd))
|
||
|
::GetWindowRect(hWnd, this);
|
||
|
else
|
||
|
SetRectEmpty();
|
||
|
}
|
||
|
|
||
|
CXTPWindowRect::CXTPWindowRect(const CWnd* pWnd)
|
||
|
{
|
||
|
if (::IsWindow(pWnd->GetSafeHwnd()))
|
||
|
::GetWindowRect(pWnd->GetSafeHwnd(), this);
|
||
|
else
|
||
|
SetRectEmpty();
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPClientRect class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPClientRect::CXTPClientRect(HWND hWnd)
|
||
|
{
|
||
|
if (::IsWindow(hWnd))
|
||
|
::GetClientRect(hWnd, this);
|
||
|
else
|
||
|
SetRectEmpty();
|
||
|
}
|
||
|
|
||
|
CXTPClientRect::CXTPClientRect(const CWnd* pWnd)
|
||
|
{
|
||
|
if (::IsWindow(pWnd->GetSafeHwnd()))
|
||
|
::GetClientRect(pWnd->GetSafeHwnd(), this);
|
||
|
else
|
||
|
SetRectEmpty();
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPBufferDC class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPBufferDC::CXTPBufferDC(HDC hDestDC, const CRect& rcPaint)
|
||
|
: m_hDestDC (hDestDC)
|
||
|
{
|
||
|
m_rect = rcPaint;
|
||
|
Attach (::CreateCompatibleDC (m_hDestDC));
|
||
|
if (!m_hDC)
|
||
|
return;
|
||
|
|
||
|
m_bitmap.Attach (::CreateCompatibleBitmap(
|
||
|
m_hDestDC, m_rect.right, m_rect.bottom));
|
||
|
m_hOldBitmap = ::SelectObject (m_hDC, m_bitmap);
|
||
|
}
|
||
|
|
||
|
CXTPBufferDC::CXTPBufferDC(HDC hDestDC, const CRect& rcPaint, const CXTPPaintManagerColorGradient& clrBack, const BOOL bHorz /*=FALSE*/)
|
||
|
: m_hDestDC (hDestDC)
|
||
|
{
|
||
|
m_rect = rcPaint;
|
||
|
Attach (::CreateCompatibleDC (m_hDestDC));
|
||
|
if (!m_hDC)
|
||
|
return;
|
||
|
|
||
|
m_bitmap.Attach (::CreateCompatibleBitmap(
|
||
|
m_hDestDC, m_rect.right, m_rect.bottom));
|
||
|
m_hOldBitmap = ::SelectObject (m_hDC, m_bitmap);
|
||
|
|
||
|
if (!clrBack.IsNull())
|
||
|
{
|
||
|
XTPDrawHelpers()->GradientFill(this, m_rect, clrBack, bHorz);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CXTPBufferDC::CXTPBufferDC(CPaintDC& paintDC)
|
||
|
{
|
||
|
m_hDestDC = paintDC.GetSafeHdc();
|
||
|
m_rect = paintDC.m_ps.rcPaint;
|
||
|
|
||
|
Attach (::CreateCompatibleDC (m_hDestDC));
|
||
|
if (!m_hDC)
|
||
|
return;
|
||
|
|
||
|
m_bitmap.Attach (::CreateCompatibleBitmap(
|
||
|
m_hDestDC, max(1, m_rect.right), max(1, m_rect.bottom)));
|
||
|
m_hOldBitmap = ::SelectObject (m_hDC, m_bitmap);
|
||
|
|
||
|
CRgn rgn;
|
||
|
rgn.CreateRectRgnIndirect(&m_rect);
|
||
|
|
||
|
SelectClipRgn(&rgn);
|
||
|
}
|
||
|
|
||
|
CXTPBufferDC::~CXTPBufferDC()
|
||
|
{
|
||
|
if (!m_hDC)
|
||
|
return;
|
||
|
|
||
|
if (m_hDestDC)
|
||
|
{
|
||
|
::BitBlt (m_hDestDC, m_rect.left, m_rect.top, m_rect.Width(),
|
||
|
m_rect.Height(), m_hDC, m_rect.left, m_rect.top, SRCCOPY);
|
||
|
}
|
||
|
::SelectObject (m_hDC, m_hOldBitmap);
|
||
|
}
|
||
|
void CXTPBufferDC::Discard()
|
||
|
{
|
||
|
m_hDestDC = 0;
|
||
|
}
|
||
|
|
||
|
CDC* CXTPBufferDC::GetDestDC()
|
||
|
{
|
||
|
return CDC::FromHandle(m_hDestDC);
|
||
|
}
|
||
|
|
||
|
void CXTPBufferDC::TakeSnapshot()
|
||
|
{
|
||
|
::BitBlt (m_hDC, m_rect.left, m_rect.top, m_rect.Width(),
|
||
|
m_rect.Height(), m_hDestDC, m_rect.left, m_rect.top, SRCCOPY);
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPBufferDC class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPBufferDCEx::CXTPBufferDCEx(HDC hDestDC, const CRect rcPaint) : m_hDestDC (hDestDC)
|
||
|
{
|
||
|
m_rect = rcPaint;
|
||
|
Attach (::CreateCompatibleDC (m_hDestDC));
|
||
|
m_bitmap = ::CreateCompatibleBitmap(
|
||
|
m_hDestDC, m_rect.Width(), m_rect.Height());
|
||
|
|
||
|
m_hOldBitmap = ::SelectObject (m_hDC, m_bitmap);
|
||
|
|
||
|
SetViewportOrg(-rcPaint.left, -rcPaint.top);
|
||
|
}
|
||
|
|
||
|
CXTPBufferDCEx::~CXTPBufferDCEx()
|
||
|
{
|
||
|
SetViewportOrg(0, 0);
|
||
|
|
||
|
::BitBlt (m_hDestDC, m_rect.left, m_rect.top, m_rect.Width(),
|
||
|
m_rect.Height(), m_hDC, 0, 0, SRCCOPY);
|
||
|
::SelectObject (m_hDC, m_hOldBitmap);
|
||
|
::DeleteObject(m_bitmap);
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPBitmapDC class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPBitmapDC::CXTPBitmapDC(CDC* pDC, CBitmap* pBitmap)
|
||
|
: m_hDC(pDC->GetSafeHdc())
|
||
|
{
|
||
|
m_hOldBitmap = SelectObject(m_hDC, pBitmap->GetSafeHandle());
|
||
|
}
|
||
|
|
||
|
|
||
|
CXTPBitmapDC::CXTPBitmapDC(CDC* pDC, HBITMAP hBitmap)
|
||
|
: m_hDC(pDC->GetSafeHdc())
|
||
|
{
|
||
|
m_hOldBitmap = SelectObject(m_hDC, hBitmap);
|
||
|
}
|
||
|
|
||
|
CXTPBitmapDC::~CXTPBitmapDC()
|
||
|
{
|
||
|
::SelectObject(m_hDC, m_hOldBitmap);
|
||
|
}
|
||
|
|
||
|
void CXTPBitmapDC::SetBitmap(CBitmap* pBitmap)
|
||
|
{
|
||
|
::SelectObject(m_hDC, m_hOldBitmap);
|
||
|
m_hOldBitmap = SelectObject(m_hDC, pBitmap->GetSafeHandle());
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPFontDC class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPFontDC::CXTPFontDC(CDC* pDC, CFont* pFont)
|
||
|
{
|
||
|
ASSERT(pDC);
|
||
|
|
||
|
m_pDC = pDC;
|
||
|
m_pOldFont = NULL;
|
||
|
m_clrOldTextColor = COLORREF_NULL;
|
||
|
|
||
|
if (pFont)
|
||
|
{
|
||
|
SetFont(pFont);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CXTPFontDC::CXTPFontDC(CDC* pDC, CFont* pFont, COLORREF clrTextColor)
|
||
|
{
|
||
|
ASSERT(pDC);
|
||
|
ASSERT(clrTextColor != COLORREF_NULL);
|
||
|
|
||
|
m_pDC = pDC;
|
||
|
m_pOldFont = NULL;
|
||
|
m_clrOldTextColor = COLORREF_NULL;
|
||
|
|
||
|
|
||
|
if (pFont)
|
||
|
{
|
||
|
SetFont(pFont);
|
||
|
}
|
||
|
|
||
|
SetColor(clrTextColor);
|
||
|
}
|
||
|
|
||
|
CXTPFontDC::~CXTPFontDC()
|
||
|
{
|
||
|
ReleaseFont();
|
||
|
ReleaseColor();
|
||
|
}
|
||
|
|
||
|
void CXTPFontDC::SetFont(CFont* pFont)
|
||
|
{
|
||
|
if (m_pDC && pFont)
|
||
|
{
|
||
|
CFont* pFontPrev = m_pDC->SelectObject(pFont);
|
||
|
|
||
|
if (!m_pOldFont && pFontPrev)
|
||
|
{
|
||
|
m_pOldFont = pFontPrev;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPFontDC::SetColor(COLORREF clrTextColor)
|
||
|
{
|
||
|
ASSERT(clrTextColor != COLORREF_NULL);
|
||
|
ASSERT(m_pDC);
|
||
|
|
||
|
if (m_pDC && clrTextColor != COLORREF_NULL)
|
||
|
{
|
||
|
COLORREF clrTextColorPrev= m_pDC->SetTextColor(clrTextColor);
|
||
|
|
||
|
if (m_clrOldTextColor == COLORREF_NULL)
|
||
|
{
|
||
|
m_clrOldTextColor = clrTextColorPrev;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPFontDC::SetFontColor(CFont* pFont, COLORREF clrTextColor)
|
||
|
{
|
||
|
SetFont(pFont);
|
||
|
SetColor(clrTextColor);
|
||
|
}
|
||
|
|
||
|
void CXTPFontDC::ReleaseFont()
|
||
|
{
|
||
|
ASSERT(m_pDC);
|
||
|
if (m_pDC && m_pOldFont)
|
||
|
{
|
||
|
m_pDC->SelectObject(m_pOldFont);
|
||
|
m_pOldFont = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPFontDC::ReleaseColor()
|
||
|
{
|
||
|
ASSERT(m_pDC);
|
||
|
if (m_pDC && m_clrOldTextColor != COLORREF_NULL)
|
||
|
{
|
||
|
m_pDC->SetTextColor(m_clrOldTextColor);
|
||
|
m_clrOldTextColor = COLORREF_NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPPenDC class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPPenDC::CXTPPenDC(CDC* pDC, CPen* pPen)
|
||
|
: m_hDC(pDC->GetSafeHdc())
|
||
|
{
|
||
|
m_hOldPen = (HPEN)::SelectObject(m_hDC, pPen->GetSafeHandle());
|
||
|
}
|
||
|
|
||
|
CXTPPenDC::CXTPPenDC(HDC hDC, COLORREF crColor)
|
||
|
: m_hDC (hDC)
|
||
|
{
|
||
|
VERIFY(m_pen.CreatePen (PS_SOLID, 1, crColor));
|
||
|
m_hOldPen = (HPEN)::SelectObject (m_hDC, m_pen);
|
||
|
}
|
||
|
|
||
|
CXTPPenDC::~CXTPPenDC ()
|
||
|
{
|
||
|
::SelectObject (m_hDC, m_hOldPen);
|
||
|
}
|
||
|
|
||
|
void CXTPPenDC::Color(COLORREF crColor)
|
||
|
{
|
||
|
::SelectObject (m_hDC, m_hOldPen);
|
||
|
VERIFY(m_pen.DeleteObject());
|
||
|
VERIFY(m_pen.CreatePen (PS_SOLID, 1, crColor));
|
||
|
m_hOldPen = (HPEN)::SelectObject (m_hDC, m_pen);
|
||
|
}
|
||
|
|
||
|
COLORREF CXTPPenDC::Color()
|
||
|
{
|
||
|
LOGPEN logPen;
|
||
|
m_pen.GetLogPen(&logPen);
|
||
|
return logPen.lopnColor;
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPBrushDC class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPBrushDC::CXTPBrushDC(HDC hDC, COLORREF crColor)
|
||
|
: m_hDC (hDC)
|
||
|
{
|
||
|
VERIFY(m_brush.CreateSolidBrush (crColor));
|
||
|
m_hOldBrush = (HBRUSH)::SelectObject (m_hDC, m_brush);
|
||
|
}
|
||
|
|
||
|
CXTPBrushDC::~CXTPBrushDC()
|
||
|
{
|
||
|
::SelectObject(m_hDC, m_hOldBrush);
|
||
|
}
|
||
|
|
||
|
void CXTPBrushDC::Color(COLORREF crColor)
|
||
|
{
|
||
|
::SelectObject(m_hDC, m_hOldBrush);
|
||
|
VERIFY(m_brush.DeleteObject());
|
||
|
VERIFY(m_brush.CreateSolidBrush(crColor));
|
||
|
m_hOldBrush = (HBRUSH)::SelectObject (m_hDC, m_brush);
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPCompatibleDC class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPCompatibleDC::CXTPCompatibleDC(CDC* pDC, CBitmap* pBitmap)
|
||
|
{
|
||
|
CreateCompatibleDC(pDC);
|
||
|
m_hOldBitmap = (HBITMAP)::SelectObject(GetSafeHdc(), pBitmap->GetSafeHandle());
|
||
|
}
|
||
|
|
||
|
CXTPCompatibleDC::CXTPCompatibleDC(CDC* pDC, HBITMAP hBitmap)
|
||
|
{
|
||
|
CreateCompatibleDC(pDC);
|
||
|
m_hOldBitmap = (HBITMAP)::SelectObject(GetSafeHdc(), hBitmap);
|
||
|
}
|
||
|
|
||
|
CXTPCompatibleDC::~CXTPCompatibleDC()
|
||
|
{
|
||
|
::SelectObject(GetSafeHdc(), m_hOldBitmap);
|
||
|
DeleteDC();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPSplitterTracker class
|
||
|
//===========================================================================
|
||
|
CXTPSplitterTracker::CXTPSplitterTracker(BOOL bSolid /*= FALSE*/, BOOL bDesktopDC /*= TRUE*/)
|
||
|
{
|
||
|
m_bSolid = bSolid;
|
||
|
m_rcBoundRect.SetRectEmpty();
|
||
|
m_pDC = 0;
|
||
|
m_bDesktopDC = bDesktopDC;
|
||
|
m_pWnd = NULL;
|
||
|
m_pSplitterWnd = NULL;
|
||
|
|
||
|
m_pfnSetLayeredWindowAttributes = NULL;
|
||
|
|
||
|
HMODULE hLib = GetModuleHandle(_T("USER32"));
|
||
|
if (hLib)
|
||
|
{
|
||
|
m_pfnSetLayeredWindowAttributes = (PVOID) ::GetProcAddress(hLib, "SetLayeredWindowAttributes");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CXTPSplitterTracker::OnInvertTracker(CRect rect)
|
||
|
{
|
||
|
ASSERT(!rect.IsRectEmpty());
|
||
|
|
||
|
if (!m_bDesktopDC)
|
||
|
{
|
||
|
m_pWnd->ScreenToClient(rect);
|
||
|
}
|
||
|
|
||
|
if (m_pSplitterWnd)
|
||
|
{
|
||
|
m_pSplitterWnd->SetWindowPos(0, rect.left, rect.top, rect.Width(), rect.Height(),
|
||
|
SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!m_pDC)
|
||
|
return;
|
||
|
|
||
|
if (m_bSolid)
|
||
|
{
|
||
|
m_pDC->InvertRect(rect);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CBrush* pDitherBrush = CDC::GetHalftoneBrush();
|
||
|
CBrush* pBrush = (CBrush*)m_pDC->SelectObject(pDitherBrush);
|
||
|
|
||
|
m_pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT);
|
||
|
m_pDC->SelectObject(pBrush);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL CXTPSplitterTracker::Track(CWnd* pTrackWnd, CRect rcAvail, CRect& rectTracker, CPoint point, BOOL bHoriz)
|
||
|
{
|
||
|
pTrackWnd->SetCapture();
|
||
|
m_pDC = 0;
|
||
|
m_pSplitterWnd = NULL;
|
||
|
|
||
|
if (m_rcBoundRect.IsRectEmpty() && m_bDesktopDC && XTPSystemVersion()->IsWinVistaOrGreater() &&
|
||
|
m_pfnSetLayeredWindowAttributes && !XTPColorManager()->IsLowResolution())
|
||
|
{
|
||
|
m_pSplitterWnd = new CWnd();
|
||
|
m_pSplitterWnd->CreateEx(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
|
||
|
AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH)), 0, WS_POPUP, CRect(0, 0, 0, 0), NULL, 0);
|
||
|
|
||
|
((PFNSETLAYEREDWINDOWATTRIBUTES)m_pfnSetLayeredWindowAttributes)(m_pSplitterWnd->m_hWnd, 0, 100, LWA_ALPHA);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (m_bDesktopDC)
|
||
|
m_pWnd = CWnd::GetDesktopWindow();
|
||
|
else
|
||
|
m_pWnd = pTrackWnd;
|
||
|
|
||
|
if (m_pWnd->LockWindowUpdate())
|
||
|
m_pDC = m_pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
|
||
|
else
|
||
|
m_pDC = m_pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE);
|
||
|
ASSERT(m_pDC != NULL);
|
||
|
}
|
||
|
|
||
|
CPoint ptOffset = bHoriz ? CPoint(rectTracker.left - point.x, 0) :
|
||
|
CPoint(0, rectTracker.top - point.y);
|
||
|
|
||
|
OnInvertTracker(rectTracker);
|
||
|
|
||
|
if (!m_rcBoundRect.IsRectEmpty())
|
||
|
OnInvertTracker(m_rcBoundRect);
|
||
|
|
||
|
BOOL bAccept = FALSE;
|
||
|
while (CWnd::GetCapture() == pTrackWnd)
|
||
|
{
|
||
|
MSG msg;
|
||
|
if (!GetMessage(&msg, NULL, 0, 0))
|
||
|
break;
|
||
|
|
||
|
if (msg.message == WM_MOUSEMOVE)
|
||
|
{
|
||
|
point = CPoint(msg.lParam);
|
||
|
pTrackWnd->ClientToScreen(&point);
|
||
|
point += ptOffset;
|
||
|
|
||
|
point.x = max(min(point.x, rcAvail.right), rcAvail.left);
|
||
|
point.y = max(min(point.y, rcAvail.bottom), rcAvail.top);
|
||
|
|
||
|
if (bHoriz)
|
||
|
{
|
||
|
if (rectTracker.left != point.x)
|
||
|
{
|
||
|
OnInvertTracker(rectTracker);
|
||
|
rectTracker.OffsetRect(point.x - rectTracker.left, 0);
|
||
|
OnInvertTracker(rectTracker);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (rectTracker.top != point.y)
|
||
|
{
|
||
|
OnInvertTracker(rectTracker);
|
||
|
rectTracker.OffsetRect(0, point.y - rectTracker.top);
|
||
|
OnInvertTracker(rectTracker);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) break;
|
||
|
else if (msg.message == WM_LBUTTONUP)
|
||
|
{
|
||
|
bAccept = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
else ::DispatchMessage(&msg);
|
||
|
}
|
||
|
|
||
|
if (!m_rcBoundRect.IsRectEmpty())
|
||
|
OnInvertTracker(m_rcBoundRect);
|
||
|
|
||
|
OnInvertTracker(rectTracker);
|
||
|
|
||
|
if (CWnd::GetCapture() == pTrackWnd) ReleaseCapture();
|
||
|
|
||
|
if (m_pSplitterWnd)
|
||
|
{
|
||
|
m_pSplitterWnd->DestroyWindow();
|
||
|
|
||
|
delete m_pSplitterWnd;
|
||
|
m_pSplitterWnd = NULL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pWnd->UnlockWindowUpdate();
|
||
|
if (m_pDC != NULL)
|
||
|
{
|
||
|
m_pWnd->ReleaseDC(m_pDC);
|
||
|
m_pDC = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bAccept;
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// CXTPDrawHelpers class
|
||
|
//===========================================================================
|
||
|
|
||
|
CXTPDrawHelpers::CXTPDrawHelpers()
|
||
|
{
|
||
|
m_pfnFastGradientFill = 0;
|
||
|
m_pfnAlphaBlend = 0;
|
||
|
m_pfnTransparentBlt = 0;
|
||
|
|
||
|
// Don't use CXTPModuleHandle to reduce dependence between common source
|
||
|
m_hMsImgDll = ::LoadLibrary(_T("msimg32.dll"));
|
||
|
|
||
|
if (m_hMsImgDll)
|
||
|
{
|
||
|
m_pfnFastGradientFill = (PFNGRADIENTFILL)GetProcAddress(m_hMsImgDll, "GradientFill");
|
||
|
m_pfnAlphaBlend = (PFNALPHABLEND)::GetProcAddress(m_hMsImgDll, "AlphaBlend");
|
||
|
m_pfnTransparentBlt = (PFNTRANSPARENTBLT)::GetProcAddress(m_hMsImgDll, "TransparentBlt");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CXTPDrawHelpers* AFX_CDECL XTPDrawHelpers()
|
||
|
{
|
||
|
static CXTPDrawHelpers s_instance; // singleton
|
||
|
return &s_instance;
|
||
|
}
|
||
|
|
||
|
CXTPDrawHelpers::~CXTPDrawHelpers()
|
||
|
{
|
||
|
if (m_hMsImgDll != NULL)
|
||
|
{
|
||
|
//::FreeLibrary(m_hMsImgDll); Dangerous to call FreeLibrary in destructor of static object.
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL CXTPDrawHelpers::GradientFill(HDC hdc, PTRIVERTEX pVertex, ULONG dwNumVertex, PVOID pMesh, ULONG dwNumMesh, ULONG dwMode)
|
||
|
{
|
||
|
if (m_pfnFastGradientFill)
|
||
|
{
|
||
|
return (*m_pfnFastGradientFill)(hdc, pVertex, dwNumVertex, pMesh, dwNumMesh, dwMode);
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::GradientFillSlow(CDC* pDC, LPCRECT lpRect, COLORREF crFrom, COLORREF crTo, BOOL bHorz)
|
||
|
{
|
||
|
int cx = max(1, lpRect->right - lpRect->left);
|
||
|
int cy = max(1, lpRect->bottom - lpRect->top);
|
||
|
|
||
|
CRect rc;
|
||
|
pDC->GetClipBox(&rc);
|
||
|
|
||
|
if (rc.IsRectEmpty())
|
||
|
rc = *lpRect;
|
||
|
else
|
||
|
rc.IntersectRect(rc, lpRect);
|
||
|
|
||
|
if (bHorz)
|
||
|
{
|
||
|
for (int nX = rc.left; nX < rc.right; nX++)
|
||
|
{
|
||
|
pDC->FillSolidRect(nX, rc.top, 1, rc.Height(), BlendColors(
|
||
|
crFrom, crTo, (double)(1.0 - ((nX - lpRect->left) / (double)cx))));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (int nY = rc.top; nY < rc.bottom; nY++)
|
||
|
{
|
||
|
pDC->FillSolidRect(rc.left, nY, rc.Width(), 1, BlendColors(
|
||
|
crFrom, crTo, (double)(1.0 - ((nY - lpRect->top)) / (double)cy)));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::GradientFillFast(CDC* pDC, LPCRECT lpRect, COLORREF crFrom, COLORREF crTo, BOOL bHorz)
|
||
|
{
|
||
|
TRIVERTEX vert[2];
|
||
|
vert[0].x = lpRect->left;
|
||
|
vert[0].y = lpRect->top;
|
||
|
vert[0].Red = (COLOR16)(GetRValue(crFrom) << 8);
|
||
|
vert[0].Green = (COLOR16)(GetGValue(crFrom) << 8);
|
||
|
vert[0].Blue = (COLOR16)(GetBValue(crFrom) << 8);
|
||
|
vert[0].Alpha = 0x0000;
|
||
|
|
||
|
vert[1].x = lpRect->right;
|
||
|
vert[1].y = lpRect->bottom;
|
||
|
vert[1].Red = (COLOR16)(GetRValue(crTo) << 8);
|
||
|
vert[1].Green = (COLOR16)(GetGValue(crTo) << 8);
|
||
|
vert[1].Blue = (COLOR16)(GetBValue(crTo) << 8);
|
||
|
vert[1].Alpha = 0x0000;
|
||
|
|
||
|
GRADIENT_RECT gRect = { 0, 1 };
|
||
|
|
||
|
GradientFill(*pDC, vert, 2, &gRect, 1, bHorz ? GRADIENT_FILL_RECT_H : GRADIENT_FILL_RECT_V);
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::GradientFill(CDC* pDC, LPCRECT lpRect, COLORREF crFrom, COLORREF crTo, BOOL bHorz)
|
||
|
{
|
||
|
if (!lpRect)
|
||
|
return;
|
||
|
|
||
|
if (::IsRectEmpty(lpRect))
|
||
|
return;
|
||
|
|
||
|
if (IsLowResolution(pDC->GetSafeHdc()))
|
||
|
{
|
||
|
pDC->FillSolidRect(lpRect, crFrom);
|
||
|
}
|
||
|
else if (crFrom == crTo)
|
||
|
{
|
||
|
pDC->FillSolidRect(lpRect, crFrom);
|
||
|
}
|
||
|
else if ((m_pfnFastGradientFill == NULL) || (IsContextRTL(pDC) && XTPSystemVersion()->IsWin9x()))
|
||
|
{
|
||
|
GradientFillSlow(pDC, lpRect, crFrom, crTo, bHorz);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
GradientFillFast(pDC, lpRect, crFrom, crTo, bHorz);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::GradientFill(CDC* pDC, LPCRECT lpRect, COLORREF crFrom, COLORREF crTo, BOOL bHorz, LPCRECT lpRectClip)
|
||
|
{
|
||
|
CRect rc(lpRect);
|
||
|
|
||
|
if (lpRectClip == NULL)
|
||
|
{
|
||
|
GradientFill(pDC, lpRect, crFrom, crTo, bHorz);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
COLORREF crFrom1 = crFrom;
|
||
|
|
||
|
if (bHorz)
|
||
|
{
|
||
|
if (rc.top < lpRectClip->top)
|
||
|
{
|
||
|
rc.top = lpRectClip->top;
|
||
|
}
|
||
|
|
||
|
if (rc.bottom > lpRectClip->bottom)
|
||
|
{
|
||
|
rc.bottom = lpRectClip->bottom;
|
||
|
}
|
||
|
|
||
|
if ((rc.left > lpRectClip->right) || (rc.right < lpRectClip->left))
|
||
|
return;
|
||
|
|
||
|
if (rc.left < lpRectClip->left)
|
||
|
{
|
||
|
rc.left = lpRectClip->left;
|
||
|
|
||
|
crFrom = BlendColors(crFrom, crTo,
|
||
|
(float)(lpRect->right - lpRectClip->left) / (float)(lpRect->right - lpRect->left));
|
||
|
}
|
||
|
|
||
|
if (rc.right > lpRectClip->right)
|
||
|
{
|
||
|
rc.right = lpRectClip->right;
|
||
|
|
||
|
crTo = BlendColors(crFrom1, crTo,
|
||
|
(float)(lpRect->right - lpRectClip->right) / (float)(lpRect->right - lpRect->left));
|
||
|
|
||
|
}
|
||
|
|
||
|
GradientFill(pDC, rc, crFrom, crTo, bHorz);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (rc.left < lpRectClip->left)
|
||
|
{
|
||
|
rc.left = lpRectClip->left;
|
||
|
}
|
||
|
|
||
|
if (rc.right > lpRectClip->right)
|
||
|
{
|
||
|
rc.right = lpRectClip->right;
|
||
|
}
|
||
|
|
||
|
if ((rc.top > lpRectClip->bottom) || (rc.bottom < lpRectClip->top))
|
||
|
return;
|
||
|
|
||
|
if (rc.top < lpRectClip->top)
|
||
|
{
|
||
|
rc.top = lpRectClip->top;
|
||
|
|
||
|
crFrom = BlendColors(crFrom, crTo,
|
||
|
(float)(lpRect->bottom - lpRectClip->top) / (float)(lpRect->bottom - lpRect->top));
|
||
|
}
|
||
|
|
||
|
if (rc.bottom > lpRectClip->bottom)
|
||
|
{
|
||
|
rc.bottom = lpRectClip->bottom;
|
||
|
|
||
|
crTo = BlendColors(crFrom1, crTo,
|
||
|
(float)(lpRect->bottom - lpRectClip->bottom) / (float)(lpRect->bottom - lpRect->top));
|
||
|
|
||
|
}
|
||
|
|
||
|
GradientFill(pDC, rc, crFrom, crTo, bHorz);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::GradientFill(CDC* pDC, LPCRECT lpRect, const CXTPPaintManagerColorGradient& grc, BOOL bHorz, LPCRECT lpRectClip)
|
||
|
{
|
||
|
// using gradient factor color gradient fill
|
||
|
if (grc.fGradientFactor != 0.5f)
|
||
|
{
|
||
|
COLORREF clrMid = BlendColors(grc.clrLight, grc.clrDark, grc.fGradientFactor);
|
||
|
|
||
|
if (bHorz)
|
||
|
{
|
||
|
CRect rcLeft(lpRect);
|
||
|
rcLeft.right -= rcLeft.Width()/2;
|
||
|
GradientFill(pDC, &rcLeft, grc.clrLight, clrMid, bHorz, lpRectClip);
|
||
|
|
||
|
CRect rcRight(lpRect);
|
||
|
rcRight.left = rcLeft.right;
|
||
|
GradientFill(pDC, &rcRight, clrMid, grc.clrDark, bHorz, lpRectClip);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CRect rcTop(lpRect);
|
||
|
rcTop.bottom -= rcTop.Height()/2;
|
||
|
GradientFill(pDC, &rcTop, grc.clrLight, clrMid, bHorz, lpRectClip);
|
||
|
|
||
|
CRect rcBottom(lpRect);
|
||
|
rcBottom.top = rcTop.bottom;
|
||
|
GradientFill(pDC, &rcBottom, clrMid, grc.clrDark, bHorz, lpRectClip);
|
||
|
}
|
||
|
}
|
||
|
// using 2 color gradient fill
|
||
|
else
|
||
|
{
|
||
|
GradientFill(pDC, lpRect, grc.clrLight, grc.clrDark, bHorz, lpRectClip);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::ExcludeCorners(CDC* pDC, CRect rc)
|
||
|
{
|
||
|
pDC->ExcludeClipRect(rc.left, rc.top, rc.left + 1, rc.top + 1);
|
||
|
pDC->ExcludeClipRect(rc.right - 1, rc.top, rc.right, rc.top + 1);
|
||
|
pDC->ExcludeClipRect(rc.left, rc.bottom - 1, rc.left + 1, rc.bottom);
|
||
|
pDC->ExcludeClipRect(rc.right - 1, rc.bottom - 1, rc.right, rc.bottom);
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::StripMnemonics(CString& strClear)
|
||
|
{
|
||
|
for (int i = 0; i < strClear.GetLength(); i++)
|
||
|
{
|
||
|
if (strClear[i] == _T('&')) // Converts "&&" to "&" and "&&&&" to "&&"
|
||
|
{
|
||
|
strClear.Delete(i);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::StripMnemonics(LPTSTR lpszClear)
|
||
|
{
|
||
|
if (lpszClear == NULL || lpszClear == LPSTR_TEXTCALLBACK)
|
||
|
return;
|
||
|
|
||
|
LPTSTR lpszResult = lpszClear;
|
||
|
|
||
|
while (*lpszClear)
|
||
|
{
|
||
|
if (*lpszClear == _T('&') && *(lpszClear + 1) != _T('&'))
|
||
|
{
|
||
|
lpszClear++;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
*lpszResult++ = *lpszClear++;
|
||
|
}
|
||
|
|
||
|
*lpszResult = 0;
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::BlurPoints(CDC* pDC, LPPOINT pts, int nCount)
|
||
|
{
|
||
|
for (int i = 0; i < nCount; i += 2)
|
||
|
{
|
||
|
CPoint ptBlur = pts[i];
|
||
|
CPoint ptDirection(pts[i].x + pts[i + 1].x, pts[i].y + pts[i + 1].y);
|
||
|
|
||
|
COLORREF clrBlur = pDC->GetPixel(ptDirection);
|
||
|
COLORREF clrDirection = pDC->GetPixel(ptBlur);
|
||
|
|
||
|
pDC->SetPixel(ptBlur, RGB(
|
||
|
(GetRValue(clrBlur) + GetRValue(clrDirection)) / 2,
|
||
|
(GetGValue(clrBlur) + GetGValue(clrDirection)) / 2,
|
||
|
(GetBValue(clrBlur) + GetBValue(clrDirection)) / 2));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
COLORREF CXTPDrawHelpers::BlendColors(COLORREF crA, COLORREF crB, double fAmountA)
|
||
|
{
|
||
|
double fAmountB = (1.0 - fAmountA);
|
||
|
int btR = (int)(GetRValue(crA) * fAmountA + GetRValue(crB) * fAmountB);
|
||
|
int btG = (int)(GetGValue(crA) * fAmountA + GetGValue(crB) * fAmountB);
|
||
|
int btB = (int)(GetBValue(crA) * fAmountA + GetBValue(crB) * fAmountB);
|
||
|
|
||
|
return RGB(min(255, btR), (BYTE)min(255, btG), (BYTE)min(255, btB));
|
||
|
}
|
||
|
|
||
|
COLORREF CXTPDrawHelpers::DarkenColor(long lScale, COLORREF lColor)
|
||
|
{
|
||
|
long red = MulDiv(GetRValue(lColor), (255 - lScale), 255);
|
||
|
long green = MulDiv(GetGValue(lColor), (255 - lScale), 255);
|
||
|
long blue = MulDiv(GetBValue(lColor), (255 - lScale), 255);
|
||
|
|
||
|
return RGB(red, green, blue);
|
||
|
}
|
||
|
|
||
|
COLORREF CXTPDrawHelpers::LightenColor(long lScale, COLORREF lColor)
|
||
|
{
|
||
|
long R = MulDiv(255 - GetRValue(lColor), lScale, 255) + GetRValue(lColor);
|
||
|
long G = MulDiv(255 - GetGValue(lColor), lScale, 255) + GetGValue(lColor);
|
||
|
long B = MulDiv(255 - GetBValue(lColor), lScale, 255) + GetBValue(lColor);
|
||
|
|
||
|
return RGB(R, G, B);
|
||
|
}
|
||
|
|
||
|
CPoint CXTPDrawHelpers::Dlu2Pix(int dluX, int dluY)
|
||
|
{
|
||
|
CPoint baseXY(::GetDialogBaseUnits());
|
||
|
CPoint pixXY(0,0);
|
||
|
pixXY.x = ::MulDiv(dluX, baseXY.x, 4);
|
||
|
pixXY.y = ::MulDiv(dluY, baseXY.y, 8);
|
||
|
return pixXY;
|
||
|
}
|
||
|
|
||
|
COLORREF CXTPDrawHelpers::RGBtoHSL(COLORREF rgb)
|
||
|
{
|
||
|
int delta, sum;
|
||
|
int nH, nS, nL;
|
||
|
int r = GetRValue(rgb);
|
||
|
int g = GetGValue(rgb);
|
||
|
int b = GetBValue(rgb);
|
||
|
int cmax = ((r) >= (g) ? ((r) >= (b) ? (r) : (b)) : (g) >= (b) ? (g) : (b));
|
||
|
int cmin = ((r) <= (g) ? ((r) <= (b) ? (r) : (b)) : (g) <= (b) ? (g) : (b));
|
||
|
|
||
|
nL = (cmax + cmin + 1) / 2;
|
||
|
if (cmax == cmin)
|
||
|
{
|
||
|
nH = 255; // H is really undefined
|
||
|
nS = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
delta = cmax - cmin;
|
||
|
sum = cmax + cmin;
|
||
|
if (nL < 127)
|
||
|
nS = ((delta + 1) * 256) / sum;
|
||
|
else
|
||
|
nS = (delta * 256) / ((2 * 256) - sum);
|
||
|
if (r == cmax)
|
||
|
nH = ((g - b) * 256) / delta;
|
||
|
else if (g == cmax)
|
||
|
nH = (2 * 256) + ((b - r) * 256) / delta;
|
||
|
else
|
||
|
nH = (4 * 256) + ((r - g) * 256) / delta;
|
||
|
nH /= 6;
|
||
|
if (nH < 0)
|
||
|
nH += 256;
|
||
|
}
|
||
|
nH = nH * 239 / 255;
|
||
|
nS = nS * 240 / 255;
|
||
|
nL = nL * 240 / 255;
|
||
|
|
||
|
return RGB((BYTE)min(nH, 239), (BYTE)min(nS, 240), (BYTE)min(nL, 240));
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::RGBtoHSL(COLORREF clr, double& h, double& s, double& l)
|
||
|
{
|
||
|
double r = (double)GetRValue(clr)/255.0;
|
||
|
double g = (double)GetGValue(clr)/255.0;
|
||
|
double b = (double)GetBValue(clr)/255.0;
|
||
|
|
||
|
double maxcolor = __max(r, __max(g, b));
|
||
|
double mincolor = __min(r, __min(g, b));
|
||
|
|
||
|
l = (maxcolor + mincolor)/2;
|
||
|
|
||
|
if (maxcolor == mincolor)
|
||
|
{
|
||
|
h = 0;
|
||
|
s = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (l < 0.5)
|
||
|
s = (maxcolor-mincolor)/(maxcolor + mincolor);
|
||
|
else
|
||
|
s = (maxcolor-mincolor)/(2.0-maxcolor-mincolor);
|
||
|
|
||
|
if (r == maxcolor)
|
||
|
h = (g-b)/(maxcolor-mincolor);
|
||
|
else if (g == maxcolor)
|
||
|
h = 2.0+(b-r)/(maxcolor-mincolor);
|
||
|
else
|
||
|
h = 4.0+(r-g)/(maxcolor-mincolor);
|
||
|
|
||
|
h /= 6.0;
|
||
|
if (h < 0.0) h += 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
double CXTPDrawHelpers::HueToRGB(double temp1, double temp2, double temp3)
|
||
|
{
|
||
|
if (temp3 < 0)
|
||
|
temp3 = temp3 + 1.0;
|
||
|
if (temp3 > 1)
|
||
|
temp3 = temp3-1.0;
|
||
|
|
||
|
if (6.0*temp3 < 1)
|
||
|
return (temp1+(temp2-temp1)*temp3 * 6.0);
|
||
|
|
||
|
else if (2.0*temp3 < 1)
|
||
|
return temp2;
|
||
|
|
||
|
else if (3.0*temp3 < 2.0)
|
||
|
return (temp1+(temp2-temp1)*((2.0/3.0)-temp3)*6.0);
|
||
|
|
||
|
return temp1;
|
||
|
}
|
||
|
|
||
|
int CXTPDrawHelpers::HueToRGB(int m1, int m2, int h)
|
||
|
{
|
||
|
if (h < 0)
|
||
|
h += 255;
|
||
|
|
||
|
if (h > 255)
|
||
|
h -= 255;
|
||
|
|
||
|
if ((6 * h) < 255)
|
||
|
return ((m1 + ((m2 - m1) / 255 * h * 6)) / 255);
|
||
|
|
||
|
if ((2 * h) < 255)
|
||
|
return m2 / 255;
|
||
|
|
||
|
if ((3 * h) < (2 * 255))
|
||
|
return ((m1 + (m2 - m1) / 255 * ((255 * 2 / 3) - h) * 6) / 255);
|
||
|
|
||
|
return (m1 / 255);
|
||
|
}
|
||
|
|
||
|
COLORREF CXTPDrawHelpers::HSLtoRGB(COLORREF hsl)
|
||
|
{
|
||
|
int r, g, b;
|
||
|
int m1, m2;
|
||
|
int nH = GetRValue(hsl) * 255 / 239;
|
||
|
int nS = GetGValue(hsl) * 255 / 240;
|
||
|
int nL = GetBValue(hsl) * 255 / 240;
|
||
|
|
||
|
if (nS == 0)
|
||
|
r = g = b = nL;
|
||
|
else
|
||
|
{
|
||
|
if (nL <= 127)
|
||
|
m2 = nL * (255 + nS);
|
||
|
else
|
||
|
m2 = (nL + nS - ((nL * nS) / 255)) * 255;
|
||
|
m1 = (2 * 255 * nL) - m2;
|
||
|
r = HueToRGB(m1, m2, nH + (255 / 3));
|
||
|
g = HueToRGB(m1, m2, nH);
|
||
|
b = HueToRGB(m1, m2, nH - (255 / 3));
|
||
|
}
|
||
|
return RGB((BYTE)min(r, 255), (BYTE)min(g, 255), (BYTE)min(b, 255));
|
||
|
}
|
||
|
|
||
|
COLORREF CXTPDrawHelpers::HSLtoRGB(double h, double s, double l)
|
||
|
{
|
||
|
double r, g, b;
|
||
|
double temp1, temp2;
|
||
|
|
||
|
if (s == 0)
|
||
|
{
|
||
|
r = g = b = l;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (l < 0.5)
|
||
|
temp2 = l*(1.0 + s);
|
||
|
else
|
||
|
temp2 = l + s-l*s;
|
||
|
|
||
|
temp1 = 2.0 * l-temp2;
|
||
|
|
||
|
r = HueToRGB(temp1, temp2, h + 1.0/3.0);
|
||
|
g = HueToRGB(temp1, temp2, h);
|
||
|
b = HueToRGB(temp1, temp2, h - 1.0/3.0);
|
||
|
}
|
||
|
|
||
|
return RGB((BYTE)(r * 255), (BYTE)(g * 255), (BYTE)(b * 255));
|
||
|
}
|
||
|
|
||
|
static int CALLBACK XTPEnumFontFamExProc(ENUMLOGFONTEX* pelf, NEWTEXTMETRICEX* /*lpntm*/, int /*FontType*/, LPVOID pThis)
|
||
|
{
|
||
|
LPCTSTR strFontName = (LPCTSTR)pThis;
|
||
|
CString strFaceName = pelf->elfLogFont.lfFaceName;
|
||
|
|
||
|
if (strFaceName.CompareNoCase(strFontName) == 0)
|
||
|
return 0;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPDrawHelpers::FontExists(LPCTSTR strFaceName)
|
||
|
{
|
||
|
// Enumerate all styles and charsets of all fonts:
|
||
|
LOGFONT lfEnum;
|
||
|
::ZeroMemory(&lfEnum, sizeof(LOGFONT));
|
||
|
|
||
|
lfEnum.lfFaceName[ 0 ] = 0;
|
||
|
lfEnum.lfCharSet = DEFAULT_CHARSET;
|
||
|
|
||
|
CWindowDC dc(NULL);
|
||
|
|
||
|
return ::EnumFontFamiliesEx(dc.m_hDC, &lfEnum, (FONTENUMPROC)
|
||
|
XTPEnumFontFamExProc, (LPARAM)strFaceName, 0) == 0;
|
||
|
}
|
||
|
|
||
|
CString CXTPDrawHelpers::GetDefaultFontName()
|
||
|
{
|
||
|
LOGFONT lfFont;
|
||
|
ZeroMemory(&lfFont, sizeof(LOGFONT));
|
||
|
::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lfFont);
|
||
|
|
||
|
return CString(lfFont.lfFaceName);
|
||
|
}
|
||
|
|
||
|
CString AFX_CDECL CXTPDrawHelpers::GetVerticalFontName(BOOL bUseOfficeFont)
|
||
|
{
|
||
|
LOGFONT lfFont;
|
||
|
ZeroMemory(&lfFont, sizeof(LOGFONT));
|
||
|
::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lfFont);
|
||
|
bool bUseSystemFont = lfFont.lfCharSet > SYMBOL_CHARSET;
|
||
|
|
||
|
if (bUseSystemFont && !XTPSystemVersion()->IsWin2KOrGreater())
|
||
|
bUseSystemFont = FALSE;
|
||
|
|
||
|
if (bUseSystemFont && (_tcsicmp(lfFont.lfFaceName, _T("MS Shell Dlg")) == 0))
|
||
|
bUseSystemFont = FALSE; // Can draw it vertically in Windows 2000.
|
||
|
|
||
|
CString strVerticalFaceName = _T("Arial");
|
||
|
LPCTSTR strOfficeFont = _T("Tahoma");
|
||
|
|
||
|
if (bUseSystemFont || !FontExists(strVerticalFaceName))
|
||
|
{
|
||
|
strVerticalFaceName = lfFont.lfFaceName;
|
||
|
}
|
||
|
else if (bUseOfficeFont && !bUseSystemFont && FontExists(strOfficeFont))
|
||
|
{
|
||
|
strVerticalFaceName = strOfficeFont;
|
||
|
}
|
||
|
|
||
|
return strVerticalFaceName;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPDrawHelpers::IsContextRTL(CDC* pDC)
|
||
|
{
|
||
|
return pDC && IsContextRTL(pDC->GetSafeHdc());
|
||
|
}
|
||
|
|
||
|
BOOL CXTPDrawHelpers::IsContextRTL(HDC hDC)
|
||
|
{
|
||
|
typedef DWORD (CALLBACK* PFNGDIGETLAYOUTPROC)(HDC);
|
||
|
static PFNGDIGETLAYOUTPROC s_pfn = (PFNGDIGETLAYOUTPROC)-1;
|
||
|
|
||
|
if (s_pfn == (PFNGDIGETLAYOUTPROC)-1)
|
||
|
{
|
||
|
HINSTANCE hInst = ::GetModuleHandleA("GDI32.DLL");
|
||
|
|
||
|
s_pfn = hInst ? (PFNGDIGETLAYOUTPROC)GetProcAddress(hInst, "GetLayout") : NULL;
|
||
|
}
|
||
|
|
||
|
return s_pfn ? (*s_pfn)(hDC) : FALSE;
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::SetContextRTL(CDC* pDC, BOOL bLayoutRTL)
|
||
|
{
|
||
|
if (pDC) SetContextRTL(pDC->GetSafeHdc(), bLayoutRTL);
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::SetContextRTL(HDC hDC, BOOL bLayoutRTL)
|
||
|
{
|
||
|
typedef DWORD (CALLBACK* PFNGDISETLAYOUTPROC)(HDC, DWORD);
|
||
|
static PFNGDISETLAYOUTPROC s_pfn = (PFNGDISETLAYOUTPROC)-1;
|
||
|
|
||
|
if (s_pfn == (PFNGDISETLAYOUTPROC)-1)
|
||
|
{
|
||
|
HINSTANCE hInst = ::GetModuleHandleA("GDI32.DLL");
|
||
|
|
||
|
s_pfn = hInst ? (PFNGDISETLAYOUTPROC)GetProcAddress(hInst, "SetLayout") : NULL;
|
||
|
}
|
||
|
|
||
|
if (s_pfn != NULL)
|
||
|
{
|
||
|
(*s_pfn)(hDC, bLayoutRTL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CXTPDrawHelpers::KeyToLayout(CWnd* pWnd, UINT& nChar)
|
||
|
{
|
||
|
ASSERT(pWnd);
|
||
|
if (!pWnd || !pWnd->GetSafeHwnd())
|
||
|
return;
|
||
|
|
||
|
if (nChar == VK_LEFT && pWnd->GetExStyle() & WS_EX_LAYOUTRTL)
|
||
|
nChar = VK_RIGHT;
|
||
|
else if (nChar == VK_RIGHT && pWnd->GetExStyle() & WS_EX_LAYOUTRTL)
|
||
|
nChar = VK_LEFT;
|
||
|
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::Triangle(CDC* pDC, CPoint pt0, CPoint pt1, CPoint pt2, COLORREF clr)
|
||
|
{
|
||
|
CXTPPenDC pen (*pDC, clr);
|
||
|
CXTPBrushDC brush (*pDC, clr);
|
||
|
|
||
|
Triangle(pDC, pt0, pt1, pt2);
|
||
|
}
|
||
|
|
||
|
BOOL CXTPDrawHelpers::DrawLine(CDC* pDC, int x, int y, int nLength, int nHeight, COLORREF crLine)
|
||
|
{
|
||
|
if (pDC->GetSafeHdc())
|
||
|
{
|
||
|
CXTPPenDC penDC(*pDC, crLine);
|
||
|
pDC->MoveTo(x, y);
|
||
|
pDC->LineTo(x + nLength, y + nHeight);
|
||
|
return TRUE;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
DWORD CXTPDrawHelpers::GetComCtlVersion()
|
||
|
{
|
||
|
return XTPSystemVersion()->GetComCtlVersion();
|
||
|
}
|
||
|
|
||
|
BOOL CXTPDrawHelpers::IsLowResolution(HDC hDC/* = 0*/)
|
||
|
{
|
||
|
return XTPColorManager()->IsLowResolution(hDC);
|
||
|
}
|
||
|
|
||
|
CRect CXTPDrawHelpers::GetWorkArea(LPCRECT rect)
|
||
|
{
|
||
|
return XTPMultiMonitor()->GetWorkArea(rect);
|
||
|
}
|
||
|
|
||
|
CRect CXTPDrawHelpers::GetWorkArea(const CWnd* pWnd)
|
||
|
{
|
||
|
return XTPMultiMonitor()->GetWorkArea(pWnd);
|
||
|
}
|
||
|
|
||
|
CRect CXTPDrawHelpers::GetScreenArea(const CWnd* pWnd)
|
||
|
{
|
||
|
return XTPMultiMonitor()->GetScreenArea(pWnd);
|
||
|
}
|
||
|
|
||
|
CRect CXTPDrawHelpers::GetWorkArea(const POINT& point)
|
||
|
{
|
||
|
return XTPMultiMonitor()->GetWorkArea(point);
|
||
|
}
|
||
|
|
||
|
CRect CXTPDrawHelpers::GetWorkArea()
|
||
|
{
|
||
|
return XTPMultiMonitor()->GetWorkArea();
|
||
|
}
|
||
|
|
||
|
BOOL CXTPDrawHelpers::TakeSnapShot(CWnd* pWnd, CBitmap& bmpSnapshot)
|
||
|
{
|
||
|
if (!::IsWindow(pWnd->GetSafeHwnd()))
|
||
|
return FALSE;
|
||
|
|
||
|
CWnd *pWndParent = pWnd->GetParent();
|
||
|
if (::IsWindow(pWndParent->GetSafeHwnd()))
|
||
|
{
|
||
|
if (bmpSnapshot.GetSafeHandle() != NULL)
|
||
|
bmpSnapshot.DeleteObject();
|
||
|
|
||
|
//convert our coordinates to our parent coordinates.
|
||
|
CXTPWindowRect rc(pWnd);
|
||
|
pWndParent->ScreenToClient(&rc);
|
||
|
|
||
|
//copy what's on the parents background at this point
|
||
|
CDC *pDC = pWndParent->GetDC();
|
||
|
|
||
|
CDC memDC;
|
||
|
memDC.CreateCompatibleDC(pDC);
|
||
|
bmpSnapshot.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());
|
||
|
|
||
|
CXTPBitmapDC bitmapDC(&memDC, &bmpSnapshot);
|
||
|
memDC.BitBlt(0, 0, rc.Width(), rc.Height(), pDC, rc.left, rc.top, SRCCOPY);
|
||
|
|
||
|
pWndParent->ReleaseDC(pDC);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPDrawHelpers::DrawTransparentBack(CDC* pDC, CWnd* pWnd, CBitmap& bmpSnapshot)
|
||
|
{
|
||
|
if (!::IsWindow(pWnd->GetSafeHwnd()))
|
||
|
return FALSE;
|
||
|
|
||
|
if (::GetWindowLong(pWnd->GetSafeHwnd(), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
|
||
|
{
|
||
|
// Get background.
|
||
|
if (!TakeSnapShot(pWnd, bmpSnapshot))
|
||
|
return FALSE;
|
||
|
|
||
|
CXTPClientRect rc(pWnd);
|
||
|
|
||
|
CDC memDC;
|
||
|
memDC.CreateCompatibleDC(pDC);
|
||
|
|
||
|
CXTPBitmapDC bitmapDC(&memDC, &bmpSnapshot);
|
||
|
pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &memDC, 0, 0, SRCCOPY);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPDrawHelpers::IsTopParentActive(HWND hWnd)
|
||
|
{
|
||
|
HWND hwndForeground = ::GetForegroundWindow();
|
||
|
|
||
|
HWND hWndT;
|
||
|
while ((hWndT = AfxGetParentOwner(hWnd)) != NULL)
|
||
|
{
|
||
|
hWnd = hWndT;
|
||
|
}
|
||
|
|
||
|
HWND hwndActivePopup = ::GetLastActivePopup(hWnd);
|
||
|
|
||
|
if (hwndForeground == hwndActivePopup)
|
||
|
return TRUE;
|
||
|
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
void CXTPDrawHelpers::ScreenToWindow(CWnd* pWnd, LPPOINT lpPoint)
|
||
|
{
|
||
|
RECT rc;
|
||
|
::GetWindowRect(pWnd->GetSafeHwnd(), &rc);
|
||
|
|
||
|
lpPoint->y -= rc.top;
|
||
|
|
||
|
if (GetWindowLong(pWnd->GetSafeHwnd(), GWL_EXSTYLE) & WS_EX_LAYOUTRTL )
|
||
|
{
|
||
|
lpPoint->x = rc.right - lpPoint->x;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lpPoint->x -= rc.left;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL CXTPDrawHelpers::RegisterWndClass(HINSTANCE hInstance, LPCTSTR lpszClassName, UINT style, HICON hIcon, HBRUSH hbrBackground)
|
||
|
{
|
||
|
WNDCLASS wndcls;
|
||
|
ZeroMemory(&wndcls, sizeof(wndcls));
|
||
|
|
||
|
wndcls.style = style;
|
||
|
wndcls.lpfnWndProc = ::DefWindowProc;
|
||
|
wndcls.hInstance = hInstance ? hInstance : AfxGetInstanceHandle();
|
||
|
wndcls.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
|
||
|
wndcls.lpszClassName = lpszClassName;
|
||
|
wndcls.hIcon = hIcon;
|
||
|
wndcls.hbrBackground = hbrBackground;
|
||
|
|
||
|
return AfxRegisterClass(&wndcls);
|
||
|
}
|
||
|
|
||
|
void CXTPDrawHelpers::GetWindowCaption(HWND hWnd, CString& strWindowText)
|
||
|
{
|
||
|
#ifdef _UNICODE
|
||
|
int nLen = (int)::DefWindowProc(hWnd, WM_GETTEXTLENGTH, 0, 0);
|
||
|
::DefWindowProc(hWnd, WM_GETTEXT, nLen + 1, (WPARAM)(LPCTSTR)strWindowText.GetBuffer(nLen));
|
||
|
strWindowText.ReleaseBuffer();
|
||
|
#else
|
||
|
int nLen = ::GetWindowTextLength(hWnd);
|
||
|
::GetWindowText(hWnd, strWindowText.GetBufferSetLength(nLen), nLen + 1);
|
||
|
strWindowText.ReleaseBuffer();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL XTPTrackMouseEvent(HWND hWndTrack, DWORD dwFlags /*= TME_LEAVE*/, DWORD dwHoverTime /*= HOVER_DEFAULT*/)
|
||
|
{
|
||
|
ASSERT(::IsWindow(hWndTrack));
|
||
|
|
||
|
TRACKMOUSEEVENT tme;
|
||
|
tme.cbSize = sizeof(TRACKMOUSEEVENT);
|
||
|
tme.dwFlags = dwFlags;
|
||
|
tme.dwHoverTime = dwHoverTime;
|
||
|
tme.hwndTrack = hWndTrack;
|
||
|
|
||
|
return ::_TrackMouseEvent(&tme);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL XTPGetPrinterDeviceDefaults(HGLOBAL& ref_hDevMode, HGLOBAL& ref_hDevNames)
|
||
|
{
|
||
|
CWinApp* pApp = AfxGetApp();
|
||
|
if (pApp)
|
||
|
{
|
||
|
PRINTDLG _pd;
|
||
|
::ZeroMemory(&_pd, sizeof(_pd));
|
||
|
if (pApp->GetPrinterDeviceDefaults(&_pd))
|
||
|
{
|
||
|
ref_hDevMode = _pd.hDevMode;
|
||
|
ref_hDevNames = _pd.hDevNames;
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPDrawHelpers::GetIconLogFont(LOGFONT* plf)
|
||
|
{
|
||
|
VERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), plf, 0));
|
||
|
plf->lfCharSet = XTPResourceManager()->GetFontCharset();
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
IMPLEMENT_DYNAMIC(CXTPPrinterInfo, CCmdTarget)
|
||
|
|
||
|
CXTPPrinterInfo::CXTPPrinterInfo()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
CXTPPrinterInfo::~CXTPPrinterInfo()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
CString CXTPPrinterInfo::GetName(XTPEnumDeviceName eNameID)
|
||
|
{
|
||
|
CString strName;
|
||
|
HGLOBAL hDevMode = NULL, hDevNames = NULL;
|
||
|
|
||
|
if (XTPGetPrinterDeviceDefaults(hDevMode, hDevNames) && hDevNames != NULL)
|
||
|
{
|
||
|
LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(hDevNames);
|
||
|
if (lpDev)
|
||
|
{
|
||
|
strName = (LPCTSTR)lpDev + _GetNameOffset(lpDev, eNameID);
|
||
|
}
|
||
|
::GlobalUnlock(hDevNames);
|
||
|
}
|
||
|
return strName;
|
||
|
}
|
||
|
|
||
|
WORD CXTPPrinterInfo::_GetNameOffset(LPDEVNAMES pDevNames, XTPEnumDeviceName eNameID)
|
||
|
{
|
||
|
ASSERT(pDevNames);
|
||
|
if (!pDevNames)
|
||
|
return 0;
|
||
|
|
||
|
switch (eNameID)
|
||
|
{
|
||
|
case xtpDevName_Driver:
|
||
|
return pDevNames->wDriverOffset;
|
||
|
case xtpDevName_Device:
|
||
|
return pDevNames->wDeviceOffset;
|
||
|
case xtpDevName_Port:
|
||
|
return pDevNames->wOutputOffset;
|
||
|
};
|
||
|
|
||
|
ASSERT(FALSE);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
IMPLEMENT_DYNAMIC(CXTPPrintPageHeaderFooter, CCmdTarget)
|
||
|
|
||
|
CXTPPrintPageHeaderFooter::CXTPPrintPageHeaderFooter(CXTPPrintOptions* pOwner, BOOL bHeader)
|
||
|
{
|
||
|
ASSERT(pOwner);
|
||
|
|
||
|
m_bHeader = bHeader;
|
||
|
m_pOwner = pOwner;
|
||
|
|
||
|
VERIFY(CXTPDrawHelpers::GetIconLogFont(&m_lfFont));
|
||
|
m_clrColor = RGB(0, 0, 0);
|
||
|
|
||
|
}
|
||
|
|
||
|
CXTPPrintPageHeaderFooter::~CXTPPrintPageHeaderFooter()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void CXTPPrintPageHeaderFooter::Set(const CXTPPrintPageHeaderFooter* pSrc)
|
||
|
{
|
||
|
ASSERT(pSrc);
|
||
|
if (!pSrc)
|
||
|
return;
|
||
|
|
||
|
m_lfFont = pSrc->m_lfFont;
|
||
|
m_clrColor = pSrc->m_clrColor;
|
||
|
|
||
|
m_strFormatString = pSrc->m_strFormatString;
|
||
|
|
||
|
m_strLeft = pSrc->m_strLeft;
|
||
|
m_strCenter = pSrc->m_strCenter;
|
||
|
m_strRight = pSrc->m_strRight;
|
||
|
}
|
||
|
|
||
|
void CXTPPrintPageHeaderFooter::Clear()
|
||
|
{
|
||
|
VERIFY(CXTPDrawHelpers::GetIconLogFont(&m_lfFont));
|
||
|
m_clrColor = RGB(0, 0, 0);
|
||
|
m_strFormatString.Empty();
|
||
|
|
||
|
m_strLeft.Empty();
|
||
|
m_strCenter.Empty();
|
||
|
m_strRight.Empty();
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPrintPageHeaderFooter::IsEmpty()
|
||
|
{
|
||
|
return m_strLeft.IsEmpty() && m_strCenter.IsEmpty() && m_strRight.IsEmpty();
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
// &w Window title
|
||
|
//
|
||
|
// &d Date in short format (as specified by Regional Settings in Control Panel)
|
||
|
// &D Date in long format (as specified by Regional Settings in Control Panel)
|
||
|
//
|
||
|
// &t Time in the format specified by Regional Settings in Control Panel
|
||
|
// &T Time in 24-hour format
|
||
|
//
|
||
|
// &p Current page number
|
||
|
// &P Total number of pages
|
||
|
// &# Ordinal page number (even for WYSIWYG mode)
|
||
|
//
|
||
|
// &b The text immediately following these characters as centered.
|
||
|
// &b&b The text immediately following the first "&b" as centered, and the text following the second "&b" as right-justified.
|
||
|
//
|
||
|
// && A single ampersand (&)
|
||
|
//===========================================================================
|
||
|
void CXTPPrintPageHeaderFooter::FormatTexts(CPrintInfo* pInfo, LPCTSTR pcszWndTitle, int nVirtualPage)
|
||
|
{
|
||
|
ASSERT(pInfo);
|
||
|
if (m_strFormatString.IsEmpty() || !pInfo)
|
||
|
return;
|
||
|
|
||
|
LCID lcidLocale = m_pOwner ? m_pOwner->GetActiveLCID() : LOCALE_USER_DEFAULT;
|
||
|
|
||
|
CString strFormat = m_strFormatString;
|
||
|
strFormat.Replace(_T("&&"), _T("\1"));
|
||
|
|
||
|
CString str_p, str_P = _T("*");
|
||
|
if (nVirtualPage > 0)
|
||
|
str_p.Format(_T("%d-%d"), pInfo->m_nCurPage, nVirtualPage);
|
||
|
else
|
||
|
str_p.Format(_T("%d"), pInfo->m_nCurPage);
|
||
|
|
||
|
if (pInfo->GetMaxPage() != 65535)
|
||
|
str_P.Format(_T("%d"), pInfo->GetMaxPage());
|
||
|
|
||
|
strFormat.Replace(_T("&p"), str_p);
|
||
|
strFormat.Replace(_T("&P"), str_P);
|
||
|
|
||
|
strFormat.Replace(_T("\\n"), _T("\n"));
|
||
|
|
||
|
_SplitFormatLCR(strFormat);
|
||
|
|
||
|
_FormatDateTime(m_strLeft, lcidLocale);
|
||
|
_FormatDateTime(m_strCenter, lcidLocale);
|
||
|
_FormatDateTime(m_strRight, lcidLocale);
|
||
|
|
||
|
if (pcszWndTitle)
|
||
|
{
|
||
|
m_strLeft.Replace(_T("&w"), pcszWndTitle);
|
||
|
m_strCenter.Replace(_T("&w"), pcszWndTitle);
|
||
|
m_strRight.Replace(_T("&w"), pcszWndTitle);
|
||
|
}
|
||
|
|
||
|
m_strLeft.Replace( _T("\1"), _T("&"));
|
||
|
m_strCenter.Replace(_T("\1"), _T("&"));
|
||
|
m_strRight.Replace(_T("\1"), _T("&"));
|
||
|
}
|
||
|
|
||
|
CString CXTPPrintPageHeaderFooter::GetParentFrameTitle(CWnd* pWnd)
|
||
|
{
|
||
|
CString strTitle;
|
||
|
|
||
|
ASSERT(pWnd);
|
||
|
if (!pWnd)
|
||
|
return strTitle;
|
||
|
|
||
|
pWnd->GetWindowText(strTitle);
|
||
|
if (strTitle.IsEmpty() || !pWnd->IsFrameWnd())
|
||
|
{
|
||
|
if (pWnd->GetParentFrame())
|
||
|
pWnd->GetParentFrame()->GetWindowText(strTitle);
|
||
|
|
||
|
if (strTitle.IsEmpty())
|
||
|
{
|
||
|
if (pWnd->GetParentOwner())
|
||
|
pWnd->GetParentOwner()->GetWindowText(strTitle);
|
||
|
}
|
||
|
}
|
||
|
return strTitle;
|
||
|
}
|
||
|
|
||
|
void CXTPPrintPageHeaderFooter::_FormatDateTime(CString& strFormat, LCID lcidLocale)
|
||
|
{
|
||
|
SYSTEMTIME stNow;
|
||
|
::GetLocalTime(&stNow);
|
||
|
|
||
|
const int cnBufferSize = 200;
|
||
|
TCHAR szDateFormatShort[cnBufferSize] = {0};
|
||
|
TCHAR szDateFormatLong[cnBufferSize] = {0};
|
||
|
|
||
|
TCHAR szTimeFormat[cnBufferSize] = {0};
|
||
|
TCHAR szTimeFormat24[cnBufferSize] = {0};
|
||
|
|
||
|
::GetDateFormat(lcidLocale, DATE_SHORTDATE, &stNow, NULL, szDateFormatShort, cnBufferSize);
|
||
|
::GetDateFormat(lcidLocale, DATE_LONGDATE, &stNow, NULL, szDateFormatLong, cnBufferSize);
|
||
|
|
||
|
::GetTimeFormat(lcidLocale, 0, &stNow, NULL, szTimeFormat, cnBufferSize);
|
||
|
DWORD dwFlags24h = TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER;
|
||
|
::GetTimeFormat(lcidLocale, dwFlags24h, &stNow, NULL, szTimeFormat24, cnBufferSize);
|
||
|
|
||
|
strFormat.Replace(_T("&d"), szDateFormatShort); // &d Date in short format (as specified by Regional Settings in Control Panel)
|
||
|
strFormat.Replace(_T("&D"), szDateFormatLong); // &D Date in long format (as specified by Regional Settings in Control Panel)
|
||
|
|
||
|
strFormat.Replace(_T("&t"), szTimeFormat); // &t Time in the format specified by Regional Settings in Control Panel
|
||
|
strFormat.Replace(_T("&T"), szTimeFormat24); // &T Time in 24-hour format
|
||
|
}
|
||
|
|
||
|
void CXTPPrintPageHeaderFooter::_SplitFormatLCR(CString strFormat)
|
||
|
{
|
||
|
m_strLeft.Empty();
|
||
|
m_strCenter.Empty();
|
||
|
m_strRight.Empty();
|
||
|
|
||
|
int nAmpBidx = strFormat.Find(_T("&b"));
|
||
|
if (nAmpBidx < 0)
|
||
|
{
|
||
|
m_strLeft = strFormat;
|
||
|
}
|
||
|
else if (nAmpBidx >= 0)
|
||
|
{
|
||
|
if (nAmpBidx > 0)
|
||
|
m_strLeft = strFormat.Left(nAmpBidx);
|
||
|
|
||
|
strFormat.Delete(0, nAmpBidx + 2);
|
||
|
|
||
|
nAmpBidx = strFormat.Find(_T("&b"));
|
||
|
if (nAmpBidx < 0)
|
||
|
{
|
||
|
m_strCenter = strFormat;
|
||
|
}
|
||
|
else if (nAmpBidx >= 0)
|
||
|
{
|
||
|
if (nAmpBidx > 0)
|
||
|
m_strCenter = strFormat.Left(nAmpBidx);
|
||
|
strFormat.Delete(0, nAmpBidx + 2);
|
||
|
|
||
|
m_strRight = strFormat;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int CXTPPrintPageHeaderFooter::fnYi(int Xi, int Wi)
|
||
|
{
|
||
|
int nYi = Wi / Xi;
|
||
|
int nYi_ = Wi % Xi;
|
||
|
return nYi + (nYi_ ? 1 : 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
int CXTPPrintPageHeaderFooter::_Calc3ColSizesIfSingleCol(CDC* pDC, int nW,
|
||
|
const CString& str1, const CString& str2, const CString& str3,
|
||
|
CSize& rsz1, CSize& rsz2, CSize& rsz3)
|
||
|
{
|
||
|
CString str1trim = str1;
|
||
|
CString str2trim = str2;
|
||
|
CString str3trim = str3;
|
||
|
|
||
|
str1trim.TrimLeft();
|
||
|
str2trim.TrimLeft();
|
||
|
str3trim.TrimLeft();
|
||
|
|
||
|
UINT uFlags = DT_TOP | DT_WORDBREAK | DT_CALCRECT;
|
||
|
rsz1 = rsz2 = rsz3 = CSize(0, 0);
|
||
|
|
||
|
if (!str1trim.IsEmpty() && str2trim.IsEmpty() && str3trim.IsEmpty())
|
||
|
{
|
||
|
CRect rcText1(0, 0, nW, 32000);
|
||
|
rsz1.cx = nW;
|
||
|
return rsz1.cy = pDC->DrawText(str1, &rcText1, uFlags | DT_LEFT);
|
||
|
|
||
|
}
|
||
|
|
||
|
if (str1trim.IsEmpty() && !str2trim.IsEmpty() && str3trim.IsEmpty())
|
||
|
{
|
||
|
CRect rcText2(0, 0, nW, 32000);
|
||
|
rsz2.cx = nW;
|
||
|
return rsz2.cy = pDC->DrawText(str2, &rcText2, uFlags | DT_CENTER);
|
||
|
}
|
||
|
|
||
|
if (str1trim.IsEmpty() && str2trim.IsEmpty() && !str3trim.IsEmpty())
|
||
|
{
|
||
|
CRect rcText3(0, 0, nW, 32000);
|
||
|
rsz3.cx = nW;
|
||
|
return rsz3.cy = pDC->DrawText(str3, &rcText3, uFlags | DT_RIGHT);
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
int CXTPPrintPageHeaderFooter::Calc3ColSizes(CDC* pDC, int nW,
|
||
|
const CString& str1, const CString& str2, const CString& str3,
|
||
|
CSize& rsz1, CSize& rsz2, CSize& rsz3)
|
||
|
{
|
||
|
ASSERT(pDC);
|
||
|
if (!pDC)
|
||
|
return 0;
|
||
|
|
||
|
int nIfSingleCol = _Calc3ColSizesIfSingleCol(pDC, nW, str1, str2, str3, rsz1, rsz2, rsz3);
|
||
|
if (nIfSingleCol >= 0)
|
||
|
return nIfSingleCol;
|
||
|
|
||
|
int nW1 = pDC->GetTextExtent(str1).cx;
|
||
|
int nW2 = pDC->GetTextExtent(str2).cx;
|
||
|
int nW3 = pDC->GetTextExtent(str3).cx;
|
||
|
|
||
|
if (!nW || !nW1 && !nW2 && !nW3)
|
||
|
return 0;
|
||
|
|
||
|
nW1 = max(nW1, 1);
|
||
|
nW2 = max(nW2, 1);
|
||
|
nW3 = max(nW3, 1);
|
||
|
|
||
|
int nYmin = INT_MAX;
|
||
|
int nYminMetric = INT_MAX;
|
||
|
int nXforYmin[4] = {0, 1, 1, 1};
|
||
|
|
||
|
int nX[4] = {0, 0, 0, 0};
|
||
|
int nX_step = 15; //nW/50;
|
||
|
|
||
|
int nX_start = nW/9;
|
||
|
int nX_stop = nW/2 - nW/9;
|
||
|
for (nX[1] = nX_start; nX[1] <= nX_stop; nX[1] += nX_step)
|
||
|
{
|
||
|
int nY[4];
|
||
|
//************************
|
||
|
nY[1] = fnYi(nX[1], nW1);
|
||
|
|
||
|
int nX2_stop = nW - nX[1] - nW/9;
|
||
|
for (nX[2] = nX_start; nX[2] <= nX2_stop; nX[2] += nX_step)
|
||
|
{
|
||
|
nX[3] = nW - nX[1] - nX[2];
|
||
|
|
||
|
//************************
|
||
|
nY[2] = fnYi(nX[2], nW2);
|
||
|
if (nY[2] > nYmin)
|
||
|
continue;
|
||
|
|
||
|
nY[3] = fnYi(nX[3], nW3);
|
||
|
if (nY[3] > nYmin)
|
||
|
break;
|
||
|
|
||
|
int nY123 = max( max(nY[1], nY[2]), max(nY[1], nY[3]) );
|
||
|
|
||
|
int nM = nW / 3;
|
||
|
int nY123Metric = abs(nM - nX[1]) + abs(nM - nX[2]) + abs(nM - nX[3]);
|
||
|
|
||
|
if (nY123 < nYmin || nY123 == nYmin && nY123Metric < nYminMetric)
|
||
|
{
|
||
|
//TRACE(_T("-- =*= %d <= %d, metrics(cur: %d, min: %d) \n"), nY123, nYmin, nY123Metric, nYminMetric);
|
||
|
//TRACE(_T("-- prev (%d, %d, %d) \n"), nXforYmin[1], nXforYmin[2], nXforYmin[3]);
|
||
|
//TRACE(_T("-- new (%d, %d, %d) \n"), nX[1], nX[2], nX[3]);
|
||
|
|
||
|
nYmin = nY123;
|
||
|
nYminMetric = nY123Metric;
|
||
|
|
||
|
nXforYmin[1] = nX[1];
|
||
|
nXforYmin[2] = nX[2];
|
||
|
nXforYmin[3] = nX[3];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ASSERT(nXforYmin[1] + nXforYmin[2] + nXforYmin[3] <= nW);
|
||
|
|
||
|
UINT uFlags = DT_TOP | DT_WORDBREAK | DT_CALCRECT;
|
||
|
CRect rcText1(0, 0, nXforYmin[1], 32000);
|
||
|
|
||
|
rsz1.cx = nXforYmin[1];
|
||
|
rsz1.cy = pDC->DrawText(str1, &rcText1, uFlags | DT_LEFT);
|
||
|
|
||
|
CRect rcText2(0, 0, nXforYmin[2], 32000);
|
||
|
rsz2.cx = nXforYmin[2];
|
||
|
rsz2.cy = pDC->DrawText(str2, &rcText2, uFlags | DT_CENTER);
|
||
|
|
||
|
CRect rcText3(0, 0, nXforYmin[3], 32000);
|
||
|
rsz3.cx = nXforYmin[3];
|
||
|
rsz3.cy = pDC->DrawText(str3, &rcText3, uFlags | DT_RIGHT);
|
||
|
|
||
|
return max( max(rsz1.cy, rsz2.cy), max(rsz1.cy, rsz3.cy) );
|
||
|
}
|
||
|
|
||
|
void CXTPPrintPageHeaderFooter::Draw(CDC* pDC, CRect& rcRect, BOOL bCalculateOnly)
|
||
|
{
|
||
|
CFont fntHF;
|
||
|
VERIFY(fntHF.CreateFontIndirect(&m_lfFont));
|
||
|
CXTPFontDC autoFont(pDC, &fntHF, m_clrColor);
|
||
|
|
||
|
int nWidth = rcRect.Width();
|
||
|
|
||
|
CSize szLeft2, szCenter2, szRight2;
|
||
|
|
||
|
int nHeight = Calc3ColSizes(pDC, nWidth, m_strLeft, m_strCenter, m_strRight,
|
||
|
szLeft2, szCenter2, szRight2);
|
||
|
|
||
|
int nBorderH = nHeight ? 3 : 0;
|
||
|
if (m_bHeader)
|
||
|
{
|
||
|
rcRect.bottom = rcRect.top + nHeight + nBorderH;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rcRect.top = rcRect.bottom - nHeight - nBorderH;
|
||
|
}
|
||
|
|
||
|
if (bCalculateOnly)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
int nBkModePrev = pDC->SetBkMode(TRANSPARENT);
|
||
|
|
||
|
UINT uFlags = DT_TOP | DT_WORDBREAK | DT_NOPREFIX;
|
||
|
|
||
|
CRect rcLeft = rcRect;
|
||
|
rcLeft.right = rcLeft.left + szLeft2.cx;
|
||
|
pDC->DrawText(m_strLeft, &rcLeft, uFlags | DT_LEFT);
|
||
|
|
||
|
CRect rcCenter = rcRect;
|
||
|
rcCenter.left = rcLeft.right;
|
||
|
rcCenter.right = rcCenter.left + szCenter2.cx;
|
||
|
pDC->DrawText(m_strCenter, &rcCenter, uFlags | DT_CENTER);
|
||
|
|
||
|
CRect rcRight = rcRect;
|
||
|
rcRight.left = rcRight.right - szRight2.cx;
|
||
|
pDC->DrawText(m_strRight, &rcRight, uFlags | DT_RIGHT);
|
||
|
|
||
|
pDC->SetBkMode(nBkModePrev);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
// CXTPDpi
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
int CXTPDpi::m_iDefaultDpi = 96; // static
|
||
|
|
||
|
CXTPDpi* XTPDpiHelper()
|
||
|
{
|
||
|
static CXTPDpi s_instance; // singleton
|
||
|
return &s_instance;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
//*************************************************************
|
||
|
IMPLEMENT_DYNAMIC(CXTPPrintOptions, CCmdTarget)
|
||
|
|
||
|
LCID CXTPPrintOptions::GetActiveLCID()
|
||
|
{
|
||
|
return LOCALE_USER_DEFAULT;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPrintOptions::IsMarginsMeasureInches()
|
||
|
{
|
||
|
TCHAR szResult[5];
|
||
|
|
||
|
int nResult = ::GetLocaleInfo(GetActiveLCID(), LOCALE_IMEASURE, szResult, 4);
|
||
|
ASSERT(nResult == 2);
|
||
|
long nIsInches = _ttoi(szResult);
|
||
|
|
||
|
return nIsInches != 0;
|
||
|
}
|
||
|
|
||
|
CXTPPrintOptions::CXTPPrintOptions()
|
||
|
{
|
||
|
BOOL bIsInches = IsMarginsMeasureInches();
|
||
|
int nMargin = bIsInches ? (1000 * 1/2 ) : (10 * 100);
|
||
|
m_rcMargins.SetRect(nMargin, nMargin, nMargin, nMargin);
|
||
|
|
||
|
m_pPageHeader = new CXTPPrintPageHeaderFooter(this, TRUE);
|
||
|
m_pPageFooter = new CXTPPrintPageHeaderFooter(this, FALSE);
|
||
|
|
||
|
m_bBlackWhitePrinting = FALSE;
|
||
|
m_nBlackWhiteContrast = 0;
|
||
|
|
||
|
//#ifdef _XTP_ACTIVEX
|
||
|
// EnableAutomation();
|
||
|
// EnableTypeLib();
|
||
|
//#endif
|
||
|
}
|
||
|
|
||
|
CXTPPrintOptions::~CXTPPrintOptions()
|
||
|
{
|
||
|
CMDTARGET_RELEASE(m_pPageHeader);
|
||
|
CMDTARGET_RELEASE(m_pPageFooter);
|
||
|
}
|
||
|
|
||
|
void CXTPPrintOptions::Set(const CXTPPrintOptions* pSrc)
|
||
|
{
|
||
|
ASSERT(pSrc);
|
||
|
if (!pSrc)
|
||
|
return;
|
||
|
|
||
|
m_rcMargins = pSrc->m_rcMargins;
|
||
|
|
||
|
if (m_pPageHeader)
|
||
|
m_pPageHeader->Set(pSrc->m_pPageHeader);
|
||
|
|
||
|
if (m_pPageFooter)
|
||
|
m_pPageFooter->Set(pSrc->m_pPageFooter);
|
||
|
|
||
|
m_bBlackWhitePrinting = pSrc->m_bBlackWhitePrinting;
|
||
|
m_nBlackWhiteContrast = pSrc->m_nBlackWhiteContrast;
|
||
|
}
|
||
|
|
||
|
CRect CXTPPrintOptions::GetMarginsHimetric()
|
||
|
{
|
||
|
BOOL bIsInches = IsMarginsMeasureInches();
|
||
|
|
||
|
if (!bIsInches)
|
||
|
{
|
||
|
return m_rcMargins;
|
||
|
}
|
||
|
|
||
|
int nMul_i2m = 254;
|
||
|
int nDiv_i2m = 100;
|
||
|
|
||
|
CRect rcMarginsHimetric;
|
||
|
rcMarginsHimetric.left = m_rcMargins.left * nMul_i2m / nDiv_i2m;
|
||
|
rcMarginsHimetric.top = m_rcMargins.top * nMul_i2m / nDiv_i2m;
|
||
|
rcMarginsHimetric.right = m_rcMargins.right * nMul_i2m / nDiv_i2m;
|
||
|
rcMarginsHimetric.bottom = m_rcMargins.bottom * nMul_i2m / nDiv_i2m;
|
||
|
|
||
|
return rcMarginsHimetric;
|
||
|
}
|
||
|
|
||
|
CRect CXTPPrintOptions::GetMarginsLP(CDC* pDC)
|
||
|
{
|
||
|
ASSERT(pDC);
|
||
|
if (!pDC)
|
||
|
return CRect(0, 0, 0, 0);
|
||
|
|
||
|
CRect rcMarginsHI = GetMarginsHimetric();
|
||
|
|
||
|
CSize szLT(rcMarginsHI.left, rcMarginsHI.top);
|
||
|
CSize szRB(rcMarginsHI.right, rcMarginsHI.bottom);
|
||
|
|
||
|
pDC->HIMETRICtoLP(&szLT);
|
||
|
pDC->HIMETRICtoLP(&szRB);
|
||
|
|
||
|
CRect rcLP(szLT.cx, szLT.cy, szRB.cx, szRB.cy);
|
||
|
|
||
|
return rcLP;
|
||
|
}
|
||
|
|
||
|
CXTPPrintPageHeaderFooter* CXTPPrintOptions::GetPageHeader()
|
||
|
{
|
||
|
return m_pPageHeader;
|
||
|
}
|
||
|
|
||
|
CXTPPrintPageHeaderFooter* CXTPPrintOptions::GetPageFooter()
|
||
|
{
|
||
|
return m_pPageFooter;
|
||
|
}
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// Printing Dialog
|
||
|
|
||
|
|
||
|
class XTP_PRINT_STATE : public CNoTrackObject
|
||
|
{
|
||
|
public:
|
||
|
// printing abort
|
||
|
BOOL m_bUserAbort;
|
||
|
};
|
||
|
|
||
|
PROCESS_LOCAL(XTP_PRINT_STATE, g_xtpPrintState)
|
||
|
|
||
|
BOOL CALLBACK _XTPAbortProc(HDC, int)
|
||
|
{
|
||
|
XTP_PRINT_STATE* pState = g_xtpPrintState;
|
||
|
MSG msg;
|
||
|
while (!pState->m_bUserAbort &&
|
||
|
::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
|
||
|
{
|
||
|
if (!XTPGetThread()->PumpMessage())
|
||
|
return FALSE; // terminate if WM_QUIT received
|
||
|
}
|
||
|
return !pState->m_bUserAbort;
|
||
|
}
|
||
|
|
||
|
CXTPPrintingDialog::CXTPPrintingDialog(CWnd* pParent)
|
||
|
{
|
||
|
Create(CXTPPrintingDialog::IDD, pParent); // modeless !
|
||
|
g_xtpPrintState->m_bUserAbort = FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPrintingDialog::OnInitDialog()
|
||
|
{
|
||
|
//SetWindowText(AfxGetAppName());
|
||
|
CenterWindow();
|
||
|
return CDialog::OnInitDialog();
|
||
|
}
|
||
|
|
||
|
void CXTPPrintingDialog::OnCancel()
|
||
|
{
|
||
|
g_xtpPrintState->m_bUserAbort = TRUE; // flag that user aborted print
|
||
|
CDialog::OnCancel();
|
||
|
}
|
||
|
|
||
|
void CXTPPrintPageHeaderFooter::DoInsertHFFormatSpecifierViaMenu(
|
||
|
CWnd* pParent, CEdit* pEdit, CButton* pButton)
|
||
|
{
|
||
|
CMap<UINT, UINT, CString, CString&> menuData;
|
||
|
menuData[XTP_ID_HF_FORMAT_D1] = _T("&d");
|
||
|
menuData[XTP_ID_HF_FORMAT_D2] = _T("&D");
|
||
|
menuData[XTP_ID_HF_FORMAT_T1] = _T("&t");
|
||
|
menuData[XTP_ID_HF_FORMAT_T2] = _T("&T");
|
||
|
menuData[XTP_ID_HF_FORMAT_P1] = _T("&p");
|
||
|
menuData[XTP_ID_HF_FORMAT_P2] = _T("&P");
|
||
|
menuData[XTP_ID_HF_FORMAT_B] = _T("&b");
|
||
|
menuData[XTP_ID_HF_FORMAT_W] = _T("&w");
|
||
|
menuData[XTP_ID_HF_FORMAT_UMP] = _T("&&");
|
||
|
menuData[XTP_ID_HF_FORMAT_N] = _T("\\n");
|
||
|
|
||
|
if (!pParent || !pEdit || !pButton)
|
||
|
{
|
||
|
ASSERT(FALSE);
|
||
|
return;
|
||
|
}
|
||
|
CRect rcButton;
|
||
|
pButton->GetWindowRect(&rcButton);
|
||
|
|
||
|
CPoint ptMenu(rcButton.left, rcButton.bottom + 1);
|
||
|
|
||
|
CMenu menu;
|
||
|
CXTPResourceManager::AssertValid(XTPResourceManager()->LoadMenu(&menu, XTP_IDR_MENU_HEADERFOOTER_FORMATS));
|
||
|
|
||
|
// track menu
|
||
|
int nMenuResult = menu.GetSubMenu(0)->TrackPopupMenu(
|
||
|
TPM_RETURNCMD | TPM_LEFTALIGN |TPM_RIGHTBUTTON,
|
||
|
ptMenu.x, ptMenu.y, pParent, NULL);
|
||
|
|
||
|
pEdit->SetFocus();
|
||
|
|
||
|
CString strItem = menuData[nMenuResult];
|
||
|
if (!strItem.IsEmpty())
|
||
|
{
|
||
|
pEdit->ReplaceSel(strItem, TRUE);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|