You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

935 lines
22 KiB
C++

2 years ago
// XTPPropertyPage.cpp : implementation file
//
// This file is a part of the XTREME CONTROLS 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 "Common/XTPDrawHelpers.h"
#include "Common/XTPColorManager.h"
#include "Common/XTPWinThemeWrapper.h"
#include "TabManager/XTPTabManager.h"
#include "TabManager/XTPTabControl.h"
#include "../Util/XTPControlTheme.h"
#include "../ListBox/XTPListBox.h"
#include "../Util/XTPGlobal.h"
#include "../Resize/XTPResizeRect.h"
#include "../Resize/XTPResizePoint.h"
#include "../Resize/XTPResize.h"
#include "XTPPropertyPage.h"
#include "XTPPropertySheet.h"
#include "XTPPropertyPageNavigator.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#pragma warning(disable: 4355) // 'this' : used in base member initializer list
/////////////////////////////////////////////////////////////////////////////
// CXTPPropertyPage property page
IMPLEMENT_DYNCREATE(CXTPPropertyPage, CPropertyPage)
CXTPPropertyPage::CXTPPropertyPage()
: CPropertyPage(), CXTPResize(this, xtpResizeNoClipChildren | xtpResizeNoSizeIcon)
{
CommonConstruct();
}
CXTPPropertyPage::CXTPPropertyPage(UINT nIDTemplate, UINT nIDCaption)
: CPropertyPage(nIDTemplate, nIDCaption), CXTPResize(this, xtpResizeNoClipChildren | xtpResizeNoSizeIcon)
{
CommonConstruct();
}
CXTPPropertyPage::CXTPPropertyPage(LPCTSTR lpszTemplateName, UINT nIDCaption)
: CPropertyPage(lpszTemplateName, nIDCaption), CXTPResize(this, xtpResizeNoClipChildren | xtpResizeNoSizeIcon)
{
CommonConstruct();
}
void CXTPPropertyPage::CommonConstruct()
{
m_pSheet = 0;
m_dwData = 0;
m_bModified = FALSE;
m_bInsideUpdate = FALSE;
m_totalDev = CSize(0, 0);
m_lineDev = CXTPDrawHelpers::Dlu2Pix(5, 5);
m_bCreated = FALSE;
}
CXTPPropertyPage::~CXTPPropertyPage()
{
}
void CXTPPropertyPage::SetCaption(LPCTSTR lpszCaption)
{
m_strCaption = lpszCaption;
m_psp.pszTitle = m_strCaption;
m_psp.dwFlags |= PSP_USETITLE;
}
CString CXTPPropertyPage::GetCaption() const
{
return m_strCaption;
}
void CXTPPropertyPage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CXTPPropertyPage)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
#pragma pack(push, 1)
struct DLGEXTEMPLATE
{
WORD dlgVer;
WORD wSignature;
DWORD helpID;
DWORD exStyle;
DWORD dwStyle;
WORD cDlgItems;
short x;
short y;
short cx;
short cy;
};
#pragma pack(pop)
BOOL CXTPPropertyPage::LoadTemplate(HGLOBAL& hTemplate, HINSTANCE& hInst)
{
hTemplate = 0;
hInst = AfxGetInstanceHandle();
if ((m_psp.dwFlags & PSP_DLGINDIRECT) && m_psp.pResource)
{
CDialogTemplate dlgTemp((LPCDLGTEMPLATE)m_psp.pResource);
hTemplate = dlgTemp.Detach();
}
else
{
hInst = AfxFindResourceHandle(m_psp.pszTemplate, RT_DIALOG);
if (!hInst)
return FALSE;
HRSRC hResource = ::FindResource(hInst, m_psp.pszTemplate, RT_DIALOG);
if (!hResource)
return FALSE;
hTemplate = LoadResource(hInst, hResource);
if (!hTemplate)
return FALSE;
DLGTEMPLATE* pTemplate = (DLGTEMPLATE*)LockResource(hTemplate);
CDialogTemplate dlgTemp(pTemplate);
UnlockResource(hTemplate);
FreeResource(hTemplate);
hTemplate = dlgTemp.Detach();
}
return TRUE;
}
BOOL CXTPPropertyPage::LoadTemplate()
{
HGLOBAL hTemplate = NULL;
HINSTANCE hInstance = NULL;
if (!LoadTemplate(hTemplate, hInstance))
return FALSE;
if (!hTemplate)
return FALSE;
DLGTEMPLATE* lpDialogTemplate = (DLGTEMPLATE*)GlobalLock(hTemplate);
if (!lpDialogTemplate)
return FALSE;
DLGEXTEMPLATE* lpDialogExTemplate = (DLGEXTEMPLATE*)lpDialogTemplate;
BOOL bDialogEx = lpDialogExTemplate->wSignature == 0xFFFF;
m_lineDev = CXTPDrawHelpers::Dlu2Pix(5, 5);
if ((m_psp.dwFlags & PSP_USETITLE) == 0)
{
WORD* lpTitle = bDialogEx ? (WORD*)(lpDialogExTemplate + 1) : (WORD*)(lpDialogTemplate + 1);
if (*lpTitle == (WORD)-1) // Skip menu name string or ordinal
lpTitle += 2;
else
while(*lpTitle++);
if (*lpTitle == (WORD)-1) // Skip class name string or ordinal
lpTitle += 2;
else
while(*lpTitle++);
m_strCaption = CString((LPWSTR)lpTitle);
}
CDialogTemplate dlgTemp(hTemplate);
dlgTemp.GetSizeInPixels(&m_totalDev);
GlobalUnlock(hTemplate);
GlobalFree(hTemplate);
return TRUE;
}
BOOL CXTPPropertyPage::CreatePage(CWnd* pParentWnd)
{
if (GetSafeHwnd())
return TRUE;
HGLOBAL hTemplate = NULL;
HINSTANCE hInstance = NULL;
if (!LoadTemplate(hTemplate, hInstance))
return FALSE;
if (!hTemplate)
return FALSE;
DLGTEMPLATE* lpDialogTemplate = (DLGTEMPLATE*)GlobalLock(hTemplate);
if (!lpDialogTemplate)
return FALSE;
DLGEXTEMPLATE* lpDialogExTemplate = (DLGEXTEMPLATE*)lpDialogTemplate;
DWORD lSaveStyle;
if (lpDialogExTemplate->wSignature == 0xFFFF)
lSaveStyle = lpDialogExTemplate->dwStyle;
else
lSaveStyle = lpDialogTemplate->style;
DWORD dwNewStyle = (lSaveStyle & (DS_LOCALEDIT | WS_CLIPCHILDREN | DS_SETFONT | DS_FIXEDSYS))
| WS_CHILD | WS_TABSTOP | DS_3DLOOK | DS_CONTROL;
if (lpDialogExTemplate->wSignature == 0xFFFF)
lpDialogExTemplate->dwStyle = dwNewStyle;
else
lpDialogTemplate->style = dwNewStyle;
BOOL bResult = CreateDlgIndirect(lpDialogTemplate, pParentWnd, hInstance);
CSize sz;
CXTPWindowRect rc(this);
m_totalDev = rc.Size();
m_bCreated = TRUE;
GlobalUnlock(hTemplate);
GlobalFree(hTemplate);
return bResult;
}
void CXTPPropertyPage::EndDialog(int nID)
{
// Normally you shouldn't call EndDialog from a page. But in case it does
// happen during error situations, call CPropertySheet::EndDialog instead.
CXTPPropertySheet* pParent = DYNAMIC_DOWNCAST(CXTPPropertySheet, GetParent());
if (pParent != NULL)
pParent->EndDialog(nID);
}
BEGIN_MESSAGE_MAP(CXTPPropertyPage, CPropertyPage)
//{{AFX_MSG_MAP(CXTPPropertyPage)
ON_WM_ERASEBKGND()
ON_WM_CTLCOLOR()
ON_WM_SIZE()
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_MOUSEWHEEL()
ON_WM_NCPAINT()
ON_WM_NCCALCSIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CXTPPropertyPage message handlers
BOOL CXTPPropertyPage::OnEraseBkgnd(CDC* pDC)
{
HBRUSH hBrush = m_pSheet ? m_pSheet->GetNavigator()->GetPageBrush(pDC, this) : NULL;
if (hBrush)
{
CXTPClientRect rc(this);
::FillRect(pDC->GetSafeHdc(), rc, hBrush);
return TRUE;
}
return CPropertyPage::OnEraseBkgnd(pDC);
}
HBRUSH CXTPPropertyPage::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if ((nCtlColor == CTLCOLOR_BTN || nCtlColor == CTLCOLOR_DLG ||
nCtlColor == CTLCOLOR_STATIC ) && m_pSheet)
{
HBRUSH hBrush = m_pSheet->GetNavigator()->GetPageBrush(pDC, this);
if (hBrush)
{
CXTPWindowRect rcPaint(pWnd);
CXTPWindowRect rcBrush(m_hWnd);
::SetBrushOrgEx(pDC->GetSafeHdc(), rcBrush.left - rcPaint.left, rcBrush.top - rcPaint.top, NULL);
::SetBkMode(pDC->GetSafeHdc(), TRANSPARENT);
::SetTextColor(pDC->GetSafeHdc(), GetSysColor(COLOR_BTNTEXT));
return hBrush;
}
}
return CPropertyPage::OnCtlColor(pDC, pWnd, nCtlColor);
}
LRESULT CXTPPropertyPage::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
return CPropertyPage::WindowProc(message, wParam, lParam);
}
BOOL CXTPPropertyPage::OnInitDialog()
{
CPropertyPage::OnInitDialog();
CXTPResize::Init();
return TRUE;
}
void CXTPPropertyPage::AdjustResizeRect(CSize& szWindow)
{
CSize szMin = m_totalDev;
szWindow.cx = max(szWindow.cx, szMin.cx);
szWindow.cy = max(szWindow.cy, szMin.cy);
}
void CXTPPropertyPage::OnSize(UINT nType, int cx, int cy)
{
CPropertyPage::OnSize(nType, cx, cy);
// UpdateBars() handles locking out recursion
UpdateBars();
CXTPResize::Size();
}
void CXTPPropertyPage::GetScrollBarSizes(CSize& sizeSb)
{
sizeSb.cx = sizeSb.cy = 0;
DWORD dwStyle = GetStyle();
if (GetScrollBarCtrl(SB_VERT) == NULL)
{
// vert scrollbars will impact client area of this window
sizeSb.cx = GetSystemMetrics(SM_CXVSCROLL);
if (dwStyle & WS_BORDER)
sizeSb.cx -= CX_BORDER;
}
if (GetScrollBarCtrl(SB_HORZ) == NULL)
{
// horz scrollbars will impact client area of this window
sizeSb.cy = GetSystemMetrics(SM_CYHSCROLL);
if (dwStyle & WS_BORDER)
sizeSb.cy -= CY_BORDER;
}
}
BOOL CXTPPropertyPage::GetTrueClientSize(CSize& size, CSize& sizeSb)
// return TRUE if enough room to add scrollbars if needed
{
CRect rect;
GetClientRect(&rect);
ASSERT(rect.top == 0 && rect.left == 0);
size.cx = rect.right;
size.cy = rect.bottom;
DWORD dwStyle = GetStyle();
// first get the size of the scrollbars for this window
GetScrollBarSizes(sizeSb);
// first calculate the size of a potential scrollbar
// (scroll bar controls do not get turned on/off)
if (sizeSb.cx != 0 && (dwStyle & WS_VSCROLL))
{
// vert scrollbars will impact client area of this window
size.cx += sizeSb.cx; // currently on - adjust now
}
if (sizeSb.cy != 0 && (dwStyle & WS_HSCROLL))
{
// horz scrollbars will impact client area of this window
size.cy += sizeSb.cy; // currently on - adjust now
}
// return TRUE if enough room
return (size.cx > sizeSb.cx && size.cy > sizeSb.cy);
}
CPoint CXTPPropertyPage::GetDeviceScrollPosition() const
{
CPoint pt(GetScrollPos(SB_HORZ), GetScrollPos(SB_VERT));
ASSERT(pt.x >= 0 && pt.y >= 0);
return pt;
}
// helper to return the state of the scrollbars without actually changing
// the state of the scrollbars
void CXTPPropertyPage::GetScrollBarState(CSize sizeClient, CSize& needSb,
CSize& sizeRange, CPoint& ptMove, BOOL bInsideClient)
{
// get scroll bar sizes (the part that is in the client area)
CSize sizeSb;
GetScrollBarSizes(sizeSb);
// enough room to add scrollbars
sizeRange = m_totalDev - sizeClient;
// > 0 => need to scroll
ptMove = GetDeviceScrollPosition();
// point to move to (start at current scroll pos)
BOOL bNeedH = sizeRange.cx > 0;
if (!bNeedH)
ptMove.x = 0; // jump back to origin
else if (bInsideClient)
sizeRange.cy += sizeSb.cy; // need room for a scroll bar
BOOL bNeedV = sizeRange.cy > 0;
if (!bNeedV)
ptMove.y = 0; // jump back to origin
else if (bInsideClient)
sizeRange.cx += sizeSb.cx; // need room for a scroll bar
if (bNeedV && !bNeedH && sizeRange.cx > 0)
{
ASSERT(bInsideClient);
// need a horizontal scrollbar after all
bNeedH = TRUE;
sizeRange.cy += sizeSb.cy;
}
// if current scroll position will be past the limit, scroll to limit
if (sizeRange.cx > 0 && ptMove.x >= sizeRange.cx)
ptMove.x = sizeRange.cx;
if (sizeRange.cy > 0 && ptMove.y >= sizeRange.cy)
ptMove.y = sizeRange.cy;
// now update the bars as appropriate
needSb.cx = bNeedH;
needSb.cy = bNeedV;
// needSb, sizeRange, and ptMove area now all updated
}
void CXTPPropertyPage::ScrollToDevicePosition(POINT ptDev)
{
ASSERT(ptDev.x >= 0);
ASSERT(ptDev.y >= 0);
// Note: ScrollToDevicePosition can and is used to scroll out-of-range
// areas as far as CXTPPropertyPage is concerned -- specifically in
// the print-preview code. Since OnScrollBy makes sure the range is
// valid, ScrollToDevicePosition does not vector through OnScrollBy.
int xOrig = GetScrollPos(SB_HORZ);
SetScrollPos(SB_HORZ, ptDev.x);
int yOrig = GetScrollPos(SB_VERT);
SetScrollPos(SB_VERT, ptDev.y);
ScrollPage(xOrig - ptDev.x, yOrig - ptDev.y);
}
void CXTPPropertyPage::ScrollPage(int xAmount, int yAmount)
{
if (xAmount == 0 && yAmount == 0)
return;
ScrollWindow(xAmount, yAmount);
for (int i = 0; i < (int)m_arrItems.GetSize(); i++)
{
CXTPResizeRect& rrcWindow = m_arrItems[i]->m_rrcWindow;
rrcWindow.left += xAmount;
rrcWindow.right += xAmount;
rrcWindow.top += yAmount;
rrcWindow.bottom += yAmount;
}
}
void CXTPPropertyPage::UpdateBars()
{
if (m_totalDev == CSize(0, 0) || !m_bCreated)
return;
// UpdateBars may cause window to be resized - ignore those resizings
if (m_bInsideUpdate)
return; // Do not allow recursive calls
// Lock out recursion
m_bInsideUpdate = TRUE;
// update the horizontal to reflect reality
// NOTE: turning on/off the scrollbars will cause 'OnSize' callbacks
ASSERT(m_totalDev.cx >= 0 && m_totalDev.cy >= 0);
CRect rectClient;
BOOL bCalcClient = TRUE;
CSize sizeClient;
CSize sizeSb;
// get client rect
if (!GetTrueClientSize(sizeClient, sizeSb))
{
// no room for scroll bars (common for zero sized elements)
CRect rect;
GetClientRect(&rect);
if (rect.right > 0 && rect.bottom > 0)
{
// if entire client area is not invisible, assume we have
// control over our scrollbars
EnableScrollBarCtrl(SB_BOTH, FALSE);
}
m_bInsideUpdate = FALSE;
return;
}
// enough room to add scrollbars
CSize sizeRange;
CPoint ptMove;
CSize needSb;
// get the current scroll bar state given the true client area
GetScrollBarState(sizeClient, needSb, sizeRange, ptMove, bCalcClient);
if (needSb.cx)
sizeClient.cy -= sizeSb.cy;
if (needSb.cy)
sizeClient.cx -= sizeSb.cx;
// first scroll the window as needed
ScrollToDevicePosition(ptMove); // will set the scroll bar positions too
// this structure needed to update the scrollbar page range
SCROLLINFO info;
info.fMask = SIF_PAGE|SIF_RANGE;
info.nMin = 0;
// now update the bars as appropriate
EnableScrollBarCtrl(SB_HORZ, needSb.cx);
if (needSb.cx)
{
info.nPage = sizeClient.cx;
info.nMax = m_totalDev.cx-1;
if (!SetScrollInfo(SB_HORZ, &info, TRUE))
SetScrollRange(SB_HORZ, 0, sizeRange.cx, TRUE);
}
EnableScrollBarCtrl(SB_VERT, needSb.cy);
if (needSb.cy)
{
info.nPage = sizeClient.cy;
info.nMax = m_totalDev.cy-1;
if (!SetScrollInfo(SB_VERT, &info, TRUE))
SetScrollRange(SB_VERT, 0, sizeRange.cy, TRUE);
}
// remove recursion lockout
m_bInsideUpdate = FALSE;
}
void CXTPPropertyPage::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (pScrollBar != NULL && pScrollBar->SendChildNotifyLastMsg())
return; // eat it
// ignore scroll bar msgs from other controls
if (pScrollBar != GetScrollBarCtrl(SB_HORZ))
return;
OnScroll(MAKEWORD(nSBCode, -1), nPos);
}
void CXTPPropertyPage::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (pScrollBar != NULL && pScrollBar->SendChildNotifyLastMsg())
return; // eat it
// ignore scroll bar msgs from other controls
if (pScrollBar != GetScrollBarCtrl(SB_VERT))
return;
OnScroll(MAKEWORD(-1, nSBCode), nPos);
}
BOOL CXTPPropertyPage::OnMouseWheel(UINT fFlags, short zDelta, CPoint point)
{
// we don't handle anything but scrolling just now
if (fFlags & (MK_SHIFT | MK_CONTROL))
return FALSE;
// we can't get out of it--perform the scroll ourselves
return DoMouseWheel(fFlags, zDelta, point);
}
// This function isn't virtual. If you need to override it,
// you really need to override OnMouseWheel() here or in
// CSplitterWnd.
BOOL CXTPPropertyPage::DoMouseWheel(UINT fFlags, short zDelta, CPoint point)
{
UNUSED_ALWAYS(point);
UNUSED_ALWAYS(fFlags);
// if we have a vertical scroll bar, the wheel scrolls that
// if we have _only_ a horizontal scroll bar, the wheel scrolls that
// otherwise, don't do any work at all
DWORD dwStyle = GetStyle();
CScrollBar* pBar = GetScrollBarCtrl(SB_VERT);
BOOL bHasVertBar = ((pBar != NULL) && pBar->IsWindowEnabled()) ||
(dwStyle & WS_VSCROLL);
pBar = GetScrollBarCtrl(SB_HORZ);
BOOL bHasHorzBar = ((pBar != NULL) && pBar->IsWindowEnabled()) ||
(dwStyle & WS_HSCROLL);
if (!bHasVertBar && !bHasHorzBar)
return FALSE;
BOOL bResult = FALSE;
UINT uWheelScrollLines = 3;
if (bHasVertBar)
{
bResult = OnScrollBy(CSize(0, (zDelta < 0 ? 1 : -1) * m_lineDev.cy * uWheelScrollLines), TRUE);
}
else if (bHasHorzBar)
{
bResult = OnScrollBy(CSize((zDelta < 0 ? 1 : -1) * m_lineDev.cy * uWheelScrollLines, 0), TRUE);
}
if (bResult)
UpdateWindow();
return bResult;
}
BOOL CXTPPropertyPage::OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll)
{
// calc new x position
int x = GetScrollPos(SB_HORZ);
int xOrig = x;
switch (LOBYTE(nScrollCode))
{
case SB_TOP:
x = 0;
break;
case SB_BOTTOM:
x = INT_MAX;
break;
case SB_LINEUP:
x -= m_lineDev.cx;
break;
case SB_LINEDOWN:
x += m_lineDev.cx;
break;
case SB_PAGEUP:
x -= CXTPClientRect(this).Width();
break;
case SB_PAGEDOWN:
x += CXTPClientRect(this).Width();
break;
case SB_THUMBTRACK:
x = nPos;
break;
}
// calc new y position
int y = GetScrollPos(SB_VERT);
int yOrig = y;
switch (HIBYTE(nScrollCode))
{
case SB_TOP:
y = 0;
break;
case SB_BOTTOM:
y = INT_MAX;
break;
case SB_LINEUP:
y -= m_lineDev.cy;
break;
case SB_LINEDOWN:
y += m_lineDev.cy;
break;
case SB_PAGEUP:
y -= CXTPClientRect(this).Height();
break;
case SB_PAGEDOWN:
y += CXTPClientRect(this).Height();
break;
case SB_THUMBTRACK:
y = nPos;
break;
}
BOOL bResult = OnScrollBy(CSize(x - xOrig, y - yOrig), bDoScroll);
if (bResult && bDoScroll)
UpdateWindow();
return bResult;
}
BOOL CXTPPropertyPage::OnScrollBy(CSize sizeScroll, BOOL bDoScroll)
{
int xOrig, x;
int yOrig, y;
// don't scroll if there is no valid scroll range (ie. no scroll bar)
CScrollBar* pBar;
DWORD dwStyle = GetStyle();
pBar = GetScrollBarCtrl(SB_VERT);
if ((pBar != NULL && !pBar->IsWindowEnabled()) ||
(pBar == NULL && !(dwStyle & WS_VSCROLL)))
{
// vertical scroll bar not enabled
sizeScroll.cy = 0;
}
pBar = GetScrollBarCtrl(SB_HORZ);
if ((pBar != NULL && !pBar->IsWindowEnabled()) ||
(pBar == NULL && !(dwStyle & WS_HSCROLL)))
{
// horizontal scroll bar not enabled
sizeScroll.cx = 0;
}
// adjust current x position
xOrig = x = GetScrollPos(SB_HORZ);
int xMax = GetScrollLimit(SB_HORZ);
x += sizeScroll.cx;
if (x < 0)
x = 0;
else if (x > xMax)
x = xMax;
// adjust current y position
yOrig = y = GetScrollPos(SB_VERT);
int yMax = GetScrollLimit(SB_VERT);
y += sizeScroll.cy;
if (y < 0)
y = 0;
else if (y > yMax)
y = yMax;
// did anything change?
if (x == xOrig && y == yOrig)
return FALSE;
if (bDoScroll)
{
// do scroll and update scroll positions
ScrollPage(-(x-xOrig), -(y-yOrig));
if (x != xOrig)
SetScrollPos(SB_HORZ, x);
if (y != yOrig)
SetScrollPos(SB_VERT, y);
}
return TRUE;
}
void CXTPPropertyPage::OnNcPaint()
{
Default();
if (!m_pSheet)
return;
CWindowDC dc(this);
CXTPWindowRect rcPage(this);
rcPage.OffsetRect(-rcPage.TopLeft());
if (m_pSheet->GetPageBorderStyle() == xtpPageBorderFrame)
{
BOOL bFrame = FALSE;
CXTPWinThemeWrapper wrpTreeView;
wrpTreeView.OpenTheme(0, L"LISTBOX");
if (wrpTreeView.IsAppThemed())
{
COLORREF clr;
if (SUCCEEDED(wrpTreeView.GetThemeColor(0, 0, TMT_BORDERCOLOR, &clr)))
{
dc.Draw3dRect(rcPage, clr, clr);
rcPage.DeflateRect(1, 1);
dc.Draw3dRect(rcPage, GetXtremeColor(COLOR_WINDOW), GetXtremeColor(COLOR_WINDOW));
rcPage.DeflateRect(1, 1);
bFrame = TRUE;
}
}
if (!bFrame)
{
dc.DrawEdge(rcPage, EDGE_SUNKEN, BF_RECT);
rcPage.DeflateRect(2, 2);
}
}
else if (m_pSheet->GetPageBorderStyle() == xtpPageBorderBottomLine)
{
dc.FillSolidRect(rcPage.left, rcPage.bottom - 2, rcPage.Width(), 1, GetXtremeColor(COLOR_BTNSHADOW));
dc.FillSolidRect(rcPage.left, rcPage.bottom - 1, rcPage.Width(), 1, GetXtremeColor(COLOR_BTNHIGHLIGHT));
rcPage.DeflateRect(0, 0, 0, 2);
}
if ((GetStyle() & (WS_HSCROLL | WS_VSCROLL)) == (WS_HSCROLL | WS_VSCROLL))
{
CRect rcSizeIcon(rcPage.right - GetSystemMetrics(SM_CXVSCROLL),
rcPage.bottom - GetSystemMetrics(SM_CYHSCROLL), rcPage.right, rcPage.bottom);
HBRUSH hBrush = m_pSheet->GetNavigator()->GetPageBrush(&dc, this);
if (hBrush)
{
CXTPClientRect rc(this);
::FillRect(dc, rcSizeIcon, hBrush);
}
else
{
dc.FillSolidRect(rcSizeIcon, GetXtremeColor(COLOR_3DFACE));
}
}
}
void CXTPPropertyPage::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
if (!m_pSheet)
{
CPropertyPage::OnNcCalcSize(bCalcValidRects, lpncsp);
return;
}
if (m_pSheet->GetPageBorderStyle() == xtpPageBorderFrame)
{
RECT& rc = lpncsp->rgrc[0];
rc.left += 2;
rc.top += 2;
rc.right -= 2;
rc.bottom -= 2;
}
if (m_pSheet->GetPageBorderStyle() == xtpPageBorderBottomLine)
{
lpncsp->rgrc[0].bottom -= 2;
}
CWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
}
void CXTPPropertyPage::OnChildSetFocus(HWND hWndFocus)
{
if ((GetStyle() & (WS_HSCROLL | WS_VSCROLL)) == 0)
return;
CWnd* pWnd = CWnd::FromHandle(hWndFocus);
if (!pWnd)
return;
CRect rc;
pWnd->GetWindowRect(rc);
ScreenToClient(rc);
CXTPClientRect rcClient(this);
CSize szScroll(0, 0);
if (rc.bottom > rcClient.bottom)
szScroll.cy = rc.bottom - rcClient.bottom;
if (rc.top - szScroll.cy < rcClient.top)
szScroll.cy = rc.top - rcClient.top;
if (rc.right > rcClient.right)
szScroll.cx = rc.right - rcClient.right;
if (rc.left - szScroll.cx < rcClient.left)
szScroll.cx = rc.left - rcClient.left;
if (szScroll != CSize(0, 0))
{
OnScrollBy(szScroll, TRUE);
}
}
//////////////////////////////////////////////////////////////////////////
// CXTPPropertyPageCaption
CXTPPropertyPageStaticCaption::CXTPPropertyPageStaticCaption()
{
};
BEGIN_MESSAGE_MAP(CXTPPropertyPageStaticCaption, CWnd)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
BOOL CXTPPropertyPageStaticCaption::OnEraseBkgnd(CDC* /*pDC*/)
{
return TRUE;
}
void CXTPPropertyPageStaticCaption::OnPaint()
{
CPaintDC dcPaint(this);
CXTPBufferDC dc(dcPaint);
CXTPClientRect rc(this);
dc.FillSolidRect(rc, RGB(221, 231, 238));
dc.FillSolidRect(rc.left, rc.bottom - 1, rc.Width(), 1, RGB(197, 197, 197));
rc.DeflateRect(7, 0);
CString strText;
GetWindowText(strText);
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(RGB(0, 21, 110));
CXTPFontDC font(&dc, &XTPAuxData().fontBold);
dc.DrawText(strText, rc, DT_VCENTER | DT_SINGLELINE);
}