// ObkjectInspector.cpp : implementation file
//
// MFC Object-Inspector Control v1.0
//
// Written by Gunnar Bolle <webmaster@beatmonsters.com>
// Copyright (c) 2001. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// Expect bugs!
//
// Additional source codes by :
//
// CMemDC - Keith Rule
// CColorButton - James White
// CColourPopup - Chris Maunder
// Alexander Bischofberger
//
// History:
// --------
//
// 1.0 30 Jun 2001
// First release version.
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MemDC.h"
#include "GfxTools.h"
#include "ColorButton.h"
#include "ObjectInspectorTest.h"
#include "ObjectInspector.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CObjectInspector
// For sorting a vector with pointers to objects
template <class T> struct iter_less : public std::binary_function<T,T,bool>
{
bool operator()(const T x, const T y) const { return *x < *y; }
};
template <class T> struct iter_greater : public std::binary_function<T,T,bool>
{
bool operator()(const T x, const T y) const { return !(*x < *y); }
};
CObjectInspector::CProperty::~CProperty()
{
DestroyInplaceControl();
delete m_pControlFont;
// Destroy childs as well
for (vector<CProperty*>::iterator i = m_Childs.begin(); i != m_Childs.end(); i++)
delete (*i);
m_Childs.clear ();
};
bool CObjectInspector::CProperty::GetValueFromControl(short *psValue)
{
if (psValue && m_ptType == ptShort && m_bEditing)
{
CString cValue;
m_pInplaceControl->GetWindowText(cValue);
int nValue = atoi(cValue);
*psValue = (short) nValue;
return true;
}
return false;
}
bool CObjectInspector::CProperty::GetValueFromControl(int *pnValue)
{
if (pnValue && m_ptType == ptInteger && m_bEditing)
{
CString cValue;
m_pInplaceControl->GetWindowText(cValue);
int nValue = atoi(cValue);
*pnValue = nValue;
return true;
}
return false;
}
bool CObjectInspector::CProperty::GetValueFromControl(bool *pbValue)
{
if (pbValue && m_ptType == ptBool && m_bEditing)
{
*pbValue = ((CButton*)m_pInplaceControl)->GetCheck () ? true : false;
return true;
}
return false;
}
bool CObjectInspector::CProperty::GetValueFromControl(float *pfValue)
{
if (pfValue && m_ptType == ptFloat && m_bEditing)
{
CString cValue;
m_pInplaceControl->GetWindowText(cValue);
*pfValue = (float) atof(cValue);
return true;
}
return false;
}
bool CObjectInspector::CProperty::GetValueFromControl(double *pdblValue)
{
if (pdblValue && m_ptType == ptDouble && m_bEditing)
{
CString cValue;
m_pInplaceControl->GetWindowText(cValue);
*pdblValue = (double) atof(cValue);
return true;
}
return false;
}
bool CObjectInspector::CProperty::GetValueFromControl(COleDateTime *pdtValue)
{
if (pdtValue && m_ptType == ptDate && m_bEditing)
{
COleDateTime dtValue;
((CDateTimeCtrl*)m_pInplaceControl)->GetTime(*pdtValue);
return true;
}
return false;
}
bool CObjectInspector::CProperty::GetValueFromControl(CString *pszValue)
{
if (pszValue && m_ptType == ptStringList && m_bEditing)
{
CString cValue;
m_pInplaceControl->GetWindowText(*pszValue);
return true;
}
return false;
}
bool CObjectInspector::CProperty::GetValueFromControl(COLORREF *pclValue)
{
if (pclValue && m_ptType == ptColor && m_bEditing)
{
*pclValue = ((CColorButton*)m_pInplaceControl)->GetColor ();
return true;
}
return false;
}
CWnd* CObjectInspector::CProperty::GetInplaceControl()
{
return m_pInplaceControl;
};
CRect CObjectInspector::CProperty::GetPropertyRect()
{
return m_rtPropertyRect;
}
CRect CObjectInspector::CProperty::GetValueRect()
{
return m_rtValueRect;
}
void CObjectInspector::CProperty::SetRectangles(CRect rtProperty, CRect rtValue)
{
m_rtPropertyRect = rtProperty;
m_rtValueRect = rtValue;
if (m_bEditing && m_pInplaceControl && ::IsWindow (m_pInplaceControl->m_hWnd))
m_pInplaceControl->MoveWindow (&m_rtValueRect);
}
CWnd *CObjectInspector::CProperty::CreateControlFromType()
{
CWnd *pWndCtrl = NULL;
switch (m_ptType)
{
case ptFloat :
case ptDouble :
{
CEdit *pCtrl = new CEdit;
if (!pCtrl->Create(ES_AUTOHSCROLL | WS_VISIBLE | WS_CHILD, m_rtValueRect, m_pParentWnd, IDC_INPLACECONTROL))
AfxThrowMemoryException();
else
pWndCtrl = pCtrl;
break;
}
case ptShort :
case ptInteger :
{
CEdit *pCtrl = new CEdit;
if (!pCtrl->Create(ES_AUTOHSCROLL | WS_VISIBLE | WS_CHILD | ES_NUMBER, m_rtValueRect, m_pParentWnd, IDC_INPLACECONTROL))
AfxThrowMemoryException();
else
pWndCtrl = pCtrl;
break;
}
case ptBool :
{
CButton *pCtrl = new CButton;
if (!pCtrl->Create("", WS_VISIBLE | WS_CHILD | BS_FLAT | (m_bRadio ? BS_RADIOBUTTON : BS_AUTOCHECKBOX ), m_rtValueRect, m_pParentWnd, IDC_INPLACECONTROL))
AfxThrowMemoryException();
else
pWndCtrl = pCtrl;
break;
}
case ptDate :
{
CDateTimeCtrl *pCtrl = new CDateTimeCtrl;
if (!pCtrl->Create(WS_VISIBLE | WS_CHILD | (m_bUseTime ? DTS_TIMEFORMAT : DTS_SHORTDATEFORMAT), m_rtValueRect, m_pParentWnd, IDC_INPLACECONTROL))
AfxThrowMemoryException();
else
pWndCtrl = pCtrl;
break;
}
case ptColor :
{
CColorButton *pCtrl = new CColorButton;
if (!pCtrl->Create("", WS_VISIBLE | WS_CHILD, m_rtValueRect, m_pParentWnd, IDC_INPLACECONTROL))
AfxThrowMemoryException();
else
pWndCtrl = pCtrl;
break;
}
case ptStringList:
{
if (m_pStringList == NULL)
{
CEdit *pCtrl = new CEdit;
if (!pCtrl->Create(WS_VISIBLE | WS_CHILD, m_rtValueRect, m_pParentWnd, IDC_INPLACECONTROL))
AfxThrowMemoryException();
else
pWndCtrl = pCtrl;
}
else
{
CComboBox *pCtrl = new CComboBox;
if (!pCtrl->Create (WS_VISIBLE | WS_CHILD | WS_VSCROLL | m_dwComboBoxStyle, RectCopyInflate(m_rtValueRect,0,0,0,100), m_pParentWnd, IDC_INPLACECONTROL))
AfxThrowMemoryException();
else
for (POSITION pos = (*m_pStringList).GetHeadPosition (); pos != NULL; )
{
CString cItem = (*m_pStringList).GetNext (pos);
pCtrl->AddString (cItem);
}
pWndCtrl = pCtrl;
}
break;
}
}
if (pWndCtrl)
pWndCtrl->SetFont (m_pControlFont);
return pWndCtrl;
}
void CObjectInspector::CProperty::Create(CString cName, EPropertyType ptType)
{
m_bVisible = true;
m_bExpanded = false;
m_bFocused = false;
m_bEditing = false;
m_bRadio = false;
m_pParentWnd = NULL;
m_pParent = NULL;
m_pInplaceControl = NULL;
m_pItemData = NULL;
m_ptType = ptType;
m_cName = cName;
m_nImage = -1;
m_cFloatFormat = _T("%-5.1f");
m_pControlFont = new CQuickFont("MS Sans Serif", 10, FW_NORMAL, false);
}
void CObjectInspector::CProperty::AddProperty(CProperty *pProperty)
{
pProperty->m_pParentWnd = m_pParentWnd;
pProperty->m_pParent = this;
pProperty->m_nIndex = m_Childs.size();
m_Childs.insert(m_Childs.end(), pProperty);
}
void CObjectInspector::CProperty::SendNotification(int nMsg)
{
NM_OIVIEW OIMsg;
ASSERT(m_pParentWnd);
UINT wParam = m_pParentWnd->GetDlgCtrlID();
OIMsg.hdr.code = nMsg;
OIMsg.hdr.hwndFrom = m_pParentWnd->m_hWnd;
OIMsg.hdr.idFrom = m_pParentWnd->GetDlgCtrlID();
OIMsg.pProperty = this;
::SendMessage(m_pParentWnd->GetParent()->m_hWnd , WM_NOTIFY, wParam, (LPARAM) &OIMsg );
}
CString CObjectInspector::CProperty::GetValueAsText()
{
switch (m_ptType)
{
case ptShort :
{
CString cValue;
cValue.Format("%d", *m_psValue);
return cValue;
}
case ptInteger :
{
CString cValue;
cValue.Format("%d", *m_pnValue);
return cValue;
}
case ptFloat :
{
CString cValue;
cValue.Format(m_cFloatFormat, *m_pfValue);
return cValue;
}
case ptDouble :
{
CString cValue;
cValue.Format(m_cFloatFormat, *m_pdblValue);
return cValue;
}
case ptBool:
return _T("");
case ptDate :
{
CString cValue;
cValue.Format("%s", (*m_pdtValue).Format(m_bUseTime ? VAR_TIMEVALUEONLY : VAR_DATEVALUEONLY));
return cValue;
}
case ptStringList:
return *m_pszValue;
}
return _T("");
}
void CObjectInspector::CProperty::RangeError(int nMin, int nMax )
{
CString cMin, cMax;
cMin.Format("%d", nMin);
cMax.Format("%d", nMax);
CString prompt;
AfxFormatString2(prompt, AFX_IDP_PARSE_INT_RANGE, cMin, cMax);
AfxMessageBox(prompt, MB_ICONEXCLAMATION, AFX_IDP_PARSE_INT_RANGE);
}
void CObjectInspector::CProperty::RangeError(float fMin, float fMax )
{
CString cMin, cMax;
cMin.Format("%.*g", FLT_DIG, fMin);
cMax.Format("%.*g", FLT_DIG, fMax);
CString prompt;
AfxFormatString2(prompt, AFX_IDP_PARSE_REAL_RANGE, cMin, cMax);
AfxMessageBox(prompt, MB_ICONEXCLAMATION, AFX_IDP_PARSE_REAL_RANGE);
}
void CObjectInspector::CProperty::RangeError(double dblMin, double dblMax )
{
CString cMin, cMax;
cMin.Format("%.*g", DBL_DIG, dblMin);
cMax.Format("%.*g", DBL_DIG, dblMax);
CString prompt;
AfxFormatString2(prompt, AFX_IDP_PARSE_REAL_RANGE, cMin, cMax);
AfxMessageBox(prompt, MB_ICONEXCLAMATION, AFX_IDP_PARSE_REAL_RANGE);
}
bool CObjectInspector::CProperty::GetValueInternal()
{
switch (m_ptType)
{
case ptShort:
{
CString cValue;
m_pInplaceControl->GetWindowText(cValue);
int nValue = atoi(cValue);
if ((double) nValue < m_dblMin || (double) nValue > m_dblMax)
{
RangeError((int)m_dblMin,(int)m_dblMax);
return false;
}
if (nValue != *m_psValue)
{
*m_psValue = (short) nValue;
SendNotification();
}
break;
}
case ptInteger:
{
CString cValue;
m_pInplaceControl->GetWindowText(cValue);
int nValue = atoi(cValue);
if ((double) nValue < m_dblMin || (double) nValue > m_dblMax)
{
RangeError((int)m_dblMin,(int)m_dblMax);
return false;
}
if (nValue != *m_pnValue)
{
*m_pnValue = nValue;
SendNotification();
}
break;
}
case ptFloat:
{
CString cValue;
m_pInplaceControl->GetWindowText(cValue);
float fValue = (float) atof(cValue);
if ((double) fValue < m_dblMin || (double) fValue > m_dblMax)
{
RangeError((float)m_dblMin,(float)m_dblMax);
return false;
}
if (fValue != *m_pfValue)
{
*m_pfValue = fValue;
SendNotification();
}
break;
}
case ptDouble:
{
CString cValue;
m_pInplaceControl->GetWindowText(cValue);
double fValue = atof(cValue);
if ((double) fValue < m_dblMin || (double) fValue > m_dblMax)
{
RangeError((double)m_dblMin,(double)m_dblMax);
return false;
}
if (fValue != *m_pdblValue)
{
*m_pdblValue = fValue;
SendNotification();
}
break;
}
case ptBool:
{
bool bValue = ((CButton*)m_pInplaceControl)->GetCheck () ? true : false;
if (m_bRadio && m_nIndex != *m_pnValue)
{
*m_pnValue = m_nIndex;
SendNotification();
}
else
if (bValue != *m_pbValue)
{
*m_pbValue = bValue;
SendNotification();
}
break;
}
case ptDate:
{
COleDateTime dtValue;
((CDateTimeCtrl*)m_pInplaceControl)->GetTime(dtValue);
if (dtValue != *m_pdtValue)
{
*m_pdtValue = dtValue;
SendNotification();
}
break;
}
case ptColor:
{
COLORREF color;
color = ((CColorButton*)m_pInplaceControl)->GetColor ();
if (color != *m_pclValue)
{
*m_pclValue = color;
SendNotification();
}
break;
}
case ptStringList:
{
CString cValue;
m_pInplaceControl->GetWindowText(cValue);
if (cValue != *m_pszValue)
{
*m_pszValue = cValue;
SendNotification();
}
}
}
return true;
}
void CObjectInspector::CProperty::SetValueInternal()
{
CString cValue;
switch (m_ptType)
{
case ptShort :
cValue.Format("%d",*m_psValue );
m_pInplaceControl->SetWindowText (cValue);
break;
case ptInteger:
cValue.Format("%d",*m_pnValue );
m_pInplaceControl->SetWindowText (cValue);
break;
case ptFloat:
cValue.Format(m_cFloatFormat, *m_pfValue );
m_pInplaceControl->SetWindowText (cValue);
break;
case ptDouble:
cValue.Format(m_cFloatFormat, *m_pdblValue );
m_pInplaceControl->SetWindowText (cValue);
break;
case ptBool:
((CButton*)m_pInplaceControl)->SetCheck (*m_pbValue);
break;
case ptDate:
((CDateTimeCtrl*)m_pInplaceControl)->SetTime(*m_pdtValue);
break;
case ptColor:
((CColorButton*)m_pInplaceControl)->SetColor(*m_pclValue);
break;
case ptStringList:
if (!m_pStringList)
m_pInplaceControl->SetWindowText (*m_pszValue);
else
((CComboBox*)m_pInplaceControl)->SelectString (-1,*m_pszValue);
break;
}
}
void CObjectInspector::CProperty::BeginEdit ()
{
m_bEditing = true;
CreateInplaceControl();
SetValueInternal();
if (m_pInplaceControl)
m_pInplaceControl->SetFocus ();
}
bool CObjectInspector::CProperty::EndEdit ()
{
if (!GetValueInternal())
return false;
m_bEditing = false;
DestroyInplaceControl();
return true;
}
void CObjectInspector::CProperty::CreateInplaceControl()
{
m_pInplaceControl = CreateControlFromType();
}
void CObjectInspector::CProperty::DestroyInplaceControl()
{
if (m_pInplaceControl)
{
delete m_pInplaceControl;
m_pInplaceControl = NULL;
}
}
CObjectInspector::CObjectInspector()
{
m_cPropertyHeaderTitle = _T("Property");
m_cPropertyValueTitle = _T("Value");
m_nXSplitterPos = -1;
m_nHeaderHeight = 0;
m_nFirstVisibleItem = 0;
m_nScrollPos = 0;
m_nMinPropertyColWidth = 50;
m_nMinValueColWidth = 50;
m_bSplitterMoving = false;
m_bScrollbarVisible = false;
m_b3dFocus = false;
m_bHotTrack = false;
m_bSorted = false;
m_bW2KStyle = true;
m_bsStyle = bsLowered;
m_clBackColor = ::GetSysColor (COLOR_BTNFACE);
m_clPropertyRowColor = (COLORREF) 0;
m_clGridLineColor = RGB(120,120,120);
m_clValueRowColor = RGB(0,0,255);
m_clFocusLineColor = RGB(100,100,255);
m_pEditingProperty = NULL;
m_pImageList = NULL;
m_pLastEnteredProperty = NULL;
m_sdSortDirection = sdUp;
WNDCLASS wndcls;
HINSTANCE hInst = AfxGetInstanceHandle();
// Register window class
if (!(::GetClassInfo(hInst, CLASS_OBJECTINSPECTOR, &wndcls)))
{
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
wndcls.hInstance = hInst;
wndcls.hIcon = NULL;
wndcls.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
wndcls.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = CLASS_OBJECTINSPECTOR;
if (!AfxRegisterClass(&wndcls))
{
AfxThrowResourceException();
return ;
}
}
}
CObjectInspector::~CObjectInspector()
{
CleanUp();
}
BEGIN_MESSAGE_MAP(CObjectInspector, CWnd)
//{{AFX_MSG_MAP(CObjectInspector)
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
ON_WM_VSCROLL()
ON_WM_LBUTTONDBLCLK()
ON_EN_CHANGE(IDC_INPLACECONTROL, OnChangeInplaceControl)
ON_NOTIFY(DTN_DATETIMECHANGE, IDC_INPLACECONTROL, OnChangeDateTimeCtrl)
ON_CBN_SELCHANGE(IDC_INPLACECONTROL, OnSelchangeComboBox)
ON_WM_MOUSEWHEEL()
ON_BN_CLICKED(IDC_INPLACECONTROL, OnRadioSelect)
ON_WM_CTLCOLOR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// Behandlungsroutinen f�r Nachrichten CObjectInspector
BOOL CObjectInspector::Create(const RECT& rect, CWnd* parent, UINT nID, DWORD dwStyle)
{
BOOL bRet = CWnd::CreateEx(WS_EX_TOOLWINDOW, CLASS_OBJECTINSPECTOR, NULL, dwStyle, rect, parent, nID, 0);
return bRet;
}
void CObjectInspector::DrawBorder(CDC *pDC, CRect& rect)
{
CBrush brush((COLORREF)0);
switch (m_bsStyle)
{
case bsNone : break;
case bsSingle : pDC->FrameRect(&rect, &brush); rect.DeflateRect (1,1,1,1); break;
case bsLowered : pDC->DrawEdge( &rect, EDGE_SUNKEN, BF_RECT); rect.DeflateRect (2,2,2,2); break;
case bsRaised : pDC->DrawEdge( &rect, EDGE_RAISED, BF_RECT); rect.DeflateRect (2,2,2,2); break;
}
}
void CObjectInspector::DrawSplitter(CDC *pDC)
{
if (m_nXSplitterPos == -1)
m_nXSplitterPos = m_rtClientRect.CenterPoint().x;
m_rtSplitterRect = CRect(m_nXSplitterPos, m_rtClientRect.top, m_nXSplitterPos + 1, m_rtClientRect.bottom );
{
CPenSelector grayPen(PS_SOLID,1, RGB(80,80,80), pDC);
pDC->MoveTo(m_rtSplitterRect.left, m_rtSplitterRect.top);
pDC->LineTo(m_rtSplitterRect.left, m_rtSplitterRect.bottom);
}
{
CPenSelector whitePen(PS_SOLID,1, RGB(255,255,255), pDC);
pDC->MoveTo(m_rtSplitterRect.right, m_rtSplitterRect.top);
pDC->LineTo(m_rtSplitterRect.right, m_rtSplitterRect.bottom);
}
}
void CObjectInspector::DrawHeader(CDC *pDC)
{
m_nHeaderHeight = pDC->GetTextExtent("pP").cy + 6;
m_rtPropertyHeaderRect = CRect (m_rtClientRect.left , m_rtClientRect.top, m_rtSplitterRect.left + 1 , m_rtClientRect.top + m_nHeaderHeight );
m_rtValueHeaderRect = CRect (m_rtSplitterRect.left + 2 , m_rtClientRect.top, m_rtClientRect.right, m_rtClientRect.top + m_nHeaderHeight);
pDC->FillSolidRect (m_rtClientRect.left, m_rtClientRect.top, m_rtClientRect.Width (), m_nHeaderHeight, ::GetSysColor(COLOR_BTNFACE));
if (m_bSorted)
{
CBrush brush (::GetSysColor(COLOR_BTNFACE));
CRect copyRect (m_rtPropertyHeaderRect);
copyRect.OffsetRect (CPoint(-4,0));
copyRect.left = copyRect.right - GetSystemMetrics(SM_CXHSCROLL);
pDC->DrawFrameControl (copyRect, DFC_SCROLL, (m_sdSortDirection == sdUp ? DFCS_SCROLLUP : DFCS_SCROLLDOWN) | DFCS_MONO );
pDC->FrameRect (copyRect, &brush);
copyRect.DeflateRect (1,1,1,1);
pDC->FrameRect (copyRect, &brush);
}
CFontSelector headerFont(&CQuickFont("MS Sans Serif", 10, FW_BOLD), pDC);
pDC->Draw3dRect (&m_rtPropertyHeaderRect, RGB(255,255,255), RGB(50,50,50));
pDC->Draw3dRect (&m_rtValueHeaderRect, RGB(255,255,255), RGB(50,50,50));
m_rtPropertyHeaderRect.DeflateRect (3,0,1,0);
m_rtValueHeaderRect.DeflateRect (3,0,1,0);
pDC->DrawText( m_cPropertyHeaderTitle, m_rtPropertyHeaderRect, DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS );
pDC->DrawText( m_cPropertyValueTitle, m_rtValueHeaderRect, DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS );
}
void CObjectInspector::DrawItem(CDC*pDC, CProperty *pProperty, int& nY, int& nCellHeight)
{
CFontSelector cellFont(&CQuickFont("MS Sans Serif", 10, FW_NORMAL, pProperty->m_bFocused && m_bHotTrack), pDC);
CRect rtPropertyRect(m_rtClientRect.left + 1, nY + 1, m_rtSplitterRect.left - 1, nY + nCellHeight - 1);
CRect rtValueRect(m_rtSplitterRect.right + 1, nY + 1, m_rtClientRect.right, nY + nCellHeight - 1);
pProperty->SetRectangles (rtPropertyRect, rtValueRect);
if (!pProperty->m_bVisible)
{
if (pProperty->m_bEditing )
{
pProperty->EndEdit ();
m_pEditingProperty = NULL;
}
return;
}
m_nExpandedItemsCount++;
if (pProperty->GetInplaceControl () && !pProperty->GetInplaceControl ()->IsWindowVisible ())
pProperty->GetInplaceControl ()->ShowWindow (SW_SHOW);
if (pProperty->m_bEditing)
{
if (m_b3dFocus)
pDC->DrawEdge (RectCopyInflate(pProperty->GetPropertyRect(),0,1,0,1), EDGE_SUNKEN, BF_RECT);
else
pDC->FillSolidRect (RectCopyInflate(pProperty->GetPropertyRect(),0,-1,0,0), m_clFocusLineColor);
}
int nBaseIndent = 12;
if (m_pImageList && m_pImageList->GetImageCount () > 0)
{
IMAGEINFO imageInfo;
m_pImageList->GetImageInfo (0, &imageInfo);
int nImageHeight = CRect(imageInfo.rcImage).Height();
if (pProperty->m_nImage != -1 && pProperty->m_Childs.size() == 0)
{
CPoint ptImage = CPoint(pProperty->GetPropertyRect().left, pProperty->GetPropertyRect().CenterPoint ().y - (nImageHeight / 2));
m_pImageList->Draw (pDC, pProperty->m_nImage, ptImage,ILD_TRANSPARENT);
}
nBaseIndent = CRect(imageInfo.rcImage).Width() + 4;
}
if (pProperty->GetType () == ptGroup)
{
CFontSelector cellFontBold(&CQuickFont("MS Sans Serif", 10, FW_BOLD, pProperty->m_bFocused && m_bHotTrack), pDC);
if (m_bW2KStyle)
{
pDC->FillSolidRect(RectCopyInflate(pProperty->m_rtPropertyRect,0,0,1,1),::GetSysColor(COLOR_INACTIVECAPTION));
pDC->FillSolidRect(RectCopyInflate(pProperty->m_rtValueRect,0,0,1,1),::GetSysColor(COLOR_INACTIVECAPTION));
pDC->SetTextColor(RGB(255,255,255));
}
else
pDC->SetTextColor (m_clPropertyRowColor);
pDC->DrawText(pProperty->m_cName, RectCopyDeflate(rtPropertyRect,nBaseIndent + (m_nIndent * 10),0,0,0),DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS);
}
else
{
pDC->SetTextColor ((!m_b3dFocus && pProperty->m_bEditing) ? RGB(255,255,255) : m_clPropertyRowColor);
pDC->DrawText(pProperty->m_cName, RectCopyDeflate(rtPropertyRect,nBaseIndent + (m_nIndent * 10),0,0,0),DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS);
}
pDC->SetTextColor (m_clValueRowColor);
if (pProperty->GetType() == ptColor)
{
CPenSelector(PS_SOLID,1,(COLORREF)0, pDC);
pDC->Rectangle (RectCopyDeflate(pProperty->GetValueRect (),2,2,2,1));
pDC->FillSolidRect (RectCopyDeflate(pProperty->GetValueRect (),3,3,3,2), *pProperty->m_pclValue);
}
else
if (pProperty->GetType() == ptBool)
{
CRect copyRect (rtValueRect);
copyRect.left += 2;
copyRect.right = copyRect.left + GetSystemMetrics(SM_CXMENUCHECK);
if (pProperty->m_bRadio)
pDC->DrawFrameControl (copyRect, DFC_BUTTON, DFCS_FLAT | DFCS_BUTTONRADIO | (*pProperty->m_pbValue ? DFCS_CHECKED : 0));
else
pDC->DrawFrameControl (copyRect, DFC_BUTTON, DFCS_FLAT | DFCS_BUTTONCHECK | (*pProperty->m_pbValue ? DFCS_CHECKED : 0));
}
else
pDC->DrawText( pProperty->GetValueAsText(), RectCopyDeflate(rtValueRect,2,0,0,0),DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS);
if (pProperty->GetType () == ptGroup)
{
CPenSelector(PS_SOLID, 1, (COLORREF)0, pDC);
pProperty->m_rtGroupRect = CRect(( m_nIndent * 10 ) + pProperty->GetPropertyRect ().left + 1 ,
pProperty->GetPropertyRect ().CenterPoint ().y - 4,
( m_nIndent * 10 ) + pProperty->GetPropertyRect ().left + 10,
pProperty->GetPropertyRect ().CenterPoint ().y + 5);
pDC->Rectangle (pProperty->m_rtGroupRect);
pDC->MoveTo (pProperty->m_rtGroupRect.left + 1, pProperty->m_rtGroupRect.CenterPoint ().y);
pDC->LineTo (pProperty->m_rtGroupRect.right - 1, pProperty->m_rtGroupRect.CenterPoint ().y);
if (!pProperty->m_bExpanded)
{
pDC->MoveTo (pProperty->m_rtGroupRect.CenterPoint().x, pProperty->m_rtGroupRect.top + 1);
pDC->LineTo (pProperty->m_rtGroupRect.CenterPoint().x, pProperty->m_rtGroupRect.bottom - 1);
}
}
nY += nCellHeight;
m_nOverallItemHeight += nCellHeight;
CPenSelector grayPen(PS_SOLID, 1, m_clGridLineColor, pDC);
pDC->MoveTo(m_rtClientRect.left, nY);
pDC->LineTo(m_rtSplitterRect.left - 1, nY);
pDC->MoveTo(m_rtSplitterRect.right + 1, nY);
pDC->LineTo(m_rtClientRect.right , nY);
}
void CObjectInspector::DrawChildItems(CDC*pDC,int& nItem, CProperty *pProperty, int& nY, int& nCellHeight)
{
if (!m_bW2KStyle)
m_nIndent ++;
for (vector<CProperty*>::iterator i = pProperty->m_Childs.begin(); i != pProperty->m_Childs.end(); i++)
{
if ((*i)->m_pParent && (!(*i)->m_pParent->m_bExpanded || !(*i)->m_pParent->m_bVisible))
(*i)->m_bVisible = false;
else
(*i)->m_bVisible = true;
DrawItem(pDC, *i, nY, nCellHeight);
nItem++;
if ((*i)->m_Childs.size() != 0 )
DrawChildItems(pDC, nItem, *i, nY, nCellHeight);
}
if (!m_bW2KStyle)
m_nIndent--;
}
void CObjectInspector::DrawItems(CDC *pDC)
{
int nCellHeight = pDC->GetTextExtent("pP").cy + 6;
m_nCellHeight = nCellHeight;
int nY = m_rtPropertyHeaderRect.bottom - m_nScrollPos;
m_nOverallItemHeight = 0;
m_nExpandedItemsCount = 0;
int nItem = 0;
for (vector<CProperty*>::iterator i = m_PropertyList.begin(); i != m_PropertyList.end(); i++, nItem++)
{
m_nIndent = 0;
DrawItem(pDC, *i, nY, nCellHeight);
if ((*i)->m_Childs.size() != 0)
DrawChildItems(pDC, nItem, *i, nY, nCellHeight);
}
if (m_nOverallItemHeight > (m_rtClientRect.Height() - m_nHeaderHeight )&& !m_bScrollbarVisible )
{
m_bScrollbarVisible = true;
Invalidate(TRUE);
return;
}
if (m_nOverallItemHeight < (m_rtClientRect.Height() - m_nHeaderHeight ) && m_bScrollbarVisible)
{
m_bScrollbarVisible = false;
Invalidate(TRUE);
return;
}
}
void CObjectInspector::CleanUp()
{
for (vector<CProperty*>::iterator i = m_PropertyList.begin(); i != m_PropertyList.end(); i++)
delete (*i);
m_PropertyList.clear ();
}
void CObjectInspector::CalculateScrollRange(CProperty *pProperty)
{
static int nItemsVisible = 0;
if (pProperty == NULL)
{
nItemsVisible = 0;
for (vector<CProperty*>::iterator i = m_PropertyList.begin(); i != m_PropertyList.end(); i++)
{
if (!((*i)->m_pParent && !(*i)->m_pParent->m_bExpanded))
nItemsVisible++;
if ((*i)->m_Childs.size () != 0)
CalculateScrollRange(*i);
}
}
else
{
if (!(pProperty->m_pParent && !pProperty->m_pParent->m_bExpanded))
nItemsVisible++;
if (pProperty->m_Childs.size != 0)
for (vector<CProperty*>::iterator i = pProperty->m_Childs.begin(); i != pProperty->m_Childs.end(); i++)
CalculateScrollRange(*i);
}
m_nScrollRange = nItemsVisible * m_nCellHeight - m_rtClientRect.Height ();
}
void CObjectInspector::DrawScrollBar()
{
if (m_bScrollbarVisible)
{
if (!::IsWindow(m_ScrollBar.m_hWnd))
m_ScrollBar.Create (SBS_VERT | SBS_TOPALIGN | WS_CHILD, CRect(0,0,0,0), this, IDC_SCROLLBAR);
m_rtClientRect.DeflateRect (0,0, ::GetSystemMetrics (SM_CXVSCROLL),0);
if (!m_ScrollBar.IsWindowVisible ())
m_ScrollBar.ShowWindow (SW_SHOW);
CRect sbRect;
m_ScrollBar.GetWindowRect (&sbRect);
CRect sbNewRect (m_rtClientRect.right, m_rtClientRect.top, m_rtClientRect.right + ::GetSystemMetrics (SM_CXVSCROLL), m_rtClientRect.top + m_rtClientRect.Height ());
if (sbRect != sbNewRect)
m_ScrollBar.MoveWindow(sbNewRect, TRUE);
m_ScrollBar.SetScrollRange (0, m_nScrollRange);
}
else
if (::IsWindow(m_ScrollBar.m_hWnd))
m_ScrollBar.ShowWindow (SW_HIDE);
}
void CObjectInspector::OnPaint()
{
CPaintDC dc(this);
CMemDC memDC(&dc);
GetClientRect(&m_rtClientRect);
CBitmap bmp;
CDC saveDC;
CDC* pControlDC;
int nBmpWidth = 0;
int nBmpHeight = 0;
CGdiObject* pOldObject = NULL;
// Check if there's a currently active inplace edit control
if (m_pEditingProperty && m_pEditingProperty->GetInplaceControl () &&
m_pEditingProperty->GetInplaceControl ()->IsWindowVisible ())
{
// Get a bitmap of the inplace control to prevent flickering
nBmpWidth = m_pEditingProperty->GetValueRect ().Width ();
nBmpHeight = m_pEditingProperty->GetValueRect ().Height();
pControlDC = m_pEditingProperty->GetInplaceControl ()->GetDC();
saveDC.CreateCompatibleDC (pControlDC);
bmp.CreateCompatibleBitmap (pControlDC, nBmpWidth, nBmpHeight);
pOldObject = saveDC.SelectObject (&bmp);
saveDC.BitBlt (0,0, nBmpWidth, nBmpHeight, pControlDC, 0, 0, SRCCOPY);
m_pEditingProperty->GetInplaceControl ()->ReleaseDC(pControlDC);
}
memDC.FillSolidRect (&m_rtClientRect, m_clBackColor);
memDC.SetBkColor(::GetSysColor (COLOR_BTNFACE));
memDC.SetBkMode (TRANSPARENT);
DrawBorder(&memDC, m_rtClientRect);
CalculateScrollRange();
DrawScrollBar();
DrawSplitter(&memDC);
DrawHeader(&memDC);
CRgn rgn;
rgn.CreateRectRgn (m_rtClientRect.left, m_rtPropertyHeaderRect.bottom, m_rtClientRect.right, m_rtClientRect.bottom-1);
memDC.SelectClipRgn(&rgn);
DrawItems(&memDC);
if (m_pEditingProperty && m_pEditingProperty->GetInplaceControl () &&
m_pEditingProperty->GetInplaceControl ()->IsWindowVisible ())
{
memDC.BitBlt (m_pEditingProperty->GetValueRect ().left , m_pEditingProperty->GetValueRect ().top, nBmpWidth, nBmpHeight, &saveDC, 0, 0, SRCCOPY);
if (pOldObject)
saveDC.SelectObject (pOldObject);
m_pEditingProperty->GetInplaceControl ()->Invalidate (TRUE);
}
}
void CObjectInspector::SetBorderStyle(EBorderStyle bsStyle)
{
if (m_bsStyle != bsStyle)
{
m_bsStyle = bsStyle;
Invalidate(TRUE);
}
}
CObjectInspector::CProperty *CObjectInspector::GetPropertyFromPoint(CPoint point, CObjectInspector::CProperty *pRoot)
{
CProperty *pProperty = NULL;
if (pRoot == NULL)
{
for (vector<CProperty*>::iterator i = m_PropertyList.begin(); i != m_PropertyList.end(); i++)
{
if (!(*i)->m_bVisible)
continue;
if ((*i)->GetPropertyRect().PtInRect (point) || (*i)->GetValueRect().PtInRect (point))
return &(**i);
if ((*i)->m_Childs.size() != 0)
{
pProperty = GetPropertyFromPoint(point, (*i));
if (pProperty)
return pProperty;
}
}
}
else
{
for (vector<CProperty*>::iterator i = pRoot->m_Childs.begin(); i != pRoot->m_Childs.end(); i++)
{
if (!(*i)->m_bVisible)
continue;
if ((*i)->GetPropertyRect().PtInRect (point) || (*i)->GetValueRect().PtInRect (point))
return &(**i);
if ((*i)->m_Childs.size() != 0)
{
pProperty = GetPropertyFromPoint(point, (*i));
if (pProperty)
return pProperty;
}
}
}
return pProperty;
}
void CObjectInspector::AddProperty(CObjectInspector::CProperty* pProperty)
{
pProperty->m_pParentWnd = this;
m_PropertyList.insert(m_PropertyList.end(), pProperty);
Invalidate(FALSE);
}
void CObjectInspector::OnMouseMove(UINT nFlags, CPoint point)
{
static CProperty *pLastFocusedProperty = NULL;
CRect rtSplitterGripRect = m_rtSplitterRect;
rtSplitterGripRect.InflateRect (2,0,2,0);
if (rtSplitterGripRect.PtInRect (point))
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
else
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
if (m_bSplitterMoving && point.x < m_rtClientRect.right && point.x > 0 && point.x > m_nMinPropertyColWidth && (m_rtClientRect.Width() - point.x) > m_nMinValueColWidth )
{
m_nXSplitterPos = point.x;
InvalidateRect(m_rtClientRect,FALSE);
}
if (m_bHotTrack)
{
CProperty *pProperty = GetPropertyFromPoint(point, NULL);
if (pProperty)
{
if (pProperty->m_bFocused)
return;
pProperty->m_bFocused = true;
if (pLastFocusedProperty)
pLastFocusedProperty->m_bFocused = false;
pLastFocusedProperty = pProperty;
InvalidateRect(m_rtClientRect,FALSE);
}
}
CWnd::OnMouseMove(nFlags, point);
}
void CObjectInspector::OnLButtonUp(UINT nFlags, CPoint point)
{
m_bSplitterMoving = false;
ReleaseCapture();
CWnd::OnLButtonUp(nFlags, point);
}
void CObjectInspector::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rtSplitterGripRect = m_rtSplitterRect;
rtSplitterGripRect.InflateRect (2,0,2,0);
if (m_rtPropertyHeaderRect.PtInRect (point))
{
m_bSorted = true;
m_sdSortDirection = (ESortDirection) (((int) m_sdSortDirection + 1 ) & 1);
if (m_sdSortDirection == sdDown)
std::sort (m_PropertyList.begin(), m_PropertyList.end(), iter_less <CProperty*>());
else
std::sort (m_PropertyList.begin(), m_PropertyList.end(), iter_greater <CProperty*>());
InvalidateRect(m_rtClientRect);
}
else
if (rtSplitterGripRect.PtInRect (point))
{
SetCapture();
m_bSplitterMoving = true;
}
else
{
CProperty *pProperty = GetPropertyFromPoint (point, NULL);
if (pProperty)
{
if (pProperty->GetType () != ptGroup )
{
if (pProperty->m_bEditing)
return;
if (m_pLastEnteredProperty && m_pLastEnteredProperty->m_bEditing)
if (!m_pLastEnteredProperty->EndEdit())
return;
if (pProperty->m_ptType == ptBool && pProperty->m_bRadio)
{
for (vector<CProperty*>::iterator i = pProperty->m_pParent->m_Childs.begin(); i!= pProperty->m_pParent->m_Childs.end(); i++)
if ((*i)->m_bRadio)
*(*i)->m_pbValue = false;
*pProperty->m_pbValue = true;
}
pProperty->BeginEdit();
if (pProperty->m_ptType == ptBool && !pProperty->m_bRadio)
((CButton*)pProperty->GetInplaceControl ())->SetCheck (!((CButton*)pProperty->GetInplaceControl ())->GetCheck());
m_pEditingProperty = pProperty;
m_pLastEnteredProperty = pProperty;
InvalidateRect(m_rtClientRect,FALSE);
}
else
{
if (pProperty->m_rtGroupRect.PtInRect(point))
{
pProperty->m_bExpanded = !pProperty->m_bExpanded;
InvalidateRect(m_rtClientRect, FALSE);
CalculateScrollRange();
}
}
}
}
CWnd::OnLButtonDown(nFlags, point);
}
void CObjectInspector::OnRadioSelect()
{
if (m_pEditingProperty && m_pEditingProperty->m_bRadio)
{
CProperty *pParent = m_pEditingProperty->m_pParent;
if (pParent)
for (vector<CProperty*>::iterator i = pParent->m_Childs.begin(); i!= pParent->m_Childs.end(); i++)
if ((*i)->m_bRadio)
*(*i)->m_pbValue = false;
if (m_pEditingProperty->GetInplaceControl())
((CButton*)m_pEditingProperty->GetInplaceControl())->SetCheck (true);
}
}
void CObjectInspector::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (!m_bScrollbarVisible)
return;
if (nSBCode == SB_LINEDOWN && m_nScrollPos < m_nScrollRange)
m_nScrollPos ++;
if (nSBCode == SB_LINEUP && m_nScrollPos > 0)
m_nScrollPos --;
if (nSBCode == SB_BOTTOM)
m_nScrollPos = m_nScrollRange;
if (nSBCode == SB_TOP)
m_nScrollPos = 0;
if (nSBCode == SB_PAGEDOWN)
{
if ((m_nScrollPos + m_nCellHeight) <= m_nScrollRange)
m_nScrollPos += m_nCellHeight;
else
m_nScrollPos = m_nScrollRange;
}
if (nSBCode == SB_PAGEUP)
{
if ((m_nScrollPos - m_nCellHeight) >= 0)
m_nScrollPos -= m_nCellHeight;
else
m_nScrollPos = 0;
}
if (nSBCode == SB_THUMBPOSITION || nSBCode == SB_THUMBTRACK)
m_nScrollPos = nPos;
if (m_pEditingProperty)
{
m_pEditingProperty->EndEdit ();
m_pEditingProperty = NULL;
}
m_ScrollBar.SetScrollPos (m_nScrollPos);
InvalidateRect(m_rtClientRect,FALSE);
}
void CObjectInspector::OnLButtonDblClk(UINT nFlags, CPoint point)
{
CProperty *pProperty = GetPropertyFromPoint (point, NULL);
if (pProperty && pProperty->GetType () == ptGroup)
{
pProperty->m_bExpanded = !pProperty->m_bExpanded;
InvalidateRect(m_rtClientRect, FALSE);
}
CWnd::OnLButtonDblClk(nFlags, point);
}
void CObjectInspector::SetHeaderTitles(CString cPropertyHeaderTitle, CString cPropertyValueTitle)
{
m_cPropertyHeaderTitle = cPropertyHeaderTitle;
m_cPropertyValueTitle = cPropertyValueTitle;
}
void CObjectInspector::SetStyle(bool bW2K)
{
m_bW2KStyle = bW2K;
Invalidate();
}
void CObjectInspector::SetHotTrack(bool bEnabled)
{
m_bHotTrack = bEnabled;
Invalidate();
};
void CObjectInspector::Set3dFocus(bool bValue)
{
m_b3dFocus = bValue;
Invalidate();
}
void CObjectInspector::SetBackColor(COLORREF clBackColor)
{
m_clBackColor = clBackColor;
Invalidate();
}
void CObjectInspector::SetMinPropertyColWidth(int nWidth)
{
m_nMinPropertyColWidth = nWidth;
Invalidate();
}
void CObjectInspector::SetMinValueColWidth(int nWidth)
{
m_nMinValueColWidth = nWidth;
Invalidate();
}
void CObjectInspector::SetPropertyColTextColor(COLORREF clPropertyRowColor)
{
m_clPropertyRowColor = clPropertyRowColor;
Invalidate();
}
void CObjectInspector::SetValueColTextColor(COLORREF clValueRowColor)
{
m_clValueRowColor = clValueRowColor;
Invalidate();
}
void CObjectInspector::SetGridLineColor(COLORREF clGridLineColor)
{
m_clGridLineColor = clGridLineColor;
Invalidate();
}
void CObjectInspector::SetFocusLineColor(COLORREF clFocusLineColor)
{
m_clFocusLineColor = clFocusLineColor;
Invalidate();
}
void CObjectInspector::GeHeaderTitles(CString& cPropertyHeaderTitle, CString& cPropertyValueTitle)
{
cPropertyHeaderTitle = m_cPropertyHeaderTitle;
cPropertyValueTitle = m_cPropertyValueTitle;
}
CObjectInspector::EBorderStyle CObjectInspector::GetBorderStyle()
{
return m_bsStyle;
}
bool CObjectInspector::GetHotTrack()
{
return m_bHotTrack;
}
bool CObjectInspector::Get3dFocus()
{
return m_b3dFocus;
}
COLORREF CObjectInspector::GetBackColor()
{
return m_clBackColor;
}
COLORREF CObjectInspector::GetPropertyColTextColor()
{
return m_clPropertyRowColor;
}
COLORREF CObjectInspector::GetValueColTextColor()
{
return m_clValueRowColor;
}
COLORREF CObjectInspector::GetGridLineColor()
{
return m_clGridLineColor;
}
COLORREF CObjectInspector::GetFocusLineColor()
{
return m_clFocusLineColor;
}
int CObjectInspector::GetMinPropertyColWidth()
{
return m_nMinPropertyColWidth;
}
int CObjectInspector::GetMinValueColWidth()
{
return m_nMinValueColWidth;
}
void CObjectInspector::OnChangeInplaceControl()
{
if (m_pEditingProperty)
m_pEditingProperty->SendNotification (OIVN_ITEMCHANGING);
}
void CObjectInspector::OnChangeDateTimeCtrl(NMHDR* pNMHDR, LRESULT* pResult)
{
if (m_pEditingProperty)
m_pEditingProperty->SendNotification (OIVN_ITEMCHANGING);
}
void CObjectInspector::OnSelchangeComboBox()
{
if (m_pEditingProperty)
m_pEditingProperty->SendNotification (OIVN_ITEMCHANGING);
}
CObjectInspector::CProperty *CObjectInspector::GetNextProperty(CProperty *pProperty)
{
if (pProperty->m_pParent)
{
vector <CProperty*>::iterator pos = find(pProperty->m_pParent->m_Childs.begin(),
pProperty->m_pParent->m_Childs.end(),
pProperty);
if (*pos != pProperty->m_pParent->m_Childs.back())
return *(++pos);
else
return GetNextProperty(pProperty->m_pParent);
}
else
{
vector <CProperty*>::iterator pos = find(m_PropertyList.begin(),
m_PropertyList.end(),
pProperty);
if (*pos != m_PropertyList.back())
return *(++pos);
else
return NULL;
}
}
CObjectInspector::CProperty *CObjectInspector::GetPrevProperty(CProperty *pProperty)
{
if (pProperty->m_pParent)
{
vector <CProperty*>::iterator pos = find(pProperty->m_pParent->m_Childs.begin(),
pProperty->m_pParent->m_Childs.end(),
pProperty);
if (*pos != pProperty->m_pParent->m_Childs.front())
return *(--pos);
else
return GetPrevProperty(pProperty->m_pParent);
}
else
{
vector <CProperty*>::iterator pos = find(m_PropertyList.begin(),
m_PropertyList.end(),
pProperty);
if (*pos != m_PropertyList.front())
return *(--pos);
else
return NULL;
}
}
BOOL CObjectInspector::PreTranslateMessage(MSG* pMsg)
{
if (m_pEditingProperty != NULL && pMsg->message == WM_KEYDOWN && IsCtrlDown())
{
int nVirtKey = (int) pMsg->wParam;
CProperty *pProperty;
if (nVirtKey == VK_DOWN)
{
pProperty = GetNextProperty(m_pEditingProperty);
if (pProperty)
{
m_pEditingProperty->EndEdit ();
m_pLastEnteredProperty = m_pEditingProperty = pProperty;
InvalidateRect(m_rtClientRect, FALSE);
m_pEditingProperty->BeginEdit ();
return TRUE;
}
else
m_pEditingProperty = NULL;
}
if (nVirtKey == VK_UP)
{
pProperty = GetPrevProperty(m_pEditingProperty);
if (pProperty)
{
m_pEditingProperty->EndEdit ();
m_pLastEnteredProperty = m_pEditingProperty = pProperty;
InvalidateRect(m_rtClientRect, FALSE);
m_pEditingProperty->BeginEdit ();
return TRUE;
}
else
m_pEditingProperty = NULL;
}
}
return CWnd::PreTranslateMessage(pMsg);
}
// Handles mouse wheel notifications
#if (_MFC_VER >= 0x0421)
BOOL CObjectInspector::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
int nRowsScrolled = zDelta / 120;
if (nRowsScrolled > 0)
for (int i = 0; i < nRowsScrolled; i++)
PostMessage(WM_VSCROLL, SB_PAGEUP, 0);
else
for (int i = 0; i > nRowsScrolled; i--)
PostMessage(WM_VSCROLL, SB_PAGEDOWN, 0);
return CWnd::OnMouseWheel(nFlags, zDelta, pt);
}
#endif // (_MFC_VER >= 0x0421)
HBRUSH CObjectInspector::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if (m_pEditingProperty && m_pEditingProperty->GetType () == ptBool)
{
m_CtrlBrush.Detach ();
m_CtrlBrush.CreateSolidBrush (m_clBackColor);
return m_CtrlBrush;
}
else
return CWnd::OnCtlColor(pDC, pWnd, nCtlColor);
}