




已阅读5页,还剩13页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1.1 基本概念Visual C:微软公司出品的C语言开发工具,允许程序员使用C语言以可视化的编程方式快速开发基于Windows平台的系统软件及应用软件。Windows API:Windows操作系统的应用编程接口,它是操作系统的一部分,由数千个函数组成,程序员可以在自己的程序里调用API函数以利用操作系统内置的一些功能。MFC:微软基础类库。依据面向对象编程思想将API函数封装在几百个C+类中,使程序员可以利用面向对象的方法开发程序。C语言标准:C语言是一种通用的计算机编程语言,国际标准化组织已经对其语法和基本类库进行了标准化,很多公司依据C语言标准推出了自己的C开发工具,Visual C只是其中一种。1、Windows应用程序的界面窗口:屏幕上的一块区域,是应用程序的主要输入输出部件,每个应用程序都拥有一个或多个窗口,开发Windows程序的第一步就是建立窗口。窗口有两种存在形式:打开的窗口和图标(最小化的窗口)编写一个Windows应用程序,首先应创建一个或多个窗口,随后应用程序的运行过程即是窗口内部、窗口与窗口之间、窗口与系统之间进行数据处理和数据交换的过程 菜单(工具栏):属于某个窗口,用户通过菜单向应用程序发送命令。对话框:一种特殊的窗口,一般用于与用户交互。控件:对话框中可以包含很多种控件,例如按钮、编辑框、列表框、滚动条等。从本质上讲,控件也是窗口。2、开发Windows应用程序的方法(1)使用Windows API函数:API函数是Windows系统提供的编程接口,大致分为3类:窗口管理函数:窗口的创建、移动、修改等。图形设备接口函数:实现在窗口的客户区绘制图形和文本。系统服务函数:实现与操作系统有关的多种功能,例如多线程控制等。(2)使用MFC类库:类库中存放了大量预先定义的类,以面向对象的思想封装了API函数,程序员可以直接将这些类放到自己的程序里。(3)使用.NET框架类库(4)使用其它类库(OWL、JAVA SSH框架)3、Windows应用程序中的数据类型为了使程序的语义更加丰富,Windows在C语言的基础上自定义了很多种数据类型。例如:HWND无符号32位整数HDC HINSTANCEDWORDunsigned longBOOLboolBYTEunsigned charUINTunsigned int注意:Windows自定义数据类型的关键字都是大写3、 Windows应用程序中的数据类型为了使Windows编程工作更为直观,微软公司的SDK软件包定义了大量的数据类型,如HWND、HINSTANCE、UINT、HDC、HPEN、HBRUSH、HANDLE等。这些数据类型大部分实际上是32位整数。(参见P3)首先需要说明的是,这些数据类型不属于标准C的范围,它们是微软公司自己使用typedef关键字定义的,目的是使编程更为方便。 另外,微软还定义了大量的符号常量(参见P4),如WM_KEYDOWN、WM_PAINT、WM_CLOSE(消息号)SW_SHOW SW_SHOWMINIMIZE SW_SHOWMAXMIZE(窗口显示方式)这些符号常量对应着一个具体的数值,例如:#define WM_KEYDOWN0x0100#define WM_KEYUP0x0101#define WM_MOUSEMOVE0x0100在程序中当然可以直接使用具体数值,但很不方便,推荐使用符号常量。数据类型和符号常量的定义带来两个结果:一方面使初学者难以入门,觉得Windows程序晦涩难懂,一方面使程序更易维护和升级。4、匈牙利表示法:一个标识符可由多个英文单词组成,每个英文单词的第一个字母大写。例如:CreateWindow、ShowWindow、GetMessageHWND CreateWindow( LPCTSTR lpClassName, / pointer to registered class name LPCTSTR lpWindowName, / pointer to window name DWORD dwStyle, / window style int x, / horizontal position of window int y, / vertical position of window int nWidth, / window width int nHeight, / window height HWND hWndParent, / handle to parent or owner window HMENU hMenu, / handle to menu or child-window identifier HANDLE hInstance, / handle to application instance LPVOID lpParam / pointer to window-creation data);5、Windows对象与句柄Windows对象是内存中构建的程序实体,Windows预定义了很多数据类型和数据结构,包括窗口、按钮、对话框、画笔、画刷、字体等。我们编程序时要按照预定义的数据结构在内存中构建具体的对象,并使用API函数操纵这些对象,最终完成用户要求的功能。句柄(handle)是应用程序中能够唯一表示对象的一个整数数值,通过句柄可访问句柄代表的对象,进行适当的操作。形象地说,句柄是Windows世界里对象的身份证号码。如HWND。(P3)注意:C对象与Windows对象是两个不同的概念,Windows对象是C语言概念上的数据集合,可以理解为Windows系统的组成部分。而C对象属于应用程序,是根据C类构造的数据的集合,并拥有自己的行为-成员函数。在MFC编程中,我们经常将一个C对象与一个Windows对象关联起来,以面向对象的方式进行编程。6、事件驱动与传统的基于DOS的程序不同(我们学C语言时编制的程序都是传统的程序)。Windows程序的运行是由事件驱动的。所谓事件,指用户对计算机的一个操作,如敲击键盘、点击鼠标等。(注:Windows内核也可以产生事件。)开发基于DOS的程序时,程序开发者处于完全支配的状态,程序执行流程遵从程序员预先规定的路径。 Windows程序的执行顺序取决于事件发生的顺序。以学生成绩管理系统为例:如果选择增加一名学生,必须将这个操作进行到底,而如果是Windows程序,可以在操作中间切换到其他操作。7、消息所谓消息,是对事件的描述。Windows系统为所有可能的事件都预定义了消息,当事件发生时,Windows就产生描述该事件的消息,并将其发往适当的应用程序,应用程序收到消息后执行与消息对应的代码段。例如,当用户敲击键盘,便产生了两条消息:WM_KEYDOWN和WM_KEYUP,它们分别对应某个键的按下与释放。如果我们在程序中为这两个消息指定了代码段,该代码段将被执行。程序的执行顺序由顺序产生的消息驱动,所以Windows程序设计的重点是编写处理消息的代码段。程序员可根据消息类型编写程序以处理接收的消息,或者发出其他消息以驱动其他程序,但是不必预先确定消息产生的次序。8、描述消息的C结构typedef struct tagMSG / msg HWND hwnd; /Handle to the window whose window procedure receives the message. UINT message; /Specifies the message numberWPARAM wParam; /Specifies additional information about the message. The exact meaning depends on the value of the message memberLPARAM lParam; /Specifies additional information about the message. The exact meaning depends on the value of the message member. DWORD time; /Specifies the time at which the message was posted. POINT pt; /Specifies the cursor position, in screen coordinates, when the message was posted MSG; MSG由Windows系统负责生成和填写,每发生一个事件,就会生成一个结构变量,然后放到消息队列中,等待应用程序将其取走。9、消息循环无论是用户消息还是系统消息,消息产生后首先交给操作系统,操作系统将消息暂存在消息队列里。Windows为每个应用程序建立了消息队列。可以同时为多个应用程序接收和分配消息。由于程序的运行是事件驱动的,所以程序加载后便开始等待消息的到来,根据到来的消息内容执行各种不同的操作。应用程序如何等待消息到来?方法是在程序中编写一个无限循环语句,每一次循环都从自己的消息队列里取出一个消息,经过适当处理后发送给相应的窗口。while(GetMessage(&Msg,NULL,0,0)TranslateMessage(&Msg);DispatchMessage(&Msg); /分发消息,实际上是调用相应窗口函数消息获取函数的原型:BOOL GetMessage( LPMSG lpMsg, / address of structure with message HWND hWnd, / handle of window UINT wMsgFilterMin, / first message UINT wMsgFilterMax / last message);注:如果第二个参数为NULL GetMessage retrieves messages for any window that belongs to the calling thread and thread messages posted to the calling thread via PostThreadMessage. 注: thread messages 表示线程消息,消息分为窗口消息和线程消息Windwos 应用程序具有相对固定的基本结构,由WinMain函数和WndProc函数构成。WinMain函数:是所有Windows程序的入口,类似C语言的main函数,完成一系列的定义和初始化工作,并产生消息循环。消息循环是整个程序运行的核心。 WndProc函数:窗口函数,与应用程序的某个窗口对应,发往窗口的消息由与之对应的窗口函数处理,编程的主要工作是编写WndProc函数。注:WinMain函数的名字是固定的,WndProc函数的名字可以自己指定,只要将它与某个窗口联系起来即可。#includeLRESULT CALLBACK WndProc();int WINAPI WinMain()/变量声明 /注册窗口类 /创建并显示窗口 /消息循环 LRESULT CALLBACK WndProc()switch(message)case :break;case WM_DESTROY:/退出PostQuitMessage(0);break;default:return DefWindowProc(hwnd,message,wParam,lParam);return 0;1、两个函数的原型:LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow)(1)WinMain函数:DOS环境下编程时,主函数的名字是main,一般没有参数,而WinMain函数有4个参数。首先的问题是:谁调用WinMain函数?调用WinMain函数时谁提供并填充4个参数?答案:Windows操作系统。Windows对应用程序的管理主要包括:加载并撤销应用程序、为应用程序传递消息、为应用程序提供功能调用。当用户双击某个可执行文件加载程序时,Windows系统在磁盘上找到该程序所在位置,将其内容拷贝到内存,同时还为应用程序指定实例句柄、命令参数、窗口显示方式等信息。 WinMain 的4个参数:HINSTANCE :Windows系统定义的数据类型,实际上是32位整数,用来代表一个应用程序的实例,称为“实例句柄”。 什么是应用程序实例?Windows中的应用程序可能被多次启动,即多个相同的应用程序同时运行,为了不造成混乱,必须把每个应用程序实例唯一的标志出来, 办法是给每个应用程序(不管相同或不同)一个唯一的句柄。Windows每次启动应用程序都要传递两个句柄,一是新形成的,准备赋给即将启动的程序实例的句柄( hInstance ),一个是以前的实例句柄(hPrevInst ),如果内存中已经有一个相同的程序实例,则把这个已经存在的实例句柄放到hPrevInst里传递给新程序实例。否则hPrevInst为NULL。LPSTR:Windows系统定义的数据类型,指向字符串的指针,表示启动应用程序时传递给它的命令参数。由用户指定。用户怎么指定?演示如何给Word传递命令参数。int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow) int nCmdShow:指定程序的窗口以何种形式显示。窗口的显示方式有很多种,如正常、最大化、最小化、隐藏等。Windows操作系统一般把整数“1”放到nCmdShow中传递给应用程序,表示常规窗口。程序员可以在程序中指定窗口的显示方式,而且不用具体指定某个整数,Windows系统定义了很多符号常量,可以使用那些容易识别和记忆的符号常量规定窗口的显示,详细内容在ShowWindow函数中有介绍。(2)窗口函数(WndProc)LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM);谁调用窗口函数?以前编程序时,除了主函数外,其他函数都会在程序中显式地调用(即明确地调用),而在Windows程序中,却找不到调用窗口函数的语句,那么窗口函数由谁来调用?答案:也是由Windows操作系统调用。当操作系统收到一个来自应用程序的消息,它就查找该应用程序的窗口函数,然后把应用程序的窗口句柄、消息号、消息附加信息等作为参数传递给该应用程序的窗口函数,让机器执行窗口函数中的语句。窗口函数的类型:LRESULT:Windows系统自定义的一种数据类型,实际上是一个32位整数,专门表示窗口函数的返回值,窗口函数必须返回一个值,一般为0。 CALLBACK:回调函数的标志,所谓回调函数,是自动由操作系统调用的函数。大多数情况下,我们在程序里调用操作系统的API函数,有时候我们需要操作系统调用我们程序里的函数,这时就把函数声明为CALL BACK这里把窗口函数定义为CALL BACK,作用是当操作系统收到发往本窗口的消息时,自动调用该窗口的窗口函数,进行相应的操作。 WndProc:窗口函数的名字,可由程序员自己指定。窗口函数的4个参数LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);HWND:Windows系统自定义的数据类型,32位整数,代表某窗口的句柄,应用程序的实例有句柄,窗口、按钮、图标、滚动条、输出设备、控制、文件等等都有自己的句柄,Windows通过句柄对它们实施管理,程序通过句柄对它们实施操作。 UINT: Windows系统自定义的数据类型,无符号32位整数,这里代表消息的编号,简称消息号,Windows为所有可能的事件指定了消息,为所有的消息编制了唯一的号码,具体定义在windows.h文件中。 WPARAM和LPARAM:与消息有关的附加信息。消息不同,其值的含义也不同。例如在键盘消息中,这两个参数中存放的是虚拟键码。窗口函数的作用: 对可能接受到的消息进行处理,由一个或多个switch语句构成,每个case对应一种消息,当应用程序接受到一个消息时,相应的case语句被激活并执行LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)switch(message)case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd,message,wParam,lParam);return 0;这里只对一种消息进行了处理,当用户关闭窗口时,Windows发送WM_DESTORY消息给窗口函数,窗口函数收到消息后,使用PostQuitMessage函数发送WM_QUIT消息给应用程序的消息队列,当WinMain函数中的消息循环收到WM_QUIT后,GetMessage函数返回FALSE,终止消息循环并退出程序。MFC类库的组织结构及主要的类MFC中有一个巨大的类族,其根类为Cobject,这个类族中的类能帮助完成各种编程任务,初学者一般首先学习界面编程。CWnd类及其派生类封装了窗口、对话框和控件,具体情况如下:CView 类:代表窗口的客户区CFrameWnd 类:代表整个窗口CDialog 类:封装了与对话框有关的操作CButton 类:封装了与按钮有关的操作CGdiObject类及其派生类封装了画笔、画刷、位图、字体等绘图工具;具体情况如下:CPen 类:封装了画笔句柄与操纵画笔的函数CBrush 类:封装了画刷句柄与操纵画刷的函数CBitmap 类:封装了位图句柄与操纵位图的函数CFont 类:封装了字体句柄与操纵字体的函数CDC类及其派生类封装了不同区域的设备DC,具体情况如下:CClientDC类:代表客户区DCCWindowDC类:代表整个窗口DCCPaintDC类:代表刷新窗口时的无效区域DCCWinApp类称作“应用程序类”,封装了WinMain函数,使用MFC编程时,不用再写WinMain函数了,只要声明一个CWinApp类的对象即可。CMenu 类:封装了菜单句柄和操纵菜单的函数。这里并没有列出Cobject 类族的所有类,只列出了比较常用的几个,如果想知道一些更多的信息,可以查阅MSDN帮助文档。除了CObject 类族外,还有几个独立的与界面编程有关的类,包括CSize 、CPoint 、CRect 。MFC类库提供了大量的类,编程时可以充分利用这些类:要以MFC中的类为基类派生我们自己的类,当然,新派生的类具有基类的所有功能。再依据新派生出的类构造对象,并调用对象的成员函数完成Windows程序的例行功能。在新派生的类中加入消息映射机制,编写消息处理函数,以处理来自Windows内核的消息。依据MFC中现成的类构造对象,直接用于程序中。编写自己的类,实现程序的特定功能。在以前学习的API编程中,每个窗口都对应着一个窗口函数,发往窗口的消息都被送到窗口函数中加以处理。在MFC程序中,窗口函数看不到了,代之以各种对象,例如,当用户在窗口上点击鼠标时,产生的消息发往隐藏在程序中的WndProc,再转发给程序中管理窗口的对象,对象再调用处理消息的成员函数。我们以前编写的程序,其实没有结构可言,只是创建并显示窗口并响应消息,没有从系统学的角度考虑程序的结构。现在我们可以使用MFC为我们提供的程序结构:文档/视图结构。可以使用AppWizard建立该程序框架:该结构主要由以下4个类构成:应用程序类Application:CMFC002App主窗口框架类Frame:CMainFrame文档类Document:CMFC002Doc视图类View:CMFC002View它们都是MFC类的派生类。我们将按照程序的启动过程依次介绍这些类。程序启动过程大致如下:(1)构造应用程序对象(2)执行CWinApp的InitInstance函数,在该函数中初始化应用环境并生成文档/视图结构的各个对象(3)进入消息循环等待用户输入(4)根据消息中的窗口句柄调用相应类的成员函数。理解MFC框架的关键是理解InitInstance函数。(1)应用程序类的声明class CSimGraphApp : public CWinApppublic:CSimGraphApp();/构造函数/ Overrides/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(CSimGraphApp)public:virtual BOOL InitInstance();/初始化应用环境/AFX_VIRTUAL/ Implementation/AFX_MSG(CSimGraphApp)afx_msg void OnAppAbout();/ NOTE - the ClassWizard will add and remove member functions here./ DO NOT EDIT what you see in these blocks of generated code !/AFX_MSGDECLARE_MESSAGE_MAP()/声明消息映射表;(2)应用程序类的InitInstance函数的关键代码:CSingleDocTemplate* pDocTemplate; /声明文档模板指针pDocTemplate = new CSingleDocTemplate( /创建文档模板IDR_MAINFRAME, /文档模板使用的资源IDRUNTIME_CLASS(CSimGraphDoc), /文档对象的信息RUNTIME_CLASS(CMainFrame), /主帧窗口对象的信息RUNTIME_CLASS(CSimGraphView);/视图窗口对象的信息AddDocTemplate(pDocTemplate);/加入文档模板列表(3)文档模板对象:用于保存文档/视图结构中各个类的信息,当新建一个文档时,VC自动生成的代码(OnFileNew函数)会被执行,并构造3个对象,共同组成一个文档/视图结构。其中RUNTIME_CLASS是一个宏调用,它返回一个指向CRuntimeClass结构的指针,该结构中保存了指定类的信息。 CRuntimeClass结构的成员如下:CRuntimeClass称为类信息表,其结构的成员如下:LPCSTR m_lpszClassName/类名int m_nObjectSize/对象大小UINT m_wSchema/对象的版本号,一般为1CObject* ( PASCAL* m_pfnCreateObject )( )/返回工厂函数的指针,CRuntimeClass* ( PASCAL* m_pfn_GetBaseClass )( ) /返回基类信息表CRuntimeClass* m_pBaseClass /基类信息表指针CObject* CreateObject( ); /工厂函数原型,用来动态创建对象BOOL IsDerivedFrom( const CRuntimeClass* pBaseClass) const;/是否为pBaseClass的基类(4)对象的动态创建在编写程序的过程中,如果需要创建对象,可以使用new操作符,但前提是程序员知道类的名字。在VC提供的框架中,组成框架的4个类的名字是根据程序员指定的项目名称自动生成的,也就是说,框架代码提前不知道类的名字。而程序启动后,对象的实例已经存在了,这些对象是如何创建的?MFC的做法是,在每个需要动态创建对象的类中加入CRunTimeClass结构,并利用宏替换的方法将类的信息添加到类信息表中,并在适当的时候调用类信息表中的工厂函数来创建对象。为了实现上述目的,需要在编程时在类的声明中(头文件)加入:DECLARE_DYNCREATE(CSimGraphView)该宏替换在类中声明了CRunTimeClass结构。并在相应的cpp文件中加入:IMPLEMENT_DYNCREATE(CSimGraphView, CView)该宏替换在cpp文件中填写CRunTimeClass结构的各个成员。(5)AddDocTemplate(pDocTemplate);/加入文档模板列表(6)处理命令行CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo);if (!ProcessShellCommand(cmdInfo)return FALSE;这几行代码用于处理命令行,在处理过程中,框架将根据命令行的内容以及文档模板中保存的类信息创建文档对象、视图对象和主帧对象。下面依次介绍。CCommandLineInfo cmdInfo; /存放命令行参数的类,可通过GotoDefinition找到它的声明,/该类中的成员用于存放用户输入命令时在命令后面附加的参数,例如:IpConfig /all , 其中/all为命令的参数。不同命令的不同参数有不同的含义。微软预先定义了几个特殊的命令参数,参照下页:(7)框架窗口类该类负责边框、标题栏,是工具条、状态条、菜单和视图对象的载体,如果希望创建自己独特的工具条,或希望在一个框架窗口内容纳多个视图,就需要在该类中添加代码。(8)文档类该类负责数据的管理,程序需要处理的数据应该在该类中定义。它提供了Serialize函数,能帮助程序员方便地将数据保存为磁盘文件。(9)视图类:负责数据的显示和操作,管理的范围是框架窗口的客户区部分。是程序员书写代码最多的地方。两个比较重要的成员函数是:GetDocument()获取文档对象的指针OnDraw()实现窗口的刷新CDC绘图、文本、坐标系、映象1、CDC绘图编程回顾(1)首先获得一个DC,例如:CClientDC dc(this);该语句定义了一个对象,其名称为dc,该对象封装了一个DC,该DC代表this所指向窗口的客户区。(2)定义绘图工具并将其选如DCCPen pen, *oldPen;pen.CreatePen(PS_SOLID,2,RGB(200,0,0);CBrush brush , *oldBrush;brush.CreateSolidBrush(RGB(0,0,200);oldPen = dc.SelectObject(&pen);oldBrush = dc.SelectObject(&brush);(3)使用绘图函数绘图并恢复原来的DC参数。dc.Ellipse(0,0,300,300);dc.selectObject(oldPen);dc.SelectObject(oldBrush);2、OnDraw函数它属于窗口客户区,即View类。当窗口客户区需要刷新时,该函数被自动调用,具体过程如下:视图窗口收到WM_PAINT消息,会自动调用OnPaint函数,在该函数中定义一个CPaint 类,void CView:OnPaint() CPaintDC dc(this); /专门用于刷新窗口的类OnprepareDC(&dc); /调整DC属性,为刷新做准备(例如CScrollView)OnDraw(&dc); /调用OnDraw函数,并将封装无效区域的CDC对象传入。MFC框架将OnPaint函数隐藏起来,是希望减少程序员的操作步骤。void CTextView:OnDraw(CDC* pDC)CTextDoc* pDoc = GetDocument(); /获取文档对象的指针ASSERT_VALID(pDoc);/ TODO: add draw code for native data here,这里直接使用pDC绘图即可。SDI视图分割实现多个视图通常,应用程序只有一个主帧窗口和嵌在其中的一个视图窗口,我们可以让一个主帧窗口中有多个视图窗口,如果视图是滚动的,用户就可以同时看到同一文档中距离较远的不同部分,或让不同视图以不同的方式对数据进行展现。这在很多应用程序中是常见的。最简单的方法是在AppWizard中的第4步,选择Advance,选择WindowStyle标签,然后复选Splittered Window。(演示)当然,也可以通过代码来实现上述效果。对窗口进行拆分需要使用CSplitterWnd类,在主帧窗口中定义一个该类的对象,然后在OnCreateClient函数中调用该类的Create或CreateStatic函数创建分割的多个视图。CSplitterWnd称为拆分窗口,用于将主帧窗口拆分为多个窗格,每个窗格种容纳一个视图对象。(1)动态拆分调用CSplitterWnd的create函数。其特点是,拆分后的多个视图是同一视图类的对象,而且新出现的视图对象是动态创建的,当取消拆分后,新视图对象被自动删除。具体做法如下:在主帧窗口类中定义CSplitterWnd类的对象:CSplitterWnd m_wndSplitter;在主帧窗口的OnCreateClient函数中输入下面代码:return m_wndSplitter.Create(this, 2, 2, CSize(10, 10), pContext);该代码创建了22个视图窗口,每个窗口的最小显示范围为1010个象素,即如果小于该范围,拆分自动取消。使用动态拆分最多拆成4个窗口。(2)静态拆分使用CreateStatic函数,拆分后的多个视图可以是不同的视图对象,而且,当取消拆分后,视图对象不会自动删除,只是隐藏了起来。具体做法是:m_wndSplitter.CreateStatic(this,1,2); /1行2列m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CMyView1),CSize(100,100),pContext);/(0,0)面板m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CMyView2),CSize(100,100),pContext);/ (0,1)面板return TRUE;文档/视图结构的优势就在于,可以利用多个视图将同一个数据显示为多种不同的形式。这种程序结构称为“一档多视”。视图窗口的滚动在实际的应用程序中,大部分窗口是可以滚动的。以前学习坐标系的概念时也接触过滚动的概念,但自己通过SetWindowOrg函数来实现滚动太麻烦。MFC提供了一个自动实现滚动的视图类:CScrollView。该类从CView 派生,进行适当的设置后,该类自动为视图窗口加上滚动条及实现滚动条功能的代码,并自动处理OnDraw函数,使之适应滚动条件下的刷新。1、实现滚动视图的方法(1)在APPWizard的第6步,选择SCrollView作为自定义视图类的基类(默认是CView)(演示)。(2)在现有的代码的自定义视图类中,把所有的CView 替换为CScrollView。(演示)注意:替换完以后一定要重载OnInitialUpdate函数,在其中设置视图的滚动范围。例如:void CWindowStyleView:OnInitialUpdate() CScrollView:OnInitialUpdate();/基类的CSize sizeTotal(2000,2000);CSize sizePage(50,50);CSize sizeLine(10,10);SetScrollSizes(MM_TEXT,sizeTotal,sizePage,sizeLine);该函数在视图第一次显示(刷新)之前被调用,或者说,在视图对象与文档结合时被程序框架调用一次,仅调用一次。是设置滚动范围的必然时机。滚动页:在滚动条空白处单击滚动行:在滚动条箭头上单击对于动态拆分,由于有多个相同的视图对象,对任何一个视图的改变都应该反映到其他视图中,方法是调用文档类的UpdateAllViews函数。void UpdateAllViews( CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL );这个函数的作用是触发所有视图对象的OnDraw函数。但可以通过第1个参数指定不调用哪个视图的OnDraw,如果该参数为NULL,则更新所有视图。例如InvalidateRect(rect); /只更新当前视图pDoc-UpdateAllViews(NULL);/更新所有视图pDoc-UpdateAllViews(this);/除当前视图之外的其他视图,在上面的通过UpdateAllViews更新视图的过程中,除了当前视图可以只更新无效区域之外,即只重新绘制无效区域。默认情况下,其他视图的更新方法是使整个视图无效,即重新绘制整个视图,显然这样做效率不高。提高拆分窗口更新效率的方法思路很简单,就是更新任何一个视图时都只重新绘制无效的区域,而不是绘制整个视窗。这就需要通过UpdateAllViews函数将无效区域的信息传递给每个视图。UpdateAllViews通过调用每个视图的OnUpdate函数对每个视图进行更新,而在OnUpdate函数中,又调用InvalidateRect函数使各自的整个视图区域无效,从而触发各自的OnDraw函数重绘整个视图。可以通过UpdateAllViews的参数CObject* pHint 将无效区域传递到OnUpdate并最终到达InvalidateRect。窗口的外观的设置1、通过AppWizard定制窗口外观(演示、解释)2、在PreCreateWindow函数中修改窗口外观该函数在MFC窗口对象创建之后,Windows窗口对象创建之前被调用。它接收一个类型为CREATESTRUCT的参数,通过修改该结构变量中成员的值来改变窗口的样式。 PreCreateWindow函数的原型如下:virtual BOOL PreCreateWindow( CREATESTRUCT& cs );它是一个在CWnd 类中定义的虚函数,其参数cs具有如下成员:(1)改变位置和大小cs.cy = :GetSystemMetrics(SM_CYSCREEN) / 3; cs.cx = :GetSystemMetrics(SM_CXSCREEN) / 3; cs.y = (cs.cy * 3) - cs.cy) / 2; cs.x = (cs.cx * 3) - cs.cx) / 2;将窗口大小设为屏幕尺寸的1/3并居中。其中GetSystemMetrics是API函数,用来获取与系统有关的尺寸信息,例如屏幕尺寸、标题栏高度(SM_CYCAPTION)、菜单栏高度(SM_CYMENU)等。都是以象素为单位。(2)改变窗口风格窗口风格是指创建窗口时指定的窗口样式,用于确定窗口的外观。窗口风格可以指定为下面的一个值或多个值的组合:WS_BORDER 新建一个有边框的窗口WS_CAPTION 新建一个有边框、标题栏的窗口。不能和 WS_DLGFRAME 一起用WS_CHILD 新建一个子窗口,不能和 WS_POPUP 一起用WS_CHILDWINDOW 和 WS_CHILD 风格一样资源和资源文件1、什么是资源资源是Windows程序的重要组成部分,它存储了Windows程序中的可见元素,如菜单、工具条、光标、图标、位图、对话框等。一个Windows程序的可执行文件可以分成两部分:代码部分和数据部分,其中数据部分的主要内容就是Windows程序的资源。资源数据不是程序的功能部件,只是存储界面元素。资源的另一个重要作用是软件的国际化。界面上出现的自然语言存放到资源文件里,对不同的国家使用不同的资源文件。不同版本的Windows系统就是这样做的。设计Windows程序时,除了编写代码之外,还要制作程序需要的资源,一般利用资源制作工具将资源制作出来并存储到若干个资源文件里,在对程序文件进行“连接”操作时,这些资源文件会被加入到程序的可执行文件中。市场上有多种Windows资源制作工具,其中大部分都与Windows开发环境捆绑在一起销售,我们将学习使用VC6.0中的制作工具,并学习如何在程序中通过代码操纵这些资源。传统的资源制作方法是单独编写资源文件和资源头文件,然后在代码中使用inlcude命令将资源引用到程序中,但这样做太麻烦了。新建一个项目,然后以文本方式打开它的资源文件,*.rc,可以看到对各种资源的描述,例如菜单资源的描述如下:IDR_MAINFRAME MENU PRELOAD DISCARDABLE BEGINPOPUP 文件(&F)BEGINMENUITEM 新建(&N)tCtrl+N, ID_FILE_NEWMENUITEM 打开(&O).tCtrl+O, ID_FILE_OPENMENUITEM 保存(&S)tCtrl+S, ID_FILE_SAVEMENUITEM 另存为(&A)., ID_FILE_SAVE_ASMENUITEM SEPARATORMENUITEM 打印(&P).tCtrl+P, ID_FILE_PRINTMENUITEM 打印预览(&V), ID_FILE_PRINT_PREVIEWEND在VC6.0中,不用专门编写资源文件,而是使用一种可视化的方法完成资源制作。没有必要学习如何编写资源文件了,但我们要清楚,程序的资源是以文本的形式在资源文件中描述的。例如:IDI_ICON1 ICON DISCARDABLE resicon1.ico“表示资源的ID号是IDI_ICON1,类型是ICON,可废弃,即在不需要时可以清出内存,对应的图标文件是icon1.ico。在程序中使用资源,主要通过资源的ID号对其进行操作。资源文件中的每个资源都有ID,而资源ID是通过#define命令定义的一个整数,可以在resource.h和StringTable中找到这些ID的定义。菜单的制作与编程从编程的角度看,菜单资源中最重要的是整个菜单的ID和各个菜单项的ID,ID是资源的唯一标识,在程序中通过资源的ID来完成对资源的操作。在MFC的消息映射中,有三个
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 防汛知识培训班新闻稿课件
- 防汛相关知识培训课件
- 摄影服务公司员工保密协议
- 防汛业务知识培训
- 金融行业营销推广方案
- 购物体验行业技术标准与规范
- 微前端与跨平台应用的无缝集成研究-洞察及研究
- 防恐怖知识培训内容课件
- 楼房外墙物业维修基金维合同2篇
- 基因表达调控网络-第4篇-洞察及研究
- 造口并发症护理
- 汽修维修外包合同范本
- 植保无人机打药合同
- 2024工勤人员考试公共课程考试题库及参考答案
- 1.2《在庆祝中国共产党成立100周年大会上的讲话》(课件)-【中职专用】高一语文同步课堂(高教版2023基础模块下册)
- 医院信息化网络安全培训
- 质量教育培训计划方案
- 产品追溯及模拟召回演练计划
- 《生死疲劳》好书分享
- Stata统计分析与应用(第3版)
- 设备使用维修和检修技术通则
评论
0/150
提交评论