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.
580 lines
13 KiB
C++
580 lines
13 KiB
C++
// XTPPropertyGridItemExt.cpp
|
|
//
|
|
// This file is a part of the XTREME PROPERTYGRID 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/XTPVC80Helpers.h"
|
|
|
|
#include "Common/XTPResourceManager.h"
|
|
#include "Common/XTPSystemHelpers.h"
|
|
|
|
#include "XTPPropertyGridDefines.h"
|
|
#include "XTPPropertyGridInplaceList.h"
|
|
#include "XTPPropertyGridInplaceButton.h"
|
|
#include "XTPPropertyGridItem.h"
|
|
#include "XTPPropertyGridItemExt.h"
|
|
#include "XTPPropertyGridView.h"
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
BEGIN_MESSAGE_MAP(CXTPPropertyGridInplaceMonthCal, CWnd)
|
|
ON_NOTIFY_REFLECT(MCN_SELECT, OnSelect)
|
|
END_MESSAGE_MAP()
|
|
|
|
void CXTPPropertyGridInplaceMonthCal::OnSelect(NMHDR*, LRESULT*)
|
|
{
|
|
OnAccept();
|
|
}
|
|
|
|
void CXTPPropertyGridInplaceMonthCal::OnCancel()
|
|
{
|
|
if (m_pItem)
|
|
{
|
|
m_pItem->OnCancelEdit();
|
|
|
|
DestroyWindow();
|
|
}
|
|
}
|
|
|
|
void CXTPPropertyGridInplaceMonthCal::OnAccept()
|
|
{
|
|
SYSTEMTIME sysTime;
|
|
::SendMessage(m_hWnd, MCM_GETCURSEL, 0, (LPARAM) &sysTime);
|
|
|
|
sysTime.wHour = sysTime.wMinute = sysTime.wSecond = sysTime.wMilliseconds = 0;
|
|
|
|
COleDateTime dtSelected(sysTime);
|
|
|
|
CString str = m_pItem->Format(dtSelected);
|
|
CString strBeforeEdit = str;
|
|
|
|
CXTPPropertyGridItemDate* pItem = m_pItem;
|
|
m_pItem = NULL;
|
|
|
|
ShowWindow(SW_HIDE);
|
|
ReleaseCapture();
|
|
PostMessage(WM_CLOSE);
|
|
|
|
if (pItem->OnAfterEdit(str))
|
|
{
|
|
if (strBeforeEdit == str) // Can changed in OnAfterEdit handler
|
|
{
|
|
pItem->SetDate(dtSelected);
|
|
pItem->NotifyValueChanged();
|
|
}
|
|
else
|
|
{
|
|
pItem->OnValueChanged(str);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPPropertyGridInplaceMonthCal::PostNcDestroy()
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
BOOL CXTPPropertyGridInplaceMonthCal::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
|
{
|
|
if (message == WM_KILLFOCUS)
|
|
{
|
|
CWnd* pWnd = CWnd::FromHandle((HWND)wParam);
|
|
if (pWnd && IsChild(pWnd))
|
|
{
|
|
return CWnd::OnWndMsg(message, wParam, lParam, pResult);
|
|
}
|
|
|
|
OnCancel();
|
|
return TRUE;
|
|
}
|
|
if (message == WM_KEYDOWN && wParam == VK_ESCAPE)
|
|
{
|
|
OnCancel();
|
|
return TRUE;
|
|
}
|
|
if (message == WM_KEYDOWN && wParam == VK_RETURN)
|
|
{
|
|
OnAccept();
|
|
return TRUE;
|
|
}
|
|
|
|
return CWnd::OnWndMsg(message, wParam, lParam, pResult);
|
|
}
|
|
|
|
IMPLEMENT_DYNAMIC(CXTPPropertyGridItemDate, CXTPPropertyGridItem)
|
|
|
|
CXTPPropertyGridItemDate::CXTPPropertyGridItemDate(LPCTSTR strCaption, const COleDateTime& oleDate, COleDateTime* pBindDate)
|
|
: CXTPPropertyGridItem(strCaption)
|
|
{
|
|
m_pBindDate = pBindDate;
|
|
Init(oleDate);
|
|
}
|
|
|
|
CXTPPropertyGridItemDate::CXTPPropertyGridItemDate(UINT nID, const COleDateTime& oleDate, COleDateTime* pBindDate)
|
|
: CXTPPropertyGridItem(nID)
|
|
{
|
|
m_pBindDate = pBindDate;
|
|
Init(oleDate);
|
|
}
|
|
|
|
CString CXTPPropertyGridItemDate::GetAllowNullDateString() const
|
|
{
|
|
return m_strNullValue;
|
|
}
|
|
|
|
void CXTPPropertyGridItemDate::Init(const COleDateTime& oleDate)
|
|
{
|
|
m_nFlags = xtpGridItemHasComboButton | xtpGridItemHasEdit;
|
|
m_strFormat = _T("%d/%m/%Y");
|
|
m_strValue = _T("00/00/0000");
|
|
m_strNullValue.Empty();
|
|
|
|
SetMask(_T("00/00/0000"), _T("__/__/____"));
|
|
|
|
SetDate(oleDate);
|
|
|
|
EnableAutomation();
|
|
m_strDefaultValue = m_strValue;
|
|
}
|
|
|
|
BOOL CXTPPropertyGridItemDate::ParseDateTime(COleDateTime& dt, LPCTSTR strValue)
|
|
{
|
|
if (m_strFormat.IsEmpty())
|
|
return FALSE;
|
|
|
|
SYSTEMTIME sysTime;
|
|
ZeroMemory(&sysTime, sizeof(SYSTEMTIME));
|
|
|
|
WORD* ptrDate[3] = {0, 0, 0};
|
|
int nResult[3] = {0, 0, 0};
|
|
|
|
CString strFormat(m_strFormat);
|
|
strFormat.MakeLower();
|
|
|
|
int nIndex = -1, i = 0;
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
nIndex = strFormat.Find(_T('%'), nIndex + 1);
|
|
|
|
if (nIndex == -1 || nIndex == strFormat.GetLength() - 1)
|
|
return FALSE;
|
|
|
|
switch (strFormat[nIndex + 1])
|
|
{
|
|
case _T('d'):
|
|
ptrDate[i] = &sysTime.wDay;
|
|
break;
|
|
|
|
case _T('y'):
|
|
ptrDate[i] = &sysTime.wYear;
|
|
break;
|
|
|
|
case _T('m'):
|
|
case _T('b'):
|
|
ptrDate[i] = &sysTime.wMonth;
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
strFormat.SetAt(nIndex + 1, _T('d'));
|
|
}
|
|
|
|
if (SCANF_S(strValue, strFormat, &nResult[0], &nResult[1], &nResult[2]) != 3)
|
|
return FALSE;
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
if (!ptrDate[i])
|
|
return FALSE;
|
|
|
|
*ptrDate[i] = (WORD)nResult[i];
|
|
}
|
|
|
|
dt = sysTime;
|
|
return dt.GetStatus() == COleDateTime::valid;
|
|
}
|
|
|
|
void CXTPPropertyGridItemDate::OnValueChanged(CString strValue)
|
|
{
|
|
if (!m_strNullValue.IsEmpty() && m_bUseMask && strValue == m_strLiteral && m_oleDate.GetStatus() == COleDateTime::null)
|
|
return;
|
|
|
|
CXTPPropertyGridItem::OnValueChanged(strValue);
|
|
}
|
|
|
|
void CXTPPropertyGridItemDate::SetValue(CString strValue)
|
|
{
|
|
COleDateTime dt;
|
|
TRY
|
|
{
|
|
if (ParseDateTime(dt, strValue))
|
|
{
|
|
SetDate(dt);
|
|
}
|
|
else if (dt.ParseDateTime(strValue, VAR_DATEVALUEONLY))
|
|
{
|
|
SetDate(dt);
|
|
}
|
|
else if (!m_strNullValue.IsEmpty())
|
|
{
|
|
COleDateTime dtNull;
|
|
dtNull.SetStatus(COleDateTime::null);
|
|
|
|
SetDate(dtNull);
|
|
}
|
|
}
|
|
CATCH(COleException, e)
|
|
{
|
|
|
|
}
|
|
END_CATCH
|
|
}
|
|
|
|
|
|
void CXTPPropertyGridItemDate::SetDateFormat(LPCTSTR strFormat)
|
|
{
|
|
m_strFormat = strFormat;
|
|
SetDate(m_oleDate);
|
|
}
|
|
|
|
CString CXTPPropertyGridItemDate::Format(const COleDateTime& oleDate)
|
|
{
|
|
if (oleDate.GetStatus() != COleDateTime::valid)
|
|
return _T("");
|
|
|
|
#if _MSC_VER > 1310
|
|
if (oleDate.GetYear() <= 1900) // Visual Studio 2005 bug.
|
|
{
|
|
CString strDate;
|
|
if (m_strFormat == _T("%d/%m/%Y"))
|
|
{
|
|
strDate.Format(_T("%.2i/%.2i/%.4i"), oleDate.GetDay(), oleDate.GetMonth(), oleDate.GetYear());
|
|
return strDate;
|
|
}
|
|
if (m_strFormat == _T("%m/%d/%Y"))
|
|
{
|
|
strDate.Format(_T("%.2i/%.2i/%.4i"), oleDate.GetMonth(), oleDate.GetDay(), oleDate.GetYear());
|
|
return strDate;
|
|
}
|
|
}
|
|
#endif
|
|
if (m_strFormat.IsEmpty())
|
|
return oleDate.Format();
|
|
|
|
return oleDate.Format(m_strFormat);
|
|
}
|
|
|
|
void CXTPPropertyGridItemDate::SetDate(const COleDateTime& oleDate)
|
|
{
|
|
if (oleDate.GetStatus() != COleDateTime::valid && !m_strNullValue.IsEmpty())
|
|
{
|
|
m_oleDate = oleDate;
|
|
if (m_pBindDate)
|
|
*m_pBindDate = oleDate;
|
|
|
|
CXTPPropertyGridItem::SetValue(m_strNullValue);
|
|
return;
|
|
}
|
|
|
|
ASSERT(oleDate.GetStatus() == COleDateTime::valid);
|
|
m_oleDate = oleDate;
|
|
|
|
if (m_pBindDate)
|
|
*m_pBindDate = oleDate;
|
|
|
|
CString strValue = Format(oleDate);
|
|
|
|
CXTPPropertyGridItem::SetValue(strValue);
|
|
}
|
|
|
|
void CXTPPropertyGridItemDate::BindToDate(COleDateTime* pBindDate)
|
|
{
|
|
m_pBindDate = pBindDate;
|
|
if (m_pBindDate)
|
|
*m_pBindDate = m_oleDate;
|
|
}
|
|
|
|
void CXTPPropertyGridItemDate::OnBeforeInsert()
|
|
{
|
|
if (m_pBindDate && *m_pBindDate != m_oleDate)
|
|
SetDate(*m_pBindDate);
|
|
}
|
|
|
|
|
|
#if _MSC_VER < 1200 // MFC 5.0
|
|
|
|
|
|
BOOL CXTPPropertyGridItemDate::GetAsSystemTime(SYSTEMTIME& sysTime)
|
|
{
|
|
BOOL bRetVal = FALSE;
|
|
if (m_oleDate.GetStatus() == COleDateTime::valid)
|
|
{
|
|
struct tm tmTemp;
|
|
if (CXTPDateTimeHelper::TmFromOleDate(m_oleDate, tmTemp))
|
|
{
|
|
sysTime.wYear = (WORD) tmTemp.tm_year;
|
|
sysTime.wMonth = (WORD) tmTemp.tm_mon;
|
|
sysTime.wDayOfWeek = (WORD) tmTemp.tm_wday;
|
|
sysTime.wDay = (WORD) tmTemp.tm_mday;
|
|
sysTime.wMinute = sysTime.wMilliseconds = sysTime.wSecond = sysTime.wHour = 0;
|
|
|
|
bRetVal = TRUE;
|
|
}
|
|
}
|
|
|
|
return bRetVal;
|
|
}
|
|
#else
|
|
|
|
BOOL CXTPPropertyGridItemDate::GetAsSystemTime(SYSTEMTIME& sysTime)
|
|
{
|
|
BOOL bRetVal = FALSE;
|
|
if (m_oleDate.GetStatus() == COleDateTime::valid)
|
|
{
|
|
bRetVal = m_oleDate.GetAsSystemTime(sysTime);
|
|
sysTime.wMinute = sysTime.wMilliseconds = sysTime.wSecond = sysTime.wHour = 0;
|
|
}
|
|
|
|
return bRetVal;
|
|
}
|
|
#endif
|
|
|
|
void CXTPPropertyGridItemDate::OnInplaceButtonDown(CXTPPropertyGridInplaceButton* pButton)
|
|
{
|
|
if (m_pGrid->SendNotifyMessage(XTP_PGN_INPLACEBUTTONDOWN, (LPARAM)pButton) == TRUE)
|
|
return;
|
|
|
|
if (!OnRequestEdit())
|
|
return;
|
|
|
|
CXTPPropertyGridInplaceMonthCal* pMonthCtrl = new CXTPPropertyGridInplaceMonthCal(this);
|
|
|
|
|
|
#if _MSC_VER < 1200 // MFC 5.0
|
|
INITCOMMONCONTROLSEX icex;
|
|
icex.dwSize = sizeof(icex);
|
|
icex.dwICC = ICC_DATE_CLASSES;
|
|
VERIFY(InitCommonControlsEx(&icex));
|
|
#else
|
|
VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_DATE_REG));
|
|
#endif // _MSC_VER < 1200
|
|
|
|
|
|
CRect rect(0, 0, 0, 0);
|
|
pMonthCtrl->CreateEx(WS_EX_TOPMOST | (m_pGrid->GetExStyle() & WS_EX_LAYOUTRTL), MONTHCAL_CLASS, NULL, WS_BORDER | WS_POPUP | WS_VISIBLE, rect, m_pGrid, 0);
|
|
|
|
SYSTEMTIME sysTime;
|
|
if (GetAsSystemTime(sysTime))
|
|
pMonthCtrl->SendMessage(MCM_SETCURSEL, 0, (LPARAM) &sysTime);
|
|
|
|
if (pMonthCtrl->GetMinReqRect(rect))
|
|
{
|
|
CRect rcItem = GetItemRect();
|
|
rect.SetRect(rcItem.right - rect.Width(), rcItem.bottom, rcItem.right, rcItem.bottom + rect.Height());
|
|
|
|
m_pGrid->ClientToScreen(&rect);
|
|
|
|
CRect rcWork = XTPMultiMonitor()->GetWorkArea(rect);
|
|
if (rect.bottom > rcWork.bottom && rect.top > rcWork.CenterPoint().y)
|
|
rect.OffsetRect(0, - rect.Height() - rcItem.Height() - 1);
|
|
|
|
if (rect.left < rcWork.left)
|
|
rect.OffsetRect(rcWork.left - rect.left, 0);
|
|
|
|
if (rect.right > rcWork.right)
|
|
rect.OffsetRect(rcWork.right - rect.right, 0);
|
|
|
|
pMonthCtrl->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER | SWP_NOACTIVATE);
|
|
}
|
|
|
|
|
|
pMonthCtrl->SetOwner(m_pGrid);
|
|
pMonthCtrl->SetFocus();
|
|
}
|
|
|
|
long CXTPPropertyGridItemDate::GetDay()
|
|
{
|
|
return m_oleDate.GetDay();
|
|
}
|
|
|
|
void CXTPPropertyGridItemDate::SetDay(long nDay)
|
|
{
|
|
COleDateTime oleDate(GetYear(), GetMonth(), nDay, 0, 0, 0);
|
|
SetDate(oleDate);
|
|
}
|
|
|
|
long CXTPPropertyGridItemDate::GetMonth()
|
|
{
|
|
return m_oleDate.GetMonth();
|
|
}
|
|
|
|
void CXTPPropertyGridItemDate::SetMonth(long nMonth)
|
|
{
|
|
COleDateTime oleDate(GetYear(), nMonth, GetDay(), 0, 0, 0);
|
|
SetDate(oleDate);
|
|
}
|
|
|
|
long CXTPPropertyGridItemDate::GetYear()
|
|
{
|
|
return m_oleDate.GetYear();
|
|
}
|
|
|
|
void CXTPPropertyGridItemDate::SetYear(long nYear)
|
|
{
|
|
COleDateTime oleDate(nYear, GetMonth(), GetDay(), 0, 0, 0);
|
|
SetDate(oleDate);
|
|
}
|
|
|
|
void CXTPPropertyGridItemDate::AllowNullDate(LPCTSTR lpszNullValue)
|
|
{
|
|
m_strNullValue = lpszNullValue;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPPropertyGridItemMultilineString
|
|
|
|
CXTPPropertyGridItemMultilineString::CXTPPropertyGridItemMultilineString(LPCTSTR lpszCaption, LPCTSTR strValue, CString* pBindString)
|
|
: CXTPPropertyGridItem(lpszCaption, strValue, pBindString)
|
|
{
|
|
m_nFlags = xtpGridItemHasComboButton | xtpGridItemHasEdit;
|
|
m_nDropDownItemCount = 8;
|
|
}
|
|
|
|
CXTPPropertyGridItemMultilineString::CXTPPropertyGridItemMultilineString(UINT nID, LPCTSTR strValue, CString* pBindString)
|
|
: CXTPPropertyGridItem(nID, strValue, pBindString)
|
|
{
|
|
m_nFlags = xtpGridItemHasComboButton | xtpGridItemHasEdit;
|
|
m_nDropDownItemCount = 8;
|
|
}
|
|
|
|
void CXTPPropertyGridItemMultilineString::OnInplaceButtonDown(CXTPPropertyGridInplaceButton* pButton)
|
|
{
|
|
if (!IsAllowEdit())
|
|
return;
|
|
|
|
if (m_pGrid->SendNotifyMessage(XTP_PGN_INPLACEBUTTONDOWN, (LPARAM)pButton) == TRUE)
|
|
return;
|
|
|
|
if ((pButton->GetID() == XTP_ID_PROPERTYGRID_COMBOBUTTON) && OnRequestEdit())
|
|
{
|
|
CXTPPropertyGridInplaceMultilineEdit* pEdit = new CXTPPropertyGridInplaceMultilineEdit();
|
|
pEdit->Create(this, GetItemRect());
|
|
m_pGrid->Invalidate(FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#ifdef __AFXCTL_H__
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPPropertyGridItemPicture
|
|
|
|
CXTPPropertyGridItemPicture::CXTPPropertyGridItemPicture(LPCTSTR strCaption)
|
|
: CXTPPropertyGridItem(strCaption)
|
|
{
|
|
m_nFlags = xtpGridItemHasExpandButton;
|
|
m_nPreviewWidth = 20;
|
|
}
|
|
|
|
BOOL CXTPPropertyGridItemPicture::OnDrawItemValue(CDC& dc, CRect rcValue)
|
|
{
|
|
COLORREF clr = dc.GetTextColor();
|
|
CRect rcSample(rcValue.left - 2, rcValue.top + 1, rcValue.left - 2 + m_nPreviewWidth, rcValue.bottom - 1);
|
|
|
|
m_olePicture.Render(&dc, rcSample, rcSample);
|
|
dc.Draw3dRect(rcSample, clr, clr);
|
|
|
|
CRect rcText(rcValue);
|
|
rcText.left += m_nPreviewWidth + 5;
|
|
|
|
short type = m_olePicture.GetType();
|
|
CString str = type == PICTYPE_ICON ? _T("(Icon)") :
|
|
type == PICTYPE_BITMAP ? _T("(Bitmap)") : _T("None");
|
|
|
|
dc.DrawText(str, rcText, DT_SINGLELINE | DT_VCENTER);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPPropertyGridItemPicture::OnInplaceButtonDown(CXTPPropertyGridInplaceButton* pButton)
|
|
{
|
|
if (m_pGrid->SendNotifyMessage(XTP_PGN_INPLACEBUTTONDOWN, (LPARAM)pButton) == TRUE)
|
|
return;
|
|
|
|
if (!OnRequestEdit())
|
|
return;
|
|
|
|
CString strFilter = _T("All Picture Types|*.bmp;*.cur;*.dib;*.emf;*.ico;*.wmf;*.gif;*.jpg|Bitmaps (*.bmp;*.dib;*.gif;*.jpg)|*.bmp;*.dib;*.gif;*.jpg |Icons/Cursors (*.ico;*.cur)|*.ico;*.cur|Metafiles (*.wmf;*.emf)|*.wmf;*.emf|All files (*.*)|*.*||");
|
|
|
|
CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, strFilter);
|
|
|
|
if (dlg.DoModal() == IDOK)
|
|
{
|
|
CString strPath(dlg.GetPathName());
|
|
|
|
if (OnAfterEdit(strPath))
|
|
{
|
|
SetPicturePath(strPath);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OnCancelEdit();
|
|
}
|
|
}
|
|
|
|
void CXTPPropertyGridItemPicture::SetPicturePath(LPCTSTR lpszPath)
|
|
{
|
|
m_strPicturePath = lpszPath;
|
|
LPPICTUREDISP pPict = NULL;
|
|
|
|
if (OleLoadPicturePath((LPOLESTR)XTP_CT2CW(m_strPicturePath), NULL, 0, 0, IID_IPictureDisp, (LPVOID*)&pPict) == S_OK)
|
|
{
|
|
m_olePicture.SetPictureDispatch(pPict);
|
|
pPict->Release();
|
|
|
|
OnValueChanged(_T(""));
|
|
((CWnd*)m_pGrid)->Invalidate(FALSE);
|
|
}
|
|
else if (m_olePicture.GetPictureDispatch())
|
|
{
|
|
m_olePicture.SetPictureDispatch(NULL);
|
|
|
|
OnValueChanged(_T(""));
|
|
((CWnd*)m_pGrid)->Invalidate(FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endif
|