CDateTimeCtrl 编辑短年份格式
CDateTimeCtrl editing short year format
如果 CDateTimeCtrl 的格式设置为 "dd.MM.yy",日期控件会在运行时正确显示格式为“05.05.15”的日期
但是如果用户将光标置于控件的年份部分,
年份从“15”切换为“2015”
通过离开年份部分(例如将光标置于日期部分),它会从“2015”重新更改为“15”
有可能暂停吗?
年份部分应始终为 2 位数。
我认为有必要从 CDateTimeCtrl
重写这种行为。
实现显示非常简单。
我已经实现了 CDateTimeCtrl2Digit
来代替标准组件,就像您必须做的示例一样。编辑比较复杂,我只做了一个很简单的。
CDateTimeCtrl2Digit m_DateTime;
m_DateTime.SetFormat( _T("dd.MM.XX"));
格式 XX
由 CDateTimeCtrl2Digitas 作为回调字段管理:
来自 MSDN:
Callback fields In addition to the standard Format Strings and body
text, you can also define certain parts of the display as Callback
fields. These fields can be used to query the user for information. To
declare a callback field, include one or more "X" characters (ASCII
Code 88) anywhere in the format string. You can create callback fields
that have a unique identity by repeating the "X" character. Thus, the
format string "XX dddd MMM dd', 'yyy XXX" contains two unique callback
fields, "XX" and "XXX". Like other DTP control fields, callback fields
are displayed in left-to-right order based on their location in the
format string. When the DTP control parses the format string and
encounters a callback field, it sends DTN_FORMAT and DTN_FORMATQUERY
notification codes. The format string element corresponding to the
callback field is included with the notifications to allow the
receiving application to determine which callback field is being
queried. The owner of the control must respond to these notifications
to ensure that the custom information is properly displayed.
所以你必须处理这个回调字段来显示年份的两位数和所有的特殊编辑。
这是一个部分工作的示例:我的意思是缺少所有编辑,这是一个非常简单的示例(我不处理箭头键,只处理数字)。
我是在 Whosebug 中发布代码的新手,所以请原谅我,如果只需复制并粘贴我写的内容就能 100% 工作!!!
但这是我所做的:
class CDateTimeCtrl2Digit : public CDateTimeCtrl
{
DECLARE_DYNAMIC(CDateTimeCtrl2Digit )
public:
CDateTimeCtrl2Digit ();
virtual ~CDateTimeCtrl2Digit ();
protected:
int nDigit;
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnDtnFormat(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnDtnFormatquery(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnDtnWmkeydown(NMHDR *pNMHDR, LRESULT *pResult);
};
和.cpp
#include "stdafx.h"
#include "MFCApplication1.h"
#include "DateTimeCtrl2Digit.h"
#define GetWindowFont(hwnd) FORWARD_WM_GETFONT((hwnd), SNDMSG)
#define FORWARD_WM_GETFONT(hwnd, fn) (HFONT)(UINT_PTR)(fn)((hwnd), WM_GETFONT, 0L, 0L)
IMPLEMENT_DYNAMIC(CDateTimeCtrl2Digit , CDateTimeCtrl)
CDateTimeCtrl2Digit ::CDateTimeCtrl2Digit ()
{
nDigit = 0;
}
CDateTimeCtrl2Digit ::~CDateTimeCtrl2Digit ()
{
}
BEGIN_MESSAGE_MAP(CDateTimeCtrl2Digit , CDateTimeCtrl)
ON_NOTIFY_REFLECT(DTN_FORMAT, &CDateTimeCtrl2Digit::OnDtnFormat)
ON_NOTIFY_REFLECT(DTN_FORMATQUERY, &CDateTimeCtrl2Digit::OnDtnFormatquery)
ON_NOTIFY_REFLECT(DTN_WMKEYDOWN, &CDateTimeCtrl2Digit::OnDtnWmkeydown)
END_MESSAGE_MAP()
void CDateTimeCtrl2Digit ::OnDtnFormat(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMDATETIMEFORMAT pDTFormat = reinterpret_cast<LPNMDATETIMEFORMAT>(pNMHDR);
COleDateTime dt;
CDateTimeCtrl::GetTime(dt);
CString year = dt.Format(_T("%y"));
_tcscpy_s( pDTFormat->szDisplay, year);
*pResult = 0;
}
void CDateTimeCtrl2Digit ::OnDtnFormatquery(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMDATETIMEFORMATQUERY pDTFmtQuery = reinterpret_cast<LPNMDATETIMEFORMATQUERY>(pNMHDR);
HDC hdc;
HFONT hFont, hOrigFont;
hdc = ::GetDC(m_hWnd);
hFont = FORWARD_WM_GETFONT(m_hWnd, ::SendMessage);
if(!hFont) hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
hOrigFont = (HFONT)::SelectObject(hdc, hFont);
::GetTextExtentPoint32 (hdc, _T("88"), 2, &pDTFmtQuery->szMax);
::SelectObject(hdc,hOrigFont);
::ReleaseDC(m_hWnd, hdc);
*pResult = 0;
}
void CMyDateTimeCtrl::OnDtnWmkeydown(NMHDR *pNMHDR, LRESULT *pResult)
{
COleDateTime oCurTime;
GetTime(oCurTime);
int century = static_cast<int>( oCurTime.GetYear() / 100 ) * 100;
int decade = oCurTime.GetYear() - century;
LPNMDATETIMEWMKEYDOWN pDTKeyDown = reinterpret_cast<LPNMDATETIMEWMKEYDOWN>(pNMHDR);
if( ( pDTKeyDown->nVirtKey >= 48 ) && ( pDTKeyDown->nVirtKey <= 57 ) )
{
if( nDigit == 0 )
{
nDigit = 1;
pDTKeyDown->st.wYear = century + pDTKeyDown->nVirtKey - 48;
}
else
{
nDigit = 0;
pDTKeyDown->st.wYear = century + decade * 10 + pDTKeyDown->nVirtKey - 48;
}
}
*pResult = 0;
}
如果 CDateTimeCtrl 的格式设置为 "dd.MM.yy",日期控件会在运行时正确显示格式为“05.05.15”的日期
但是如果用户将光标置于控件的年份部分, 年份从“15”切换为“2015”
通过离开年份部分(例如将光标置于日期部分),它会从“2015”重新更改为“15”
有可能暂停吗?
年份部分应始终为 2 位数。
我认为有必要从 CDateTimeCtrl
重写这种行为。
实现显示非常简单。
我已经实现了 CDateTimeCtrl2Digit
来代替标准组件,就像您必须做的示例一样。编辑比较复杂,我只做了一个很简单的。
CDateTimeCtrl2Digit m_DateTime;
m_DateTime.SetFormat( _T("dd.MM.XX"));
格式 XX
由 CDateTimeCtrl2Digitas 作为回调字段管理:
来自 MSDN:
Callback fields In addition to the standard Format Strings and body text, you can also define certain parts of the display as Callback fields. These fields can be used to query the user for information. To declare a callback field, include one or more "X" characters (ASCII Code 88) anywhere in the format string. You can create callback fields that have a unique identity by repeating the "X" character. Thus, the format string "XX dddd MMM dd', 'yyy XXX" contains two unique callback fields, "XX" and "XXX". Like other DTP control fields, callback fields are displayed in left-to-right order based on their location in the format string. When the DTP control parses the format string and encounters a callback field, it sends DTN_FORMAT and DTN_FORMATQUERY notification codes. The format string element corresponding to the callback field is included with the notifications to allow the receiving application to determine which callback field is being queried. The owner of the control must respond to these notifications to ensure that the custom information is properly displayed.
所以你必须处理这个回调字段来显示年份的两位数和所有的特殊编辑。 这是一个部分工作的示例:我的意思是缺少所有编辑,这是一个非常简单的示例(我不处理箭头键,只处理数字)。
我是在 Whosebug 中发布代码的新手,所以请原谅我,如果只需复制并粘贴我写的内容就能 100% 工作!!!
但这是我所做的:
class CDateTimeCtrl2Digit : public CDateTimeCtrl
{
DECLARE_DYNAMIC(CDateTimeCtrl2Digit )
public:
CDateTimeCtrl2Digit ();
virtual ~CDateTimeCtrl2Digit ();
protected:
int nDigit;
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnDtnFormat(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnDtnFormatquery(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnDtnWmkeydown(NMHDR *pNMHDR, LRESULT *pResult);
};
和.cpp
#include "stdafx.h"
#include "MFCApplication1.h"
#include "DateTimeCtrl2Digit.h"
#define GetWindowFont(hwnd) FORWARD_WM_GETFONT((hwnd), SNDMSG)
#define FORWARD_WM_GETFONT(hwnd, fn) (HFONT)(UINT_PTR)(fn)((hwnd), WM_GETFONT, 0L, 0L)
IMPLEMENT_DYNAMIC(CDateTimeCtrl2Digit , CDateTimeCtrl)
CDateTimeCtrl2Digit ::CDateTimeCtrl2Digit ()
{
nDigit = 0;
}
CDateTimeCtrl2Digit ::~CDateTimeCtrl2Digit ()
{
}
BEGIN_MESSAGE_MAP(CDateTimeCtrl2Digit , CDateTimeCtrl)
ON_NOTIFY_REFLECT(DTN_FORMAT, &CDateTimeCtrl2Digit::OnDtnFormat)
ON_NOTIFY_REFLECT(DTN_FORMATQUERY, &CDateTimeCtrl2Digit::OnDtnFormatquery)
ON_NOTIFY_REFLECT(DTN_WMKEYDOWN, &CDateTimeCtrl2Digit::OnDtnWmkeydown)
END_MESSAGE_MAP()
void CDateTimeCtrl2Digit ::OnDtnFormat(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMDATETIMEFORMAT pDTFormat = reinterpret_cast<LPNMDATETIMEFORMAT>(pNMHDR);
COleDateTime dt;
CDateTimeCtrl::GetTime(dt);
CString year = dt.Format(_T("%y"));
_tcscpy_s( pDTFormat->szDisplay, year);
*pResult = 0;
}
void CDateTimeCtrl2Digit ::OnDtnFormatquery(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMDATETIMEFORMATQUERY pDTFmtQuery = reinterpret_cast<LPNMDATETIMEFORMATQUERY>(pNMHDR);
HDC hdc;
HFONT hFont, hOrigFont;
hdc = ::GetDC(m_hWnd);
hFont = FORWARD_WM_GETFONT(m_hWnd, ::SendMessage);
if(!hFont) hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
hOrigFont = (HFONT)::SelectObject(hdc, hFont);
::GetTextExtentPoint32 (hdc, _T("88"), 2, &pDTFmtQuery->szMax);
::SelectObject(hdc,hOrigFont);
::ReleaseDC(m_hWnd, hdc);
*pResult = 0;
}
void CMyDateTimeCtrl::OnDtnWmkeydown(NMHDR *pNMHDR, LRESULT *pResult)
{
COleDateTime oCurTime;
GetTime(oCurTime);
int century = static_cast<int>( oCurTime.GetYear() / 100 ) * 100;
int decade = oCurTime.GetYear() - century;
LPNMDATETIMEWMKEYDOWN pDTKeyDown = reinterpret_cast<LPNMDATETIMEWMKEYDOWN>(pNMHDR);
if( ( pDTKeyDown->nVirtKey >= 48 ) && ( pDTKeyDown->nVirtKey <= 57 ) )
{
if( nDigit == 0 )
{
nDigit = 1;
pDTKeyDown->st.wYear = century + pDTKeyDown->nVirtKey - 48;
}
else
{
nDigit = 0;
pDTKeyDown->st.wYear = century + decade * 10 + pDTKeyDown->nVirtKey - 48;
}
}
*pResult = 0;
}