isual c++ 提 供 了 功 能 强 大 的 类 库, 基 本 上 应 用 开 发 的 要 求, 但 对 于 某 些 特 殊 要 求 的 界 面, 如 图 像 兼 文 字 的 按 纽, 列 表 框 中 插 入 图 像, 中 国 式 报 表 等 等, 仍 显 得 力 不 从 心, 因 而 很 有 必 要 创 建 扩 展MFC 类 库, 以 满 足 实 际 开 发 的 需 求。But,Toolkit Pro 是MFC开发中最全面界面控件套包,它提供了Windows开发所需要的11种主流的Visual C++ MFC控件。 根据需要可进行下载体验!
本文通过实例说明MFC工具栏的创建、设计和使用方法,包括三个demo。
demo1:创建一个工具栏
C++代码
//摘抄自MSDN
demo1 (创建一个工具栏)
1.Create a toolbar resource.
/*可以先插入一个新的工具栏资源
添加分隔符,将按钮向右拖动一小下
删除按钮,将按钮拖动出工具栏
*/
2.Construct the CToolBar object.
/*
工具栏是 CToolBar 对象,声明为应用程序的 CMainFrame 类的数据成员。也就是说,工具栏对象嵌入到主框架窗口对象中。这意味着 MFC 在创建框架窗口时创建工具栏,在销毁框架窗口时销毁工具栏。
*/
3.Call the Create (or CreateEx) function to create
the Windows toolbar and attach it to the CToolBar object.
4.Call LoadToolBar to load the toolbar resource.
/*
工具栏创建发生在 CMainFrame::OnCreate 中。MFC 在创建框架窗口之后且在窗口可见之前调用 OnCreate。
在 OnCreate 中调用适当的函数来停靠或浮动工具栏、设置它的样式等。
应用程序向导”生成的默认 OnCreate 执行以下工具栏任务:
1.调用 CToolBar 对象的 Create 成员函数来创建基础 CToolBarCtrl 对象。
2.调用 LoadToolBar 来加载工具栏资源信息。
3.调用函数来启用停靠、浮动和工具提示。
*/
class CMainFrame : public CMDIFrameWnd
{
// ...
// Implementation
// ...
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
// Generated message map functions
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP()
};
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
return -1;
//框架类中m_wndMyToolBar成员变量先调用CreateEx函数,再调用LoadToolBar函数
if (! m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
! m_wndToolBar.LoadToolBar(IDR_MYTOOLBAR))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
//调用CToolBar中的成员函数设置工具栏可停靠的位置
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
//调用框架类中的成员函数设置哪里可以被停靠
EnableDocking(CBRS_ALIGN_ANY);
//Points to the control bar to be docked.
DockControlBar(&m_wndToolBar);
return 0;
}
demo2:停靠和浮动工具栏
C++代码
demo2 (停靠和浮动工具栏)
/*
如果使用“应用程序向导”来生成应用程序的主干,向导将要求您选择是否想要可停靠的工具栏。
默认情况下,“应用程序向导”生成代码来执行将可停靠工具栏放置在应用程序中所需的三个操作:
1.在框架窗口中启用停靠。
2.为工具栏启用停靠。
3.停靠工具栏(靠向框架窗口)。
如果这些步骤中的任何一个缺少,应用程序都将显示标准工具栏。
后两个步骤对应用程序中的每一个可停靠工具栏都必须执行。
*/
CFrameWnd::EnableDocking()//在框架窗口中启用停靠
/*
若要将工具栏停靠到某个框架窗口,则必须启用该框架窗口(或目标)以允许停靠。
这可通过使用 CFrameWnd::EnableDocking 函数来实现,该函数采用一个 DWORD 参数,这是一组指示框架窗口的哪一个边接受停靠的样式位。
如果一个工具栏即将停靠并且有多个边可以停靠,则在传递给 EnableDocking 的参数中指示的边按以下顺序使用:顶边、底边、左边、右边。
如果希望能够将控制条停靠在任意位置,请将 CBRS_ALIGN_ANY 传递给 EnableDocking。
*/
CControlBar::EnableDocking()//为工具栏启用停靠
/*
准备好停靠目标后,必须以相似的方式准备工具栏(或源)。为想要停靠的每一个工具栏调用 CControlBar::EnableDocking,指定工具栏应停靠的目标边。如果在 CControlBar::EnableDocking 调用中所指定的边没有一个与框架窗口中为停靠启用的边匹配,则工具栏无法停靠(它将浮动)。
工具栏一旦浮动,将保持为浮动工具栏,不能停靠到框架窗口。
如果希望工具栏永久浮动,请调用参数为 0 的 EnableDocking。然后调用 CFrameWnd::FloatControlBar。工具栏将保持浮动,永远不能在任意位置停靠。
*/
CFrameWnd::DockControlBar()//停靠工具栏
/*
当用户试图将工具栏放置在允许停靠的框架窗口某一边时,框架调用 CFrameWnd::DockControlBar。
另外,可以随时调用该函数将控制条停靠在框架窗口中。这通常在初始化过程中完成。
框架窗口的具体某个边上可停靠多个工具栏。
*/
CFrameWnd::FloatControlBar()//浮动工具栏
/*
从框架窗口分离可停靠工具栏称为浮动工具栏。调用 CFrameWnd::FloatControlBar 来执行该操作。指定要浮动的工具栏、将放置的点以及决定浮动工具栏是水平还是垂直的对齐样式。
当用户拖动工具栏离开停靠位置并将它放置在一个未启用停靠的位置时,框架调用该函数。
这可以是框架窗口的内部或外部的任意位置。同 DockControlBar 一样,也可以在初始化过程中调用该函数。
可停靠工具栏的 MFC 实现不提供一些支持可停靠工具栏的应用程序中有的扩展功能。诸如可自定义工具栏这样的功能不提供。
*/
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
//...
//部分代码略
//...
//调用CToolBar中的成员函数设置工具栏可停靠的位置
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
//调用框架类中的成员函数设置哪里可以被停靠
EnableDocking(CBRS_ALIGN_ANY);
//Points to the control bar to be docked.
DockControlBar(&m_wndToolBar);
return 0;
}
demo3:点击菜单项显示和隐藏工具栏
C++代码
demo3 (点击菜单项显示和隐藏工具栏)
CFrameWnd::ShowControlBar//显示和隐藏菜单项
void ShowControlBar( CControlBar* pBar, BOOL bShow, BOOL bDelay );
void CMainFrame::OnViewNewtool()
{
ShowControlBar(&m_newToolBar,!m_newToolBar.IsWindowVisible(),FALSE);//控制显示和隐藏
}
void CMainFrame::OnUpdateViewNewtool(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_newToolBar.IsWindowVisible());//为菜单项打标记
}
MFC扩展类库
在平时练习的时候我们可以自己手动进行,但是一旦接受一些项目,应用程序开发等,对界面的要求就会高出许多。这时候就有必要借助这些“半成品”实现界面美化提升效率。这里简单介绍一下,具体可点进去查看每个的详情以及教程,案例!
Toolkit Pro:
Codejock软件公司的Xtreme Toolkit Pro是屡获殊荣的VC界面库,是MFC开发中最全面界面控件套包,它提供了Windows开发所需要的11种主流的Visual C++ MFC控件,包括Command Bars、Controls、Chart Pro、Calendar、Docking Pane、Property Grid、Report Control、Shortcut Bar、Syntax Edit、Skin Framework 和Task Panel。
BCGControlBar ("Business Components Gallery ControlBar")是MFC扩展库,使您可以创建具有完全自定义选项(功能区、可自定义工具栏、菜单等)以及一组专业设计的丰富Microsoft Office和Microsoft Visual Studio的应用程序 GUI控件,例如图表、日历、网格、编辑器、甘特图和许多其他控件。
BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。可以轻松地集成到你的应用程序中,并为你节省数百个开发和调试时间。
转载自:http://www.jizhuomi.com/software/494.html
关注我或者点击下方“了解更多”获取一手开发资讯哦!
Windows标准控件:
windows标准控件由Windows 操作系统提供,在Windows 95中还提供了一些新增的控件。所有这些控件对象都是可编程的,我们可以使用Visual C++提供的对话框编辑器把它们添加到对话框中。Microsoft基础类库(MFC)提供了封装这些控件的类,它们列于表6.1。
在MFC 中,类CWnd是所有窗口类的基类,很自然的,它也是所控件类的基类。
Windows标准控件在以下环境下提供:
windows 95
Windows NT 3.51及以后版本
win32s 1.3
注意:visual C++4.2及以后版本不再支持Win32s.
VC++控件工具箱:
用来接收用户的命令,应用程序在接收到用户命令后,通常需要进行一些后台工作。按钮可以响应单击或双击动作,在按钮接收到鼠标动作后,向其父窗口发送相应的控件通知,用户可以对这些控件通知进行消息映射,从而进行相应的处理。
在一个对话框中,可以定义一个默认按钮,这只要选中按钮属性中的“Default”选项。如果在对话框活动的时候按下了Enter键,则等同于单击了默认按钮。MFC提供了CButton类支持按钮控件。
用来显示某种可能的选择,该项选择是独立的,用户可以选中或取消该选项。在选项被选中的时候核选标记出现,选项被取消时核选标记消失。MFC中由CButton类对核选框进行支持,用户可以通过SetCheck()函数和GetCheck()函数设置或获取核选框当前的状态。
BST_UNCHECKED==((CButton*)GetDlgItem(IDC_CHECK_RES1))->GetCheck()
((CButton*)GetDlgItem(IDC_CHECK_RES1))->SetCheck(true);
用来接收用户输入的字符串。通过选择编辑框的选项,编辑框可以接收字符串、数字、密码等;编辑框还可以设置成接收多行字符串的模式;可以自动进行大小写转换。编辑框可能向父窗口发送多种控件通知,如果用户需要,可以对这些控件通知进行处理。MFC提供了CEdit类支持编辑框控件。
GetDlgItem(IDC_***)->SetWindowText(Cstring);
GetDlgItem(IDC_***)->GetWindowText(Cstring);
列表框和编辑框的组合,用户除了可以在列表中对已经存在的选项进行选择外,还可以输入新的选择。MFC提供了CComboBox类对组合框控件进行支持。
CComboBox * AAA = (CComboBox*)(GetDlgItem(IDC_***));
AAA->AddString(_T("***"));
AAA->SelectString(0, _T("***"));
AAA->SetCurSel(0);
int nSel = AAA->GetCurSel();
AAA->GetLBText(nSel, Cstring);
if(strType.Trim() == _T("***"))
用来选择一系列的可能选择,用户通过滚动条可以在这些选择中浏览。在列表框中,可以进行单项选择,也可以进行多项选择,这取决于用户在控件属性对话框中的设置。MFC提供了CListBox类对列表框控件进行支持。
用来包围具有逻辑关系的一组控件,在这些控件的周围加上边界和标题。需注意的是,组成框仅仅是在视觉效果上对控件进行“成组”,真正的“成组”工作还需要另外一些工作。仅仅在视觉上展现出一组的逻辑关系,并不添加任何代码
用来选择某种可能的选择,与 (Check Box)复选框不同,该选项不是独立的。
一般是几个单选按钮组成一组,同组中的单选按钮仅有一个按钮被选中。
MFC同样使用CButton类对单选按钮控件进行支持,
SetCheck()函数和GetCheck()函数对单选按钮也是适用的。
用来在指定的位置显示特定的字符串,一般用来标识附近另一个控件的内容。显示在静态文本控件中的字符串一般不再改变,但是在需要的时候,必须为其指定一个不同食物ID号,通过调用相应的函数来进行设置。MFC提供了CStatic类支持静态控件。
显示位图(Bitmap)和图标(Icon),图形绘制与显示,主要是其方形的区域适合显示,同样方形区域也可利用(Static Text)静态文本框。
这包括水平滚动条和垂直滚动条,除了在视觉效果上的方向不同外,水平滚动条在被滚动时发生WM_HSCROLL消息,而垂直滚动条在被滚动时发送WM_VSCROLL消息。MFC提供了CScrollBar进行支持。
通常用来在程序中接受一系列离散的数值。
用户可以设置滑块控件的取值范围,并可以为控件加上刻度标记以显示特定位置的含义。
MFC提供了CSliderCtrl类进行支持。
包括一对紧靠在一起的上下箭头,使用微调按钮可以增大或者缩小某个特定的数值。
微调按钮往往都需要一个“伙伴”控件,这通常都是一个编辑框。
当微调按钮的向上箭头被单击时,编辑框中的数字就增大;反之则减小。MFC提供了CPinButtonCtrl类进行支持。
在进行一项需要较长时间的操作时来反应当前的进度。
当操作的进度不断前进时,进度条就用特色颜色填充进度条框。用户可以设定进度条的范围和当前位置。
MFC提供了CProgressCtrl类进行支持。
CProgressCtrl* progressbar = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS_1);
progressbar->SetRange(0, 4);
progressbar->SetPos(0);
热键控件看起来就像一个编辑框,但是在热键控件中能够立刻反应用户刚刚按下的键组合,这在设置程序的热键时特别有用。
热键控件只是在“视觉”上显示了按键组合,设置热键的工作还需要用户添加代码完成。
MFC提供了CHotKey类进行支持。
按一定的排列顺序显示一系列带图标的字符串。
列表控件提供了四种显示模式:大图标(Icon)、小图标(Small Icon)、列表(List)和报表(Report)。
用户可以向列表控件中添加新的项,也可以控制列表控件的显示模式。
MFC提供了CListCtrl类进行支持。
初始化:
struct INFO { int id; CString time; CString type; }info; CString id; int nRow=0; id.Format(_T("%d"), info.id); m_ListCtrl.InsertItem(nRow,id); m_ListCtrl.SetItemText(nRow, 1, info.time); m_ListCtrl.SetItemText(nRow, 2, info.type); nRow ++;
添加记录:
struct INFO
{
int id;
CString time;
CString type;
}info;
CString id;
int nRow=0;
id.Format(_T("%d"), info.id);
m_ListCtrl.InsertItem(nRow,id);
m_ListCtrl.SetItemText(nRow, 1, info.time);
m_ListCtrl.SetItemText(nRow, 2, info.type);
nRow ++;
显示一系列项目的层次关系,最典型的例子是显示磁盘上的文件与文件夹。
如果有子项目的话,单击树形控件中的项目可以展开或者收缩其子项目。
MFC提供了CTreeCtrl类进行支持。
初始化
void CConfigDlg::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); // TODO: 在此处添加消息处理程序代码 CRect rcWnd; GetClientRect(&rcWnd); CRect rcChild = rcWnd; rcChild.top = rcWnd.top+10; rcChild.bottom -=10; rcChild.left += 160; rcChild.right -= 10; CRect laneRect = rcChild; if(::IsWindow(m_1Dlg)) m_1Dlg.MoveWindow(rcChild); if(::IsWindow(m_2Dlg)) m_2Dlg.MoveWindow(rcChild); if ( ::IsWindow( pTree.GetSafeHwnd() ) ) { pTree.MoveWindow(rcWnd.left+10,rcWnd.top+30,130,350,1); } }
树节点切换
void CConfigDlg::OnTvnSelchangedTree(NMHDR *pNMHDR, LRESULT *pResult) { LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 HTREEITEM hSelected=pNMTreeView->itemNew.hItem; if(hSelected!=NULL) { pTree.SelectItem(hSelected); int nDat = pTree.GetItemData(hSelected); switch(nDat) { case 1: /*MessageBox(_T("YNAME"));*/ if(m_pPreWnd) m_pPreWnd->ShowWindow(SW_HIDE); m_1Dlg.ShowWindow(SW_SHOW); m_pPreWnd = &m_1Dlg; break; case 3: /*MessageBox(_T("XNAME"));*/ if(m_pPreWnd) m_pPreWnd->ShowWindow(SW_HIDE); m_2Dlg.ShowWindow(SW_SHOW); m_pPreWnd = &m_2Dlg; break; default: break; } } *pResult = 0; }
改变位置
void CConfigDlg::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); // TODO: 在此处添加消息处理程序代码 CRect rcWnd; GetClientRect(&rcWnd); CRect rcChild = rcWnd; rcChild.top = rcWnd.top+10; rcChild.bottom -=10; rcChild.left += 160; rcChild.right -= 10; CRect laneRect = rcChild; if(::IsWindow(m_1Dlg)) m_1Dlg.MoveWindow(rcChild); if(::IsWindow(m_2Dlg)) m_2Dlg.MoveWindow(rcChild); if ( ::IsWindow( pTree.GetSafeHwnd() ) ) { pTree.MoveWindow(rcWnd.left+10,rcWnd.top+30,130,350,1); } }
包含大量的控件,可以满足用户显示或者获取大量数据分类显示的要求,典型例子是Windows任务栏每个程序标签。
每个属性表又分为好几个属性页,这些属性页由各自的标签进行区分,这些属性页中都可以包容其他控件。
在显示属性表的时候,一次只能够显示一个属性页的全部内容,同时显示其他属性页的标签,用户通过单击标签打开相应的属性页。
MFC提供了CTabCtrl类进行支持。
初始化绑定变量
m_tab_Light.DeleteAllItems();
m_LightParkingDlg.DestroyWindow();
m_LightStatusDlg.DestroyWindow();
m_tab_Light.InsertItem(0, _T("0001")); // 插入第一个标签
m_tab_Light.InsertItem(1, _T("0002")); // 插入第二个标签
CRect tabRect; // 标签控件客户区的位置和大小
m_tab_Light.GetClientRect(&tabRect); // 获取标签控件客户区Rect
// 调整tabRect,使其覆盖范围适合放置标签页
tabRect.left += 2;
tabRect.right -= 1;
tabRect.top += 21;
tabRect.bottom -= 2;
m_LightParkingDlg.Create(IDD_DIALOG_LIGHT_PARKING, &m_tab_Light); // 创建第一个标签页
m_LightStatusDlg.Create(IDD_DIALOG_LIGHT_STATUS, &m_tab_Light); // 创建第二个标签页
//m_LightParkingDlg.InitData();
m_LightParkingDlg.SetWindowPos(NULL, tabRect.left, tabRect.top, tabRect.Width(), tabRect.Height(),SWP_SHOWWINDOW);
控件页面切换
CRect tabRect; // 标签控件客户区的位置和大小
m_tab_Light.GetClientRect(&tabRect); // 获取标签控件客户区Rect
// 调整tabRect,使其覆盖范围适合放置标签页
tabRect.left += 2;
tabRect.right -= 1;
tabRect.top += 21;
tabRect.bottom -= 2;
switch (m_tab_Light.GetCurSel())
{
case 0:
m_LightStatusDlg.SetWindowPos(NULL, tabRect.left, tabRect.top, tabRect.Width(), tabRect.Height(), SWP_HIDEWINDOW);
m_LightParkingDlg.SetWindowPos(NULL, tabRect.left, tabRect.top, tabRect.Width(), tabRect.Height(), SWP_SHOWWINDOW);
break;
case 1:
m_LightParkingDlg.SetWindowPos(NULL, tabRect.left, tabRect.top, tabRect.Width(), tabRect.Height(), SWP_HIDEWINDOW);
m_LightStatusDlg.SetWindowPos(NULL, tabRect.left, tabRect.top, tabRect.Width(), tabRect.Height(), SWP_SHOWWINDOW);
break;
}
用来播放一段AVI格式的视频剪辑。用户可以控制视频剪辑的播放、停止和定位,但也仅限于这些功能。动画控件设置不能播放音频剪辑,如果用户需要更高层次的视频或者音频的支持,请选用MCIWnd控件。
MFC提供了CAnimateCtrl类对动画控件进行支持。
编辑控件(Edit Control)功能的扩展。在高级编辑框中,除了简单的输入和编辑字符串外,用户还可以为字符或段落指定特定的格式,用户甚至还可以向高级编辑框中插入OLE项。
高级编辑框基本上实现了一个带格式的文本编辑器功能,而只需要用户添加少量的接口。
MFC提供了CRichEditCtrl类进行支持。
向用户提供了一种直观的选择日期和时间的方法、日期/时间选择器在外观上类似于一个组合框,但是当用户单击下拉箭头时就会展开一个日历控件供用户选择,而一旦用户做出了选择,日期/时间选择器会自动显示新的日期/时间。MFC提供了CDateTimeCtrl类进行支持。
SYSTEMTIME times_1; //开始时间日期
SYSTEMTIME timee_1; //结束时间日期
CDateTimeCtrl* dtPickctrs_1 = (CDateTimeCtrl*)GetDlgItem(IDC_DATETIMEPICKER_START1); //获取时间控件句柄
CDateTimeCtrl* dtPickctre_1 = (CDateTimeCtrl*)GetDlgItem(IDC_DATETIMEPICKER_END1);
memset(×_1,0,sizeof(times_1)); //时钟初始化
memset(&timee_1,0,sizeof(timee_1));
dtPickctrs_1->GetTime(×_1); //获取控件所选时间,保存至变量
dtPickctre_1->GetTime(&timee_1);
CString strTimeStart; //将时间转换为字符串
strTimeStart.Format(_T("%04d-%02d-%02d %02d:%02d:%02d"), times_1.wYear,times_1.wMonth,times_1.wDay,times_2.wHour,times_2.wMinute,times_2.wSecond);
CString strTimeEnd;
strTimeEnd.Format(_T("%04d-%02d-%02d %02d:%02d:%02d"), timee_1.wYear,timee_1.wMonth,timee_1.wDay,timee_2.wHour,timee_2.wMinute,timee_2.wSecond);
获取系统时间
SYSTEMTIME time;
::GetLocalTime(&time);
如下图,看似与真正的日历类似,操作也类似,直观的为用户提供了观察和显示当前日期的途径。MFC提供了CMonthCalCtrl类进行支持。
IP地址控件用来输入和编辑IP地址,MFC提供了CIPAddressCtrl类进行支持。
该控件外观类似于一个编辑框,但是可以自动对输入的字符按3个一组进行区分和加间隔圆点。IP地址控件为开发支持Internet技术的程序提供了方便。
在普通组合框(Combo Box)的基础上还支持图像列表。
可以在组合框中显示特定的图标表示相应的选择,而不仅仅是显示文本。
MFC提供了CComboBoxEx类进行支持。
控件使用的时候,它的Class必须有一个类的支持这个窗口类可以VC的类,例如:Button、Edit.在头文件增加一个CEdit类的成员变量:CEdit m_Text(即点击右键添加变量),然后按照Edit控件使用即可。
1.用于在 MFC 应用程序上添加超链接,就像html中的超链接一样。你点下可以链接到一个网页上去。拖控件到页面上,并绑定一个变量(m_linkCtrl),里面的内容全部是按照标准的html中href的用法写的。写错了自然链接不了的。
可以去瞧下html里面的href属性是怎/么设置的.另外要注意的是字符串中双引号的处理(记得加个转义符\),添加单击响应消息
m_linkCtrl.SetWindowTextW(_T("<a href=\"http://blog.csdn.net/miko_xiaoming\">Miko's Note</a>"));
PNMLINK pNMLink = (PNMLINK) pNMHDR;
ShellExecuteW(NULL, L"open", pNMLink->item.szUrl, NULL, NULL, SW_SHOWNORMAL); //在浏览器中打开
2.同按钮(Button)控件一样,响应相应的消息
如下图,实现多选按钮选择功能,使用时添加相应菜单
可以直接作为inet_addr(ip)的输入,分隔符为逗号(,)
不仅可以为按钮添加相应命令还可以对命令做出注解
ID:控件的资源标识。
Visiable:控件是否可见。
Disabled:控件是否被禁止、被禁止的控件无法接受键盘和鼠标输入。
Group:是否从这个空间开始一个新组。
Tab stop:在程序中是否可以用【Tab】键切换到这个控件。
Help ID:是否给控件分配一个帮助标识,帮助标识基于控件本身的资源标识。
Client edge:给控件增加一个凹陷的边界,使整个控件看起来像是凹下去的一样。
Static edge:给控件增加一个边界。
Modal frame:给控件增加一个3维的框架,与Client edge相反,它是凸出来的。
Transparent:拥有此属性的窗口是透明的,它下面的窗口不会被它遮掩住。
Accept files:拥有此属性的窗口可以接收拖放文件,如果一个文件被拖动到这个控件上面,控件会收到WM_DROPFILES消息。
No parent notify:表示控件不向其父窗口发送WM_PARENTNOTIFY消息。
Right aligned text:表示文本右对齐。
以上属性可通过控件的属性对话框进行设置,在属性对话框中按【F1】键可以查看属性的帮助信息。
每一种控件都由一个MFC控件类来管理,当通过资源编辑器在对话框上添加一个控件时,visualC++会自动为控件类生成一个实例,即对象,并调用构造函数,当对话框关闭时,其各个子控件对象被自动销毁。
也可以不使用资源编辑器,自己在程序中写代码创建、显示控件并设置控件的属性。
所有的控件类都来自CWnd,控件的某些操作和属性设置需要用到CWnd本身的成员函数,CWnd某些函数经常用来操纵控件和设置控件属性。
SetWindowText:设置控件上要显示的标题文本,即用来设置控件的caption属性
GetWindowText:得到控件的标题文本
EnableWindow:设置控件的Disabled属性,即社会自控件是否可以接收键盘和鼠标的输入
SetWindowPos:改变窗口的大小、位置和Z轴次序。
MoveWindow:改变窗口的大小和位置
GetWindowRec:得到窗口的大小、位置(信息存放在一个矩形结构中)。
GetClientRect:得到窗口客户区的大小(信息存放在一个矩形结构中 )
ShowWindow:设置窗口的可见性(即窗口是否可见)
SetWindowText/GetWindowText还可以用来设置/得到对话框的标题文本。
福利来啦~
学习从来不是一个人的事情,要有个相互监督的伙伴,对于C/C++感兴趣可以关注小编在后台私信我:【编程交流】一起来学习哦!可以领取一些C/C++的项目学习视频资料哦!
T之外,画画也是我的一大爱好。
在当今基于C++的图形界面开发领域,能与Qt相抗衡的也只有MFC,MFC是微软公司的基础类库,自然得天独厚,比如开发深层次的Windows应用,MFC当然远超Qt,但Qt也有杀手锏,那就是跨平台。这两点大家一目了然。下面我们再来比较它们的其他特点。
(1)开发速度
就整体而言,MFC可能会快捷一些,因为Windows平台的开发工具大多很智能,因为立足于Windows的开发人群很广,从菜鸟到专业人士(开发人员一多,技术参考就多,周围可以咨询问题的人就多)。相比较而言,Qt基于Linux,可用的开发工具不多,而且这些工具大都比较专业,多是第三方的产品,加上这些工具的集成度不高,支持的第三方库也没有支持MFC的第三方库多,因而从这一点看,MFC略胜一筹。不过,Qt自从被诺基亚公司收购后,官方发布了跨平台集成开发环境Qt Creator,之后的走向就不好说了,作者个人的总体感觉是Qt Creator和VS差距比较大,还需要改进。
从库本身来说,Qt集成的功能比MFC庞大,而且使用的封装技术(信号/槽)倍受赞许,比如Qt Script为Qt提供了嵌入式脚本,Qt界面库支持CSS,所以Qt构建出来的界面比MFC要好,且实现过程也比较容易。为了降低使用Windows SDK开发的难度以及提高使用Windows SDK开发的效率,MFC采用的是浅层封装(最新的2008 sp1加入了BCG的高级界面库,可能有所改善)Windows SDK。这个方面相比而言,Qt库比MFC优秀。不过,这两个库都久经时间的考验,稳定性都很高,几乎没有什么Bug。
(2)运行效率
MFC采用浅层封装,运行效率比较高,加上VC对Windows进行了针对性的优化,因而整体性能是比较高的,但是如果加入第三方库就不敢保证整体的高性能了。Qt库比较庞大,封装层次较深,所以运行效率比MFC低,但是在如今主流计算机系统的配置下,人们还会介意这点性能差别吗?(反正大家都不介意C#对性能略微拉低的影响了。)
(3)应用范围
如今Windows的普及率无人能及,MFC的使用人数自然就多,相比而言,Qt主要是Linux下的开发人员在使用。MFC不支持嵌入式开发(主要是指手机平台),而Qt有对应的支持模块,虽然这一手机开发领域被Java碾压,但总归还是有Qt的使用空间。
(4)学习难度
Qt的封装方式比较明晰,和系统隔离得比较好,作者个人觉得学习的门槛不高。而MFC则较难精通,因为深入开发之后还需要了解SDK,否则开发出的程序比较初级。
(5)伪对象vs真对象
归根结底,Qt和MFC的差异在于其设计的差异。MFC的根本目的是让开发者调用封装好的、用C语言编写的Windows API。但是,这绝非好的面向对象的程序设计模式,因为在很多场合,我们必须提供一个包含15个结构成员的C语言的struct(结构类型),但是其中只有一个结构成员是我们需要使用的,或者必须用在调用函数中使用参数的方式来获得我们需要的结构成员。MFC还有许多让人摸不着头脑的地方,例如函数名没有任何连续性,假如我们创建了一个graphical类,直到调用了creat()以后该类才会被创建。然而对于dialogs类,必须要等到调用OnInitDialog()才能创建这个类的实例对象。奇怪的是到了views,创建该类的函数名竟然成了OnInitUpdate(),使用VC/MFC中的库函数调用总是要十分小心,不如Qt那样一看函数名就知道对应函数的作用是什么。
(6)消息循环
MFC是事件驱动的架构。必须对任何操作对应的特定消息做出响应。Windows中应用程序发送的信息数以千计,遗憾的是,要厘清这些纷繁芜杂的消息很困难,通过参考这方面的文档资料并不能很好地解决这些问题。
Qt的消息机制建立在SIGNAL()发送和SLOT()接收的基础上。这个机制是对象间建立联系的核心机制。利用SIGNAL()可以传递任何参数,它的功能非常强大,可以直接传递信号给SLOT(),因此可以清楚地理解要发生的事情。一个类所发送的信号数量通常非常少(4个或者5个),相关的帮助文档资料也非常齐全。这让我们会觉得到一切尽在掌握之中。信号/槽(Signal/Slot)机制类似于Java中的listener机制,不过这种机制更加轻量级,功能更齐全。
(7)创建界面
MFC无法创建大小动态可变的子窗口 ,必须重新手动修改代码来改变窗口的位置(这恰好解释了为什么Windows里的对话框dialog是不可以改变的),这个问题在软件进行多语言化版本设计时更加严重,因为许多国家或地区在表达相同意思时可能需要更长的词汇和句子,于是软件开发者必须对每种语言的版本重新修改自己的软件。
在Qt中,界面需要的任何设计都可以手动编写出来,因为它很简单:为了得到一个按钮(button),可以将代码写为“button = new PushButton( "buttonName", MyParentName );”,如果想在按下某个按钮以后调用某段执行代码,则可以编写为“connect(button, SIGNAL(clicked()), qApp, SLOT(action()));”。Qt拥有非常简单而又不失强大的设计机制,不使用它实在可惜。
Qt还提供了一个图形用户工具——Qt Designer,可以用来协助建立用户界面。可以使用Qt Designer修改所使用的任何控件的属性,不用将这些控件拖放到设计严格限定的位置,因为可以通过设计机制更完美地组织这些控件。
Qt Designer这个工具所生成的代码可阅读、可理解。所生成的代码单独放在一个文件中,在编程的同时,我们可以随心所欲地多次重新生成用户界面。
Qt Designer可以让我们完成许多在MFC中不可能完成的任务,比如用预先填好的内容生成列表视图(listview),在每个页签(tab)上使用不同的视图(view)。
(8)帮助文档
用户选择图形开发环境的时候,帮助文档是否周全是左右用户选择图形开发环境的重要因素。Visual开发环境的帮助文档MSDN(这个还要单独掏钱购买)非常庞大,有10个CD-ROM光盘容量之大,它包罗万象,涵盖广泛,但难免有泥沙俱下、主题模糊、关键信息不突出的遗憾。MSDN的链接设计也很糟糕,通过链接很难从一个类跳转到它的父类或者子类以及相关的类。如果搜索一个关键字,结果找到的内容不管是否直接关联,只要包含这个关键字的信息统统都会搜索出来,让用户再从中选择。
Qt的文档设计得相当优秀,可以到https://doc.qt.io/上面一睹它的芳容。Qt的文档完备且详细地覆盖了Qt的方方面面,然而文档的整体容量竟然仅有18MB。其中每一个类和方法都被详尽描述,巨细靡遗,举例充实。通过Trolltech公司提供的链接或者是Qt Assistant工具可以方便地从一个类或者方法跳转到其他的类。文档还包含了一个初学者教程和一些典型应用的例子。同时还提供了FAQ和邮件列表,方便用户通过用户群或通过Internet来查阅。如果我们购买了授权,在一天之内就会得到Trolltech公司的技术支持。实际上,Qt优秀的帮助文档使得寻求外部帮助的机会大大减少。Trolltech公司的宗旨之一是:有如此优秀的Qt产品及其帮助文档,其他外部的技术支持就是多余的。
总之,MSDN用熟了也很好用、很全面,相关的背景知识、例子都能找到,而且网上还有丰富的范例程序可以参考。同样的,仅凭Qt的帮助文档也绝对不足以解决所有问题,以作者的亲历,在网上只找到了一个Qt中文论坛,提过几个问题,有的问题给出了解决办法,有的问题则没人回答,最后还要靠自己试。
(9)Unicode编码
使用MFC,如果要显示Unicode编码的字符,在编译链接时必须用到特殊的参数(还要改变可执行文件执行的入口),必须在每个string前面加上T,将char修改成TCHAR,每个字符串处理函数(strcpy()、strdup()、strcat()等等)都要改变成另外的字符串处理函数名。更令人恼火的是,支持Unicode的软件竟然不能和不支持Unicode编码的DLL一起工作。这是一个很严重的问题,但是我们却别无选择。
使用Qt,字符串用QString类来处理,QString类与生俱来就采用Unicode编码,因而不需要改变任何东西:不需要在编译/链接时增添参数,不需要修改代码,只需要使用QString类即可。QString类功能强大、应用广泛,也不用担心Unicode问题。QString类提供了转换为char * 和UTF8的函数。MFC的CString类设计相比于Qt的QString类设计则有着巨大的不同,CString类以char *为基础提供的功能很少,它的特点是当需要char *类型时,可以直接使用CString类。乍看起来这好像是个优点,实质上有很大缺陷,特别是可以直接修改char *内容而不用更新类,在转变为Unicode时就会遭遇到很大的麻烦(CString类随编译选项可以是Unicode版)。相反,QString类在内部以Unicode编码方式来存储字符串,需要时提供char *功能,实际上很少用到char *,因为整个Qt的API用文本的方式响应QString参数。QString还附带了许多其他的功能,比如自动分享QString的内容。总之QString是一个非常强大的类,需要用到它的地方很多。
(10)支持软件的多语种功能
MFC可以支持软件的多语种功能,需要将每一个语种的字符串放在一个字符串表中,在代码中需要之处调用LoadString(IDENTIFIET),然后把这些字符串资源转化到DLL中,这些字符串对应到所需要的语言,改变图形界面,再通过程序调用这个DLL。整个过程是如此的烦琐,可谓牵一发而动全身。
Qt支持软件多语种的方式有所不同,只需要将字符串置于函数tr()中,可以直接在代码中改变字符串的引用。Qt Linguist(Qt的一个工具)能够提取所有待翻译的字符串并按照对应语种的用户界面显示出来,这个工具非常适合进行用户界面的多语种翻译,它功能齐全:通过查询字典数据显示出对应语种的字符串内容,正确显示出Unicode编码,以快捷方式检测出未翻译的字符串,检测字符串修改的情况。这个工具甚至可以提供给没有任何编程经验的翻译人员用于翻译软件的用户界面。该软件的发布遵循GPL版权规则,开发者可以根据具体的开发需求来修改它。翻译之后的文档保存在XML中,符合软件复用的原则。由此可见,为软件增加一种新的语言版本仅仅是用Qt Linguist工具生成一个新的文件而已。
(11)资源问题
使用MFC时,一部分开发过程要依靠“资源”(resources),在很多的案例中开发者都必须使用它们。这样会导致如下后果:除了Visual Studio,很难使用其他的工具来完成开发。资源编辑器仅有有限的功能,比如通过Dialog编辑器不能改变所有的属性。
然而,Qt并没有资源的概念,这就解决了MFC所遇到的问题。Qt提供了一个界面设计器以可视化的方式来设计界面,并把设计后生成的代码存储到一个脚本文件中。
(12)价格
用户一旦购买了Visual Studio,将免费获得MFC SDK。Qt在UNIX上可以免费获得遵守GPL版权规则的版本(现在可以免费获得Windows平台上的GPL版本)。如果要开发不公开源代码的软件,则必须购买Qt的授权。在特定平台下,每个开发者购买一个永久性授权,并可获得一年的技术支持。
(13)发布
在发布基于MFC的软件时,必须依靠存储在客户计算机上的MFC,但是这是不安全的,同样是MFC42.dll,基于相同的库可得到3个不同的版本。因而需要检查是否拥有正确的MFC42.dll版本,如果版本不对,就升级它。但是,升级MFC42.dll会改变很多软件的行为。这让开发者感到很不“爽”,如果用户在安装软件以后导致用户的计算机死机了,该怎么办呢?
Qt则没有这个风险,因为Qt压根就没有“升级整个系统”的概念。不过,如果开发的软件不是基于同一个版本的Qt来运行,还是会有潜在的问题。
*请认真填写需求信息,我们会在24小时内与您取得联系。