VC开发详细教程Word下载.docx
《VC开发详细教程Word下载.docx》由会员分享,可在线阅读,更多相关《VC开发详细教程Word下载.docx(93页珍藏版)》请在冰豆网上搜索。
1.2理解Windows消息机制
Windows系统是一个消息驱动的OS,什么是消息呢?
我很难说得清楚,也很难下一个定义(谁在嘘我),我下面从不同的几个方面讲解一下,希望大家看了后有一点了解。
1、消息的组成:
一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)。
当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。
例如当菜单转中之后会有WM_COMMAND消息发送,WPARAM的高字中(HIWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。
当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。
2、谁将收到消息:
一个消息必须由一个窗口接收。
在窗口的过程(WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。
例如你希望对菜单选择进行处理那么你可以定义对WM_COMMAND进行处理的代码,如果希望在窗口中进行图形输出就必须对WM_PAINT进行处理。
3、未处理的消息到那里去了:
M$为窗口编写了默认的窗口过程,这个窗口过程将负责处理那些你不处理消息。
正因为有了这个默认窗口过程我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。
例如窗口在被拖动时会有很多消息发送,而我们都可以不予理睬让系统自己去处理。
4、窗口句柄:
说到消息就不能不说窗口句柄,系统通过窗口句柄来在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。
而每个窗口都会有自己的窗口过程,所以用户的输入就会被正确的处理。
例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时消息就会通过窗口一的句柄被发送到窗口一而不是窗口二。
5、示例:
下面有一段伪代码演示如何在窗口过程中处理消息
LONGyourWndProc(HWNDhWnd,UINTuMessageType,WPARAMwP,LPARAM)
{
switch(uMessageType)
{//使用SWITCH语句将各种消息分开
case(WM_PAINT):
doYourWindow(...);
//在窗口需要重新绘制时进行输出
break;
case(WM_LBUTTONDOWN):
doYourWork(...);
//在鼠标左键被按下时进行处理
default:
callDefaultWndProc(...);
//对于其它情况就让系统自己处理
}
}
接下来谈谈什么是消息机制:
系统将会维护一个或多个消息队列,所有产生的消息都回被放入或是插入队列中。
系统会在队列中取出每一条消息,根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。
每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。
而在没有消息时消息循环就将控制权交给系统所以Windows可以同时进行多个任务。
下面的伪代码演示了消息循环的用法:
while
(1)
id=getMessage(...);
if(id==quit)
translateMessage(...);
当该程序没有消息通知时getMessage就不会返回,也就不会占用系统的CPU时间。
下图为消息投递模式
在16位的系统中系统中只有一个消息队列,所以系统必须等待当前任务处理消息后才可以发送下一消息到相应程序,如果一个程序陷如死循环或是耗时操作时系统就会得不到控制权。
这种多任务系统也就称为协同式的多任务系统。
Windows3.X就是这种系统。
而32位的系统中每一运行的程序都会有一个消息队列,所以系统可以在多个消息队列中转换而不必等待当前程序完成消息处理就可以得到控制权。
这种多任务系统就称为抢先式的多任务系统。
Windows95/NT就是这种系统。
1.3利用VisualC++/MFC开发Windows程序的优势
MFC借助C++的优势为Windows开发开辟了一片新天地,同时也借助ApplicationWizzard使开发者摆脱离了那些每次都必写基本代码,借助ClassWizard和消息映射使开发者摆脱了定义消息处理时那种混乱和冗长的代码段。
更令人兴奋的是利用C++的封装功能使开发者摆脱Windows中各种句柄的困扰,只需要面对C++中的对象,这样一来使开发更接近开发语言而远离系统。
(但我个人认为了解系统原理对开发很有帮助)
正因为MFC是建立在C++的基础上,所以我强调C/C++语言基础对开发的重要性。
利用C++的封装性开发者可以更容易理解和操作各种窗口对象;
利用C++的派生性开发者可以减少开发自定义窗口的时间和创造出可重用的代码;
利用虚拟性可以在必要时更好的控制窗口的活动。
而且C++本身所具备的超越C语言的特性都可以使开发者编写出更易用,更灵活的代码。
在MFC中对消息的处理利用了消息映射的方法,该方法的基础是宏定义实现,通过宏定义将消息分派到不同的成员函数进行处理。
下面简单讲述一下这种方法的实现方法:
代码如下
BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_COMMAND(ID_FONT_DROPDOWN,DoNothing)
END_MESSAGE_MAP()
经过编译后,代码被替换为如下形式(这只是作讲解,实际情况比这复杂得多):
//BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)
CMainFrame:
:
newWndProc(...)
switch(...)
{
//{{AFX_MSG_MAP(CMainFrame)
//ON_WM_CREATE()
case(WM_CREATE):
OnCreate(...);
//}}AFX_MSG_MAP
//ON_COMMAND(ID_FONT_DROPDOWN,DoNothing)
case(WM_COMMAND):
if(HIWORD(wP)==ID_FONT_DROPDOWN)
{
DoNothing(...);
}
//END_MESSAGE_MAP()
newWndProc就是窗口过程只要是该类的实例生成的窗口都使用该窗口过程。
所以了解了Windows的消息机制在加上对消息映射的理解就很容易了解MFC开发的基本思路了。
1.4利用MFC进行开发的通用方法介绍
以下是我在最初学习VC时所常用的开发思路和方法,希望能对初学VC的朋友有所帮助和启发。
1、开发需要读写文件的应用程序并且有简单的输入和输出可以利用单文档视结构。
2、开发注重交互的简单应用程序可以使用对话框为基础的窗口,如果文件读写简单这可利用CFile进行。
3、开发注重交互并且文件读写复杂的的简单应用程序可以利用以CFormView为基础视的单文档视结构。
4、利用对话框得到用户输入的数据,在等级提高后可使用就地输入。
5、在对多文档要求不强烈时尽量避免多文档视结构,可以利用分隔条产生单文档多视结构。
6、在要求在多个文档间传递数据时使用多文档视结构。
7、学会利用子窗口,并在自定义的子窗口包含多个控件达到封装功能的目的。
8、尽量避免使用多文档多视结构。
9、不要使用多重继承并尽量减少一个类中封装过多的功能。
1.5MFC中常用类,宏,函数介绍
常用类
CRect:
用来表示矩形的类,拥有四个成员变量:
topleftbottomright。
分别表是左上角和右下角的坐标。
可以通过以下的方法构造:
CRect(intl,intt,intr,intb);
指明四个坐标
CRect(constRECT&
srcRect);
由RECT结构构造
CRect(LPCRECTlpSrcRect);
CRect(POINTpoint,SIZEsize);
有左上角坐标和尺寸构造
CRect(POINTtopLeft,POINTbottomRight);
有两点坐标构造
下面介绍几个成员函数:
intWidth()const;
得到宽度
intHeight()const;
得到高度
CSizeSize()const;
得到尺寸
CPoint&
TopLeft();
得到左上角坐标
BottomRight();
得到右下角坐标
CPointCenterPoint()const;
得当中心坐标
此外矩形可以和点(CPoint)相加进行位移,和另一个矩形相加得到“并”操作后的矩形。
CPoint:
用来表示一个点的坐标,有两个成员变量:
xy。
可以和另一个点相加。
CString:
用来表示可变长度的字符串。
使用CString可不指明内存大小,CString会根据需要自行分配。
GetLength得到字符串长度
GetAt得到指定位置处的字符
operator+相当于strcat
voidFormat(LPCTSTRlpszFormat,...);
相当于sprintf
Find查找指定字符,字符串
Compare比较
CompareNoCase不区分大小写比较
MakeUpper改为小写
MakeLower改为大写
CStringArray:
用来表示可变长度的字符串数组。
数组中每一个元素为CString对象的实例。
Add增加CString
RemoveAt删除指定位置CString对象
RemoveAll删除数组中所有CString对象
GetAt得到指定位置的CString对象
SetAt修改指定位置的CString对象
InsertAt在某一位置插入CString对象
常用宏
RGB
TRACE
ASSERT
VERIFY
常用函数
CWindApp*AfxGetApp();
HINSTANCEAfxGetInstanceHandle();
HINSTANCEAfxGetResourceHandle();
intAfxMessageBox(LPCTSTRlpszText,UINTnType=MB_OK,UINTnIDHelp=0);
用于弹出一个消息框
2.1和GUI有关的各种对象
在Windows中有各种GUI对象(不要和C++对象混淆),当你在进行绘图就需要利用这些对象。
而各种对象都拥有各种属性,下面分别讲述各种GUI对象和拥有的属性。
字体对象CFont用于输出文字时选用不同风格和大小的字体。
可选择的风格包括:
是否为斜体,是否为粗体,字体名称,是否有下划线等。
颜色和背景色不属于字体的属性。
关于如何创建和使用字体在2.2在窗口中输出文字中会详细讲解。
刷子CBrush对象决定填充区域时所采用的颜色或模板。
对于一个固定色的刷子来讲它的属性为颜色,是否采用网格和网格的类型如水平的,垂直的,交叉的等。
你也可以利用8*8的位图来创建一个自定义模板的刷子,在使用这种刷子填充时系统会利用位图逐步填充区域。
关于如何创建和使用刷子在2.3使用刷子,笔进行绘图中会详细讲解。
画笔CPen对象在画点和画线时有用。
它的属性包括颜色,宽度,线的风格,如虚线,实线,点划线等。
关于如何创建和使用画笔在2.3使用刷子,笔进行绘图中会详细讲解。
位图CBitmap对象可以包含一幅图像,可以保存在资源中。
关于如何使用位图在2.4在窗口中绘制设备相关位图,图标,设备无关位图中会详细讲解。
还有一种特殊的GUI对象是多边形,利用多边形可以很好的限制作图区域或是改变窗口外型。
关于如何创建和使用多边形在2.6多边形和剪贴区域中会详细讲解。
在Windows中使用GUI对象必须遵守一定的规则。
首先需要创建一个合法的对象,不同的对象创建方法不同。
然后需要将该GUI对象选入DC中,同时保存DC中原来的GUI对象。
如果选入一个非法的对象将会引起异常。
在使用完后应该恢复原来的对象,这一点特别重要,如果保存一个临时对象在DC中,而在临时对象被销毁后可能引起异常。
有一点必须注意,每一个对象在重新创建前必须销毁,下面的代码演示了这一种安全的使用方法:
OnDraw(CDC*pDC)
CPenpen1,pen2;
pen1.CreatePen(PS_SOLID,2,RGB(128,128,128));
//创建对象
pen2.CreatePen(PS_SOLID,2,RGB(128,128,0));
CPen*pPenOld=(CPen*)pDC->
SelectObject(&
pen1);
//选择对象进DC
drawWithPen1...
(CPen*)pDC->
pen2);
drawWithPen2...
pen1.DeleteObject();
//再次创建前先销毁
pen1.CreatePen(PS_SOLID,2,RGB(0,0,0));
//再次创建对象
pDC->
SelectObject(pOldPen);
//恢复
此外系统中还拥有一些库存GUI对象,你可以利用CDC:
SelectStockObject(SelectStockObject(intnIndex)选入这些对象,它们包括一些固定颜色的刷子,画笔和一些基本字体。
∙BLACK_BRUSH
Blackbrush.
∙DKGRAY_BRUSH
Darkgraybrush.
∙GRAY_BRUSH
Graybrush.
∙HOLLOW_BRUSH
Hollowbrush.
∙LTGRAY_BRUSH
Lightgraybrush.
∙NULL_BRUSH
Nullbrush.
∙WHITE_BRUSH
Whitebrush.
∙BLACK_PEN
Blackpen.
∙NULL_PEN
Nullpen.
∙WHITE_PEN
Whitepen.
∙ANSI_FIXED_FONT
ANSIfixedsystemfont.
∙ANSI_VAR_FONT
ANSIvariablesystemfont.
∙DEVICE_DEFAULT_FONT
Device-dependentfont.
∙OEM_FIXED_FONT
OEM-dependentfixedfont.
∙SYSTEM_FONT
Thesystemfont.Bydefault,Windowsusesthesystemfonttodrawmenus,dialog-boxcontrols,andothertext.InWindowsversions3.0andlater,thesystemfontisproportionalwidth;
earlierversionsofWindowsuseafixed-widthsystemfont.
∙SYSTEM_FIXED_FONT
Thefixed-widthsystemfontusedinWindowspriortoversion3.0.ThisobjectisavailableforcompatibilitywithearlierversionsofWindows.
∙DEFAULT_PALETTE
Defaultcolorpalette.Thispaletteconsistsofthe20staticcolorsinthesystempalette.
这些对象留在DC中是安全的,所以你可以利用选入库存对象来作为恢复DC中GUI对象。
大家可能都注意到了绘图时都需要一个DC对象,DC(DeviceContext设备环境)对象是一个抽象的作图环境,可能是对应屏幕,也可能是对应打印机或其它。
这个环境是设备无关的,所以你在对不同的设备输出时只需要使用不同的设备环境就行了,而作图方式可以完全不变。
这也就是Windows耀眼的一点设备无关性。
如同你将对一幅画使用照相机或复印机将会产生不同的输出,而不需要对画进行任何调整。
DC的使用会穿插在本章中进行介绍。
2.2在窗口中输出文字
在这里我假定读者已经利用ApplicationWizard生成了一个SDI界面的程序代码。
接下来的你只需要在CView派生类的OnDraw成员函数中加入绘图代码就可以了。
在这里我需要解释一下OnDraw函数的作用,OnDraw函数会在窗口需要重绘时自动被调用,传入的参数CDC*pDC对应的就是DC环境。
使用OnDraw的优点就在于在你使用打印功能的时候传入OnDraw的DC环境将会是打印机绘图环境,使用打印预览时传入的是一个称为CPreviewDC的绘图环境,所以你只需要一份代码就可以完成窗口/打印预览/打印机绘图三重功能。
利用Windows的设备无关性和M$为打印预览所编写的上千行代码你可以很容易的完成一个具有所见即所得的软件。
输出文字一般使用CDC:
BOOLTextOut(intx,inty,constCString&
str)和CDC:
intDrawText(constCString&
str,LPRECTlpRect,UINTnFormat)两个函数,对TextOut来讲只能输出单行的文字,而DrawText可以指定在一个矩形中输出单行或多行文字,并且可以规定对齐方式和使用何种风格。
nFormat可以是多种以下标记的组合(利用位或操作)以达到选择输出风格的目的。
∙DT_BOTTOM底部对齐
Specifiesbottom-justifiedtext.ThisvaluemustbecombinedwithDT_SINGLELINE.
∙DT_CALCRECT计算指定文字时所需要矩形尺寸
Determinesthewidthandheightoftherectangle.Iftherearemultiplelinesoftext,DrawTextwillusethewidthoftherectanglepointedtobylpRectandextendthebaseoftherectangletoboundthelastlineoftext.Ifthereisonlyonelineoftext,DrawTextwillmodifytherightsideoftherectanglesothatitboundsthelastcharacterintheline.Ineithercase,DrawTextreturnstheheightoftheformattedtext,butdoesnotdrawthetext.
∙DT_CENTER中部对齐
Centerstexthorizontally.
∙DT_END_ELLIPSISorDT_PATH_ELLIPSIS
Replacespartofthegivenstringwithellipses,ifnecessary,sothattheresultfitsinthespecifiedrectangle.ThegivenstringisnotmodifiedunlesstheDT_MODIFYSTRINGflagisspecified.
YoucanspecifyDT_END_ELLIPSIStoreplacecharactersattheendofthestring,orDT_PATH_ELLIPSIStoreplacecharactersinthemiddleofthestring.Ifthestringcontainsbackslash(\)characters,DT_PATH_ELLIPSISpreservesasmuchaspossibleofthetextafterthelastbackslash.
∙DT_EXPANDTABS
Expandstabcharacters.Thedefaultnumberofcharacterspertabiseight.
∙DT_EXTERNALLEADING
Includesthefont抯externalleadinginthelineheight.No