如果CDateTimeCtrl的格式设置为“dd.MM.yy”,则日期控件在运行时以“05.05.15”格式正确显示日期
但是如果用户将光标放入控件的年份部分, 年份从“15”切换到“2015”
通过离开年度部分(例如将光标放在日期部分),它会从“2015”重新更改为“15”
是否有可能暂停此活动?
年份部分应始终保持2位数。
答案 0 :(得分:1)
我认为必须从CDateTimeCtrl
推导出这种行为。
实现显示非常简单。
我已经实现了CDateTimeCtrl2Digit
来代替标准组件,就像你要做的样本一样。编辑更复杂,我只是一个非常简单的。
CDateTimeCtrl2Digit m_DateTime;
m_DateTime.SetFormat( _T("dd.MM.XX"));
格式XX
由CDateTimeCtrl2Digitas作为回调字段管理:
来自MSDN:
回调字段除标准格式字符串和正文外 在文本中,您还可以将显示的某些部分定义为Callback 领域。这些字段可用于向用户查询信息。至 声明一个回调字段,包含一个或多个" X"字符(ASCII 代码88)格式字符串中的任何位置。您可以创建回调字段 通过重复" X"具有独特的身份。字符。就这样 格式字符串" XX dddd MMM dd',' yyy XXX"包含两个独特的回调 领域," XX"和" XXX"。与其他DTP控制字段一样,回调字段 根据它们在中的位置以从左到右的顺序显示 格式字符串。当DTP控件解析格式字符串时 遇到一个回调字段,它发送DTN_FORMAT和DTN_FORMATQUERY 通知代码。对应的格式字符串元素 回调字段包含在通知中以允许 接收应用程序以确定正在使用哪个回调字段 查询。控件的所有者必须响应这些通知 确保正确显示自定义信息。
因此,您必须处理此回调字段以显示年份的两位数和所有特殊编辑。 这是一个部分工作的样本:我的意思是所有编辑都缺失,这里是一个非常简单的编辑(我不处理箭头键,只处理数字)。
我在stackoverflow中发布代码非常新,所以请原谅我,如果有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;
}