Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem with CDateTimeCtrl class with custom format

136 views
Skip to first unread message

Hari

unread,
Mar 18, 2004, 2:36:11 PM3/18/04
to
I created CDateTimeCtrlExt classs from MFC's CDateTimeCtrl class to handle custom date format and i implemented the following dtn messages according to the msdn library.
initialy i set the format as "XXXX/XX/XX" custom format to get the notification. ( so the control will appear as ----/--/-- initialy and as soon i start typing a digit i will put the numbers.
so far its good. The control is implemented in a dialog box and The problem is when i close the dialog box, the application crashes. ( this happens only when i use the close "x" button in the topright of the dialog. if use cancel button it closes fine without any crashes. also this happens only when i start in the debug mode. any idea???

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);
}

0 new messages