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++

// 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