Thanks in advance any of your suggentions and clues...
-Hari
//Here is my extended class definition file -- DateTimeCtrlExt.h
class CDateTimeCtrlExt : public CDateTimeCtrl
{
public:
enum eStatus {
dt_null, //indicate invalid or null value
dt_valid
};
CDateTimeCtrlExt(BOOL bUseDsplusStyle = TRUE);
BOOL SetTime(const COleDateTime& timeNew);
virtual ~CDateTimeCtrlExt();
void setAsTimeCtrl() { m_bIsTimeCtrl = TRUE;}
void setAsDateCtrl() { m_bIsTimeCtrl = FALSE;}
BOOL GetTime(COleDateTime& timeDest) const;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDateTimeCtrlExt)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL
// Generated message map functions
protected:
//{{AFX_MSG(CDateTimeCtrlExt)
afx_msg void OnFormat(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnFormatquery(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnWmkeydown(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnDatetimechange(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
LRESULT SendMessageToParent(int nMessage) const;
//Methods for customizing user entries in the date field
void WINAPI DoFormat(HWND hwndDP, LPNMDATETIMEFORMAT lpDTFormat);
void WINAPI DoFormatQuery( HWND hwndDP,
LPNMDATETIMEFORMATQUERY lpDTFQuery);
DECLARE_MESSAGE_MAP()
private:
const CString m_defaultCustomDateFmt; // default format used for this control
const CString m_defaultDateFmt; // default format used for this control
CString m_curDateFormat; //Current format
BOOL m_bUseDSPlusStyle;
BOOL m_bIsTimeCtrl;
eStatus m_bStatus;
};
//implementation file DateTimeCtrlExt.cpp
#include "stdafx.h"
#include <WindowsX.h>
#include "dsplus.h"
#include "DateTime.h"
#include "DateTimeCtrlExt.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CDateTimeCtrlExt::CDateTimeCtrlExt(BOOL bUseDsplusStyle) :
m_defaultCustomDateFmt(_T("XXXX/XX/XX")), m_defaultDateFmt(_T("yyyy/MM/dd"))
{
m_bUseDSPlusStyle = bUseDsplusStyle;
m_curDateFormat = m_defaultCustomDateFmt;
m_bIsTimeCtrl = FALSE;
m_bStatus = dt_valid;
}
CDateTimeCtrlExt::~CDateTimeCtrlExt() {}
BEGIN_MESSAGE_MAP(CDateTimeCtrlExt, CDateTimeCtrl)
//{{AFX_MSG_MAP(CDateTimeCtrlExt)
ON_NOTIFY_REFLECT(DTN_FORMAT, OnFormat)
ON_NOTIFY_REFLECT(DTN_FORMATQUERY, OnFormatquery)
ON_NOTIFY_REFLECT(DTN_WMKEYDOWN, OnWmkeydown)
ON_NOTIFY_REFLECT(DTN_DATETIMECHANGE, OnDatetimechange)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CDateTimeCtrlExt::OnFormat(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMDATETIMEFORMAT lpNMFormat = (LPNMDATETIMEFORMAT) pNMHDR;
// Process DTN_FORMAT to supply information about callback
// fields (fields) in the DTP control.
DoFormat(m_hWnd, lpNMFormat);
*pResult = 0;
}
void CDateTimeCtrlExt::OnFormatquery(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMDATETIMEFORMATQUERY lpDTFQuery = (LPNMDATETIMEFORMATQUERY)pNMHDR;
// Process DTN_FORMATQUERY to ensure that the control
// displays callback information properly.
DoFormatQuery(m_hWnd, lpDTFQuery);
*pResult = 0;
}
void CDateTimeCtrlExt::OnWmkeydown(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMDATETIMEWMKEYDOWN lpDTKeystroke = (LPNMDATETIMEWMKEYDOWN)pNMHDR;
if(lpDTKeystroke->nVirtKey >= 0x31 && lpDTKeystroke->nVirtKey <= 0x39) {
//SetFormat(m_curDateFormat);
lpDTKeystroke->st.wYear = lpDTKeystroke->nVirtKey;
}
*pResult = 0;
}
void WINAPI CDateTimeCtrlExt::DoFormatQuery( HWND hwndDP, LPNMDATETIMEFORMATQUERY lpDTFQuery)
{
HDC hdc;
HFONT hFont, hOrigFont;
// Prepare the device context for GetTextExtentPoint32 call.
hdc = ::GetDC(hwndDP);
hFont = FORWARD_WM_GETFONT(hwndDP, ::SendMessage);
if(!hFont)
hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
hOrigFont = (HFONT)::SelectObject(hdc, hFont);
// Check to see if this is the callback segment desired. If so,
// use the longest text segment to determine the maximum
// width of the callback field, and then place the information into
// the NMDATETIMEFORMATQUERY structure.
if(!_tcscmp(_T("XX"),lpDTFQuery->pszFormat))
::GetTextExtentPoint32 (hdc,
_T("366"), // widest date string
3,
&lpDTFQuery->szMax);
else if(!_tcscmp(_T("XXXX"),lpDTFQuery->pszFormat)) {
int len = _tcslen(_T("36666"));
::GetTextExtentPoint32 (hdc,
_T("36666"), // widest date string
len,
&lpDTFQuery->szMax);
}
// Reset the font in the device context; then release the context.
::SelectObject(hdc,hOrigFont);
::ReleaseDC(hwndDP, hdc);
}
// DoFormat processes DTN_FORMAT to provide the text for a callback// field in a DTP control.
void WINAPI CDateTimeCtrlExt::DoFormat(HWND hwndDP, LPNMDATETIMEFORMAT lpDTFormat)
{
int fmtLen = _tcslen(lpDTFormat->pszFormat);
if( fmtLen == 2) {
_tcscpy(lpDTFormat->szDisplay, _T("--"));
}else {
_tcscpy(lpDTFormat->szDisplay, _T("----"));
}
//TRACE(_T(" %d %d\n"), lpDTFormat->st.wMonth, lpDTFormat->st.wDay);
}
void CDateTimeCtrlExt::OnDatetimechange(NMHDR* pNMHDR, LRESULT* pResult)
{
//check date is valid or not
COleDateTime dt;
CDateTimeCtrl::GetTime(dt);
if(dt.GetStatus() == COleDateTime::null) {
m_bStatus = dt_null;
if(!m_bIsTimeCtrl) {
if(m_bUseDSPlusStyle) {
SetFormat(GetDateTime()->GetCustomDateFormat());
}
else {
SetFormat(m_defaultCustomDateFmt);
}
}
else {
dt.SetTime(0,0,0);
CDateTimeCtrl::SetTime(dt);
}
}
else {
m_bStatus = dt_valid;
if(!m_bIsTimeCtrl)
SetFormat(m_curDateFormat);
}
*pResult = 0;
}
BOOL CDateTimeCtrlExt::SetTime(const COleDateTime& timeNew)
{
if(timeNew.GetStatus() == COleDateTime::null) {
m_bStatus = dt_null;
if(!m_bIsTimeCtrl) {
if(m_bUseDSPlusStyle) {
SetFormat(GetDateTime()->GetCustomDateFormat());
m_curDateFormat = GetDateTime()->GetDateFormat();
}
else {
SetFormat(m_defaultCustomDateFmt);
m_curDateFormat = m_defaultDateFmt;
}
}
else {
//Defaulted to 12.00
COleDateTime t;
t.SetTime(0,0,0);
CDateTimeCtrl::SetTime(t);
}
}
else {
m_bStatus = dt_valid;
if(!m_bIsTimeCtrl) {
if(m_bUseDSPlusStyle) {
SetFormat(GetDateTime()->GetDateFormat());
m_curDateFormat = GetDateTime()->GetDateFormat();
}
else {
SetFormat(m_defaultDateFmt);
m_curDateFormat = m_defaultDateFmt;
}
}
}
return CDateTimeCtrl::SetTime(timeNew);
}
BOOL CDateTimeCtrlExt::GetTime(COleDateTime& timeDest) const
{
if(m_bStatus == dt_null) {
if(m_bIsTimeCtrl)
timeDest.SetTime(0,0,0);
timeDest.SetStatus(COleDateTime::null);
return TRUE;
}
else return CDateTimeCtrl::GetTime(timeDest);
}