MFC控件的使用
MFC是什么
Windows 下的应用程序开发框架.
MFC现在无法提供一个完善的界面, 但是可以提供一个可用的界面.
MFC足够简单.
MFC是一种经典.
MFC编程注意事项
在MFC编程中, 控件的ID属性是十分重要的. 一定要起一个规范的, 简单易懂的 ID.
无论是Win32编程还是MFC编程, 在Windows下, 核心的机制就是消息机制
在使用的控件比较频繁的时候, 建议以添加变量的方式来进行控件的操作
当对控件的使用不频繁的时候, 可以直接用 GetDlgItem 方法
Edit Control
编辑框控件
有几个需要注意的属性:
Multiline
- 多行
Want Return
- 配合 Multiline, 能够接收回车
Vertoocal Scroll
- 垂直滚动条
Auto VScroll
- 自动垂直滚动条
Horizontal Scroll
- 水平滚动条
Auto HScroll
- 自动水平滚动条
Button Control
按钮控件
Caption 属性是按钮上显示的文本- ID 记得一定要取一个 语义明确的 ID
- 双击可以自动添加事件
Static Control
静态文本控件
- 主要起到一些提示性的作用
- 对于静态文本, 基本上不会存在什么操作
Caption 属性是需要显示在静态文本上的信息
// Edit, Button, Static综合示例
// 双击按钮, 添加的事件
void CEditDemoDlg::OnBnClickedBtnCount()
{
// TODO: 在此添加控件通知处理程序代码
CString szInput;
// 获得 Edit 中的内容, 并判断字数
if (0 == GetDlgItemTextW(IDC_EDT_INPUT, szInput))
{
// 将文本设置到 ID为 IDC_STATIC_OUTPUT 的控件上, 在这里就是 Static
SetDlgItemTextW(IDC_STATIC_OUTPUT, L"获取统计资料失败!");
return;
}
CString szOutput;
szOutput.Format(L"%d", szInput.GetLength());
SetDlgItemTextW(IDC_STATIC_OUTPUT, szOutput);
}Check Box Control
多选框控件
Caption 属性设置显示的文本使用 GetCheck() 方法获取选中状态
- ((CButton*)GetDlgItem(IDC_CHK_RED))->GetCheck();
Radio Button Control
单选按钮控件
Caption 属性设置显示的文本使用 GetCheck() 方法获取选中状态
- ((CButton*)GetDlgItem(IDC_RADIO_RECT))->GetCheck();
Combo Box Control
组合框控件
Type 属性- 规定了 ComboBox 控件的样式
- Dropdown 可下拉, 可编辑
- Simple 简单模式
- 下拉列表 可下拉, 不可编辑
Sort 属性- 排序
Data 属性- 初始化的数据
- 格式: 1;3;5;7;9;
List Box Control
列表框控件
Sort 属性- 排序
MultiColumn 属性- 多列显示
Selection
- 选择时的样式
// ListBox和ComboBox的添加和删除数据
// 添加数据
void CComboBoxDemoDlg::OnBnClickedBtnAdd()
{
// TODO: 在此添加控件通知处理程序代码
CString szInput;
// 获取文本框里的值 当做数据添加
if (0 != GetDlgItemTextW(IDC_EDT_INPUT, szInput))
{
int nIndex = m_cbDemo.AddString(szInput);
m_cbDemo.SetCurSel(nIndex);
nIndex = m_lstDemo.AddString(szInput);
m_lstDemo.SetCurSel(nIndex);
SetDlgItemTextW(IDC_EDT_INPUT, L"");
GetDlgItem(IDC_EDT_INPUT)->SetFocus();
}
}
// 删除数据
void CComboBoxDemoDlg::OnBnClickedBtnDel()
{
// TODO: 在此添加控件通知处理程序代码
int nIndex = m_cbDemo.GetCurSel();
if (nIndex > -1)
{
m_cbDemo.DeleteString(nIndex);
if (nIndex < m_cbDemo.GetCount())
m_cbDemo.SetCurSel(nIndex);
else
m_cbDemo.SetCurSel(0);
}
else
{
MessageBoxW(L"下拉框未选中待删除的项!", L"花心胡萝卜工作室提示", MB_OK | MB_ICONINFORMATION);
}
nIndex = m_lstDemo.GetCurSel();
if (nIndex > -1)
{
m_lstDemo.DeleteString(nIndex);
if (nIndex < m_lstDemo.GetCount())
m_lstDemo.SetCurSel(nIndex);
else
m_lstDemo.SetCurSel(0);
}
else
{
MessageBoxW(L"列表未选中待删除的项!", L"花心胡萝卜工作室提示", MB_OK | MB_ICONINFORMATION);
}
}
ScrollBar Control
滚动条控件
- 横向
- 纵向
默认添加的滚动条控件, 不写任何代码, 是不能使用的. 要使用滚动条, 必须进行代码编写实现.
必须响应 WM_HSCROLL 或者 WM_VSCROLL 消息
滚动条有一系列内部的行为的命令定义代码, 比如:
SB_THUMBTRACK
- 拖动滚动条
SB_LINELEFT
- 左边的按钮被点击
SB_LINERIGHT
- 右边的按钮被点击
SB_PAGELEFT
- 点击左翻页
SB_PAGERIGHT
- 点击右翻页
- ....
- 大家可以按下
转到定义进行查看.
// 水平滚动条使用的例子
BOOL CScrollBarDemoDlg::OnInitDialog()
{
// .....省略无关代码
// TODO: 在此添加额外的初始化代码
SCROLLINFO scrollInfo = { 0 };
scrollInfo.cbSize = sizeof(SCROLLINFO);
// 表示滚动条需要有 滚动范围, 可以按页滚动
scrollInfo.fMask = SIF_RANGE | SIF_PAGE;
// 设置范围
scrollInfo.nMax = 100;
scrollInfo.nMin = 0;
// 按页滚动的大小
scrollInfo.nPage = 10;
// m_hScrollBar是一个SCROLLBAR控件的变量
m_hScrollBar.SetScrollInfo(&scrollInfo);
// .....省略无关代码
}
void CScrollBarDemoDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
SCROLLINFO scrollInfo = { 0 };
scrollInfo.cbSize = sizeof(SCROLLINFO);
scrollInfo.fMask = SIF_ALL;
pScrollBar->GetScrollInfo(&scrollInfo);
int nNewPos = scrollInfo.nPos;
switch (nSBCode)
{
case SB_THUMBTRACK: // 用户拖动滚动消息
nNewPos = nPos;
break;
case SB_LINELEFT: // 左边的按钮被按下
nNewPos -= 1;
break;
case SB_LINERIGHT: // 右边的按钮被按下
nNewPos += 1;
break;
case SB_PAGELEFT: // 左翻页
nNewPos -= scrollInfo.nPage;
break;
case SB_PAGERIGHT: // 右翻页
nNewPos += scrollInfo.nPage;
break;
default:
break;
}
if (nNewPos > scrollInfo.nMax)
nNewPos = scrollInfo.nMax;
if (nNewPos < scrollInfo.nMin)
nNewPos = scrollInfo.nMin;
scrollInfo.nPos = nNewPos;
pScrollBar->SetScrollInfo(&scrollInfo);
CString szPos;
szPos.Format(L"滚动条当前位置:%d", nNewPos);
SetDlgItemTextW(IDC_STATIC_POS, szPos);
CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}Spin Control
数值控件, 必须与其他控件组合使用, 一般都与Edit控件一起使用
使用步骤
- 首先在界面上拖放一个 Edit Control
- 然后在拖动一个 Spin Control
设置 Spin Control 的
Auto Buddy属性为TRUE- 注意, 这是
按照Z顺序选择上一个控件作为数值调节按钮控件的合作者窗口 - 所以才先拖放 Edit Control
- 注意, 这是
- 设置 Spin Control 的
Set Buddy Integer属性为TRUE - 运行, 看看效果
- 没放到一起 想要更美观?
- 设置 Spin Control 的
Alignment属性为Left或者Right后在试试~~
代码调整
BOOL CSpinDemoDlg::OnInitDialog()
{
// ... 省略无关代码
// TODO: 在此添加额外的初始化代码
// 获取Spin的一个控件
CSpinButtonCtrl* pSpinDec = (CSpinButtonCtrl*)GetDlgItem(IDC_SPIN_DEC);
// 设置范围
pSpinDec->SetRange32(0, 100);
CSpinButtonCtrl* pSpinHex = (CSpinButtonCtrl*)GetDlgItem(IDC_SPIN_HEX);
pSpinHex->SetRange32(0, 100);
// 设置16进制
pSpinHex->SetBase(16);
// ... 省略无关代码
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}Progress Control
进度条控件
// 进度条的应用
// 使用 Timer 进行进度条的进度走动
BOOL CProgressDemoDlg::OnInitDialog()
{
// ... 省略无关代码
// TODO: 在此添加额外的初始化代码
m_progressBar.SetRange32(0, 100);
m_progressBar.SetStep(1);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 开始按钮 1
void CProgressDemoDlg::OnBnClickedBtnBegin()
{
// TODO: 在此添加控件通知处理程序代码
m_progressBar.SetPos(0);
SetTimer(1, 100, nullptr);
GetDlgItem(IDC_BTN_BEGIN)->EnableWindow(FALSE);
GetDlgItem(IDC_BTN_START)->EnableWindow(FALSE);
}
// 开始按钮 2
void CProgressDemoDlg::OnBnClickedBtnStart()
{
// TODO: 在此添加控件通知处理程序代码
m_progressBar.SetPos(0);
SetTimer(2, 100, nullptr);
GetDlgItem(IDC_BTN_BEGIN)->EnableWindow(FALSE);
GetDlgItem(IDC_BTN_START)->EnableWindow(FALSE);
}
void CProgressDemoDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
switch (nIDEvent)
{
case 1:
{
//方法1
int nMin, nMax, nPos;
m_progressBar.GetRange(nMin, nMax);
nPos = m_progressBar.GetPos();
++nPos;
if (nPos > nMax)
{
KillTimer(1);
GetDlgItem(IDC_BTN_BEGIN)->EnableWindow();
GetDlgItem(IDC_BTN_START)->EnableWindow();
}
m_progressBar.SetPos(nPos);
break;
}
case 2:
{
// 方法2
int nMin, nMax, nPos;
m_progressBar.GetRange(nMin, nMax);
nPos = m_progressBar.StepIt();
if (nPos + 1 >= nMax)
{
GetDlgItem(IDC_BTN_BEGIN)->EnableWindow();
GetDlgItem(IDC_BTN_START)->EnableWindow();
KillTimer(2);
}
break;
}
default:
break;
}
CDialogEx::OnTimer(nIDEvent);
}
Slider Control
滑块控件
Orientation 属性来控制滑动方向- Vertical 垂直滑动
- Horizontal 水平滑动
- 使用
SetRange(0, 100);函数设置范围 - 它也会响应
WM_HSCROLL或者WM_VSCROLL消息
// 使用示例
// 横向滑块的消息响应
void CSliderDemoDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
int nNowPos = m_hSlider.GetPos();
CString szInfo;
szInfo.Format(L"当前水平滑块位置为:[%d]", nNowPos);
SetDlgItemTextW(IDC_STATIC_INFO, szInfo);
CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}
// 纵向滑块的消息响应
void CSliderDemoDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
int nNowPos = m_vSlider.GetPos();
CString szInfo;
szInfo.Format(L"当前垂直滑块位置为:[%d]", nNowPos);
SetDlgItemTextW(IDC_STATIC_INFO, szInfo);
CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar);
}HotKey Control
热键控件, 可以自动获取按下的键
- 可以使用
GetHotKey函数来进行获取按下的键
// 热键控件使用示例
void CHotKeyDemoDlg::OnBnClickedBtnSetHotkey()
{
// TODO: 将HotKey控件中按下的热键注册到系统中
WORD wVK, wMod;
m_hotkey.GetHotKey(wVK, wMod);
if (RegisterHotKey(m_hWnd, 1, wMod, wVK))
{
ShowWindow(SW_HIDE);
}
else
{
MessageBoxW(L"热键注册失败!", L"花心胡萝卜工作室提示", MB_OK | MB_ICONINFORMATION);
}
}
void CHotKeyDemoDlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
// TODO: 响应热键消息
switch (nHotKeyId)
{
case 1:
ShowWindow(SW_SHOW);
// 不需要使用了 就反注册
UnregisterHotKey(m_hWnd, 1);
break;
default:
break;
}
CDialogEx::OnHotKey(nHotKeyId, nKey1, nKey2);
}
List Control
列表控件, 注意, 不是 ListBox, 是List
View 属性控制显示的样式- List 列表形式(无表头)
- Report 详细形式(有表头)
- Icon 大图标形式
- Small Icon 小图标形式
Sort 属性排序
// 使用示例
// m_list 为 List Control 的添加变量
// 头文件中声明变量 CImageList m_imageList;
BOOL CListCtrlDemoDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// ... 省略无关代码
// TODO: 在此添加额外的初始化代码
// 设置风格
//LONG lStyle;
//lStyle = GetWindowLong(m_list.m_hWnd, GWL_STYLE);//获取当前窗口style
//lStyle &= ~LVS_TYPEMASK; //清除显示方式位
//lStyle |= LVS_REPORT; //设置style
//SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle);//设置style
// 设置扩展风格
//DWORD dwStyle = m_list.GetExtendedStyle();
//dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl)
//dwStyle |= LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl)
//dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件
//m_list.SetExtendedStyle(dwStyle); //设置扩展风格
// 整行选中 + 网格线 + 跟踪选中
m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_TRACKSELECT);
// 初始化列
// 由于第一列不会对齐 所以先随意插入一列 然后在干掉
m_list.InsertColumn(0, L"", LVCFMT_CENTER, 0);
m_list.InsertColumn(1, L"第一列", LVCFMT_CENTER, 150);
m_list.InsertColumn(2, L"第二列", LVCFMT_CENTER, 150);
m_list.DeleteColumn(0);
// 初始化图标组
m_imageList.Create(32, 32, ILC_COLOR32, 1, 1);
m_imageList.Add(m_hIcon);
// 设置小图标组
m_list.SetImageList(&m_imageList, LVSIL_SMALL);
// 设置大图标组
m_list.SetImageList(&m_imageList, LVSIL_NORMAL);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 往 List Control 中添加行
void CListCtrlDemoDlg::OnBnClickedBtnAdd()
{
// TODO: 在此添加控件通知处理程序代码
int nCount = m_list.GetItemCount();
int nTmp = 1;
// 进行列表行的插入
CString szBuf;
// 第一列的设置
szBuf.Format(L"第 %d 行的第 %d 列", nCount + 1, nTmp++);
m_list.InsertItem(nCount, szBuf, 0);
// 第二列的设置
szBuf.Format(L"第 %d 行的第 %d 列", nCount + 1, nTmp++);
m_list.SetItemText(nCount, 1, szBuf);
}
// 从 List Control 中删除当前选中的行
void CListCtrlDemoDlg::OnBnClickedBtnDel()
{
// TODO: 在此添加控件通知处理程序代码
// 方式1
//int nCount = m_list.GetItemCount();
//for (int i = nCount - 1; i >=0; --i)
//{
// if (m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED)
// {
// m_list.DeleteItem(i);
// break;
// }
//}
//方法二:
POSITION pos = m_list.GetFirstSelectedItemPosition();
if (pos != NULL)
{
//while (pos)
//{
// int nItem = m_list.GetNextSelectedItem(pos);
// m_list.DeleteItem(nItem);
// break;
//}
int nItem = m_list.GetNextSelectedItem(pos);
m_list.DeleteItem(nItem);
}
}
// 动态改变 List Control 的视图样式
void CListCtrlDemoDlg::OnSelchangeComboListMode()
{
// TODO: 在此添加控件通知处理程序代码
CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_LIST_MODE);
DWORD dwStyle = 0;
switch (pCombo->GetCurSel())
{
case 0: // 大图标
dwStyle = LVS_ICON;
break;
case 1: // 小图标
dwStyle = LVS_SMALLICON;
break;
case 2: // 列表
dwStyle = LVS_LIST;
break;
case 3: // 详细信息
dwStyle = LVS_REPORT;
break;
default:
break;
}
m_list.ModifyStyle(LVS_TYPEMASK, dwStyle);
}
Tree Control
树形控件
// 树形控件的使用示例
// m_tree 是 Tree Control 的添加变量
void CTreeCtrlDemoDlg::OnBnClickedBtnAdd()
{
// TODO: 新增数据到Tree
CString szInput;
GetDlgItemTextW(IDC_EDIT_INPUT, szInput);
HTREEITEM hItem = m_tree.GetSelectedItem();
if (!hItem)
hItem = TVI_ROOT;
TVINSERTSTRUCTW ts = { 0 };
ts.hParent = hItem;
// 可以用如下方式来搞一搞, CString重载了LPCTSTR的转换
ts.item.pszText = (LPWSTR)(LPCTSTR)szInput;
ts.item.mask = TVIF_TEXT;
ts.hInsertAfter = TVI_LAST;
HTREEITEM hNewItem = m_tree.InsertItem(&ts);
m_tree.SelectItem(hNewItem);
// 保证新添加的可以显示
m_tree.EnsureVisible(hNewItem);
}
void CTreeCtrlDemoDlg::OnBnClickedBtnDel()
{
// TODO: 删除Tree中选中的节点
HTREEITEM hItem = m_tree.GetSelectedItem();
if (!hItem)
return;
HTREEITEM hParentItem = m_tree.GetParentItem(hItem);
m_tree.DeleteItem(hItem);
m_tree.SelectItem(hParentItem);
}
void CTreeCtrlDemoDlg::OnBnClickedBtnModify()
{
// TODO: 修改Tree中选中的节点
HTREEITEM hItem = m_tree.GetSelectedItem();
if (hItem)
{
CString szInput;
GetDlgItemTextW(IDC_EDIT_INPUT, szInput);
m_tree.SetItemText(hItem, szInput);
}
}
void CTreeCtrlDemoDlg::OnSelchangedTree(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: 点击Tree节点之后的事件
HTREEITEM hItem = m_tree.GetSelectedItem();
if (hItem)
{
CString szInput = m_tree.GetItemText(hItem);
SetDlgItemTextW(IDC_EDIT_INPUT, szInput);
}
*pResult = 0;
}RichEdit Control
富文本框控件
可以为文本附加额外的格式.
Multiline
- 多行
Want Return
- 配合 Multiline, 能够接收回车
Vertoocal Scroll
- 垂直滚动条
Auto VScroll
- 自动垂直滚动条
Horizontal Scroll
- 水平滚动条
Auto HScroll
- 自动水平滚动条
注意, 要使用 RichEdit 控件, 必须在 InitInstance() 方法中调用 AfxInitRichEdit2() 方法.
// RichEdit Control 使用示例
// m_richEdit是RichEdit的添加变量
void CRichEditDemoDlg::OnBnClickedBtnColor()
{
// TODO: 设置RichEdit的文字颜色
CHARFORMAT cf = { 0 };
cf.cbSize = sizeof(CHARFORMAT);
m_richEdit.GetSelectionCharFormat(cf);
CColorDialog colorDlg(cf.crTextColor);
if (colorDlg.DoModal() == IDOK)
{
cf.crTextColor = colorDlg.GetColor();
cf.dwMask = CFM_COLOR;
cf.dwEffects = 0;
m_richEdit.SetSelectionCharFormat(cf);
}
}
void CRichEditDemoDlg::OnBnClickedBtnFont()
{
// TODO: 设置RichEdit的文字字体
CHARFORMAT cf = { 0 };
cf.cbSize = sizeof(CHARFORMAT);
m_richEdit.GetSelectionCharFormat(cf);
CFontDialog fontDlg(cf);
if (fontDlg.DoModal() == IDOK)
{
fontDlg.GetCharFormat(cf);
m_richEdit.SetSelectionCharFormat(cf);
}
}
Tab Control
选项卡控件
需要使用 Dialog 来填充 Tab 页
- 在 Dialog 中设计好之后, 就可以添加到 Tab 中了
- 需要注意的是, Dialog 的 Style 必须是 Child
- Dialog 的 Frame 需要是 None
- Dialog 必须生成对应的 类
// Tab使用示例
// m_tab 为 Tab 的添加变量
// m_dlgPage1 和 m_dlgPage2 是自己新建的 Dialog 的对应的类
BOOL CTabCtrlDemoDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// ... 省略无关代码
// TODO: 在此添加额外的初始化代码
m_tab.InsertItem(0, L"第一页");
m_tab.InsertItem(1, L"第二页");
// 创建标签页
m_dlgPage1.Create(MAKEINTRESOURCE(IDD_DIALOG_PAGE1), &m_tab);
m_dlgPage2.Create(MAKEINTRESOURCE(IDD_DIALOG_PAGE2), &m_tab);
// 设置标签页
CRect rect;
m_tab.GetClientRect(rect);
// 进行一点处理
rect.top += 25;
// 设置标签页的大小
m_dlgPage1.MoveWindow(rect);
m_dlgPage2.MoveWindow(rect);
// 显示一个标签页
m_dlgPage1.ShowWindow(SW_SHOW);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CTabCtrlDemoDlg::OnSelchangeTabMain(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 选项卡标签页切换
switch (m_tab.GetCurSel())
{
// 可以搞个enum
case 0:
m_dlgPage1.ShowWindow(SW_SHOW);
m_dlgPage2.ShowWindow(SW_HIDE);
break;
case 1:
m_dlgPage2.ShowWindow(SW_SHOW);
m_dlgPage1.ShowWindow(SW_HIDE);
break;
default:
break;
}
*pResult = 0;
}
Animate Control
动画控件
播放的文件为 .avi 格式
- 不是普通的 avi 文件, 是专门的avi文件
- 比如它没有声音
- 比如 Windows 资源管理器在复制文件的时候出现的那个动画
// 示例
// 打开文件
void CAnimateDemoDlg::OnBnClickedBtnSel()
{
// TODO: 在此添加控件通知处理程序代码
CFileDialog dlgFile(TRUE, NULL, NULL, OFN_FILEMUSTEXIST, L"*.avi|*.avi|*.*|*.*", this);
if (dlgFile.DoModal() == IDOK)
{
SetDlgItemTextW(IDC_EDIT_FILEPATH, dlgFile.GetPathName());
}
}
// 播放文件
void CAnimateDemoDlg::OnBnClickedBtnPlay()
{
// TODO: 在此添加控件通知处理程序代码
CString szPath;
GetDlgItemTextW(IDC_EDIT_FILEPATH, szPath);
if (m_animate.Open(szPath))
{
m_animate.Play(0, -1, -1);
}
else
{
MessageBoxW(L"打开文件失败!", L"花心胡萝卜工作室", MB_OK | MB_ICONERROR);
}
}DateTime Control
日期选择控件
// 使用示例
BOOL CDataTimeDemoDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// ... 省略无关代码
// TODO: 在此添加额外的初始化代码
// 设置显示格式
m_dateCtrlBegin.SetFormat(L"yyyy-MM-dd HH:mm:ss");
m_dateCtrlEnd.SetFormat(L"yyyy-MM-dd HH:mm:ss");
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 计算日期时间之间的间隔
void CDataTimeDemoDlg::SpanCount()
{
SYSTEMTIME timeBegin = { 0 };
SYSTEMTIME timeEnd = { 0 };
// 获取当前控件时间
m_dateCtrlBegin.GetTime(&timeBegin);
// 获取另外的一个时间
m_dateCtrlEnd.GetTime(&timeEnd);
// 计算时间差
FILETIME ftBegin, ftEnd;
SystemTimeToFileTime(&timeBegin, &ftBegin);
SystemTimeToFileTime(&timeEnd, &ftEnd);
ULARGE_INTEGER uBegin, uEnd;
uBegin.u.HighPart = ftBegin.dwHighDateTime;
uBegin.u.LowPart = ftBegin.dwLowDateTime;
uEnd.u.HighPart = ftEnd.dwHighDateTime;
uEnd.u.LowPart = ftEnd.dwLowDateTime;
ULONGLONG ullSpan = uEnd.QuadPart >= uBegin.QuadPart
? uEnd.QuadPart - uBegin.QuadPart
: uBegin.QuadPart - uEnd.QuadPart;
ULONGLONG ullSeconds = ullSpan / 10000000; // 转换到秒
ULONGLONG nMins = ullSeconds / 60;
int nHours = nMins / 60;
int nDays = nHours / 24;
//WCHAR szBuf[MAXBYTE] = { 0 };
//wsprintf(szBuf, L"两个时间间隔: \r\n秒数: %ull, \r\n分钟数: %d, \r\n小时数: %d, \r\n天数: %d",
// ullSeconds, nMins, nHours, nDays);
//CString szOutput(szBuf);
CString szOutput;
szOutput.Format(L"两个时间间隔: \r\n秒数: %d, \r\n分钟数: %d, \r\n小时数: %d, \r\n天数: %d",
(int)ullSeconds, (int)nMins, nHours, nDays);
SetDlgItemTextW(IDC_EDIT_OUTPUT, szOutput);
}
// DateTime控件的选择事件
void CDataTimeDemoDlg::OnDatetimechangeDatetimepickerBegin(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMDATETIMECHANGE pDTChange = reinterpret_cast<LPNMDATETIMECHANGE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
SpanCount();
*pResult = 0;
}
// DateTime控件的选择事件
void CDataTimeDemoDlg::OnDatetimechangeDatetimepickerEnd(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMDATETIMECHANGE pDTChange = reinterpret_cast<LPNMDATETIMECHANGE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
SpanCount();
*pResult = 0;
}
Calendar Control
日历控件
// 使用示例
void CCalendarDemoDlg::OnSelchangeMonthcalendar(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMSELCHANGE pSelChange = reinterpret_cast<LPNMSELCHANGE>(pNMHDR);
// TODO: 点击日期的时候的处理
SYSTEMTIME st = { 0 };
m_calendar.GetCurSel(&st);
CTime time(st);
int nDayOfWeek = time.GetDayOfWeek();
CString szOutput;
szOutput.Format(L"%d年%d月%d日, 是星期 %d. \r\n星期 0是星期日的意思.", st.wYear, st.wMonth, st.wDay, nDayOfWeek - 1);
SetDlgItemTextW(IDC_STATIC_OUTPUT, szOutput);
*pResult = 0;
}
完整工程下载
以上控件的所有工程测试代码, 点我下载
一个可被 Animate控件播放的 AVI文件, 点我下载
工程说明:
- VS2017环境
- 如果会用低版本VS, 需要修改编译工具集版本
解压密码为: 【http://www.hxhlb.net】
- 不包括中括号哦
如有错误,请提出指正!谢谢.
本文由 花心胡萝卜 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: 2017-05-02 at 03:16 pm