《孙鑫C++教程(全20讲)PPT讲义》由会员分享,可在线阅读,更多相关《孙鑫C++教程(全20讲)PPT讲义(134页珍藏版)》请在金锄头文库上搜索。
1、1.Windows程序内部运行原理 主讲人:孙鑫http:/www.sunxin.orgWindows应用程序,操作系统,计应用程序,操作系统,计算机硬件之间的相互关系算机硬件之间的相互关系 http:/www.sunxin.org关于关于API向下的箭头表示应用程序可以通知操作系统执行某个具体的动作,如操作系统能够控制声卡发出声音,但它并不知道应该何时发出何种声音,需要应用程序告诉操作系统该发出什么样的声音。这个关系好比有个机器人能够完成行走的功能,但是,如果人们不告诉它往哪个方向上走,机器人是不会主动行走的。这里的机器人就是操作系统,人们就是应用程序。 http:/www.sunxin.o
2、rg关于关于API 那么,应用程序是如何通知操作系统执行某个功能的呢?有过编程经验的读者都应该知道,在应用程序中要完成某个功能,都是以函数调用的形式实现的,同样,应用程序也是以函数调用的方式来通知操作系统执行相应的功能的。操作系统所能够完成的每一个特殊功能通常都有一个函数与其对应,也就是说,操作系统把它所能够完成的功能以函数的形式提供给应用程序使用,应用程序对这些函数的调用就叫做系统调用,这些函数的集合就是Windows操作系统提供给应用程序编程的接口(Application Programming Interface),简称Windows API。如CreateWindow就是一个API函数
3、,应用程序中调用这个函数,操作系统就会按照该函数提供的参数信息产生一个相应的窗口。 http:/www.sunxin.org关于消息及消息队列关于消息及消息队列向上的箭头表示操作系统能够将输入设备的变化上传给应用程序。如用户在某个程序活动时按了一下键盘,操作系统马上能够感知到这一事件,并且能够知道用户按下的是哪一个键,操作系统并不决定对这一事件如何作出反应,而是将这一事件转交给应用程序,由应用程序决定如何对这一事件作出反应。好比有个蚊子叮了我们一口,我们的神经末梢(相当于操作系统)马上感知到这一事件,并传递给了我们的大脑(相当于应用程序),我们的大脑最终决定如何对这一事件作出反应,如将蚊子赶走
4、,或是将蚊子拍死。对事件作出反应的过程就是消息响应。 http:/www.sunxin.org关于消息及消息队列关于消息及消息队列 操作系统是怎样将感知到的事件传递给应用程序的呢操作系统是怎样将感知到的事件传递给应用程序的呢?这是通过消息机制?这是通过消息机制(Message)(Message)来实现的。操作系统将来实现的。操作系统将每个事件都包装成一个称为消息的结构体每个事件都包装成一个称为消息的结构体MSGMSG来传递来传递给应用程序,参看给应用程序,参看MSDNMSDN。MSGMSG结构定义如下:结构定义如下: typedef struct tagMSG typedef struct t
5、agMSG HWND hwnd; HWND hwnd; UINT message;UINT message; WPARAM wParam;WPARAM wParam; LPARAM lParam;LPARAM lParam; DWORD time;DWORD time; POINT pt;POINT pt; MSG; MSG; http:/www.sunxin.org关于句柄关于句柄 n n句柄(HANDLE),资源的标识。n n操作系统要管理和操作这些资源,都是通过句柄来找到对应的资源。按资源的类型,又可将句柄细分成图标句柄(HICON),光标句柄(HCURSOR),窗口句柄(HWND),应
6、用程序实例句柄(HINSTANCE)等等各种类型的句柄。操作系统给每一个窗口指定的一个唯一的标识号即窗口句柄。 http:/www.sunxin.org从变量的类型区分变量的用途从变量的类型区分变量的用途int x,y;int x,y;x=30;x=30;y=30;y=30;/x/x和和y y既可以用来表示坐标点,也可以用来表示宽度和既可以用来表示坐标点,也可以用来表示宽度和高度,还可以用来表示身高和体重。高度,还可以用来表示身高和体重。typedef int WIDTHtypedef int WIDTHtypedef int HEIGHTtypedef int HEIGHTWIDTH x;W
7、IDTH x;HEIGHT y;HEIGHT y;/好处:我们从变量的类型上就可以知道好处:我们从变量的类型上就可以知道x x和和y y是用来表是用来表示宽度和高度。示宽度和高度。http:/www.sunxin.orgWinMain函数函数 n nWindows程序的入口函数int WINAPI WinMain(int WINAPI WinMain( HINSTANCE HINSTANCE hInstancehInstance, / handle to current instance, / handle to current instance HINSTANCE HINSTANCE hPr
8、evInstancehPrevInstance, / handle to previous instance, / handle to previous instance LPSTR LPSTR lpCmdLinelpCmdLine, / command line, / command line int int nCmdShownCmdShow / show state / show state); );http:/www.sunxin.org窗口的创建窗口的创建 创建一个完整的窗口需要经过下面四个操作步骤:n n设计一个窗口类;n n注册窗口类;n n创建窗口;n n显示及更新窗口。http
9、:/www.sunxin.org设计窗口类设计窗口类typedef struct _WNDCLASS UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HANDLE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; WNDCLASS; http:/www.sunxin.org窗口类的类型窗口类的类型在我们的程序中经常要用到一类变量,这个变量里的每一位(
10、bit)都对应某一种特性。当该变量的某位为1时,表示有该位对应的那种特性,当该位为0时,即没有该位所对应的特性。当变量中的某几位同时为1时,就表示同时具有几种特性的组合。一个变量中的哪一位代表哪种意义,不容易记忆,所以我们经常根据特征的英文拼写的大写去定义一些宏,该宏所对应的数值中仅有与该特征相对应的那一位(bit)为1,其余的bit都为0。我们使用goto definition就能发现CS_VREDRAW=0x0001,CS_HREDRAW=0x0002,CS_DBLCLKS =0x0008,CS_NOCLOSE=0x0200。他们的共同点就是只有一位为1,其余位都为0。如果我们希望某一变量
11、的数值既有CS_VREDRAW特性,又有CS_HREDRAW特性,我们只需使用二进制OR(|)操作符将他们进行或运算相组合,如style=CS_VREDRAW | CS_HREDRAW | CS_NOCLOSE。如果我们希望在某一变量原有的几个特征上去掉其中一个特征,用取反()之后再进行与(&)运算,就能够实现,如在刚才的style的基础上去掉CS_NOCLOSE特征,可以用style & CS_NOCLOSE实现。 http:/www.sunxin.org窗口过程函数窗口过程函数第二个成员变量lpfnWndProc指定了这一类型窗口的过程函数,也称回调函数。回调函数的原理是这样的,当应用程序
12、收到给某一窗口的消息时(还记得前面讲过的消息通常与窗口相关的吗?),就应该调用某一函数来处理这条消息。这一调用过程不用应用程序自己来实施,而由操作系统来完成,但是,回调函数本身的代码必须由应用程序自己完成。对于一条消息,操作系统到底调用应用程序中的哪个函数(回调函数)来处理呢?操作系统调用的就是接受消息的窗口所属的类型中的lpfnWndProc成员指定的函数。每一种不同类型的窗口都有自己专用的回调函数,该函数就是通过lpfnWndProc成员指定的。 http:/www.sunxin.org窗口过程函数窗口过程函数举例:汽车厂家生产汽车好比应用程序创建窗口,用户使用汽车好比操作系统管理窗口,某
13、种汽车在销售前就指定好了修理站(类似回调函数),当用户的汽车出现故障后(类似窗口收到消息),汽车用户(类似操作系统)自己直接找到修理站去修理,不用厂家(类似应用程序)亲自将车送到修理站去修理,但修理站还得由厂家事先建造好。 http:/www.sunxin.org2.掌握掌握C+主讲人:孙鑫http:/www.sunxin.orgC+的标准输入输出流的标准输入输出流 C+中提供了一套输入输出流类的对象,它们是cin 、cout和cerr,对应c语言中的三个文件指针stdin、stdout、stderr,分别指向终端输入、终端输出和标准出错输出(也从终端输出)。cin与一起完成输入操作,cout
14、、cerr与i;注意箭头的方向。在输出中我们还使用endl(end of line),表示换行,注意最后一个是字符l,而不是数字1,endl相当于C语言的n,表示输出一个换行。 http:/www.sunxin.orgC+的特性的特性n n构造函数构造函数1、构造函数最重要的作用是创建对象本身 。2、C+规定,每个类必须有一个构造函数,没有构造函数,就不能创建任何对象。 http:/www.sunxin.orgC+的特性的特性n n构造函数构造函数3 3、C+C+又规定,如果一个类没有提供任何的构造函数,则又规定,如果一个类没有提供任何的构造函数,则C+C+提供一个默认的构造函数(由提供一个默
15、认的构造函数(由C+C+编译器提供),这编译器提供),这个默认的构造函数是一个不带参数的构造函数,它只负责个默认的构造函数是一个不带参数的构造函数,它只负责创建对象,而不做任何的初始化工作。创建对象,而不做任何的初始化工作。 4 4、只要一个类定义了一个构造函数,不管这个构造函数是、只要一个类定义了一个构造函数,不管这个构造函数是否是带参数的构造函数,否是带参数的构造函数,C+C+就不再提供默认的构造函数。就不再提供默认的构造函数。也就是说,如果为一个类定义了一个带参数的构造函数,也就是说,如果为一个类定义了一个带参数的构造函数,还想要无参数的构造函数,则必须自己定义。还想要无参数的构造函数,
16、则必须自己定义。 http:/www.sunxin.orgC+的特性的特性n n析构函数析构函数 1、当一个对象生命周期结束时,其所占有的内存空间就要被回收,这个工作就由析构函数来完成。 2、析构函数是“反向”的构造函数,析构函数不允许有返回值,更重要的是析构函数不允许带参数,并且一个类中只能有一个析构函数。 http:/www.sunxin.orgC+的特性的特性n n析构函数析构函数3、析构函数的作用正好与构造函数相反,对象超出其作用范围,对应的内存空间被系统收回或被程序用delete删除时,析构函数被调用。 4、根据析构函数的这种特点,我们可以在构造函数中初始化对象的某些成员变量,给其分
17、配内存空间(堆内存),在析构函数中释放对象运行期间所申请的资源。 http:/www.sunxin.orgC+的特性的特性n n函数的重载函数的重载 重载构成的条件:函数的参数类型、参数个数不同,才能构成函数的重载。 http:/www.sunxin.orgC+的特性的特性n n函数的重载函数的重载分析以下两种情况,是否构成函数的重载。分析以下两种情况,是否构成函数的重载。第一种情况:(第一种情况:(1)void output(); (2)int output();第二种情况:(第二种情况:(1)void output(int a,int b=5); (2)void output(int a)
18、; http:/www.sunxin.orgC+的特性的特性n nthisthis指针指针指针指针 1 1、thisthis指针是一个隐含的指针,它是指向对象本身,指针是一个隐含的指针,它是指向对象本身,代表了对象的地址代表了对象的地址 2 2、一个类所有的对象调用的成员函数都是同一代码、一个类所有的对象调用的成员函数都是同一代码段。那么成员函数又是怎么识别属于同一对象的段。那么成员函数又是怎么识别属于同一对象的数据成员呢?原来,在对象调用数据成员呢?原来,在对象调用pt.output(10,10)pt.output(10,10)时,成员函数除了接受时,成员函数除了接受2 2个实参外,还接受到
19、了一个实参外,还接受到了一个对象个对象s s的地址。这个地址被一个隐含的形参的地址。这个地址被一个隐含的形参thisthis指针所获取,它等同于执行指针所获取,它等同于执行this=&ptthis=&pt。所有对数。所有对数据成员的访问都隐含地被加上前缀据成员的访问都隐含地被加上前缀this-this-。例如:。例如:x=0; x=0; 等价于等价于 this-x=0 this-x=0。 http:/www.sunxin.org小技巧:小技巧:在以后的MFC编程中,如果在成员函数中想调用同类中的某个成员,可以使用VC+提供的自动列出成员函数功能,使用this-,VC+将列出该类中的所有成员,我
20、们可以从列表中选择我们想调用的成员。自动列出成员函数功能,可以提高编写速度,减少拼写错误。我们经常不能完全记住某个函数的完整拼写,但却能够从列表中辨别出该函数,自动列出成员函数的功能在这时就显得更加有用了。事实上,在各种IDE编程环境中,我们通常都不可能记住也没有必要记住所有的函数,只要将常用的函数记住,其他不常用的函数只要记住其大概的写法和功能,在调用该函数时可以从自动列出成员函数中选取,这样可以大大节省我们的学习时间。我们不用花费大量的时间去死记硬背许多函数,利用自动列出成员函数功能和帮助系统,就能够在编程时顺利地使用这些函数,等用的次数多了,也就在不知不觉中完全掌握了这些函数。 http
21、:/www.sunxin.orgC+的特性的特性n n类的继承类的继承 在在C+中,给我们提供了一种重要的机制,中,给我们提供了一种重要的机制,就是继承。就是继承。 理解继承是理解面向对象程序设计的关键。 http:/www.sunxin.org类的继承访问特性类的继承访问特性 基基类的的访问特性特性类的的继承特性承特性子子类的的访问特性特性PublicProtectedPrivatePublicPublicProtectedNo accessPublicProtectedPrivateProtectedProtectedProtectedNo accessPublicProtectedPri
22、vatePrivatePrivatePrivateNo accesshttp:/www.sunxin.orgC+的特性的特性n n函数的覆盖函数的覆盖函数的覆盖是发生在父类与子类之间的。函数的覆盖是发生在父类与子类之间的。 http:/www.sunxin.org类型转换类型转换char ch;int i;1Bytech=(char)i;i=(int)ch;1Byte1Byte1Byte1Bytehttp:/www.sunxin.orgFish对象内存布局对象内存布局Animal对象内存Fish继承部分this指针Fish对象的内存图 Fish对象内存布局http:/www.sunxin.or
23、gC+的特性的特性n n多态性多态性 当C+编译器在编译的时候,发现Animal类的breathe()函数是虚函数,这个时候C+就会采用迟绑定(late binding)的技术,在运行时,依据对象的类型(在程序中,我们传递的Fish类对象的地址)来确认调用的哪一个函数,这种能力就做C+的多态性。http:/www.sunxin.org引用和指针变量的内存模型引用和指针变量的内存模型 http:/www.sunxin.orgVC+程序编译链接原理与过程程序编译链接原理与过程 Animal.cppFish.cppmain.cppAnimal.hFish.h翻译单元1翻译单元2翻译单元3Animal
24、.objFish.objmain.obj.libC+的标准库函数标准类库.exe可执行文件编译(Compile)预处理链接(Link)#include#includehttp:/www.sunxin.org5.文本编程文本编程主讲人:孙鑫http:/www.sunxin.org字体的信息字体的信息 ghtmAscenttmDescentbase linehttp:/www.sunxin.org6.菜单菜单主讲人:孙鑫http:/www.sunxin.org消息的分类消息的分类 n n标准消息标准消息 除WM_COMMAND之外,所有以WM_开头的消息。 从CWnd派生的类,都可以接收到这类消息
25、。n n命令消息命令消息 来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的wParam参数识别。从CCmdTarget派生的类,都可以接收到这类消息。n n通告消息通告消息 由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。这类消息也是以WM_COMMAND形式呈现。从CCmdTarget派生的类,都可以接收到这类消息。http:/www.sunxin.org命令消息的路由命令消息的路由AfxWndProcAfxCallWnd
26、ProcWindowProcOnWndMsgOnCommandOnNotifyOnCmdMsghttp:/www.sunxin.org300300301301302302303303304304012301234楼层房间菜单的结构菜单的结构http:/www.sunxin.org命令更新命令更新 菜单项状态的维护是依赖于CN_UPDATE_COMMAND_UI消息,谁捕获CN_UPDATE_COMMAND_UI消息,MFC就在其中创建一个CCmdUI对象。我们可以通过手工或利用ClassWizard在消息映射中添加ON_UPDATE_COMMAND_UI宏来捕获CN_UPDATE_COMMAN
27、D_UI消息。 在后台所做的工作是:操作系统发出WM_INITMENUPOPUP消息,然后由MFC的基类如CFrameWnd接管。它创建一个CCmdUI对象,并与第一个菜单项相关联,调用对象的一个成员函数DoUpdate()。这个函数发出CN_UPDATE_COMMAND_UI消息,这条消息带有指向CCmdUI对象的指针。同一个CCmdUI对象就设置为与第二个菜单项相关联,这样顺序进行,直到完成所有菜单项。 更新命令UI处理程序仅应用于弹出式菜单项上的项目,不能应用于永久显示的顶级菜单项目。http:/www.sunxin.org7.对话框对话框主讲人:孙鑫http:/www.sunxin.o
28、rg对话框控件访问七种方式对话框控件访问七种方式n nGetDlgItem()-Get(Set)WindowText()n nGetDlgItemText()/SetDlgItemText()n nGetDlgItemInt()/SetDlgItemInt()n n将控件和整型变量相关联n n将控件和控件变量相关联n nSendMessage()n nSendDlgItemMessage()Z-order 窗口的Z次序表明了重叠窗口堆中窗口的位置,这个窗口堆是按一个假想的轴定位的,这个轴就是从屏幕向外伸展的Z轴。Z次序最上面的窗口覆盖所有其它的窗口,Z次序最底层的窗口被所有其它的窗口覆盖。应用
29、程序设置窗口在Z次序中的位置是通过把它放在一个给定窗口的后面,或是放在窗口堆的顶部或底部。 Windows系统管理三个独立的Z次序一个用于顶层窗口、一个用于兄弟窗口,还有一个是用于最顶层窗口。最顶层窗口覆盖所有其它非最顶层窗口,而不管它是不是活动窗口或是前台窗口。应用程序通过设置WS_EX_TOPMOST风格创建最顶层窗口。 一般情况下,Windows系统把刚刚创建的窗口放在Z次序的顶部,用户可通过激活另外一个窗口来改变Z次序;Windows系统总是把活动的窗口放在Z次序的顶部,应用程序可用函数BringWindowToTop把一个窗口放置到Z次序的顶部。函数SetWindowPos和Defe
30、rWindowPos用来重排Z次序。http:/www.sunxin.org窗口窗口n n兄弟窗口 共享同一个父窗口的多个子窗口叫兄弟窗口。共享同一个父窗口的多个子窗口叫兄弟窗口。n n活动窗口 活动窗口是应用程序的顶层窗口,也就是当前使用的活动窗口是应用程序的顶层窗口,也就是当前使用的窗口。只有一个顶层窗口可以是活动窗口,如果用户使用窗口。只有一个顶层窗口可以是活动窗口,如果用户使用的是一个子窗口,的是一个子窗口,WindowsWindows系统就激活与这个子窗口相应系统就激活与这个子窗口相应的顶层窗口。的顶层窗口。 任何时候系统中只能有一个顶层窗口是活动的。用户任何时候系统中只能有一个顶层
31、窗口是活动的。用户通过单击窗口(或其中的一个子窗口)、使用通过单击窗口(或其中的一个子窗口)、使用ALT+TABALT+TAB或或ALT+ESCALT+ESC组合键来激活一个顶层窗口,应用程序则调用函组合键来激活一个顶层窗口,应用程序则调用函数数SetActiveWindowSetActiveWindow来激活一个顶层窗口。来激活一个顶层窗口。http:/www.sunxin.org窗口窗口n n前台窗口和后台窗口 在在WindowsWindows系统中,每一个进程可运行多个线程,每系统中,每一个进程可运行多个线程,每个线程都能创建窗口。创建正在使用窗口的线程称之为前个线程都能创建窗口。创建正
32、在使用窗口的线程称之为前台线程,这个窗口就称之为前台窗口。所有其它的线程都台线程,这个窗口就称之为前台窗口。所有其它的线程都是后台线程,由后台线程所创建的窗口叫后台窗口。是后台线程,由后台线程所创建的窗口叫后台窗口。 用户通过单击一个窗口、使用用户通过单击一个窗口、使用ALT+TABALT+TAB或或ALT+ESCALT+ESC组组合键来设置前台窗口,应用程序则用函数合键来设置前台窗口,应用程序则用函数SetForegroundWindowSetForegroundWindow设置前台窗口。如果新的前台窗口设置前台窗口。如果新的前台窗口是一个顶层窗口,那么是一个顶层窗口,那么WindowsWi
33、ndows系统就激活它,换句话说,系统就激活它,换句话说,WindowsWindows系统激活相应的顶层窗口。系统激活相应的顶层窗口。http:/www.sunxin.org8.对话框对话框(续续)主讲人:孙鑫http:/www.sunxin.orgpWeiXinBtn=0088:4400pWeiXinBtn=0088:46600088:44000088:4660m_btn1m_btn2CWeiXinBtn m_btn1;CWeiXinBtn m_btn2;http:/www.sunxin.org10.在窗口中贴图在窗口中贴图主讲人:孙鑫http:/www.sunxin.org在窗口中贴图在窗
34、口中贴图1、创建位图CBitmap bitmap;bitmap.LoadBitmap(IDB_BITMAP1);2、创建兼容DCCDC dcCompatible;dcCompatible.CreateCompatibleDC(pDC);3、将位图选到兼容DC中dcCompatible.SelectObject(&bitmap);4、将兼容DC中的位图贴到当前DC中。pDC-BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);位图兼容DC当前DChttp:/www.sunxin.org11
35、. 图形的图形的保存和重绘保存和重绘主讲人:孙鑫http:/www.sunxin.org在在OnLButtonUp函数中0088:4400CGraph graph();CGraph的对象在栈中的内存0088:4400CPtrArray m_ptrArray;m_ptrArray.Add(&graph)http:/www.sunxin.orgCGraph的对象发生析构,内存被回收。如何解决这个问题呢?http:/www.sunxin.org在在OnLButtonUp函数中1244:EE00CGraph的对象在堆中的内存CPtrArray m_ptrArray;CGraph *pGraph;008
36、8:46601244:EE001244:EE00pGraph的内存m_ptrArray.Add(pGraph);pGraph=new CGraph();http:/www.sunxin.org仍然能索引到CGraph的对象pGraph的内存被回收坐标空间坐标空间n n Microsoft WindowsMicrosoft Windows下的程序运用坐标空间和转换来对图下的程序运用坐标空间和转换来对图形输出进行缩放、旋转、平移、斜切和反射。形输出进行缩放、旋转、平移、斜切和反射。n n一个坐标空间是一个平面的空间,通过使用两个相互垂直一个坐标空间是一个平面的空间,通过使用两个相互垂直并且长度相等
37、的轴来定位二维对象。并且长度相等的轴来定位二维对象。(0,0)XmaxXminYmaxYminhttp:/www.sunxin.org坐标空间坐标空间n nWin32Win32应用程序设计接口应用程序设计接口(API)(API)使用四种坐标空间:使用四种坐标空间:世界坐标系空间、页面空间、设备空间、和物理世界坐标系空间、页面空间、设备空间、和物理设备空间。应用程序运用世界坐标系空间对图形设备空间。应用程序运用世界坐标系空间对图形输出进行旋转、斜切或者反射。输出进行旋转、斜切或者反射。n nWin32 APIWin32 API把世界坐标系空间和页面空间称为逻辑把世界坐标系空间和页面空间称为逻辑空
38、间;最后一种坐标空间空间;最后一种坐标空间( (即物理设备空间即物理设备空间) )通常通常指应用程序窗口的客户区;但是它也包括整个桌指应用程序窗口的客户区;但是它也包括整个桌面、完整的窗口面、完整的窗口( (包括框架、标题栏和菜单栏包括框架、标题栏和菜单栏) )或或打印机的一页或绘图仪的一页纸。物理设备的尺打印机的一页或绘图仪的一页纸。物理设备的尺寸随显示器、打印机或绘图仪所设置的尺寸而变寸随显示器、打印机或绘图仪所设置的尺寸而变化。化。,http:/www.sunxin.org转换转换n n如要在物理设备上绘制输出,如要在物理设备上绘制输出,WindowsWindows把一个矩形区域从把一个
39、矩形区域从一个坐标空间拷贝到一个坐标空间拷贝到( (或映射到或映射到) )另一个坐标空间,直至最另一个坐标空间,直至最终完整的输出呈现在物理设备上(通常是屏幕或打印机)终完整的输出呈现在物理设备上(通常是屏幕或打印机) 。n n如果该应用程序调用了如果该应用程序调用了SetWorldTransformSetWorldTransform函数,那么映函数,那么映射就从应用程序的世界坐标系空间开始;否则,映射在页射就从应用程序的世界坐标系空间开始;否则,映射在页面空间中进行。在面空间中进行。在WindowsWindows把矩形区域的每一点从一个空把矩形区域的每一点从一个空间拷贝到另一个空间时,它采用
40、了一种被称作转换的算法,间拷贝到另一个空间时,它采用了一种被称作转换的算法,转换是把对象从一个坐标空间拷贝到另一个坐标空间时改转换是把对象从一个坐标空间拷贝到另一个坐标空间时改变变( (或转变或转变) )这一对象的大小、方位、和形态,尽管转换把这一对象的大小、方位、和形态,尽管转换把对象看成一个整体,但它也作用于对象中的每一点或每条对象看成一个整体,但它也作用于对象中的每一点或每条线。线。http:/www.sunxin.org转换转换YmaxYmin世界坐标系空间 下图是运用下图是运用SetWorldTransform函数而函数而进行的一个典型转换。进行的一个典型转换。YmaxYmin页面空
41、间YminYmax设备空间物理设备http:/www.sunxin.org页面空间到设备空间的转换页面空间到设备空间的转换n n页面空间到设备空间的转换是原Windows接口的一部分。这种转换确定与一特定设备描述表相关的所有图形输出的映射方式。n n所谓映射方式是指确定用于绘图操作的单位大小的一种量度转换。映射方式是一种影响几乎任何客户区绘图的设备环境属性。另外还有四种设备环境属性:窗口原点、视口原点、窗口范围和视口范围,这四种属性与映射方式密切相关。http:/www.sunxin.org页面空间到设备空间的转换页面空间到设备空间的转换n n页面空间到设备空间的转换所用的是两个矩形的宽与高的
42、比率,其中页面空页面空间到设备空间的转换所用的是两个矩形的宽与高的比率,其中页面空间中的矩形被称为窗口,设备空间中的矩形被称为视口,间中的矩形被称为窗口,设备空间中的矩形被称为视口,WindowsWindows把窗口原把窗口原点映射到视口原点,把窗口范围映射到视口范围,就完成了这种转换,如下点映射到视口原点,把窗口范围映射到视口范围,就完成了这种转换,如下图所示:图所示:窗口原点视口原点窗口视口页面空间设备空间http:/www.sunxin.org设备空间到物理空间的转换设备空间到物理空间的转换n n设备空间到物理空间的转换有几个独特之处:它只限于平移,并由Windows的窗口管理部分控制,
43、这种转换的唯一用途是确保设备空间的原点被映射到物理设备上的适当点上。没有函数能设置这种转换,也没有函数可以获取有关数据。http:/www.sunxin.org默认转换默认转换n n一旦应用程序建立了设备描述表,并立即开始调用一旦应用程序建立了设备描述表,并立即开始调用GDIGDI绘图或输出函绘图或输出函数,则运用默认页面空间到设备空间的转换和设备空间到客户区的转数,则运用默认页面空间到设备空间的转换和设备空间到客户区的转换换( (在应用程序调用在应用程序调用SetWorldTransformSetWorldTransform函数之前,不会出现世界坐标函数之前,不会出现世界坐标空间到页面空间的
44、转换空间到页面空间的转换) )。n n 默认页面空间到设备空间的转换结果是一对一的映射;即页面空间上默认页面空间到设备空间的转换结果是一对一的映射;即页面空间上给出的一点映射到设备空间的一个点。正如前文讲到的,这种转换没给出的一点映射到设备空间的一个点。正如前文讲到的,这种转换没有以矩阵指定,而是通过把视口宽除以窗口宽,把视口高除以窗口高有以矩阵指定,而是通过把视口宽除以窗口宽,把视口高除以窗口高而得出的。在默认的情况下,视口尺寸为而得出的。在默认的情况下,视口尺寸为1x11x1个象素,窗口尺寸为个象素,窗口尺寸为1x11x1页单位。页单位。n n 设备空间到物理设备设备空间到物理设备( (客
45、户区、桌面或打印机客户区、桌面或打印机) )的转换结果总是一对一的转换结果总是一对一的;即设备空间的一个单位总是与客户区、桌面、或打印机上的一个的;即设备空间的一个单位总是与客户区、桌面、或打印机上的一个单位相对应。这一转换的唯一用途是平移。无论窗口移到桌面的什么单位相对应。这一转换的唯一用途是平移。无论窗口移到桌面的什么位置,它永远确保输出能够正确无误地出现在窗口上。位置,它永远确保输出能够正确无误地出现在窗口上。n n默认转换的一个独特之处是设备空间和应用程序窗口的默认转换的一个独特之处是设备空间和应用程序窗口的y y轴方向。在轴方向。在默认的状态下,默认的状态下,y y轴正向朝下,负轴正
46、向朝下,负y y方向朝上。方向朝上。http:/www.sunxin.org逻辑坐标和设备坐标逻辑坐标和设备坐标n n几乎在所有的几乎在所有的GDIGDI函数中使用的坐标值都是采用的逻辑单函数中使用的坐标值都是采用的逻辑单位。位。WindowsWindows必须将逻辑单位转换为必须将逻辑单位转换为“ “设备单位设备单位” ”,即像,即像素。这种转换是由映射方式、窗口和视口的原点以及窗口素。这种转换是由映射方式、窗口和视口的原点以及窗口和视口的范围所控制的。和视口的范围所控制的。n nWindowsWindows对所有的消息对所有的消息( (如如WM_SIZEWM_SIZE、WM_MOUSEMO
47、VEWM_MOUSEMOVE、WM_LBUTTONDOWNWM_LBUTTONDOWN、WM_LBUTTONUP)WM_LBUTTONUP),所有的非,所有的非GDIGDI函数和一些函数和一些GDIGDI函数函数( (例如例如GetDeviceCapsGetDeviceCaps函数函数) ),永远使用,永远使用设备坐标。设备坐标。n n“ “窗口窗口” ”是基于逻辑坐标的,逻辑坐标可以是象素、毫米、是基于逻辑坐标的,逻辑坐标可以是象素、毫米、英寸等单位;英寸等单位;“ “视口视口” ”是基于设备坐标是基于设备坐标( (象素象素) )的。通常,的。通常,视口和客户区是相同的。视口和客户区是相同的
48、。n n缺省的映射模式为缺省的映射模式为MM_TEXTMM_TEXT。在这种映射模式下,逻辑。在这种映射模式下,逻辑单位和设备单位相同。单位和设备单位相同。http:/www.sunxin.org逻辑坐标和设备坐标的相互转换逻辑坐标和设备坐标的相互转换n n窗口窗口( (逻辑逻辑) )坐标转换为视口坐标转换为视口( (设备设备) )坐标的两个公式:坐标的两个公式:xViewport=(xWindow-xWinOrg)* +xViewOrgxViewport=(xWindow-xWinOrg)* +xViewOrgyViewport=(yWindow-yWinOrg)* +yViewOrgyVi
49、ewport=(yWindow-yWinOrg)* +yViewOrgn n视口视口( (设备设备) )坐标转换为窗口坐标转换为窗口( (逻辑逻辑) )坐标的两个公式:坐标的两个公式:xWindow=(xViewPort-xViewOrg)* +xWinOrgxWindow=(xViewPort-xViewOrg)* +xWinOrgyWindow=(yViewPort-yViewOrg)* +yWinOrgyWindow=(yViewPort-yViewOrg)* +yWinOrgxViewExtxWinExtyViewExtyWinExtxWinExtxViewExtyWinExtyVie
50、wExthttp:/www.sunxin.org在在MM_TEXT映射方式下逻辑坐标和映射方式下逻辑坐标和设备坐标的相互转换设备坐标的相互转换n n窗口窗口( (逻辑逻辑) )坐标转换为视口坐标转换为视口( (设备设备) )坐标的两个公式:坐标的两个公式:xViewport = xWindow-xWinOrg+xViewOrgxViewport = xWindow-xWinOrg+xViewOrgyViewport = yWindow-yWinOrg+yViewOrgyViewport = yWindow-yWinOrg+yViewOrgn n视口视口( (设备设备) )坐标转换为窗口坐标转换
51、为窗口( (逻辑逻辑) )坐标的两个公式:坐标的两个公式:xWindow = xViewport-xViewOrg+xWinOrgxWindow = xViewport-xViewOrg+xWinOrgyWindow = yViewport-yViewOrg+yWinOrgyWindow = yViewport-yViewOrg+yWinOrghttp:/www.sunxin.org视口和窗口原点的改变视口和窗口原点的改变n nCDCCDC中提供了两个成员函数函数中提供了两个成员函数函数SetViewportOrgSetViewportOrg和和SetWindowOrgSetWindowOrg
52、,用来改变视口和窗口的原点。,用来改变视口和窗口的原点。n n如果将视口原点设置为如果将视口原点设置为(xViewOrg,yViewOrg)(xViewOrg,yViewOrg),则,则逻辑点逻辑点(0,0)(0,0)就会被映射为设备点就会被映射为设备点(xViewOrg,yViewOrg)(xViewOrg,yViewOrg)。如果将窗口原点改变为。如果将窗口原点改变为(xWinOrg,yWinOrg)(xWinOrg,yWinOrg),则逻辑点,则逻辑点(xWinOrg,yWinOrg)(xWinOrg,yWinOrg)将会被映射为设备点将会被映射为设备点(0,0)(0,0),即左上角。即
53、左上角。n n不管对窗口和视口原点作什么改变,设备点不管对窗口和视口原点作什么改变,设备点(0,0)(0,0)始终是客户区的左上角。始终是客户区的左上角。http:/www.sunxin.org关于图形错位的说明关于图形错位的说明n n当我们在窗口中点击鼠标左键的时候,得到的是设备坐标当我们在窗口中点击鼠标左键的时候,得到的是设备坐标(680,390)(680,390),在,在MM_TEXTMM_TEXT的映射模式下,逻辑坐标和设备的映射模式下,逻辑坐标和设备坐标是相等的,所以我们利用集合类保存的这个点的坐标坐标是相等的,所以我们利用集合类保存的这个点的坐标是以象素为单位,坐标值为是以象素为单
54、位,坐标值为(680,390)(680,390)。在调用。在调用OnDrawOnDraw函函数前,在数前,在OnPaintOnPaint函数中调用了函数中调用了OnPrepareDCOnPrepareDC函数,调整了函数,调整了显示上下文的属性,将视口的原点设置为了显示上下文的属性,将视口的原点设置为了(0,-150)(0,-150),这,这样的话,窗口的原点,也就是逻辑坐标样的话,窗口的原点,也就是逻辑坐标(0,0)(0,0)将被映射为将被映射为设备坐标设备坐标(0,-150)(0,-150),在画线的时候,因为,在画线的时候,因为GDIGDI的函数使用的函数使用的是逻辑坐标,而图形在显示的
55、时候,的是逻辑坐标,而图形在显示的时候,WindowsWindows需要将逻需要将逻辑坐标转化为设备坐标,因此,原先保存的坐标点辑坐标转化为设备坐标,因此,原先保存的坐标点(680,390)(680,390)(在(在GDIGDI函数中,作为逻辑坐标使用),根据转函数中,作为逻辑坐标使用),根据转换公式换公式xViewport = xWindow-xWinOrg+xViewOrgxViewport = xWindow-xWinOrg+xViewOrg 和和yViewport = yWindow-yWinOrg+yViewOrgyViewport = yWindow-yWinOrg+yViewOr
56、g,得到设备点,得到设备点的的x x坐标为坐标为680-0+0=680680-0+0=680,设备点的,设备点的y y坐标为坐标为390-0+(-390-0+(-150)=240150)=240,于是我们看到图形在原先显示地方的上方出现,于是我们看到图形在原先显示地方的上方出现了。了。http:/www.sunxin.org关于解决方法的说明关于解决方法的说明n n首先我们在绘制图形之后,在保存坐标点之前,调用首先我们在绘制图形之后,在保存坐标点之前,调用OnPrepareDCOnPrepareDC函数,调整显示上下文的属性,将视口的原函数,调整显示上下文的属性,将视口的原点设置为点设置为(0
57、,-150)(0,-150),这样的话,窗口的原点,也就是逻辑,这样的话,窗口的原点,也就是逻辑坐标坐标(0,0)(0,0)将被映射为设备坐标将被映射为设备坐标(0,-150)(0,-150),然后我们调用,然后我们调用DPtoLPDPtoLP函数将设备坐标函数将设备坐标(680,390)(680,390)转换为逻辑坐标,根据转换为逻辑坐标,根据设备坐标转换为逻辑坐标的公式:设备坐标转换为逻辑坐标的公式: xWindow = xViewport-xViewOrg+xWinOrgxWindow = xViewport-xViewOrg+xWinOrg, yWindow = yViewport-y
58、ViewOrg+yWinOrgyWindow = yViewport-yViewOrg+yWinOrg,得到逻辑点,得到逻辑点的的x x坐标为坐标为680-0+0=680680-0+0=680,y y坐标为坐标为390-(-150)+0=540390-(-150)+0=540,将,将逻辑坐标逻辑坐标(680,540)(680,540)保存起来,在窗口重绘时,会先调用保存起来,在窗口重绘时,会先调用OnPrepareDCOnPrepareDC函数,调整显示上下文的属性,将视口的原函数,调整显示上下文的属性,将视口的原点设置为了点设置为了(0,-150)(0,-150),然后,然后GDIGDI函数
59、用逻辑坐标点函数用逻辑坐标点(680,540)(680,540)绘制图形,被绘制图形,被WindowsWindows转换为设备坐标点转换为设备坐标点(680,390)(680,390),和原先显示图形时的设备点是一样的,当然,和原先显示图形时的设备点是一样的,当然图形就还在原先的地方显示出来。图形就还在原先的地方显示出来。http:/www.sunxin.org OnPrepareDC会随时根据滚动窗会随时根据滚动窗口的位置来调整视口的原点。口的位置来调整视口的原点。http:/www.sunxin.org CreateCompatibleBitmap返回的位图对象只包含相应设备描述表中的位图
60、的位图信息头,不包含颜色表和象素数据块。因此,选入该位图对象的设备描述表不能像选入普通位图对象的设备描述表一样应用,必须在SelectObject函数之后,调用BitBlt将原始设备描述表的颜色表及象素数据块拷贝到兼容设备描述表。http:/www.sunxin.org12. 文件操作文件操作主讲人:孙鑫http:/www.sunxin.org指向常量的指针指向常量的指针char ch5=“lisi”;const char * pStr=ch;表示指向的对象是常量lisi0pStr=0088:44000088:4400指向内容不可改变*pStr=w;/errorpStr=“wangwu”; /
61、okch指针值可以修改http:/www.sunxin.org指针常量指针常量char ch5=“lisi”;char * const pStr=ch;表示指针本身是常量lisi0pStr=0088:44000088:4400指针值不可修改pStr=“zhangsan”; /error*pStr=W;/okch指向的内容可以修改http:/www.sunxin.org二进制文件和文本文件二进制文件和文本文件n n文件是在计算机内存中以二进制表示的数据在外文件是在计算机内存中以二进制表示的数据在外部存储介质上的另一种存放形式。部存储介质上的另一种存放形式。n n文件通常分为二进制文件和文本文件。
62、文件通常分为二进制文件和文本文件。n n二进制文件是包含在二进制文件是包含在 ASCII ASCII 及扩展及扩展 ASCII ASCII 字符中编字符中编写的数据或程序指令的文件。一般是可执行程序、写的数据或程序指令的文件。一般是可执行程序、图形、图象、声音等等文件。图形、图象、声音等等文件。n n文本文件文本文件( (也称为也称为ASCIIASCII文件文件) ):它的每一个字节存:它的每一个字节存放的是可表示为一个字符的放的是可表示为一个字符的ASCIIASCII代码的文件。它代码的文件。它是以是以 “ “行行” ”为基本结构的一种信息组织和存储方为基本结构的一种信息组织和存储方式的文件
63、,可用任何文字处理程序阅读的简单文式的文件,可用任何文字处理程序阅读的简单文本文件。本文件。 http:/www.sunxin.org文本方式和二进制方式文本方式和二进制方式n n当我们按照文本方式往文件中写入数据时,一旦遇到换行字符(ASCII为10),则会转换为回车换行(ASCII为13、10)。在读取文件时,一旦遇到回车换行的组合(即连续的ASCII 13、10),则会转换为换行字符(ASCII为10)。n n当我们按照二进制方式往文件中写入数据,则将数据在内存中的存储形式原样输出到文件中。http:/www.sunxin.org问题问题n n给你一个整数,例如:给你一个整数,例如:98
64、34198341,将这个整数保存,将这个整数保存到文件中,要求在以记事本程序打开文件时,显到文件中,要求在以记事本程序打开文件时,显示的是示的是9834198341。如下图所示:。如下图所示:http:/www.sunxin.org13.文档与串行化文档与串行化主讲人:孙鑫http:/www.sunxin.orgString Table中中IDR_MAINFRAME字字符串资源中各子串的含义符串资源中各子串的含义n n(1)CDocTemplate:windowTitle(1)CDocTemplate:windowTitle,主窗口标题栏,主窗口标题栏上的字符串,上的字符串,MDIMDI程序不
65、需要指定,将以程序不需要指定,将以IDR_MAINFRAMEIDR_MAINFRAME字符串为默认值。字符串为默认值。n n(2)CDocTemplate:docName(2)CDocTemplate:docName,缺省文档的名称。,缺省文档的名称。如果没有指定,缺省文档的名称是无标题。如果没有指定,缺省文档的名称是无标题。n n(3)CDocTemplate:fileNewName(3)CDocTemplate:fileNewName,文档类型的名,文档类型的名称。如果应用程序支持多种类型的文档,此字符称。如果应用程序支持多种类型的文档,此字符串将显示在串将显示在File/NewFile/
66、New对话框中。如果没有指定,对话框中。如果没有指定,就不能够在就不能够在File/NewFile/New对话框处理这种文件。对话框处理这种文件。http:/www.sunxin.orgString Table中中IDR_MAINFRAME字字符串资源中各子串的含义符串资源中各子串的含义n n(4)CDocTemplate:filterName(4)CDocTemplate:filterName,文档类型的描述和一个,文档类型的描述和一个适用于此类型的通配符过滤器。这个字符串将出现在适用于此类型的通配符过滤器。这个字符串将出现在“File/Open”“File/Open”对话框中的文件类型列表
67、框中。要和对话框中的文件类型列表框中。要和CDocTemplate:filterExtCDocTemplate:filterExt一起使用。一起使用。n n(5)CDocTemplate:filterExt(5)CDocTemplate:filterExt,文档的扩展名。如果没有,文档的扩展名。如果没有指定,就不能够在指定,就不能够在“File/Open”“File/Open”对话框中处理这种文档。对话框中处理这种文档。要和要和CDocTemplate:filterNameCDocTemplate:filterName一起使用。一起使用。n n(6)CDocTemplate:regFileTy
68、peId(6)CDocTemplate:regFileTypeId,如果你以,如果你以:RegisterShellFileTypes:RegisterShellFileTypes向系统的注册表注册文件类型,向系统的注册表注册文件类型,此值会出现在此值会出现在HEY_CLASSES_ROOTHEY_CLASSES_ROOT之下成为其子项,并仅之下成为其子项,并仅供供WindowsWindows内部使用。如果没有指定,这种文件类型就无内部使用。如果没有指定,这种文件类型就无法注册。法注册。n n(7)CDocTemplate:regFileTypeName(7)CDocTemplate:regFi
69、leTypeName,这也是存储在注册,这也是存储在注册表中的文件类型名称。它会显示于程序中用以访问注册表表中的文件类型名称。它会显示于程序中用以访问注册表的对话框内。的对话框内。http:/www.sunxin.orgDocument/View结构结构n n在在MFCMFC中,文档类负责管理数据,提供保存和加载数据的功能。视类中,文档类负责管理数据,提供保存和加载数据的功能。视类负责数据的显示,以及给用户提供对数据的编辑和修改功能。负责数据的显示,以及给用户提供对数据的编辑和修改功能。n nMFCMFC给我们提供给我们提供Document/ViewDocument/View结构,将一个应用程
70、序所需要的结构,将一个应用程序所需要的“ “数数据处理与显示据处理与显示” ”的函数空壳都设计好了,这些函数都是虚函数,我们的函数空壳都设计好了,这些函数都是虚函数,我们可以在派生类中重写这些函数。有关文件读写的操作在可以在派生类中重写这些函数。有关文件读写的操作在CDocumentCDocument的的SerializeSerialize函数中进行,有关数据和图形显示的操作在函数中进行,有关数据和图形显示的操作在CViewCView的的OnDrawOnDraw函数中进行。我们在其派生类中,只需要去关注函数中进行。我们在其派生类中,只需要去关注SerializeSerialize和和OnDra
71、wOnDraw函函数就可以了,其它的细节我们不需要去理会,程序就可以良好地运行。数就可以了,其它的细节我们不需要去理会,程序就可以良好地运行。n n当我们按下当我们按下“File/Open”“File/Open”,Application FrameworkApplication Framework会激活文件打开会激活文件打开对话框,让你指定文件名,然后自动调用对话框,让你指定文件名,然后自动调用CGraphicDoc:SerializeCGraphicDoc:Serialize读取读取文件。文件。Application FrameworkApplication Framework还会调用还会调
72、用CGraphicView:OnDrawCGraphicView:OnDraw,传递,传递一个显示一个显示DCDC,让你重新绘制窗口内容。,让你重新绘制窗口内容。n nMFCMFC给我们提供给我们提供Document/ViewDocument/View结构,是希望我们将精力放在数据结结构,是希望我们将精力放在数据结构的设计和数据显示的操作上,而不要把时间和精力花费在对象与对构的设计和数据显示的操作上,而不要把时间和精力花费在对象与对象之间、模块与模块之间的通信上。象之间、模块与模块之间的通信上。n n一个文档对象可以和多个视类对象相关联,而一个视类对象只能和一一个文档对象可以和多个视类对象相关
73、联,而一个视类对象只能和一个文档对象相关联。个文档对象相关联。http:/www.sunxin.org15.多线程与聊天室程多线程与聊天室程序的创建序的创建主讲人:孙鑫http:/www.sunxin.org程序、进程和线程程序、进程和线程程序和进程程序和进程程序和进程程序和进程n n程序是计算机指令的集合,它以文件的形式存储在磁盘上。程序是计算机指令的集合,它以文件的形式存储在磁盘上。n n进程:通常被定义为一个正在运行的程序的实例,是一个进程:通常被定义为一个正在运行的程序的实例,是一个程序在其自身的地址空间中的一次执行活动。程序在其自身的地址空间中的一次执行活动。n n进程是资源申请、调
74、度和独立运行的单位,因此,它使用进程是资源申请、调度和独立运行的单位,因此,它使用系统中的运行资源;而程序不能申请系统资源,不能被系系统中的运行资源;而程序不能申请系统资源,不能被系统调度,也不能作为独立运行的单位,因此,它不占用系统调度,也不能作为独立运行的单位,因此,它不占用系统的运行资源。统的运行资源。n n进程由两个部分组成:进程由两个部分组成:1、操作系统用来管理进程的内核对象。内核对象也是系统用来存放关于进程的统计信息的地方。2、地址空间。它包含所有可执行模块或DLL模块的代码和数据。它还包含动态内存分配的空间。如线程堆栈和堆分配空间。http:/www.sunxin.org程序、
75、进程和线程程序、进程和线程进程进程进程进程n进程是不活泼的。进程从来不执行任何东西,它只是线程的容器。若要使进程完成某项操作,它必须拥有一个在它的环境中运行的线程,此线程负责执行包含在进程的地址空间中的代码。n单个进程可能包含若干个线程,这些线程都“同时” 执行进程地址空间中的代码。n每个进程至少拥有一个线程,来执行进程的地址空间中的代码。当创建一个进程时,操作系统会自动创建这个进程的第一个线程,称为主线程。此后,该线程可以创建其他的线程。http:/www.sunxin.org程序、进程和线程程序、进程和线程进程地址空间进程地址空间进程地址空间进程地址空间n系统赋予每个进程独立的虚拟地址空间
76、。对于32位进程来说,这个地址空间是4GB。n每个进程有它自己的私有地址空间。进程A可能有一个存放在它的地址空间中的数据结构,地址是0x12345678,而进程B则有一个完全不同的数据结构存放在它的地址空间中,地址是0x12345678。当进程A中运行的线程访问地址为0x12345678的内存时,这些线程访问的是进程A的数据结构。当进程B中运行的线程访问地址为0x12345678的内存时,这些线程访问的是进程B的数据结构。进程A中运行的线程不能访问进程B的地址空间中的数据结构,反之亦然。n4GB是虚拟的地址空间,只是内存地址的一个范围。在你能成功地访问数据而不会出现非法访问之前,必须赋予物理存
77、储器,或者将物理存储器映射到各个部分的地址空间。n4GB虚拟地址空间中,2GB是内核方式分区,供内核代码、设备驱动程序、设备I/O高速缓冲、非页面内存池的分配和进程页面表等使用,而用户方式分区使用的地址空间约为2GB,这个分区是进程的私有地址空间所在的地方。一个进程不能读取、写入、或者以任何方式访问驻留在该分区中的另一个进程的数据。对于所有应用程序来说,该分区是维护进程的大部分数据的地方。http:/www.sunxin.org程序、进程和线程程序、进程和线程线程线程线程线程n线程由两个部分组成:1、线程的内核对象,操作系统用它来对线程实施管理。内核对象也是系统用来存放线程统计信息的地方。2、
78、线程堆栈,它用于维护线程在执行代码时需要的所有参数和局部变量。n当创建线程时,系统创建一个线程内核对象。该线程内核对象不是线程本身,而是操作系统用来管理线程的较小的数据结构。可以将线程内核对象视为由关于线程的统计信息组成的一个小型数据结构。 n线程总是在某个进程环境中创建。系统从进程的地址空间中分配内存,供线程的堆栈使用。新线程运行的进程环境与创建线程的环境相同。因此,新线程可以访问进程的内核对象的所有句柄、进程中的所有内存和在这个相同的进程中的所有其他线程的堆栈。这使得单个进程中的多个线程确实能够非常容易地互相通信。 n线程只有一个内核对象和一个堆栈,保留的记录很少,因此所需要的内存也很少。
79、n因为线程需要的开销比进程少,因此在编程中经常采用多线程来解决编程问题,而尽量避免创建新的进程。http:/www.sunxin.org程序、进程和线程程序、进程和线程线程运行线程运行线程运行线程运行n n操作系统为每一个运行线程安排一定的CPU时间 时间片。系统通过一种循环的方式为线程提供时间片,线程在自己的时间内运行,因时间片相当短,因此,给用户的感觉,就好像线程是同时运行的一样。n如果计算机拥有多个CPU,线程就能真正意义上同时运行了。http:/www.sunxin.org单线程程序与多线程程序单线程程序与多线程程序单线程程序多线程程序一个线程两个线程http:/www.sunxin.
80、org互斥对象互斥对象n n互斥对象(mutex)属于内核对象,它能够确保线程拥有对单个资源的互斥访问权。n n互斥对象包含一个使用数量,一个线程ID和一个计数器。n nID用于标识系统中的哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数。http:/www.sunxin.org16.线程同步与异步套线程同步与异步套接字编程接字编程主讲人:孙鑫http:/www.sunxin.org事件对象事件对象n n事件对象也属于内核对象,包含一个使用计数,事件对象也属于内核对象,包含一个使用计数,一个用于指明该事件是一个自动重置的事件还是一个用于指明该事件是一个自动重置的事件还是一个人工
81、重置的事件的布尔值,另一个用于指明一个人工重置的事件的布尔值,另一个用于指明该事件处于已通知状态还是未通知状态的布尔值。该事件处于已通知状态还是未通知状态的布尔值。n n有两种不同类型的事件对象。一种是人工重置的有两种不同类型的事件对象。一种是人工重置的事件,另一种是自动重置的事件。当人工重置的事件,另一种是自动重置的事件。当人工重置的事件得到通知时,等待该事件的所有线程均变为事件得到通知时,等待该事件的所有线程均变为可调度线程。当一个自动重置的事件得到通知时,可调度线程。当一个自动重置的事件得到通知时,等待该事件的线程中只有一个线程变为可调度线等待该事件的线程中只有一个线程变为可调度线程。程
82、。http:/www.sunxin.org关键代码段关键代码段n n关键代码段(临界区)工作在用户方式下。n n关键代码段(临界区)是指一个小代码段,在代码能够执行前,它必须独占对某些资源的访问权。http:/www.sunxin.org线程死锁线程死锁n n哲学家进餐的问题n n线程1拥有了临界区对象A,等待临界区对象B的拥有权,线程2拥有了临界区对象B,等待临界区对象A的拥有权,就造成了死锁。http:/www.sunxin.org互斥对象、事件对象与关键代码段互斥对象、事件对象与关键代码段的比较的比较n n互斥对象和事件对象属于内核对象,利用内核对象进行线程同步,速度较慢,但利用互斥对象
83、和事件对象这样的内核对象,可以在多个进程中的各个线程间进行同步。n n关键代码段是工作在用户方式下,同步速度较快,但在使用关键代码段时,很容易进入死锁状态,因为在等待进入关键代码段时无法设定超时值。http:/www.sunxin.org推荐书目推荐书目 Windows核心编程机械工业出版社http:/www.sunxin.org基于消息的异步套接字基于消息的异步套接字n nWindowsWindows套接字在两种模式下执行套接字在两种模式下执行I/OI/O操作,阻塞和非阻操作,阻塞和非阻塞。在阻塞模式下,在塞。在阻塞模式下,在I/OI/O操作完成前,执行操作的操作完成前,执行操作的Winso
84、ckWinsock函数会一直等待下去,不会立即返回程序函数会一直等待下去,不会立即返回程序( (将控制将控制权交还给程序权交还给程序) )。而在非阻塞模式下,。而在非阻塞模式下,WinsockWinsock函数无论如函数无论如何都会立即返回。何都会立即返回。n nWindows SocketsWindows Sockets为了支持为了支持WindowsWindows消息驱动机制,使应消息驱动机制,使应用程序开发者能够方便地处理网络通信,它对网络事件采用程序开发者能够方便地处理网络通信,它对网络事件采用了基于消息的异步存取策略。用了基于消息的异步存取策略。n nWindows SocketsWi
85、ndows Sockets的异步选择函数的异步选择函数WSAAsyncSelect()WSAAsyncSelect()提供提供了消息机制的网络事件选择,当使用它登记的网络事件发了消息机制的网络事件选择,当使用它登记的网络事件发生时,生时,WindowsWindows应用程序相应的窗口函数将收到一个消息,应用程序相应的窗口函数将收到一个消息,消息中指示了发生的网络事件,以及与事件相关的一些信消息中指示了发生的网络事件,以及与事件相关的一些信息。息。相关函数说明相关函数说明 int WSAEnumProtocols( LPINT int WSAEnumProtocols( LPINT lpiPro
86、tocolslpiProtocols, , LPWSAPROTOCOL_INFO LPWSAPROTOCOL_INFO lpProtocolBufferlpProtocolBuffer, , ILPDWORD ILPDWORD lpdwBufferLengthlpdwBufferLength ); );n nWin32Win32平台支持多种不同的网络协议,采用平台支持多种不同的网络协议,采用Winsock2Winsock2,就可以编写可,就可以编写可直接使用任何一种协议的网络应用程序了。通过直接使用任何一种协议的网络应用程序了。通过WSAEnumProtocolsWSAEnumProtocol
87、s函数可以获得系统中安装的网络协议的相关信息。函数可以获得系统中安装的网络协议的相关信息。n nlpiProtocolslpiProtocols,一个以一个以NULLNULL结尾的协议标识号数组。这个参数是可选的,结尾的协议标识号数组。这个参数是可选的,如果如果lpiProtocolslpiProtocols为为NULLNULL,则返回所有可用协议的信息,否则,只返,则返回所有可用协议的信息,否则,只返回数组中列出的协议信息。回数组中列出的协议信息。n nlpProtocolBufferlpProtocolBuffer,outout,一个用一个用WSAPROTOCOL_INFOWSAPROTO
88、COL_INFO结构体填充的结构体填充的缓冲区。缓冲区。 WSAPROTOCOL_INFO WSAPROTOCOL_INFO结构体用来存放或得到一个指定协议结构体用来存放或得到一个指定协议的完整信息。的完整信息。n nlpdwBufferLengthlpdwBufferLength,in, outin, out,在输入时,指定传递给在输入时,指定传递给WSAEnumProtocolsWSAEnumProtocols()()函数的函数的lpProtocolBufferlpProtocolBuffer缓冲区的长度;在输出时,存有获取所有请缓冲区的长度;在输出时,存有获取所有请求信息需传递给求信息需
89、传递给WSAEnumProtocols ()WSAEnumProtocols ()函数的最小缓冲区长度。这个函数的最小缓冲区长度。这个函数不能重复调用,传入的缓冲区必须足够大以便能存放所有的元素。函数不能重复调用,传入的缓冲区必须足够大以便能存放所有的元素。这个规定降低了该函数的复杂度,并且由于一个这个规定降低了该函数的复杂度,并且由于一个 机器上装载的协议数机器上装载的协议数目往往是很少的,所以并不会产生问题。目往往是很少的,所以并不会产生问题。相关函数说明相关函数说明 SOCKET WSASocket( int SOCKET WSASocket( int afaf, , int int t
90、ypetype, , int int protocolprotocol, , LPWSAPROTOCOL_INFO LPWSAPROTOCOL_INFO lpProtocolInfolpProtocolInfo, , GROUP GROUP g g, , DWORD DWORD dwFlagsdwFlags ); );n n前三个参数和前三个参数和前三个参数和前三个参数和socket()socket()函数的前三个参数含义一样。函数的前三个参数含义一样。函数的前三个参数含义一样。函数的前三个参数含义一样。n nlpProtocolInfolpProtocolInfo,一个指向一个指向WSAPR
91、OTOCOL_INFOWSAPROTOCOL_INFO结构体的指结构体的指针,该结构定义了所创建的套接字的特性。如果针,该结构定义了所创建的套接字的特性。如果lpProtocolInfolpProtocolInfo为为NULLNULL,则,则WinSock2 DLLWinSock2 DLL使用前三个参数使用前三个参数来决定使用哪一个服务提供者,它选择能够支持规定的地来决定使用哪一个服务提供者,它选择能够支持规定的地址族、套接字类型和协议值的第一个传输提供者。如果址族、套接字类型和协议值的第一个传输提供者。如果lpProtocolInfolpProtocolInfo不为不为NULLNULL,则套
92、接字绑定到与指定的结构,则套接字绑定到与指定的结构WSAPROTOCOL_INFOWSAPROTOCOL_INFO相关的提供者。相关的提供者。n ng g,保留的。保留的。n ndwFlagsdwFlags,套接字属性的描述。套接字属性的描述。相关函数说明相关函数说明 int WSARecvFrom( SOCKET int WSARecvFrom( SOCKET s s, , LPWSABUF LPWSABUF lpBufferslpBuffers, , DWORD DWORD dwBufferCountdwBufferCount, , LPDWORD LPDWORD lpNumberOfBy
93、tesRecvdlpNumberOfBytesRecvd, , LPDWORDLPDWORD lpFlagslpFlags, , struct sockaddr FAR struct sockaddr FAR * *lpFromlpFrom, , LPINT LPINT lpFromlenlpFromlen, , LPWSAOVERLAPPED LPWSAOVERLAPPED lpOverlappedlpOverlapped, , LPWSAOVERLAPPED_COMPLETION_ROUTINE LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletion
94、RoutinelpCompletionRoutine ); ); n ns s,标识套接字的描述符。标识套接字的描述符。n nlpBufferslpBuffers,in, outin, out,一个指向一个指向WSABUFWSABUF结构体的指针。每一个结构体的指针。每一个WSABUFWSABUF结构结构体包含一个缓冲区的指针和缓冲区的长度。体包含一个缓冲区的指针和缓冲区的长度。n ndwBufferCountdwBufferCount, lpBufferslpBuffers数组中数组中WSABUFWSABUF结构体的数目。结构体的数目。n nlpNumberOfBytesRecvdlpNum
95、berOfBytesRecvd,outout,如果接收操作立即完成,则为一个指向本次如果接收操作立即完成,则为一个指向本次调用所接收的字节数的指针。调用所接收的字节数的指针。n nlpFlagslpFlags,in, outin, out,一个指向标志位的指针。一个指向标志位的指针。n nlpFromlpFrom,outout,可选指针,指向重叠操作完成后存放源地址的缓冲区。可选指针,指向重叠操作完成后存放源地址的缓冲区。n nlpFromlenlpFromlen,in, outin, out,指向指向fromfrom缓冲区大小的指针,仅当指定了缓冲区大小的指针,仅当指定了lpFromlpFr
96、om才需才需要。要。n nlpOverlappedlpOverlapped,一个指向一个指向WSAOVERLAPPEDWSAOVERLAPPED结构体的指针结构体的指针( (对于非重叠套接字对于非重叠套接字则忽略则忽略) )。n nlpCompletionRoutinelpCompletionRoutine,一个指向接收操作完成时调用的完成例程的指针一个指向接收操作完成时调用的完成例程的指针( (对于对于非重叠套接字则忽略非重叠套接字则忽略) )。相关函数说明相关函数说明 int WSASendTo( SOCKET int WSASendTo( SOCKET s s, , LPWSABUFLP
97、WSABUF lpBufferslpBuffers, , DWORD DWORD dwBufferCountdwBufferCount, , LPDWORD LPDWORD lpNumberOfBytesSentlpNumberOfBytesSent, , DWORD DWORD dwFlagsdwFlags, , const struct sockaddr const struct sockaddr FAR FAR * *lpTolpTo, , int int iToLeniToLen, , LPWSAOVERLAPPED LPWSAOVERLAPPED lpOverlappedlpOver
98、lapped, , LPWSAOVERLAPPED_COMPLETION_ROUTINELPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutinelpCompletionRoutine ); );n ns s,标识一个套接字标识一个套接字( (可能已连接可能已连接) )的描述符。的描述符。n nlpBufferslpBuffers,一个指向一个指向WSABUFWSABUF结构体的指针。每一个结构体的指针。每一个WSABUFWSABUF结构体包含一个结构体包含一个缓冲区的指针和缓冲区的长度。缓冲区的指针和缓冲区的长度。n ndwBufferCou
99、ntdwBufferCount, lpBufferslpBuffers数组中数组中WSABUFWSABUF结构体的数目。结构体的数目。n nlpNumberOfBytesSentlpNumberOfBytesSent,outout,如果发送操作立即完成,则为一个指向本次调如果发送操作立即完成,则为一个指向本次调用所发送的字节数的指针。用所发送的字节数的指针。n ndwFlagsdwFlags,指示影响操作行为的标志位。指示影响操作行为的标志位。n nlpTolpTo,可选指针,指向目标套接字的地址。可选指针,指向目标套接字的地址。n niToLeniToLen,lpTolpTo中地址的长度。中
100、地址的长度。n nlpOverlappedlpOverlapped,一个指向一个指向WSAOVERLAPPEDWSAOVERLAPPED结构的指针结构的指针( (对于非重叠套接字则对于非重叠套接字则忽略忽略) )。n nl lpCompletionRoutinepCompletionRoutine,一个指向接收操作完成时调用的完成例程的指针一个指向接收操作完成时调用的完成例程的指针( (对于对于非重叠套接字则忽略非重叠套接字则忽略) )。17.进程间通信进程间通信主讲人:孙鑫http:/www.sunxin.org进程间通信的四种方式进程间通信的四种方式n n剪贴板n n匿名管道n n命名管道
101、n n邮槽http:/www.sunxin.org命名管道命名管道 n n命名管道是通过网络来完成进程间的通信,它屏蔽了底层命名管道是通过网络来完成进程间的通信,它屏蔽了底层的网络协议细节。我们在不了解网络协议的情况下,也可的网络协议细节。我们在不了解网络协议的情况下,也可以利用命名管道来实现进程间的通信。以利用命名管道来实现进程间的通信。n n命名管道充分利用了命名管道充分利用了Windows NTWindows NT和和Windows 2000Windows 2000内建的内建的安全机制。安全机制。n n将命名管道作为一种网络编程方案时,它实际上建立了一将命名管道作为一种网络编程方案时,它
102、实际上建立了一个客户机服务器通信体系,并在其中可靠地传输数据。个客户机服务器通信体系,并在其中可靠地传输数据。n n命名管道是围绕命名管道是围绕WindowsWindows文件系统设计的一种机制,采用文件系统设计的一种机制,采用“ “命名管道文件系统命名管道文件系统(Named Pipe File System(Named Pipe File System,NPFS)”NPFS)”接口,接口,因此,客户机和服务器可利用标准的因此,客户机和服务器可利用标准的Win32Win32文件系统函数文件系统函数( (例如:例如:ReadFileReadFile和和WriteFile)WriteFile)来
103、进行数据的收发。来进行数据的收发。http:/www.sunxin.org命名管道命名管道n n命名管道服务器和客户机的区别在于:服务器是唯一一个命名管道服务器和客户机的区别在于:服务器是唯一一个有权创建命名管道的进程,也只有它才能接受管道客户机有权创建命名管道的进程,也只有它才能接受管道客户机的连接请求。而客户机只能同一个现成的命名管道服务器的连接请求。而客户机只能同一个现成的命名管道服务器建立连接。建立连接。n n命名管道服务器只能在命名管道服务器只能在Windows NTWindows NT或或Windows 2000Windows 2000上创上创建,所以,我们无法在两台建,所以,我们
104、无法在两台Windows 95Windows 95或或Windows 98Windows 98计计算机之间利用管道进行通信。不过,客户机可以是算机之间利用管道进行通信。不过,客户机可以是Windows 95Windows 95或或Windows 98Windows 98计算机,与计算机,与Windows NTWindows NT或或Windows 2000Windows 2000计算机进行连接通信。计算机进行连接通信。n n命名管道提供了两种基本通信模式:字节模式和消息模式。命名管道提供了两种基本通信模式:字节模式和消息模式。在字节模式中,数据以一个连续的字节流的形式,在客户在字节模式中,数据
105、以一个连续的字节流的形式,在客户机和服务器之间流动。而在消息模式中,客户机和服务器机和服务器之间流动。而在消息模式中,客户机和服务器则通过一系列不连续的数据单位,进行数据的收发,每次则通过一系列不连续的数据单位,进行数据的收发,每次在管道上发出了一条消息后,它必须作为一条完整的消息在管道上发出了一条消息后,它必须作为一条完整的消息读入。读入。http:/www.sunxin.org邮槽邮槽n n邮槽是基于广播通信体系设计出来的,它采用无连接的不可靠的数据传输。n n邮槽是一种单向通信机制,创建邮槽的服务器进程读取数据,打开邮槽的客户机进程写入数据。n n为保证邮槽在各种Windows平台下都能
106、够正常工作,我们传输消息的时候,应将消息的长度限制在424字节以下。http:/www.sunxin.org18.ActiveX控件控件主讲人:孙鑫http:/www.sunxin.org容器和服务器程序容器和服务器程序n n容器应用程序是可以嵌入或链接对象的应用程序。Word就是容器应用程序。n n服务器应用程序是创建对象并且当对象被双击时,可以被启动的应用程序。Excel就是服务器应用程序。http:/www.sunxin.orgActiveX控件的四种属性控件的四种属性n nStock:为每个控件提供的标准属性,如字体或颜色。n nAmbient:围绕控件的环境属性已被置入容器的属性。这
107、些属性不能被更改,但控件可以使用它们调整自己的属性。n nExtended:这些是由容器处理的属性,一般包括大小和在屏幕上的位置。nCustom:由控件开发者添加的属性。http:/www.sunxin.org19.动态链接库动态链接库主讲人:孙鑫http:/www.sunxin.org动态链接库动态链接库n自从微软推出第一个版本的Windows操作系统以来,动态链接库(DLL)一直是Windows操作系统的基础。n动态链接库通常都不能直接运行,也不能接收消息。它们是一些独立的文件,其中包含能被可执行程序或其它DLL调用来完成某项工作的函数。只有在其它模块调用动态链接库中的函数时,它才发挥作用
108、。nWindows API中的所有函数都包含在DLL中。其中有3个最重要的DLL,Kernel32.dll,它包含用于管理内存、进程和线程的各个函数;User32.dll,它包含用于执行用户界面任务(如窗口的创建和消息的传送)的各个函数;GDI32.dll,它包含用于画图和显示文本的各个函数。http:/www.sunxin.org静态库和动态库静态库和动态库n n静态库:函数和数据被编译进一个二进制文件静态库:函数和数据被编译进一个二进制文件( (通通常扩展名为常扩展名为.LIB).LIB)。在使用静态库的情况下,在编。在使用静态库的情况下,在编译链接可执行文件时,链接器从库中复制这些函译链
109、接可执行文件时,链接器从库中复制这些函数和数据并把它们和应用程序的其它模块组合起数和数据并把它们和应用程序的其它模块组合起来创建最终的可执行文件来创建最终的可执行文件(.EXE(.EXE文件文件) )。n n在使用动态库的时候,往往提供两个文件:一个在使用动态库的时候,往往提供两个文件:一个引入库和一个引入库和一个DLLDLL。引入库包含被。引入库包含被DLLDLL导出的函数导出的函数和变量的符号名,和变量的符号名,DLLDLL包含实际的函数和数据。包含实际的函数和数据。在编译链接可执行文件时,只需要链接引入库,在编译链接可执行文件时,只需要链接引入库,DLLDLL中的函数代码和数据并不复制到
110、可执行文件中的函数代码和数据并不复制到可执行文件中,在运行的时候,再去加载中,在运行的时候,再去加载DLLDLL,访问,访问DLLDLL中导中导出的函数。出的函数。http:/www.sunxin.org使用动态链接库的好处使用动态链接库的好处n n可以采用多种编程语言来编写。n n增强产品的功能。n n提供二次开发的平台。n n简化项目管理。n n可以节省磁盘空间和内存。n n有助于资源的共享。n n有助于实现应用程序的本地化。http:/www.sunxin.org动态链接库被多个进程访问动态链接库被多个进程访问代码页面2代码页面1数据页面2代码页面3数据页面1DLL的虚拟内存的虚拟内存代
111、码页面2代码页面1数据页面2代码页面3数据页面1代码页面2代码页面1代码页面2代码页面3数据页面1数据页面2代码页面2代码页面2代码页面3数据页面1数据页面2代码页面1第一个进程的第一个进程的地址空间地址空间第二个进程的第二个进程的地址空间地址空间http:/www.sunxin.org动态链接库加载的两种方式动态链接库加载的两种方式n n隐式链接n n显示加载20.HOOK和数据库访和数据库访问问主讲人:孙鑫http:/www.sunxin.orgWindows的消息机制的消息机制应用程序操作系统消息队列窗口过程http:/www.sunxin.org动态链接库被多个进程访问动态链接库被多个
112、进程访问代码页面2代码页面1数据页面2代码页面3数据页面1DLL的虚拟内存的虚拟内存代码页面2代码页面1数据页面2代码页面3数据页面1代码页面2代码页面1代码页面2代码页面3数据页面1数据页面2代码页面2代码页面2代码页面3数据页面1数据页面2代码页面1第一个进程的第一个进程的地址空间地址空间第二个进程的第二个进程的地址空间地址空间http:/www.sunxin.org新页面数据库访问技术数据库访问技术n nODBC(Open Database Connectivity)ODBC(Open Database Connectivity),开放数据库互连。,开放数据库互连。ODBCODBC是上个
113、世纪八十年代末九十年代初出现的技术,它是上个世纪八十年代末九十年代初出现的技术,它为编写关系数据库的客户软件提供了一种统一的接口。为编写关系数据库的客户软件提供了一种统一的接口。ODBCODBC提供一个单一的提供一个单一的APIAPI,可用于处理不同数据库的客户,可用于处理不同数据库的客户应用程序。使用应用程序。使用ODBC APIODBC API的应用程序可以与任何具有的应用程序可以与任何具有ODBCODBC驱动程序的关系数据库进行通信。驱动程序的关系数据库进行通信。n nDAO(Data Access Object)DAO(Data Access Object),数据访问对象。,数据访问对
114、象。DAODAO就是一组就是一组Microsoft Access/JetMicrosoft Access/Jet数据库引擎的数据库引擎的COMCOM自动化接口。自动化接口。 DAO DAO不像不像ODBCODBC那样是面向那样是面向C/C+C/C+程序员的,它是微软提供给程序员的,它是微软提供给Visual BasicVisual Basic开发人员的一种简单的数据访问方法,用于操开发人员的一种简单的数据访问方法,用于操纵纵AccessAccess数据库。数据库。 n nRDO(Remote Data Object)RDO(Remote Data Object),远程数据对象。由于,远程数据对
115、象。由于RDORDO直接直接调用调用ODBC API(ODBC API(而不是像而不是像DAODAO那样通过那样通过JetJet引擎引擎) ),所以,可,所以,可以为使用关系数据库的应用程序提供更好的性能。以为使用关系数据库的应用程序提供更好的性能。http:/www.sunxin.orgODBC体系架构体系架构客户程序ODBC驱动程序管理器ODBC驱动程序 各种关系数据库http:/www.sunxin.org数据库访问技术数据库访问技术n nOLE DBOLE DB,对象链接与嵌入数据库。,对象链接与嵌入数据库。 OLE DB OLE DB在两在两个方面对个方面对ODBCODBC进行了扩展
116、。首先,进行了扩展。首先, OLE DB OLE DB提供提供了一个数据库编程的了一个数据库编程的COMCOM接口;第二,接口;第二, OLE DB OLE DB提提供了一个可用于关系型和非关系型数据源的接口。供了一个可用于关系型和非关系型数据源的接口。 OLE DBOLE DB的两个基本结构是的两个基本结构是OLE DBOLE DB提供程序提供程序(Provider)(Provider)和和OLE DBOLE DB用户程序用户程序(Consumer)(Consumer)。n nADO(ActiveX Data Object)ADO(ActiveX Data Object),ActiveXAc
117、tiveX数据对象,它数据对象,它建立在建立在OLE DBOLE DB之上。之上。ADOADO是一个是一个OLE DBOLE DB用户程序。用户程序。使用使用ADOADO的应用程序都要间接地使用的应用程序都要间接地使用OLE DBOLE DB。ADOADO简化了简化了OLE DBOLE DB,提供了对自动化的支持,使,提供了对自动化的支持,使得像得像VBScriptVBScript这样的脚本语言也能够使用这样的脚本语言也能够使用ADOADO访访问数据库。问数据库。http:/www.sunxin.orgOLE DB体系架构体系架构ADO使用ADO的客户程序使用OLE DB访问数据库的程序ODB
118、COLE DB用户程序ODBC数据库ODBC数据库电子表格电子邮件其它非关系型存储http:/www.sunxin.orgOLE DB提供程序ADO的三个核心对象的三个核心对象n nConnectionConnection对象对象对象对象ConnectionConnection对象表示了到数据库的连接,它管理应用对象表示了到数据库的连接,它管理应用程序和数据库之间的通信。程序和数据库之间的通信。 Recordset Recordset和和CommandCommand对象都对象都有一个有一个ActiveConnectionActiveConnection属性,该属性用来引用属性,该属性用来引用C
119、onnectionConnection对象。对象。n nCommandCommand对象对象对象对象CommandCommand对象被用来处理重复执行的查询,或处理需对象被用来处理重复执行的查询,或处理需要检查在存储过程调用中的输出或返回参数的值的查询。要检查在存储过程调用中的输出或返回参数的值的查询。n nRecordsetRecordset对象对象对象对象RecordsetRecordset对象被用来获取数据。对象被用来获取数据。 Recordset Recordset对象存放对象存放查询的结果,这些结果由数据的行查询的结果,这些结果由数据的行( (称为记录称为记录) )和列和列( (称为称为字段字段) )组成。每一列都存放在组成。每一列都存放在RecordsetRecordset的的FieldsFields集合中的集合中的一个一个FieldField对象中。对象中。http:/www.sunxin.org