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.
852 lines
19 KiB
C++
852 lines
19 KiB
C++
// XTPEdit.cpp : implementation of the CXTPEdit class.
|
|
//
|
|
// 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/XTPResourceManager.h"
|
|
#include "Common/XTPDrawHelpers.h"
|
|
#include "Common/XTPColorManager.h"
|
|
#include "Common/XTPResourceImage.h"
|
|
#include "Common/XTPRegExp.h"
|
|
#include "Common/XTPMaskEditT.h"
|
|
#include "Common/XTPWinThemeWrapper.h"
|
|
#include "../Util/XTPControlTheme.h"
|
|
|
|
#include "../Util/XTPGlobal.h"
|
|
#include "../Resource.h"
|
|
#include "../Util/XTPFunctions.h"
|
|
#include "XTPEdit.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
#pragma warning(disable: 4097)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPMaskEdit
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
CXTPEdit::CXTPEdit()
|
|
{
|
|
m_bPreSubclassInit = TRUE;
|
|
|
|
m_bUseVisualStyle = TRUE;
|
|
m_nTheme = xtpControlThemeDefault;
|
|
|
|
m_bHighlighted = FALSE;
|
|
m_bFocused = FALSE;
|
|
m_bFlatStyle = FALSE;
|
|
|
|
m_bShowBorder = TRUE;
|
|
|
|
m_pRegExp = NULL;
|
|
|
|
m_themeEdit = new CXTPWinThemeWrapper();
|
|
}
|
|
|
|
CXTPEdit::~CXTPEdit()
|
|
{
|
|
SAFE_DELETE(m_pRegExp);
|
|
SAFE_DELETE(m_themeEdit);
|
|
}
|
|
|
|
|
|
IMPLEMENT_DYNAMIC(CXTPEdit, CEdit)
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPEdit, CEdit)
|
|
ON_MASKEDIT_REFLECT()
|
|
ON_WM_CREATE()
|
|
ON_WM_NCPAINT()
|
|
ON_WM_PAINT()
|
|
ON_WM_ERASEBKGND()
|
|
ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
|
|
ON_WM_NCCALCSIZE()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_KILLFOCUS()
|
|
ON_WM_SETFOCUS()
|
|
ON_WM_SYSCOLORCHANGE()
|
|
|
|
ON_WM_CONTEXTMENU()
|
|
ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
|
|
ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
|
|
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
|
|
ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
|
|
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
|
|
ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
|
|
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
|
|
ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
|
|
ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
|
|
ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR, OnUpdateEditClear)
|
|
ON_COMMAND(ID_EDIT_SELECT_ALL, OnEditSelectAll)
|
|
ON_UPDATE_COMMAND_UI(ID_EDIT_SELECT_ALL, OnUpdateEditSelectAll)
|
|
ON_WM_INITMENUPOPUP()
|
|
|
|
ON_CONTROL_REFLECT_EX(EN_CHANGE, OnChange)
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
|
|
BOOL CXTPEdit::SetEditMask(LPCTSTR lpszMask, LPCTSTR lpszLiteral, LPCTSTR lpszDefault /*= NULL*/)
|
|
{
|
|
return TBase::SetEditMask(lpszMask, lpszLiteral, lpszDefault);
|
|
}
|
|
|
|
void CXTPEdit::Init()
|
|
{
|
|
RefreshMetrics();
|
|
|
|
if (m_bShowBorder)
|
|
{
|
|
m_bShowBorder = GetExStyle() & WS_EX_CLIENTEDGE;
|
|
}
|
|
|
|
if (m_bShowBorder)
|
|
{
|
|
ModifyStyleEx(WS_EX_CLIENTEDGE, 0, 0);
|
|
ModifyStyle(WS_BORDER, 0, SWP_FRAMECHANGED);
|
|
PostMessage(WM_NCPAINT);
|
|
}
|
|
}
|
|
|
|
void CXTPEdit::PreSubclassWindow()
|
|
{
|
|
TBase::PreSubclassWindow();
|
|
|
|
if (m_bPreSubclassInit)
|
|
{
|
|
// Initialize the control.
|
|
Init();
|
|
}
|
|
}
|
|
|
|
int CXTPEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if (TBase::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
// Initialize the control.
|
|
Init();
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL CXTPEdit::PreCreateWindow(CREATESTRUCT& cs)
|
|
{
|
|
if (!TBase::PreCreateWindow(cs))
|
|
return FALSE;
|
|
|
|
// When creating controls dynamically Init() must
|
|
// be called from OnCreate() and not from
|
|
// PreSubclassWindow().
|
|
|
|
m_bPreSubclassInit = FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPEdit::OnContextMenu(CWnd*, CPoint point)
|
|
{
|
|
if (point.x == -1 && point.y == -1)
|
|
{
|
|
//keystroke invocation
|
|
CRect rect;
|
|
GetClientRect(rect);
|
|
ClientToScreen(rect);
|
|
|
|
point = rect.TopLeft();
|
|
point.Offset(5, 5);
|
|
}
|
|
|
|
SetFocus();
|
|
|
|
CMenu menu;
|
|
CXTPResourceManager::AssertValid(XTPResourceManager()->LoadMenu(&menu, XTP_IDM_POPUP));
|
|
|
|
CMenu* pPopup = menu.GetSubMenu(1);
|
|
ASSERT(pPopup != NULL);
|
|
CWnd* pWndPopupOwner = this;
|
|
|
|
XTPContextMenu(pPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON,
|
|
point.x, point.y, pWndPopupOwner, XTP_IDR_TBAR_HEXEDIT, FALSE);
|
|
}
|
|
|
|
void CXTPEdit::OnEditUndo()
|
|
{
|
|
MaskUndo();
|
|
}
|
|
|
|
void CXTPEdit::OnUpdateEditUndo(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(CanUndo());
|
|
}
|
|
|
|
void CXTPEdit::OnEditCut()
|
|
{
|
|
MaskCut();
|
|
}
|
|
|
|
void CXTPEdit::OnUpdateEditCut(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(HasSelection() && ((GetStyle() & ES_READONLY) == 0));
|
|
}
|
|
|
|
void CXTPEdit::OnEditCopy()
|
|
{
|
|
MaskCopy();
|
|
}
|
|
|
|
void CXTPEdit::OnUpdateEditCopy(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(HasSelection());
|
|
}
|
|
|
|
void CXTPEdit::OnEditPaste()
|
|
{
|
|
MaskPaste();
|
|
}
|
|
|
|
void CXTPEdit::OnUpdateEditPaste(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(CanPaste());
|
|
}
|
|
|
|
void CXTPEdit::OnEditClear()
|
|
{
|
|
MaskClear();
|
|
}
|
|
|
|
void CXTPEdit::OnUpdateEditClear(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(HasSelection() && ((GetStyle() & ES_READONLY) == 0));
|
|
}
|
|
|
|
void CXTPEdit::OnEditSelectAll()
|
|
{
|
|
SetSel(0, -1);
|
|
}
|
|
|
|
void CXTPEdit::OnUpdateEditSelectAll(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(GetWindowTextLength() > 0);
|
|
}
|
|
|
|
BOOL CXTPEdit::CanPaste()
|
|
{
|
|
return IsWindowEnabled() && ((GetStyle() & ES_READONLY) == 0) & ::IsClipboardFormatAvailable(CF_TEXT);
|
|
}
|
|
|
|
BOOL CXTPEdit::HasSelection() const
|
|
{
|
|
int nStartChar, nEndChar;
|
|
GetSel(nStartChar, nEndChar);
|
|
return (nStartChar < nEndChar);
|
|
}
|
|
|
|
BOOL CXTPEdit::OnEraseBkgnd(CDC* /*pDC*/)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPEdit::IsPatternValid()
|
|
{
|
|
if (!m_pRegExp)
|
|
return TRUE;
|
|
|
|
CString strWindowText;
|
|
GetWindowText(strWindowText);
|
|
|
|
int nCount = m_pRegExp->Execute(strWindowText);
|
|
if (nCount != 1)
|
|
return FALSE;
|
|
|
|
long nStart, nLength;
|
|
m_pRegExp->GetMatch(0, &nStart, &nLength);
|
|
|
|
return nStart == 0 && nLength == strWindowText.GetLength();
|
|
|
|
}
|
|
|
|
void CXTPEdit::OnPaint()
|
|
{
|
|
CPaintDC dcPaint(this); // device context for painting
|
|
|
|
// Get the client rect.
|
|
CXTPClientRect rectClient(this);
|
|
|
|
// Paint to a memory device context to help
|
|
// eliminate screen flicker.
|
|
CXTPBufferDC memDC(dcPaint);
|
|
::FillRect(memDC, rectClient, GetClientBrush(&memDC));
|
|
|
|
// Now let the window do its default painting...
|
|
CEdit::DefWindowProc(WM_PAINT, (WPARAM)memDC.m_hDC, 0);
|
|
|
|
if (!IsPatternValid())
|
|
{
|
|
CString strText;
|
|
GetWindowText(strText);
|
|
|
|
CRect rect;
|
|
const int iIncrement = 2;
|
|
|
|
// Get the rect for the entire edit control
|
|
((CEdit*)this)->GetRect(&rect);
|
|
|
|
// Check that wavy line will not over-write edit control border...
|
|
if (rectClient.bottom - rect.bottom >= iIncrement + 1)
|
|
{
|
|
CSize size;
|
|
int iX = 0;
|
|
|
|
rect.bottom -= iIncrement - 2;
|
|
|
|
// We must use the correct font when using GetTextExtent..!
|
|
CXTPFontDC font(&memDC, CWnd::GetFont());
|
|
CXTPPenDC pen(memDC, 0xFF);
|
|
|
|
BOOL bLayoutRLT = GetExStyle() & WS_EX_RIGHT;
|
|
|
|
if (bLayoutRLT)
|
|
{
|
|
size = memDC.GetTextExtent (strText);
|
|
|
|
// Check for case of empty string
|
|
if (size.cx == 0) size.cx = iIncrement * 3;
|
|
// Dont draw off the end of the edit control
|
|
else if (size.cx > rect.Width()) size.cx = rect.Width();
|
|
|
|
int iOffset = 0;
|
|
|
|
if (GetStyle () & ES_CENTER)
|
|
{
|
|
iOffset = (rect.Width () - size.cx) / 2;
|
|
}
|
|
|
|
rect.right -= iOffset;
|
|
// Starting x co-ordinate to start drawing from
|
|
iX = rect.right;
|
|
// Start at the bottom left of the edit control
|
|
memDC.MoveTo(rect.right, rect.bottom);
|
|
|
|
// Draw the wavy line like in Microsoft Word
|
|
while (iX > rect.right - size.cx)
|
|
{
|
|
iX -= iIncrement;
|
|
|
|
if (iX < rect.right - size.cx)
|
|
break;
|
|
|
|
memDC.LineTo (iX, rect.bottom + iIncrement);
|
|
iX -= iIncrement;
|
|
|
|
if (iX < rect.right - size.cx)
|
|
break;
|
|
|
|
memDC.LineTo(iX, rect.bottom);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
// This part deals with the *displayed* Text Extent
|
|
size = memDC.GetTextExtent (strText.
|
|
Mid(((CEdit*)this)->CharFromPos (CPoint (rect.left + 1, rect.top))));
|
|
|
|
// Check for case of empty string
|
|
if (size.cx == 0) size.cx = iIncrement * 3;
|
|
// Dont draw off the end of the edit control
|
|
else if (size.cx > rect.right) size.cx = rect.right;
|
|
|
|
int iOffset = 0;
|
|
|
|
if (GetStyle () & ES_CENTER)
|
|
{
|
|
iOffset = (rect.Width () - size.cx) / 2;
|
|
}
|
|
else if (GetStyle () & ES_RIGHT)
|
|
{
|
|
iOffset = rect.Width () - size.cx;
|
|
}
|
|
|
|
rect.left += iOffset;
|
|
// Starting x co-ordinate to start drawing from
|
|
iX = rect.left;
|
|
// Start at the bottom left of the edit control
|
|
memDC.MoveTo(rect.left, rect.bottom);
|
|
|
|
// Draw the wavy line like in Microsoft Word
|
|
while (iX < size.cx + rect.left)
|
|
{
|
|
iX += iIncrement;
|
|
|
|
if (iX > size.cx + rect.left)
|
|
break;
|
|
|
|
memDC.LineTo (iX, rect.bottom + iIncrement);
|
|
iX += iIncrement;
|
|
|
|
if (iX > size.cx + rect.left)
|
|
break;
|
|
|
|
memDC.LineTo(iX, rect.bottom);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRACE (_T("Edit Control too small to draw wavy line!\r\n"));
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void CXTPEdit::OnInitMenuPopup(CMenu* pPopupMenu, UINT /*nIndex*/, BOOL bSysMenu)
|
|
{
|
|
Default();
|
|
|
|
if (!bSysMenu)
|
|
{
|
|
ASSERT(pPopupMenu != NULL);
|
|
if (!pPopupMenu)
|
|
return;
|
|
|
|
// check the enabled state of various menu items
|
|
CCmdUI state;
|
|
state.m_pMenu = pPopupMenu;
|
|
ASSERT(state.m_pOther == NULL);
|
|
|
|
state.m_nIndexMax = pPopupMenu->GetMenuItemCount();
|
|
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
|
|
state.m_nIndex++)
|
|
{
|
|
state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);
|
|
if (state.m_nID == 0)
|
|
continue; // menu separator or invalid cmd - ignore it
|
|
|
|
ASSERT(state.m_pOther == NULL);
|
|
ASSERT(state.m_pMenu != NULL);
|
|
if (state.m_nID == (UINT)-1)
|
|
{
|
|
// possibly a popup menu, route to first item of that popup
|
|
state.m_pSubMenu = pPopupMenu->GetSubMenu(state.m_nIndex);
|
|
if (state.m_pSubMenu == NULL)
|
|
continue;
|
|
|
|
state.m_nID = state.m_pSubMenu->GetMenuItemID(0);
|
|
if (state.m_nID == 0 || state.m_nID == (UINT)-1)
|
|
continue; // first item of popup can't be routed to
|
|
|
|
state.DoUpdate(this, FALSE); // popups are never auto disabled
|
|
}
|
|
else
|
|
{
|
|
// normal menu item
|
|
// Auto enable/disable if command is _not_ a system command
|
|
state.m_pSubMenu = NULL;
|
|
state.DoUpdate(this, state.m_nID < 0xF000);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CXTPEdit::Initialize(CWnd* /*pParentWnd*/)
|
|
{
|
|
// edit control must be valid in order to initialize.
|
|
ASSERT_VALID(this);
|
|
if (!::IsWindow(m_hWnd))
|
|
return false;
|
|
|
|
// set the font and parent for the browse edit.
|
|
SetFont(&XTPAuxData().font);
|
|
|
|
return true;
|
|
}
|
|
|
|
void CXTPEdit::SetTheme(XTPControlTheme nTheme)
|
|
{
|
|
m_nTheme = nTheme;
|
|
|
|
m_bUseVisualStyle = (m_nTheme == xtpControlThemeDefault);
|
|
|
|
RefreshMetrics();
|
|
|
|
RedrawEdit();
|
|
}
|
|
|
|
void CXTPEdit::RefreshMetrics()
|
|
{
|
|
RefreshXtremeColors();
|
|
m_clrBorderNormal = m_clrBorderHot = GetXtremeColor(COLOR_3DSHADOW);
|
|
|
|
if (m_nTheme == xtpControlThemeFlat)
|
|
{
|
|
m_clrBorderNormal = m_clrBorderHot = GetXtremeColor(COLOR_WINDOWFRAME);
|
|
|
|
}
|
|
if (m_nTheme == xtpControlThemeOfficeXP || m_nTheme == xtpControlThemeOffice2003)
|
|
{
|
|
m_clrBorderHot = GetXtremeColor(XPCOLOR_HIGHLIGHT_BORDER);
|
|
}
|
|
|
|
if (m_nTheme == xtpControlThemeOffice2003)
|
|
{
|
|
XTPCurrentSystemTheme systemTheme = XTPColorManager()->GetCurrentSystemTheme();
|
|
switch (systemTheme)
|
|
{
|
|
case xtpSystemThemeBlue:
|
|
case xtpSystemThemeRoyale:
|
|
case xtpSystemThemeAero:
|
|
m_clrBorderNormal = RGB(127, 157, 185);
|
|
m_clrBorderHot = RGB(0, 0, 128);
|
|
break;
|
|
|
|
case xtpSystemThemeOlive:
|
|
m_clrBorderNormal = RGB(164, 185, 127);
|
|
m_clrBorderHot = RGB(63, 93, 56);
|
|
break;
|
|
|
|
case xtpSystemThemeSilver:
|
|
m_clrBorderNormal = RGB(165, 172, 178);
|
|
m_clrBorderHot = RGB(75, 75, 11);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (m_nTheme == xtpControlThemeResource)
|
|
{
|
|
CXTPResourceImages* pImages = XTPResourceImages();
|
|
|
|
m_clrBorderHot = m_clrBorderNormal = pImages->GetImageColor(_T("Toolbar"), _T("ControlEditBorder"));
|
|
}
|
|
|
|
m_themeEdit->OpenTheme(0, L"EDIT");
|
|
}
|
|
|
|
void CXTPEdit::OnNcPaint()
|
|
{
|
|
TBase::OnNcPaint();
|
|
if (!m_bShowBorder)
|
|
return;
|
|
|
|
CWindowDC dc(this);
|
|
|
|
CRect rc;
|
|
GetWindowRect(&rc);
|
|
rc.OffsetRect(-rc.TopLeft());
|
|
|
|
DrawNcBorders(&dc, rc);
|
|
|
|
if ((GetStyle() & (WS_VSCROLL | WS_HSCROLL)) == (WS_VSCROLL | WS_HSCROLL))
|
|
{
|
|
if (m_bShowBorder) rc.DeflateRect(2, 2);
|
|
rc.SetRect(rc.right - GetSystemMetrics(SM_CXVSCROLL), rc.bottom - GetSystemMetrics(SM_CYHSCROLL), rc.right, rc.bottom);
|
|
dc.FillSolidRect(rc, GetSysColor(COLOR_BTNFACE));
|
|
}
|
|
}
|
|
|
|
void CXTPEdit::FillSolidRect(HDC hdc, int x, int y, int cx, int cy, HBRUSH hBrush)
|
|
{
|
|
::FillRect(hdc, CRect(x, y, x + cx, y + cy), hBrush);
|
|
}
|
|
|
|
void CXTPEdit::DrawFrame(HDC hdc, LPRECT lprc, int nSize, HBRUSH hBrush)
|
|
{
|
|
FillSolidRect(hdc, lprc->left, lprc->top, lprc->right - lprc->left - nSize, nSize, hBrush);
|
|
FillSolidRect(hdc, lprc->left, lprc->top, nSize, lprc->bottom - lprc->top - nSize, hBrush);
|
|
FillSolidRect(hdc, lprc->right - nSize, lprc->top, nSize, lprc->bottom - lprc->top, hBrush);
|
|
FillSolidRect(hdc, lprc->left, lprc->bottom - nSize, lprc->right - lprc->left, nSize, hBrush);
|
|
}
|
|
|
|
void CXTPEdit::DrawNcBorders(CDC* pDC, CRect rc)
|
|
{
|
|
if (!m_bShowBorder)
|
|
return;
|
|
|
|
CRect rcIntersect(0, 0, 0, 0);
|
|
|
|
HWND hwndBuddy = ::GetWindow(m_hWnd, GW_HWNDNEXT);
|
|
if (hwndBuddy)
|
|
{
|
|
CXTPWindowRect rcSpin(hwndBuddy);
|
|
CXTPWindowRect rcEdit(m_hWnd);
|
|
|
|
if (rcIntersect.IntersectRect(rcSpin, rcEdit))
|
|
{
|
|
rcIntersect.OffsetRect(-rcEdit.TopLeft());
|
|
pDC->ExcludeClipRect(rcIntersect);
|
|
}
|
|
else
|
|
{
|
|
rcIntersect.SetRectEmpty();
|
|
}
|
|
|
|
}
|
|
|
|
HBRUSH hBrush = GetClientBrush(pDC);
|
|
|
|
if (!m_bHighlighted && !m_bFocused && m_bFlatStyle)
|
|
{
|
|
DrawFrame(*pDC, rc, 2, hBrush);
|
|
return;
|
|
}
|
|
|
|
if (m_bUseVisualStyle && m_themeEdit->IsAppThemed())
|
|
{
|
|
CRect rcClient(rc.left + 1, rc.top + 1, rc.right - 1, rc.bottom - 1);
|
|
pDC->ExcludeClipRect(rcClient);
|
|
|
|
if (SUCCEEDED(m_themeEdit->DrawThemeBackground(*pDC, 0, IsWindowEnabled() ? ETS_NORMAL : ETS_DISABLED, &rc, NULL)))
|
|
{
|
|
pDC->SelectClipRgn(NULL);
|
|
if (!rcIntersect.IsRectEmpty()) pDC->ExcludeClipRect(rcIntersect);
|
|
rc.DeflateRect(1, 1);
|
|
DrawFrame(*pDC, rc, 1, hBrush);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (m_nTheme == xtpControlThemeDefault)
|
|
{
|
|
pDC->DrawEdge(rc, EDGE_SUNKEN, BF_RECT);
|
|
return;
|
|
}
|
|
if (m_nTheme == xtpControlThemeOffice2000)
|
|
{
|
|
pDC->Draw3dRect(rc, m_clrBorderNormal, GetXtremeColor(COLOR_BTNHIGHLIGHT));
|
|
}
|
|
else
|
|
{
|
|
COLORREF clrBorder = m_bHighlighted || m_bFocused ? m_clrBorderHot : m_clrBorderNormal;
|
|
pDC->Draw3dRect(rc, clrBorder, clrBorder);
|
|
}
|
|
|
|
rc.DeflateRect(1, 1);
|
|
DrawFrame(*pDC, rc, 1, hBrush);
|
|
}
|
|
|
|
void CXTPEdit::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
|
|
{
|
|
TBase::OnNcCalcSize(bCalcValidRects, lpncsp);
|
|
|
|
if (!m_bShowBorder)
|
|
return;
|
|
|
|
lpncsp[0].rgrc->top += 2;
|
|
lpncsp[0].rgrc->left += 2;
|
|
lpncsp[0].rgrc->right -= 2;
|
|
lpncsp[0].rgrc->bottom -= 2;
|
|
}
|
|
|
|
void CXTPEdit::OnMouseLeave()
|
|
{
|
|
OnMouseMove(0, CPoint(-1, -1));
|
|
}
|
|
|
|
void CXTPEdit::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
CRect rc;
|
|
GetClientRect(&rc);
|
|
|
|
BOOL bHot = rc.PtInRect(point);
|
|
if (m_bFlatStyle && bHot != m_bHighlighted)
|
|
{
|
|
m_bHighlighted = bHot;
|
|
RedrawFocusedFrame();
|
|
|
|
if (bHot)
|
|
{
|
|
TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd, HOVER_DEFAULT};
|
|
_TrackMouseEvent(&tme);
|
|
}
|
|
}
|
|
|
|
|
|
TBase::OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
void CXTPEdit::OnKillFocus(CWnd* pNewWnd)
|
|
{
|
|
TBase::OnKillFocus(pNewWnd);
|
|
|
|
m_bFocused = FALSE;
|
|
RedrawFocusedFrame();
|
|
}
|
|
|
|
void CXTPEdit::OnSetFocus(CWnd* pOldWnd)
|
|
{
|
|
TBase::OnSetFocus(pOldWnd);
|
|
|
|
m_bFocused = TRUE;
|
|
RedrawFocusedFrame();
|
|
}
|
|
|
|
void CXTPEdit::RedrawEdit()
|
|
{
|
|
if (m_hWnd) SendMessage(WM_NCPAINT);
|
|
}
|
|
void CXTPEdit::RedrawFocusedFrame()
|
|
{
|
|
if (m_clrBorderHot == m_clrBorderNormal && !m_bFlatStyle)
|
|
return;
|
|
|
|
if (!m_bShowBorder)
|
|
return;
|
|
|
|
RedrawEdit();
|
|
}
|
|
|
|
HBRUSH CXTPEdit::GetClientBrush(CDC* pDC)
|
|
{
|
|
BOOL bEnabled = IsWindowEnabled() && ((GetStyle() & ES_READONLY) == 0);
|
|
|
|
HBRUSH hBrush = (HBRUSH)::SendMessage(::GetParent(m_hWnd), !bEnabled ? WM_CTLCOLORSTATIC : WM_CTLCOLOREDIT, (WPARAM)pDC->GetSafeHdc(), (LPARAM)m_hWnd);
|
|
|
|
if (hBrush)
|
|
return hBrush;
|
|
|
|
return GetSysColorBrush(!bEnabled ? COLOR_3DFACE : COLOR_WINDOW);
|
|
}
|
|
|
|
void CXTPEdit::SetUseVisualStyle(BOOL bUseVisualStyle/* = TRUE*/)
|
|
{
|
|
m_bUseVisualStyle = bUseVisualStyle;
|
|
|
|
RefreshMetrics();
|
|
RedrawEdit();
|
|
}
|
|
|
|
BOOL CXTPEdit::OnChange()
|
|
{
|
|
if (m_pRegExp)
|
|
{
|
|
Invalidate(FALSE);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void CXTPEdit::SetPattern(LPCTSTR lpszPattern)
|
|
{
|
|
SAFE_DELETE(m_pRegExp);
|
|
|
|
if (lpszPattern && lpszPattern[0] != 0)
|
|
{
|
|
m_pRegExp = new CXTPRegExp();
|
|
m_pRegExp->SetPattern(lpszPattern);
|
|
}
|
|
|
|
if (m_hWnd) Invalidate(FALSE);
|
|
|
|
}
|
|
|
|
void CXTPEdit::AdjustBuddyRect(CWnd* pBuddy, CRect& rcUpDown, int nAlignemnt)
|
|
{
|
|
if (m_bFlatStyle)
|
|
return;
|
|
|
|
|
|
if (!m_bShowBorder && ((GetStyle() & WS_BORDER) == 0))
|
|
return;
|
|
|
|
if (m_bUseVisualStyle && m_themeEdit->IsAppThemed())
|
|
{
|
|
if (nAlignemnt == UDS_ALIGNRIGHT) rcUpDown.DeflateRect(0, 1, 1, 1) ; else rcUpDown.DeflateRect(1, 1, 0, 1);
|
|
}
|
|
else if (m_nTheme == xtpControlThemeDefault || m_nTheme == xtpControlThemeOffice2000)
|
|
{
|
|
if (nAlignemnt == UDS_ALIGNRIGHT) rcUpDown.DeflateRect(0, 2, 2, 2); else rcUpDown.DeflateRect(2, 2, 0, 2);
|
|
}
|
|
else if (m_nTheme == xtpControlThemeResource && DYNAMIC_DOWNCAST(CSpinButtonCtrl, pBuddy) == 0)
|
|
{
|
|
if (nAlignemnt == UDS_ALIGNRIGHT) rcUpDown.DeflateRect(0, 2, 2, 2); else rcUpDown.DeflateRect(2, 2, 0, 2);
|
|
}
|
|
}
|
|
|
|
void CXTPEdit::DrawBuddyBorders(CWnd* pBuddy, CDC* pDC, CRect rc, int nAlignemnt)
|
|
{
|
|
HBRUSH hBrush = GetClientBrush(pDC);
|
|
|
|
if (m_bFlatStyle)
|
|
return;
|
|
|
|
if (!m_bShowBorder && (GetStyle() & WS_BORDER))
|
|
{
|
|
if (nAlignemnt == UDS_ALIGNRIGHT) rc.left -= 2; else rc.right += 2;
|
|
|
|
pDC->Draw3dRect(rc, GetXtremeColor(COLOR_WINDOWFRAME), GetXtremeColor(COLOR_WINDOWFRAME));
|
|
return;
|
|
|
|
}
|
|
|
|
if (!m_bShowBorder)
|
|
return;
|
|
|
|
if (m_bUseVisualStyle && m_themeEdit->IsAppThemed())
|
|
{
|
|
::FillRect(pDC->GetSafeHdc(), rc, hBrush);
|
|
|
|
if (nAlignemnt == UDS_ALIGNRIGHT) rc.left -= 2; else rc.right += 2;
|
|
|
|
if (SUCCEEDED(m_themeEdit->DrawThemeBackground(*pDC, 0, ETS_NORMAL, &rc, NULL)))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (m_nTheme == xtpControlThemeDefault)
|
|
{
|
|
pDC->DrawEdge(rc, EDGE_SUNKEN,
|
|
(nAlignemnt == UDS_ALIGNRIGHT) ? BF_TOP | BF_BOTTOM | BF_RIGHT : BF_TOP | BF_BOTTOM | BF_LEFT);
|
|
return;
|
|
}
|
|
|
|
if (m_nTheme == xtpControlThemeOffice2000)
|
|
{
|
|
::FillRect(pDC->GetSafeHdc(), rc, hBrush);
|
|
if (nAlignemnt == UDS_ALIGNRIGHT) rc.left -= 2; else rc.right += 2;
|
|
|
|
pDC->Draw3dRect(rc, m_clrBorderNormal, GetXtremeColor(COLOR_BTNHIGHLIGHT));
|
|
return;
|
|
}
|
|
|
|
if (m_nTheme == xtpControlThemeResource && DYNAMIC_DOWNCAST(CSpinButtonCtrl, pBuddy) == 0)
|
|
{
|
|
::FillRect(pDC->GetSafeHdc(), rc, hBrush);
|
|
if (nAlignemnt == UDS_ALIGNRIGHT) rc.left -= 2; else rc.right += 2;
|
|
|
|
pDC->Draw3dRect(rc, m_clrBorderNormal, m_clrBorderNormal);
|
|
return;
|
|
|
|
}
|
|
}
|
|
|
|
void CXTPEdit::OnSysColorChange()
|
|
{
|
|
TBase::OnSysColorChange();
|
|
|
|
RefreshMetrics();
|
|
Invalidate(FALSE);
|
|
|
|
SendMessage(WM_NCPAINT);
|
|
}
|