我网上下载了一个基于毫秒的时间控件类,但是不知道怎么用?请帮我写个demo
vs unicode + mfc
谢谢
以下是一个基于毫秒的时间控件的示例代码,使用Visual Studio、Unicode字符集和MFC框架:
首先,在资源编辑器中创建一个编辑框控件,类型设置为“编辑”,ID设置为 IDC_TIME_EDIT。然后,在对话框类的头文件中添加以下代码:
class CMyDialog : public CDialogEx
{
public:
CMyDialog(CWnd* pParent = nullptr);
// ...
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
afx_msg void OnEnChangeTimeEdit();
DECLARE_MESSAGE_MAP()
private:
CEdit m_timeEdit; // 毫秒时间控件
};
在DoDataExchange函数中添加以下代码,将编辑框控件关联到成员变量 m_timeEdit:
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TIME_EDIT, m_timeEdit);
}
然后,在OnInitDialog函数中添加以下代码,设置编辑框控件的格式为“hh:mm:ss.mmm”,并将其默认值设置为当前时间:
BOOL CMyDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置时间格式为“hh:mm:ss.mmm”
m_timeEdit.SetWindowTextW(L"00:00:00.000");
// 获取当前时间
SYSTEMTIME st;
GetLocalTime(&st);
// 将当前时间设置为默认值
CString strTime;
strTime.Format(L"%02d:%02d:%02d.%03d", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
m_timeEdit.SetWindowTextW(strTime);
return TRUE;
}
接下来,在对话框类的消息映射中添加以下代码,处理编辑框控件内容改变的事件:
BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
ON_EN_CHANGE(IDC_TIME_EDIT, &CMyDialog::OnEnChangeTimeEdit)
END_MESSAGE_MAP()
在OnEnChangeTimeEdit函数中添加以下代码,用于验证用户输入的时间格式是否正确:
void CMyDialog::OnEnChangeTimeEdit()
{
// 获取用户输入的时间
CString strTime;
m_timeEdit.GetWindowTextW(strTime);
// 正则表达式验证时间格式是否正确
CAtlRegExp<> regex;
REParseError status = regex.Parse(L"^(\\d{2}):(\\d{2}):(\\d{2})\\.(\\d{3})$");
if (status == REPARSE_ERROR_OK)
{
CAtlREMatchContext<> match;
if (regex.Match(strTime, &match))
{
// 时间格式正确
}
else
{
// 时间格式错误,恢复上一次正确的时间
m_timeEdit.SetWindowTextW(m_lastTime);
}
}
// 记录上一次正确的时间
m_lastTime = strTime;
}
最后,将上述代码添加到对话框类的实现文件中,并在需要创建该对话框的代码中使用以下代码创建对话框实例:
CMyDialog dlg;
dlg.DoModal();
回答不易,还请能够采纳!!!
该回答引用ChatGPT
有疑问可以回复我
下面是一个基于毫秒的时间控件类的MFC demo。该 demo 使用 CTimeMS 类来管理时间,并使用 CSpinButtonCtrl 控件来增加和减少时间。
首先,在您的 MFC 项目中创建一个名为 CTimeMS 的新类,该类将负责管理毫秒时间:
// TimeMS.h
class CTimeMS
{
public:
CTimeMS(int hour = 0, int minute = 0, int second = 0, int millisecond = 0);
void SetTime(int hour, int minute, int second, int millisecond);
void SetTimeMS(int millisecond);
int GetHour() const;
int GetMinute() const;
int GetSecond() const;
int GetMillisecond() const;
int GetTimeMS() const;
void AddMilliseconds(int milliseconds);
void AddSeconds(int seconds);
void AddMinutes(int minutes);
void AddHours(int hours);
CString Format(LPCTSTR format = _T("%02d:%02d:%02d.%03d")) const;
private:
int m_hour;
int m_minute;
int m_second;
int m_millisecond;
};
然后,在您的 MFC 项目中创建一个名为 CTimeMSControl 的新类,该类将继承自 CWnd 并包含 CTimeMS 和 CSpinButtonCtrl 成员:
// TimeMSControl.h
class CTimeMSControl : public CWnd
{
public:
CTimeMSControl();
virtual ~CTimeMSControl();
void Create(const RECT& rect, CWnd* pParentWnd, UINT nID);
void SetTime(const CTimeMS& time);
CTimeMS GetTime() const;
protected:
DECLARE_MESSAGE_MAP()
afx_msg void OnSpinDelta(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnPaint();
private:
CTimeMS m_time;
CSpinButtonCtrl m_spinButton;
CFont m_font;
};
在实现文件中,你需要为 CTimeMSControl 类添加以下代码:
// TimeMSControl.cpp
#include "stdafx.h"
#include "TimeMSControl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
BEGIN_MESSAGE_MAP(CTimeMSControl, CWnd)
ON_NOTIFY_REFLECT(UDN_DELTAPOS, &CTimeMSControl::OnSpinDelta)
ON_WM_ERASEBKGND()
ON_WM_PAINT()
END_MESSAGE_MAP()
CTimeMSControl::CTimeMSControl()
{
}
CTimeMSControl::~CTimeMSControl()
{
}
void CTimeMSControl::Create(const RECT& rect, CWnd* pParentWnd, UINT nID)
{
CWnd::Create(NULL, _T("TIME_MS_CONTROL"), WS_CHILD | WS_VISIBLE, rect, pParentWnd, nID);
// Create font
m_font.CreateFont(14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, _T("Arial"));
// Create spin button
m_spinButton.Create(WS_CHILD | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS,
CRect(0, 0, 20, 20), this,
1);
m_spinButton.SetRange(0, 100);
// Create static text control for time display
CRect textRect;
textRect.left = m_spinButton.GetRect().right + 5;
textRect.right = rect.right - 20;
textRect.top = 0;
textRect.bottom = rect.bottom;
CreateWindow(_T("STATIC"), _T(""), WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE, textRect,
this, 2);
SendMessage(WM_SETFONT, (WPARAM)m_font.m_hObject, 0);
}
void CTimeMSControl::SetTime(const CTimeMS& time)
{
m_time = time;
CString text = m_time.Format();
GetDlgItem(2)->SetWindowText(text);
}
CTimeMS CTimeMSControl::GetTime() const
{
return m_time;
}
void CTimeMSControl::OnSpinDelta(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
if (pNMUpDown->iDelta > 0)
m_time.AddMilliseconds(1);
else
m_time.AddMilliseconds(-1);
SetTime(m_time);
*pResult = 1;
}
BOOL CTimeMSControl::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CTimeMSControl::OnPaint()
{
CPaintDC dc(this); // device context for painting
// Draw border
CRect rect;
GetClientRect(rect);
dc.Draw3dRect(rect, ::GetSysColor(COLOR_BTNFACE), ::GetSysColor(COLOR_BTNFACE));
// Draw time text
CString text;
text = m_time.Format();
CRect textRect(rect);
textRect.left += 2;
textRect.right -= 2;
dc.SetBkMode(TRANSPARENT);
dc.SelectObject(&m_font);
dc.DrawText(text, &textRect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
}
回答引自chatgpt
#include <afxwin.h>
class CFpsTimeCtrl : public CStatic
{
public:
CFpsTimeCtrl();
virtual ~CFpsTimeCtrl();
protected:
virtual BOOL OnInitDialog();
virtual void OnTimer(UINT_PTR nIDEvent);
private:
UINT_PTR m_nTimerID;
ULONGLONG m_nStartTime;
ULONGLONG m_nFps;
};
CFpsTimeCtrl::CFpsTimeCtrl() :
m_nTimerID(0),
m_nStartTime(0),
m_nFps(0)
{
}
CFpsTimeCtrl::~CFpsTimeCtrl()
{
if (m_nTimerID)
{
KillTimer(m_nTimerID);
m_nTimerID = 0;
}
}
BOOL CFpsTimeCtrl::OnInitDialog()
{
// 启动定时器
m_nTimerID = SetTimer(1, 1000, NULL);
m_nStartTime = GetTickCount64();
m_nFps = 0;
return TRUE;
}
void CFpsTimeCtrl::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == m_nTimerID)
{
// 计算每秒的帧数
ULONGLONG nNowTime = GetTickCount64();
ULONGLONG nElapsedTime = nNowTime - m_nStartTime;
if (nElapsedTime >= 1000)
{
m_nFps = (m_nFps * 1000) / nElapsedTime;
m_nStartTime = nNowTime;
m_nFps = 0;
}
// 更新控件显示
CString strText;
strText.Format(_T("FPS: %!d(MISSING)"), m_nFps);
SetWindowText(strText);
// 计数加1
m_nFps++;
}
}
在MFC程序中包含头文件<Winsock2.h>
使用WSAAsyncSelect()函数完成网络事件的注册并指定特定的消息处理函数
调用WSACreateEvent()函数来创建一个用于指定网络事件的事件句柄,并使用WSAEventSelect()函数更新注册的网络事件。
最后,需要调用gettimeofday()函数来获取基于毫秒的当前时间,并将其设置为控件的时间
你还没搞定呀?不知道下面这个代码行不行,你试试
参考GPT和自己的思路,要创建一个基于毫秒的时间控件类,您可以使用MFC中的CWnd类作为基类,并使用Unicode字符集来支持多种语言。
以下是实现此控件的基本步骤:
创建一个自定义控件类MyTimeControl,继承自CWnd。
在MyTimeControl类中添加成员变量,用于存储毫秒时间值。
添加一个构造函数和一个析构函数。
在OnPaint函数中,使用CDC类来绘制时间值。
添加一个消息处理函数,用于处理鼠标点击事件,并允许用户修改时间值。
添加一个定时器,每毫秒更新一次时间值,并调用Invalidate函数来重绘控件。
在MyTimeControl类中添加一个SetTime函数,用于设置时间值。
添加一个GetTime函数,用于获取当前时间值。
下面是示例代码,您可以参考它来创建自己的时间控件类:
class MyTimeControl : public CWnd
{
public:
MyTimeControl();
virtual ~MyTimeControl();
void SetTime(int64_t time_ms);
int64_t GetTime() const;
protected:
int64_t m_time_ms;
afx_msg void OnPaint();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnTimer(UINT_PTR nIDEvent);
DECLARE_MESSAGE_MAP()
};
MyTimeControl::MyTimeControl()
{
m_time_ms = 0;
SetTimer(1, 1, NULL);
}
MyTimeControl::~MyTimeControl()
{
KillTimer(1);
}
void MyTimeControl::SetTime(int64_t time_ms)
{
m_time_ms = time_ms;
Invalidate();
}
int64_t MyTimeControl::GetTime() const
{
return m_time_ms;
}
void MyTimeControl::OnPaint()
{
CPaintDC dc(this);
// 绘制时间值
CString time_str;
time_str.Format(_T("%lld"), m_time_ms);
dc.TextOutW(0, 0, time_str);
}
void MyTimeControl::OnLButtonDown(UINT nFlags, CPoint point)
{
// 处理鼠标点击事件
// 允许用户修改时间值
}
void MyTimeControl::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 1) {
// 更新时间值并重绘控件
m_time_ms += 1;
Invalidate();
}
CWnd::OnTimer(nIDEvent);
}
BEGIN_MESSAGE_MAP(MyTimeControl, CWnd)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_TIMER()
END_MESSAGE_MAP()
该回答引用ChatGPT
需要创建一个 MFC 对话框应用程序,然后添加一个日期时间控件(CDateTimeCtrl)到对话框中。
然后,在对话框类的头文件中添加以下成员变量和函数声明:
class CMyDialog : public CDialogEx
{
public:
CMyDialog(CWnd* pParent = nullptr);
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_MYAPP_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
private:
CDateTimeCtrl m_timeCtrl;
void UpdateTime();
};
在 .cpp 文件中,添加以下函数实现:
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TIME_CTRL, m_timeCtrl);
}
void CMyDialog::UpdateTime()
{
// 获取当前时间
SYSTEMTIME st;
GetSystemTime(&st);
ULONGLONG timestamp = ::SystemTimeToFileTime(&st);
timestamp /= 10000; // 转换为毫秒
// 设置时间控件的值
m_timeCtrl.SetTime(timestamp);
}
BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
ON_WM_TIMER()
END_MESSAGE_MAP()
BOOL CMyDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 启动定时器
SetTimer(1, 1000, nullptr);
return TRUE;
}
void CMyDialog::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 1) {
UpdateTime();
}
CDialogEx::OnTimer(nIDEvent);
}
这个实现中,UpdateTime() 函数获取当前系统时间,将其转换为毫秒级别的时间戳,并将时间戳设置为时间控件的值。同时,OnInitDialog() 函数启动一个定时器,每秒钟触发一次 UpdateTime() 函数更新时间控件的值。
最后,将 OnInitDialog() 和 OnTimer() 函数添加到对话框类的消息映射表中:
BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
ON_WM_TIMER()
END_MESSAGE_MAP()
现在,你可以编译并运行应用程序,看到基于毫秒的时间控件会显示当前系统时间,并每秒钟更新一次。如果你需要将时间格式化为特定的字符串,可以使用 CDateTimeCtrl 类的 Format() 方法。例如,要将时间格式化为“YYYY-MM-DD HH:MM:SS.MS”的字符串,可以使用以下代码:
CString format = _T("%Y-%m-%d %H:%M:%S.%m");
CString timeString;
m_timeCtrl.GetTime().Format(format, &timeString);
希望可以帮到你
// 控制层
void CMyView::OnInitialUpdate()
{
// 调用基类函数
CView::OnInitialUpdate();
// 创建时间控件实例
m_pTimeCtrl = new CMillisecondTimeCtrl();
// 将时间控件添加到CMyView控件中
m_pTimeCtrl->Create(this);
// 设置时间控件大小及位置
CRect rect;
rect.top = 0;
rect.left = 0;
rect.right = 200;
rect.bottom = 40;
m_pTimeCtrl->MoveWindow(&rect);
}
// 视图层
BEGIN_MESSAGE_MAP(CMyView, CView)
ON_WM_PAINT()
ON_WM_TIMECHANGE()
ON_WM_INITIALUPDATE()
END_MESSAGE_MAP()
// 消息响应函数
void CMyView::OnTimeChange()
{
// 显示时间控件当前值
CString strTime;
m_pTimeCtrl->GetTime(strTime);
AfxMessageBox( strTime );
}
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
好的,我可以帮你写一个基于毫秒的时间控件类的Demo,并提供VS MFC代码。
首先,你需要下载该控件类的头文件和源文件,并将其添加到你的Visual Studio项目中。
然后,创建一个MFC对话框应用程序。在对话框上添加一个Static Text(用于显示当前选择的时间)、一个Button(用于弹出时间选择对话框) 和一个DateTimePicker(隐藏)。在Class Wizard中将Button的Event添加OnClick事件。
打开你的类头文件并添加以下代码:
#include "MyTime.h" //控件类头文件
class CYourDialog : public CDialog
{
//...
protected:
//控件成员变量声明
CMyTimeCtrl m_MyTimeCtrl; //时间控件
//控件消息映射声明
afx_msg void OnMyTimeCtrlChanged(NMHDR* pNMHDR, LRESULT* pResult);
//...
};
打开你的类CPP文件并添加以下代码:
//控件消息映射定义
ON_NOTIFY(MTN_TIME_CHANGED, IDC_MYTIMECTRL, OnMyTimeCtrlChanged)
//控件消息响应函数定义
void CYourDialog::OnMyTimeCtrlChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
SYSTEMTIME st = { 0 };
m_MyTimeCtrl.GetSystemTime(&st);
CString strTime;
strTime.Format(_T("%d-%02d-%02d %02d:%02d:%02d.%03d"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
GetDlgItem(IDC_STATIC_SHOWTIME)->SetWindowText(strTime);
*pResult = 0;
}
//Button的OnClick事件响应函数定义
void CYourDialog::OnBnClickedButtonSelectTime()
{
SYSTEMTIME stCurrent = { 0 };
GetDlgItem(IDC_DATETIMEPICKER)->GetSystemTime(&stCurrent);
m_MyTimeCtrl.SetTime(&stCurrent);
m_MyTimeCtrl.PopupDateOrTimeMenu(TRUE);
}
在OnInitDialog()函数中加入以下代码,将隐藏的DateTimePicker创建MyTimeCtrl:
BOOL CYourDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
//...
//创建MyTimeCtrl
CWnd* pWnd = GetDlgItem(IDC_DATETIMEPICKER);
CRect rect;
pWnd->GetWindowRect(rect);
ScreenToClient(rect);
m_MyTimeCtrl.Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD, rect, this, IDC_MYTIMECTRL);
pWnd->ShowWindow(SW_HIDE);
//...
return TRUE;
}
编译并运行程序,在选择时间Button点击事件响应函数中,调用控件类的SetTime方法设置初始时间(可省略),再弹出时间选择对话框菜单,最后在控件类的DateTimeCtrlChanged事件响应函数中获取当前时间并显示到Static Text上。
完整代码如下:
YourDialog.h:
#pragma once
#include "MyTime.h"
class CYourDialog : public CDialogEx
{
public:
CYourDialog(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CYourDialog();
//{{AFX_DATA(CYourDialog)
enum { IDD = IDD_YOURDIALOG };
//}}AFX_DATA
protected:
// 控件成员变量声明
CMyTimeCtrl m_MyTimeCtrl; // 时间控件
// 控件消息映射声明
afx_msg void OnMyTimeCtrlChanged(NMHDR* pNMHDR, LRESULT* pResult);
//{{AFX_MSG(CYourDialog)
virtual BOOL OnInitDialog();
afx_msg void OnBnClickedButtonSelectTime();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
YourDialog.cpp:
#include "stdafx.h"
#include "YourDialog.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CYourDialog::CYourDialog(CWnd* pParent)
: CDialogEx(IDD_YOURDIALOG, pParent)
{
//...
}
CYourDialog::~CYourDialog()
{
//...
}
void CYourDialog::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
//...
}
BEGIN_MESSAGE_MAP(CYourDialog, CDialogEx)
// 控件消息映射定义
ON_NOTIFY(MTN_TIME_CHANGED, IDC_MYTIMECTRL, OnMyTimeCtrlChanged)
//{{AFX_MSG_MAP(CYourDialog)
ON_BN_CLICKED(IDC_BUTTON_SELECT_TIME, &CYourDialog::OnBnClickedButtonSelectTime)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CYourDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 创建MyTimeCtrl
CWnd* pWnd = GetDlgItem(IDC_DATETIMEPICKER);
CRect rect;
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect);
m_MyTimeCtrl.Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD, rect, this, IDC_MYTIMECTRL);
pWnd->ShowWindow(SW_HIDE);
//...
return TRUE;
}
// 控件消息响应函数定义
void CYourDialog::OnMyTimeCtrlChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
SYSTEMTIME st = { 0 };
m_MyTimeCtrl.GetSystemTime(&st);
CString strTime;
strTime.Format(_T("%d-%02d-%02d %02d:%02d:%02d.%03d"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
GetDlgItem(IDC_STATIC_SHOWTIME)->SetWindowText(strTime);
*pResult = 0;
}
// Button的OnClick事件响应函数定义
void CYourDialog::OnBnClickedButtonSelectTime()
{
SYSTEMTIME stCurrent = { 0 };
GetDlgItem(IDC_DATETIMEPICKER)->GetSystemTime(&stCurrent);
m_MyTimeCtrl.SetTime(&stCurrent);
m_MyTimeCtrl.PopupDateOrTimeMenu(TRUE);
}
在这个示例中,控件类使用NMHDR和LRESULT时间控制通知消息,生成事件响应函数OnMyTimeCtrlChanged,GetSystemTime功能用于获取当前选择的时间,格式化显示在Static Text上。
这应该可以帮助你开始使用这个控件类了。
如果我的回答解决了您的问题,请采纳!