从零开始学VC系列教程完整版.docx
- 文档编号:9788327
- 上传时间:2023-02-06
- 格式:DOCX
- 页数:52
- 大小:2.88MB
从零开始学VC系列教程完整版.docx
《从零开始学VC系列教程完整版.docx》由会员分享,可在线阅读,更多相关《从零开始学VC系列教程完整版.docx(52页珍藏版)》请在冰豆网上搜索。
从零开始学VC系列教程完整版
Corporationstandardizationoffice#QS8QHH-HHGX8Q8-GNHHJ8
从零开始学VC系列教程完整版
从零开始学VC系列教程一.信息显示实验
题外话:
第一次写教程,不知道该怎么开始.以前见过的教程可能都会介绍比较多的理论然后才开始讲实际操作,我想对于VC,理论讲得太多大家可能更糊涂,所以选择了这个方案,我们先一步步照着做,每一次只介绍一两个知识点,并且把理论放在后面说明,希望大家能喜欢这种方式,并对这种方式提出意见和建议,以便以后章节更适合大家的学习.
或许我写的还不能称之为教程,只是一些操作步骤及说明,通过这些练习,希望能使大家对VC有一个新的认识.VC的功能是十分强大的,但我们一般并不会用到所有的功能,就像大家熟悉的KeilC一样,其实Keil功能也是很多的,平时也没见谁把Keil的功能都用到了.基于此,我写的这个教程可能在VC专业人士看来比较简单.不是要班门弄斧,而是希望推行上位机技术,形成一个氛围让大家来学习交流,PC机与下位机结合毕竟也是发展的一个方向.望高手谅解小辈的不自量力.同时,我们结合单片机编程,让大家明白上位机控制方法及原理,当然这是今后章节的内容了.
本节内容:
学会在文本框中显示文本,学会弹出式对话框使用.
学习目的:
信息显示是人机交互的基础,同时,信息显示也为以后的程序调试打下基础.
1.新建工程.打开点击[文件]->[新建],弹出如下对话框.
在工程选项中选择MFCAppWizard[exe],选择好工程存入的位置,然后在工程名称中填入工程的名称,例如Eg01,填入Eg01后.VC会在我们选择的路径后自动加入一个以工程名命名的文件夹作为工程目录.完成按[确定]就会进入工程向导,出现以下的提示.
在这个我们选择[基于对话框]就行了.单文档及多文档方式会在以后详细介绍.这里也简要说明一下.①单文档.程序一次只能处理一个文档对象(文件).像写字板,记事本等.②多文档.程序一次可以处理多个对象(文件),像word之类的,可以同时打开多个文件.③基本对话框.程序一般用于处理一些比较小的,工具型的软件.像双龙的ISP下载软件,Easy51Pro等都是基于对话框.一些不是很复杂的工业软件也通常可以用基于对话框的形式,这种方式的优点是所见即所得,一些控件可以像VB一样拖到工作区就行了.选好以后直接按[完成]就可以了.至于[下一步]的向导,这里我们先不管.然后会进入以下的画面.其中红色及绿色是我的标注,看不清图片可以下载图片放大.
选中静态文本框[TODO:
在这里设置对话框控制],单击指标右键,在弹出的快捷菜单中选择[属性Properties]菜单项,弹出如下对话框
修改IDC_STATIC为IDC_FIRSTLABEL,标题可以写为”第一个应用程序”然后关闭这个对话框,就可以看到刚才的静态文本框内容变为”第一个应用程序”了.
在刚才的操作中,我们将静态文本框的ID改为了IDC_FIRSTLABEL,在VC中,ID是控件的标志,不能有相同的ID出现,但允许多个名为IDC_STATIC的ID号.所以,一般并不把文件名命为IDC_STATIC,除非以后我们不想在程序中改变这个控件的属性.有一些控制,例如GroupBox一般并不在程序中改变什么,所以不改变其ID号.ID是程序访问控件的标识,所以一个应用程序中不能有重复ID.
按下来我们要添加一个按钮.
用鼠标将控件条上的按钮拖到对话框上,可以看到对话框上多了一个按钮.用上叙方法,改变按钮ID为IDC_BTN1,标题改为”显示”,这样就做好一个按钮了.下面我们为按钮添加代码.
双击按钮,会出现以下的提示框.
按[OK]为按钮添加响应函数,出面以下画面
voidCEg01Dlg:
:
OnBtn1()
{
然,现在还没有响应.现在我们添加一个事件,让这个按钮按下后上面的静态文本框的内容变为”串口号:
COM1波特率:
57600”把上面的代码改为
voidCEg01Dlg:
:
OnBtn1()
{
57600”果编译通过,按F5运行,可以看到程序运行后的对话框
按下按钮,可以看到上面的静态文本框的内容改变了.那么恭喜你,完成我们这个例子的第一步操作了.
当然,我这里的对话框看起来没那么高,大家可以调一下高度.怎么退回到控件编辑状态呢
首先,我们单击选项卡中的[ResorceView],现在大家只能看到[Reso…]看到IDD_EG01_DIALG了吧,这个其实也是一个ID,是我们对话框的ID,如果大家改一下对话框的ID,就可以看到这里的ID也变了.在VC中,所有的控件都认为是窗体,只是形式不同.双击IDD_EG01_DIALG就可以看到我们刚才的控制编辑状态了.双击[显示]按钮又可以回到代码状态.
刚才的例子很简单,却是我们以后会用得最多的.下面我们来分析一下代码
voidCEg01Dlg:
:
OnBtn1()
{
57600”面我们提到过,VC中的控件都认为是窗体,所以,对于所有的文本显示,我们都可以用这个函数来做,大家可以试着加入一个编辑框(Edit),同样可以使用用这个函数,只要ID号对了就可以了.VC对大小写敏感,大家要注意大小写.
下面我们用另一个方法来实现.
把代码改为
voidCEg01Dlg:
:
OnBtn1()
{
57600”以看到运行结果是一样的.
大家可以看到,我们把变量a定义为CString类型,这个类型我们在C中可能没有见过.CString
其实是VC中的一个类.这里我们要引入类的概念了.类跟C语言结构体很像,结构体可以有成员变量,但不能有成员函数,类不但可以有成员变量,还可以有成员函数,并且支持多种方法.在VC中,类用class标识.下面是一个类的定义,我们来分析一下.
classCEg01Dlg:
publicCDialog
{
public:
CStringGetPath(void);
protected:
intGetMax(inta,intb);
public:
inta;
intb;
};
这个类是我改过的,为了大家看得明白一点.首先,我们从这句classCEg01Dlg:
publicCDialog知道这个类名是CEg01Dlg,那么public后面的CDialog是什么意思呢CDialog其实也是一个类,是VC中标准对话框类.publicCDialog意思是我们定义的这个类CEg01Dlg从CDialog派生,也叫从CDialog继承,从继承这个词语大家就会明白CEg01Dlg不但可以有自身函数,而且还可以用到CDialog里的变量及函数,所以说是继承,就像我们说的继承财产一样,儿子不但可以有自己的钱,还有从老爸那里继承的产财,这些钱都能花.所以,我们也叫CDialog为父类(不是爸类啊),把CEg01Dlg称为子类.当然,这是相对的.如果再定义一个类从CEg01Dlg派生,那么CEg01Dlg也就是父类,派生出来的类就是子类.这段可能有点难明白,大家可以慢慢体会.我们再回到CString上面来,这个类不是派生的,所以也没有父类了.用CString定义一个变量a,我们称为类变量,CString有很强大的功能,我们这里只用到一个功能,就是字符串,a可以是一个不定长度的字符串,所以我们可以给a赋一个任意的字符串而不用关心长度.当然,我们也可以用intStringLen=();来获得这个字符串的长度.从这句可以看到,GetLength()是类CString里的一个函数.大家可能又会关心一个问题,怎么把长度显示出来呢我们把代码改为
voidCEg01Dlg:
:
OnBtn1()
{
式化后的字符串还是存放在a中,在这里,我们还用到了一个新的函数MessageBox();我们只是用了这个函数最简单的用法,显示一个字符串.MessageBox用于弹出一个提示对话框.查查MSDN就知道,函数原型是
intMessageBox(LPCTSTRlpszText,LPCTSTRlpszCaption=NULL,UINTnType=MB_OK);
在VC里面,函数可以有默认值,例如LPCTSTRlpszCaption=NULL,UINTnType=MB_OK变量lpszCaption的默认值是NULL,nType的默认值是MB_OK,这些有默认值的变量我们可以不传值,所以这个函数使用时,最简单的用法就是传lpszText就可以了.如果我们要显示一个固定的字串,可以这样调用MessageBox(“大家好”);是不是很简单啊
这一章就写到这里了,一些问题大家可以提.未尽知识点,会在以后再详细介绍.
从零开始学VC系列教程二.对话框及常用控件实验
恭喜你,进入VC学习的第二节了.这一节是人机交互的基础.所谓人机交互,说通俗点就是与机器对话.然而我们现在的技术还不能像科幻片里一样与机器人直接说话就行了.所以,我们的操作意图还得通过文本输入,命令按钮等等来实现.
本节内容:
学会对话框调用及一些常用控件的使用方法.
学习目的:
学习人机交互,为软件开发提供界面基础.
1.新建工程.参考第一节的方法新建一个工程,名字为Eg02完成后如下图
细心的朋友一定会发现.新建的工程里还有一个对话框,ID名是IDD_ABOUTBOX这个是做什么用的呢我们用到的软件都会有一个版权声明.通过第一章的学习,大家应该知道怎么观看这个IDD_ABOUTBOX对话框了吧.没错!
双击IDD_ABOUTBOX就可以了.我们会看到如下的一个对话框
这就是我们这个程序的关于对话框,一般用于版权声明及版本号标识.大家看到的这个对话框里有两个静态文本框和一个图像框(Picture),静态文本框我们在前一节已经介绍过了.大家可以修改一下版权所有这一行,填什么都可以,签个大名也行.完成以后你一定想看看效果,这个对话框怎么打开呢其实VC已经为我们做好了.先按F7编译,然后按F5运行.大家可以看到程序运行了.
单击应用程序图标,就会出现一个菜单,选最后一个[关于Eg02],关于对话框就弹出来了.
当然,这是系统为我们做好的.自己怎么在程序中调用这个对话框呢为了演示,首先参考第一节的内容添加一个按钮,然后把按钮的ID改为IDC_BTN_ABOUTME,把标题,也就是Caption改为[关于].最终效果如下
下面我们为按钮添加代码.相信大家一定还记得怎么进入代码吧..对了,双击[关于]按钮,在弹出的对话框中点[确定]就可以了.为了让大家更好的理解下面的操作,我们先要解释一下关于对话框的类.VC向导会为关于对话框建立一个类,大家看看下面的图
单击标签ClassView(这里显示的是[Class…])就可以看到Eg02这个应用程序的类.第一个CAboutDlg就是关于对话框的类.CEg02Dlg对应IDD_EG02_DIALOG.中间的Ceg02App是应用程序的基础类.所以,如果要对关于对话框进行操作,就要用到类CAboutDlg,因为与此有关的函数及变量都封装在CAboutDlg中.看到这里大家可能又糊涂了,没关系,在以后的教程中,通过一些练习大家就会慢慢领会到的.这里还是先为[关于]按钮添加代码.
voidCEg02Dlg:
:
OnBtnAboutme()
{
们添加代码成以下所示
voidCEg02Dlg:
:
OnBtnAboutme()
{
二句是();功能是调用类CAboutDlg里的一个函数DoModal();这个函数在MSDN里的解释是Callthismemberfunctiontoinvokethemodaldialogboxandreturnthedialog-boxresultwhendone.Thismemberfunctionhandlesallinteractionwiththeuserwhilethedialogboxisactive.Thisiswhatmakesthedialogboxmodal;thatis,theusercannotinteractwithotherwindowsuntilthedialogboxisclosed.一般我们用于显示一个对话框.其实大家看看CAboutDlg这个类下面,只有两个函数
DoModal()这个函数并不在这个里面.第一章我们提到过类的派生和继承.其实CAboutDlg这个类是派生于CDialog类,DoModal()这个函数是CDialog的成员函数,由于CAboutDlg是继承父类CDialog的,所以CDialog里的函数在CAboutDlg中也可以使用.
下面我们来说说几个常用控件的使用.
首先在IDD_EG02_DIALOG对话框中加入一个Edit(编辑框)控件.Edit一般用于输入输出数据文本.相当于VB里的TextBox.加入Edit控件后,编辑其属性为
然后,我们再加一个按钮(PushButton),并编辑其属性为
接下来,我们先说一下要实现的效果.很简单,在编辑框里输入一个文本,然后按显示,就把文本显示在静态文本框中.所以,这里要把静态文本编辑框的ID改为IDC_DISPLABEL
下面我们为[显示]按钮添加代码
voidCEg02Dlg:
:
OnBtnShow()
{
查MSDN就知道函数原型了.
intGetDlgItemText(intnID,LPTSTRlpStr,intnMaxCount)const;
intGetDlgItemText(intnID,CString&rString)const;
大家看看就觉得奇怪了,怎么有两个原型啊并且一个是传两个参数,另一个是传三个参数.在VC里面,同一个类下是可以存在多个同名函数的,具体调用哪个函数要看参数的不同.在这里我们传入了两个参数,所以VC会调用intGetDlgItemText(intnID,CString&rString)const;这个函数.第一个函数是控件的ID号,第二个是字串.第二个传了地址,所以我们在下一句中用的a已经是获得IDC_EDIT_INPUT的文本了.运行效果如下
下面介绍一下进度条的使用以及定时器的使用.
我们要实现的效果是进度从0到满格,然后再从0到满格,依次循环.每跳一格间隔500ms,这个时间我们用定时器来实现.
首先从控件条里拖出一个进程条到对话框,修改属性如下
然后我们要介绍一下VC的定时器.VC里面使用定时器有多种方式,我们先介绍一种作为抛砖引玉
首先添加一个Windows消息处理器.消息这个词语可能很陌生,我们会在后面很多次说明.这里先照图做
在类管理器里选中Ceg02Dlg这个类,然后点右键,就会弹出一个菜单,选择[AddWindowsMessageHandler…],接下来会弹出另一个菜单
双击WM_TIMER然后按[确定]就可以了.大家会看到,CEg02Dlg类中多了一个函数
这个就是VC中的定时器响应函数.然后双击这个函数就进入代码了
然后我们为Timer事件添加代码.
voidCEg02Dlg:
:
OnTimer(UINTnIDEvent)
{
认时,进度条0为空,100为满格.从后的程序大家可以看到,这个变量自加到100就变为0.最难理解的就是
((CProgressCtrl*)(GetDlgItem(IDC_PROGRESS)))->SetPos(nPos);
首先,GetDlgItem(IDC_PROGRESS)这个函数用来获取IDC_PROGRESS的句柄,在VC里面引入了句柄这个词语,我们将在下一章中对消息和句柄进行详细的说明,句柄是WINDOWS用来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等。
WINDOWS句柄有点象C语言中的文件句柄。
在这里,GetDlgItem获取了窗体句柄,大家应该还记得,在VC里面,控制就看成窗体。
(CProgressCtrl*)这个地方是将返回的句柄强制转换为CProgressCtrl类型,与C语言的中的强制转换是一样的.进度条的控制类是CprogressCtrl.而前面返回的是一个窗体类型,所以先要强制转换.在第一章中,我们提到过,VC中的控件都认为是窗体,在这里就体现出来了.SetPos(nPos);这个函数是类CprogressCtrl的成员函数,用来指定当前进度条的进度.最后还有一步,就是激活这个定时器.像我们的C51或AVR一样,要初始化定时器.而voidCEg02Dlg:
:
OnTimer(UINTnIDEvent)这个函数就像我们单片机的定时器中断服务函数一样.时间到了就会自动执行.
参考上面的图,双击OnInitDialog(),就可以进入对话框初始化函数,只要添加一句就可以了.完成后如下
BOOLCEg02Dlg:
:
OnInitDialog()
{
CDialog:
:
OnInitDialog();
."menuitemtosystemmenu.
ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX<0xF000);
CMenu*pSysMenu=GetSystemMenu(FALSE);
if(pSysMenu!
=NULL)
{
CStringstrAboutMenu;
(IDS_ABOUTBOX);
if(!
())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
Theframeworkdoesthisautomatically
二个参数500是定时器的时间,单位为ms,后面的NULL是指不要回调函数.
按F7编译后运行就可以看到运行效果了.
或许大家有个问题,为什么开始时是添加了一个WM_TIMER的消息处理器呢我们使用SetTimer开始定时器后,如果没有回调函数,系统会在每次定时时间到后发送一个WM_TIMER消息到窗体.窗体收到这个信息后,调用OnTimer()函数进行处理.系统定义这个函数为afx_msgvoidOnTimer(UINTnIDEvent);可以看到是以afx_msg修饰的,这种函数会与其中一个信息关联,或者说是消息影射到这个函数.每当有消息发过来,都会执行这个函数.大家只要好好想想单片机的定时器中断就会明白的,原理一样,只是传输机制不同.
如果上面的内容你制作成功了,那么恭喜你,第二节就基本学完了.
下面我们也来说说多任务和消息机制吧.
Windows是基于消息机制的,它是一个多任务的操作系统,也就是说,同一时间内,系统会挂起多个任务.为了说明多任务,我们先来看一段单片机程序.
Voidmain(void)
{
While
(1)
{
TaskA();
}
}
这个程序很简单,单片机工作后就进入while()循环了,单片机这个时候就干一件事,那就是执行任务TaskA.这样的工作总是在一个主循环内实施,一次只执行一个任务的我们称为单任务系统.单片机程序只要不引入操作系统并且由一个主循环一直执行完毕的基本都是单任务的.有些程序也是这样写的.
Voidmain(void)
{
While
(1)
{
TaskA();
TaskB();
TaskC();
}
}
这样的程序看起来似乎是有三个任务了.这三个任务是顺序执行的,也就是说,必须让A完成后,才能到B,B完成后才能到C.如果A有一个长时间的延时,系统就会在A中空等,然而B与A本来是无关的,这样空等的时间就算是浪费了.如果我们的windows也是顺序执行的就麻烦了,那时我们不仅仅会说Windows有点慢,而是说Windows像蜗牛一样在爬.如果我们让这些任务更合理的安排一下,在执行A的时候,有空就去执行B,而在B的空闲时间去执行C或者A,那么时间就节省下来了.如果时间切换够快,那么我们可以认为A,B,C三个任务在同时进行.所以,如果我们把单片机的执行时间分成若干等份,每份1ms或者更小,这种时间等份我们称为时间片,每次时间到了就换一个任务.也就是说,第一毫秒执行A,这时我们并不等A全部执行完,并记住这个断点,到了第二毫秒执行B,第三毫秒执行C,第四毫秒又执行A并从原来的断点开始执行,依次直至三个任务都完成.大家可以看到,任务A每三毫秒执行了一次.这就是多任务的模型了.
Windows其实就是这么干的.只是每次任务时间不一定是我们上面说的3ms,因为系统同一时间内可能会有很多待执行的任务,这些任务就被系统按优先级排成队,一个个取出来执行.比如我们现在打开VC,系统在加载VC,同时我们还可以移动鼠标,这些好像都是在同时进行,其实它们也是按时间片分时执行的.
现在分析一下这个工作过程吧.现在我们要打开VC,系统开始加载VC了,可以看到VC的LOGO界面,但这个时候我们还可以动一下鼠标,硬件首先会响应,并给软件发个通知,而软件这个时候可能还没有轮到鼠标程序的执行,怎么办呢系统会先把这个鼠标操作保存起来,轮到鼠标时间片时再来处理鼠标操作.大家可能觉得,这样鼠标操作不是滞后了吗确实是这样的,但这个滞后时间是很短的,我们基本不会察觉出来.
我们来看看消息的定义.
消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉。
一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向Windows发出一个通知,告诉应用程序某个事情发生了。
例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。
消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。
例如,对于单击鼠标所产生的消息来说,这个记录中包含了单击鼠标时的坐标。
综合前面的分析,消息就好理解了,鼠标动一下会产生一个事件,这个事件必须要告诉系统啊,怎么告诉系统呢Windows把这个定义为Message也就是消息,所以,消息可以认为是一个操作记号,记录上一步所发生的或者说是下一步所要处理的事件.系统为消息安排了一个队列,里面可以存放很多个消息,我们称为消息队列.有键盘操作时,把键盘操作放到消息队列里面,相当于做一个记号,我们动了键盘,有鼠标操作时,把鼠标操作放到消息队列,也便记住我们在键盘后还动了鼠标,系统就把这些东西一个个按时间取出来执行.在Windows里面,鼠标消息可以有几种,例如单击落了左键,系统会产生一个消息为WM_LBUTTONDOWN如果我们移动了鼠标,就像产生一个消息为WM_MOUSEMOVE消息入队后,系统会依次处理.当然,我们这样的解释虽然容易懂,但不是非常专业,并且Windows内部处理消息也比这复杂多了,但基本原理就是这样的了,并且,我们在进行操作时,并不用关心Windows的底层是怎么处理这些事件的,除非我们的操作真的让Windows生气了,就必须去查查出什么问题了.
说了这么多,消息可能还是一个十分飘渺的概念,倒底要怎么用呢我们来举个例子说明一下.给系统发消息一般会用到两个函数,一个是SendMessage,另一个是PostMessage,这两个是有点区别的,具体区别作为这次的作品,大家去网上查查
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 从零开始 VC 系列 教程 完整版