《Visual C++ 2010程序设计案例教程[精品]》-笔记

2016-05-10
原文:www.hzbook.com


2016-05-19
原文:Visual C++ 2010程序设计案例教程


2016-05-19
原文:CTaskDialog类提供了很多简单实用的函数,可以轻松上手,使用任务对话框来改善应用程序的用户体验,使自己的应用程序的界面风格与Vista系统保持一致。


2016-05-19
原文:#pragma once行指明编译器只包含该文件一次。


2016-05-19
原文:开始输入“pl”或“to”时,可以按“Ctrl+空格键”,以便自动完成输入“players”或“totalparticipants”的操作。


2016-05-19
原文:请突出显示错误,并按F1键。


2016-05-20
原文:Visual C++程序的发布与部署将更加简单。首先,生成前面项目的Release文件,具体方法是选中解决方案,修改配置管理器中的配置为“Release”,然后单击“生成解决方案”即可。接着,在前面创建的解决方案中,添加“安装和部署”项目,步骤如下:1)选择“文件→新建→项目”,打开“新建项目”窗体。2)选择“安装和部署→Visual Studio Installer→安装项目”,单击“确定”。3)选中“Setup1”,单击右键,选择“添加→项目输出”。4)在“添加项目输出组”中选择“主输出”,配置选择“Release Win32”。5)单击“重新生成”,即可


2016-05-20
原文:产生相应文件,将Setup1.msi和setup.exe复制到第二台计算机上,按照安装向导提示的步骤完成安装。如果将应用程序部署到应用程序本地文件夹,只需生成Release文件,然后复制WinFormDemo和C运行库(CRT)文件、mfc100u.dll和msvcr100.dll。


2016-05-20
原文:Visual C++ 2010新增了重新启动管理器功能。重新启动管理器是Visual Studio for Windows Vista的一项新增功能,增加了在应用程序意外关闭或重新启动的情况下对应用程序的支持。重新启动管理器的行为与应用程序的类型有关,如果是文档编辑器之类的应用程序,重新启动管理器让应用程序器能够自动保存已经打开的文档的状态和内容,在程序异常的时候,能够保存运行时的数据,自动恢复到未发生异常时的情况,从而提高了程序的稳健性与可靠性。如果应用程序不是文档编辑器,则重新启动管理器将重新启动应用程序,但默认情况下无法保存应用程序的状态。重新启动后,根据不同的应用程序,有任务对话框、Windows消息框等消息提示框,供用户选择


2016-05-20
原文:是否还原到自动保存前的状态,如果用户选择不还原,重新启动管理器将丢弃临时保存的文件。向现有应用程序中添加对重新启动管理器支持的具体步骤是:1)在Visual Studio 2010中打开一个现有WinFormDemo应用程序。2)打开主应用程序的源文件。默认情况下,此文件是与应用程序同名的.cpp文件。例如,WinFormDemo的主应用程序源文件是WinFormDemo.cpp。3)查找主应用程序的构造函数。例如,如果项目为MyProject,则构造函数为:


2016-05-20
原文:CWinFormDemoApp:CWinFormDemoApp()4)将以下代码行添加到构造函数中:m_dwRestartManagerSupportFlags=AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTSL;5)确保应用程序的InitInstance方法调用其父级InitInstance方法:CWinApp:InitInstance或CWinAppEx:InitInstance。InitInstance方法负责检查m_dwRestartManagerSupportFlags参数。


2016-05-20
原文:std:unique_ptr


2016-05-20
原文:除了使用Assert:AreEqual断言函数对结果进行判断之外,Visual C++ 2010还提供了多种断言函数,以满足对不同类型的返回结果进行判断的需要。更人性化的是,我们还可以在断言函数中添加对测试结果的说明,这样我们可更容易以测试的结果来驱动开发。例如://判断不相等Assert:AreNotEqual(0,(DWORD_PTR)pClass,"pClass指针不应该为空指针");//判断相等Assert:AreEqual(0,(DWORD_PTR)pClass,"pClass指针应该为空指针");//判断比较结果是否为trueAssert:IsTrue(pClass==nullptr,"pClass指针应该为空指针");//判断StringValue()返回的字符串


2016-05-20
原文:是否与期望的结果相等Assert:AreEqual("期望的结果",gcnew String(pClass->StringValue());


2016-05-20
原文:测试驱动开发


2016-05-20
原文:因为关注用户反馈,所以可以及时响应需求变更;因为从使用者角度出发进行简单设计,所以也可以更快地适应变化。同时,因为测试驱动开发将测试工作提到编码之前,并频繁地运行所有测试,所以可以尽量地避免和尽早地发现错误,极大地降低了后续测试及修复的成本,提高了代码的质量。在测试的保护下,不断重构代码,以消除重复设计,优化设计结构,提高了代码的重用性,从而提高了软件产品的质量。


2016-05-20
原文:CLR是Common Language Runtime的缩写,即运行时。CLR负责在执行时管理代码,提供内存管理和线程管理等核心服务,同时又确保代码的安全性和准确性。CLR利用metadata加载代码段、管理内存、执行方法调用等操作。


2016-05-20
原文:Console:ReadLine()语句执行时,程序将暂停下来显示控制台窗口。按下Enter键将继续执行程序,并允许执行到结束。通常情况下需要对所有C++/CLI控制台示例程序进行该处理,才能看到输出信息。


2016-05-20
原文:Console:ReadLine();


2016-05-23
原文:其中的“.”称为对象选择符,简称点运算符。


2016-05-23
原文:类是对具有相同性质和操作的一个或多个对象的描述,是一组对象的集合,为属于该类的全部对象提供了统一的抽象描述,其内部包括属性和服务两个主要部分。类与对象的关系是:类给出了该类中所有对象的抽象定义(主要指属性和内部操作两个部分),而对象是符合该定义的一个实例。实例是一个具体的对象,是动态的运行实体。实例需要分配存储空间来存放属性的实际值和服务过程代码。某个类的上层类称为父类,下层类称为子类,从而形成类的层次结构。如“研究生”类的上层类是学生,下层类可以是“硕士研究生”类等。


2016-05-23
原文:隐式声明:直接将成员函数定义在类内部。


2016-05-23
原文:定义成员函数的第二种方式是在类的内部定义成员函数,即将成员函数声明为内联函数。内联函数的声明有显式声明和隐式声明两种形式。


2016-05-23
原文:


2016-05-23
原文:显式声明:将内联函数定义在类外,其声明的形式与在类外定义成员函数的形式类似,但为了使成员函数起到内联函数的作用,在函数定义前要加关键字inline,以显式地声明这是一个内联函数。


2016-05-23
原文:将简单的成员函数声明为内联函数可以提高程序的运行效率,但当函数体较长时,将使程序的长度增加很多,因此,一般对简单的函数才声明为内联函数。


2016-05-24
原文:采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,以此提供类与外界间的通信接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高程序的运行效率(减少了类型检查和安全性检查,因为在运行类型检查和安全性检查时都需要时间开销),但是友元破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。


2016-05-24
原文:1. 友元函数友元函数是可以直接访问类的私有成员的非成员函数,是定义在类外的普通函数,不属于任何类,但是需要在类的定义中加以声明,声明时只需要在友元的名称前加上关键字friend,其格式如下:friend 类型 函数名(形式参数);友元函数的声明放在类的私有部分还是公有部分,是没有区别的,都说明该函数是类的一个友元函数。


2016-05-24
原文:一个函数可以是多个类的友元函数,只需要在各个类中分别声明。友元函数的调用与一般函数的调用方式和原理一致。2. 友元类友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一个类的友元类。定义友元类的语句格式如下:friend class 类名;


2016-05-24
原文:其中,friend和class是关键字,类名必须是程序中的一个已定义过的类。


2016-05-24
原文:使用友元类时应注意:1)友元关系不能被继承。2)友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。3)友元关系不具有传递性。若类B是类A的友元,类C是类B的友元,类C不一定是类A的友元,同样要看类中是否有相应的声明。在类里声明一个普通函数,在前面加上friend修饰,那么这个函数就成了该类的友元,可以访问该类的一切成员。


2016-05-24
原文:一个类的成员函数也可以是另一个类的友元,从而使得一个类的成员函数可以操作另一个类的数据成员


2016-05-24
原文:整个类也可以是另一个类的友元,该友元也可以称作友类。友类的每个成员函数都可以访问另一个类的所有成员。


2016-05-24
原文:在基类Item_base中可以看到,其中存在public、protected和private三种访问控制标号。public成员可以被一切用户代码所访问;protected成员可以由基类及派生类访问,但不能由普通用户代码访问;private成员可以由基类和友元访问。其实派生类对基类成员的访问是由基类中的成员访问控制级别和派生类派生列表中使用的访问标号共同控制的


2016-05-24
原文:无论上面哪种继承,如果基类中的访问控制为private成员,则派生类是不能访问的。对于基类中的访问控制为public成员和protected成员,当public成员继承时,基类成员性质不变;当protected成员继承时,基类中的public成员会变为protected成员;当private成员继承时,基类中的所有成员在派生类中都是private成员。


2016-05-24
原文:方法的重写,也称为方法覆盖,当子类继承父类时,父类中的public和protected修饰的属性和方法可以被子类继承,但是父类中的方法在某些情况下不能够满足子类的需求,所以需要对其进行修改。在一个类中可以定义多个相同方法名的方法,但是这些方法不能够具有相同的参数列表,这样的一种形式我们称为方法的重载。


2016-05-24
原文:在定义和使用构造函数时要注意以下几个问题:1)构造函数的名称必须与类名相同,否则编译程序将把它作为一般的成员函数来处理。2)构造函数没有返回值,在声明和定义构造函数时是不能说明它的类型的。3)构造函数的功能是对对象进行初始化,因此在构造函数中只能对属性进行初始化,这些属性一般为私有成员。4)构造函数不能像其他方法一样被显式地调用。


2016-05-24
原文:拷贝构造函数拷贝构造函数是一种特殊的构造函数,即复制另一个对象的构造函数。一般在下述三种情况下会用到拷贝构造函数:1)用一个类对象显式初始化另一个类对象。2)把类对象作为实参传递给函数。3)将类对象作为函数的返回值。在这些情况下,系统就会自动调用拷贝构造函数,将参数代表的对象中的属性逐个拷贝到新创建的对象中。拷贝构造函数有两种形式:系统默认形式和自定义形式。


2016-05-24
原文:实际上,拷贝构造函数就是用类作为构造函数的参数。提示 如果类不定义构造函数,则编译器生成默认构造函数。这种构造函数不进行任何初始化,因此生成对象时,不能保证处于一致状态。


2016-05-24
原文:析构函数也是一种特殊的成员函数,用来释放类中申请的内存或在退出前设置某些变量的值。当类对象离开它所在的作用范围或者释放一个指向类对象的指针时,系统就会自动调用析构函数。析构函数不是必需的,主要用于释放互斥锁或者释放内存,或者当类对象不再使用时需要执行该特殊操作。析构函数的函数名和类名相同,并且在前面加上一个“~”。该函数没有任何参数,不返回任何值,声明格式:~<函数名>();


2016-05-24
原文:C++提供了丰富的数据类型,包括基本类型和非基本类型。基本类型主要包括char(字符型)、int(整型)、short(短整型)、long(长整型)、bool(布尔型)、float(单精度实数)、double(双精度实数)等。在非基本类型中,主要包括枚举型(enum)、数组型、指针型、空类型(void)、结构体类型(struct)、公用体类型(union)和类类型(class)。


2016-05-24
原文:标识符的命名规则:1)所有标识符必须由一个字母(a~z或A~Z)或下划线(_)开头。2)标识符的其他部分可以用字母、下划线或数字(0~9)组成。3)大小写字母表示不同意义,即代表不同的标识符,如cout和Cout表示不同的标识符。在定义标识符时,虽然从语法上允许用下划线开头,但是,最好避免定义用下划线开头的标识符,因为编译器常常定义一些下划线开头的标识符。C++语言的标识符经常用在以下情况中:1)标识对象或变量的名称。2)类、结构和联合的成员。3)函数或类的成员函数。4)自定义类型名。5)标识宏的名称。6)宏的参数。


2016-05-24
原文:在C++中有一些预定义的标识符,称为关键字,也可称为保留字。如int、void等都是关键字,关键字是一种特殊的标识符。关键字具有特定的含义,不能对它们再定义。例如int、void在C++中被预定义为特定的数据类型,不能把它们再定义为变量的标识符。C++的关键字很多,除int和void外,标准C++中预定义了63个关键字,参见表4-4。另外,还定义了11个运算符关键字,它们分别是:and、and_eq、bitand、bitor、compl、not、not_eq、or、or_eq、xor和xor_eq。


2016-05-24
原文:“*”是说明符,说明其后的标识符为指针名


2016-05-24
原文:int(*p3)[6];//p3为指向一维数组的指针变量,该一维数组含有6个int型的元素int(*p4)();//p4为指向函数的指针变量,该函数的返回值为int型


2016-05-24
原文:指针的类型是它所指向变量的类型,而不是指针本身数据值的类型,任何一个指针的数据值都是unsigned long int型。因此,指向的类型不同,指针的类型就不同。指针可以指向简单类型、数组、数组元素、函数和对象,同样还可以指向指针。


2016-05-24
原文:1. 数组指针数组指针是一个指向一维数组的指针变量,定义数组指针的格式为:数据类型(*指针名)[常量表达式];例如:int(*p)[5];上面的语句定义了一个数组指针p,它指向一个包含5个元素的一维数组,数组元素为整型。*p两侧的圆括号不能省略,它表示p先与星号“*”结合,是指针变量。如果省略了圆括号,即写成*p[5]的形式,由于方括号的优先级比星号高,则p先与方括号[]结合,是数组类型,那么语句“int *p[5]”;是定义了一个指针数


2016-05-24
原文:. 指针数组指针数组就是其元素为指针的数组。它是指针的集合,它的每一个元素都是指针变量,并且它们具有相同的存储类型和指向相同的数据类型。声明指针数组的语法格式为:数据类型*指针数组名[常量表达式];其中,数据类型是指数组中各元素指针所指向的类型,同一指针数组中各指针元素指向的类型相同;指针数组名也即数组的首地址,是一个标识符;常量表达式指出这个数组中的元素个数。例如:下面定义了几个指针数组。int *p1[6];float *p2[3][4];具有相同类型的指针数组可以在一起声明,它们也可以与变量、指针等一起声明。如:int a,*p[2];指针数组在使用前必须先赋


2016-05-24
原文:值,可以利用初始化赋值。指针数组主要用于字符串的操作,例如:static char *name[5]={"Tom","John","Mary","Smith Black","Rose"};其中name是一维数组,每一个元素都是指向字符数组的指针类型数据,其中name[0]指向第一个字符串“Tom”,name[1]指向第二个字符串“John”……用指针数组处理字符串不仅可以节省内存,而且提高运算效率。例如,想对5个姓名排序,若将字符串交换位置速度慢,而交换地址则快得多。


2016-05-24
原文:应用程序数据所占的内存可以分为3类:静态存储区、栈、堆。在程序运行开始前就分配的存储空间都在静态存储区中;局部变量分配的存储空间在栈中;动态内存分配的存储空间在堆中,堆也称为自由存储单元。new运算符与delete运算符一起使用,就可以直接进行动态内存的申请和释放(也称为创建和删除)。


2016-05-24
原文:C++语言保留了C语言中的两个库函数:malloc()与free()。这两个函数的作用也是实现动态内存分配的,其功能分别与运算符new和delete相似。但是最好不要将库函数和运算符混合使用,否则可能导致系统崩溃。


2016-05-24
原文:引用是一个变量的别名,是一个目标对象的替代名,由符号“&”引导。对一个变量的引用操作,就是对这个变量的操作。


2016-05-24
原文:引用与指针的区别引用和指针在函数参数传递时作用相似,但也有如下不同:1)指针是一个变量的地址,而引用则是变量的别名。因此,在程序中表示对象变量时,前者要通过取内容运算符“*”,而后者可以直接代表。2)指针是可变的,可以忽而指向变量a,忽而指向变量b。而引用则只能在声明时一次初始化,不能在随后变成别的变量的引用。3)引用没有空间的概念。


2016-05-24
原文:C++中有一些操作字符串的标准库函数,头文件string.h包含所有字符串处理函数的说明。常用的一些函数如下:strcpy(char destination[],const char source[]);strncpy(char destination[],const char source[],int numchars);strcat(char target[],const char source[]);strncat(char target[],const char source[],int numchars);int strcmp(const char firststring[],const char secondstring[]);strlen(const char string[]);


2016-05-24
原文:strlen函数函数原型:strlen(const char string[]);功能:测试字符串长度。用法解析:其函数的值为字符串中的实际长度,不包括'\0'在内。


2016-05-24
原文:引入了插入运算符“<<”,使ostream类具有了通用性和设备无关性,这是通过多态来实现的。用户可以通过重载插入运算符,将自定义的数据类型进行翻译转换,并插入数据流中。应用“<<”运算符,执行格式化插入到ostream类中的对象并不像它们原来那样发送到输出,而是首先被转换成简单的数据类型(字节流)。但是在许多情况下,我们希望将数据直接插入到流中而不进行转换。为此ostream类提供了两个函数:put()和write()。前者是将一个字符、无符号字符或者有符号字符插入字节流中;后者用于插入一个字符数组到字节流中,但不进行任何转换,用于将非格式化的二进制组写到文件和输出设备中。


2016-05-24
原文:stream类有三个从流中进行非格式化抽取的成员函数:get()、getline()和read()。


2016-05-24
原文:MFC(Microsoft Foundation Classes,微软基础类),是一种Application Framework,随微软Visual C++开发工具发布,目前最新版本为10.0(截至2010年3月),提供一组通用的可重用的类库供开发人员使用。其大部分类均从CObject类直接或间接派生,只有少部分类例外。


2016-05-24
原文:MFC应用程序的总体结构通常由开发人员从MFC类派生的几个类和一个CWinApp类对象(应用程序对象)组成。MFC提供MFC AppWizard的自动生成框架。在Windows应用程序中,MFC的主包含文件为“afxwin.h”。此外MFC的部分类为MFC/ATL通用,可以在Win32应用程序中单独包含并使用这些类。


2016-05-24
原文:MFC不只是一个功能单纯的界面开发系统。虽然MFC提供的类绝大部分用来进行界面开发,关联一个窗口的动作,但是MFC提供的类中有很多类不与窗口关联,即类的作用不是一个界面类,不实现对一个窗口对象的控制(如创建、销毁),而是一些在WinDOS(用MFC编写的程序绝大部分都在WinDOS中运行)中实现内部处理的类,如数据库的管理类等。


2016-05-24
原文:1)应用程序类CtestApp——从MFC的CWinApp类派生,对应的源文件为Test.h和Test.cpp。为应用程序的入口,负责应用程序对象的定义与创建、程序的启动、命令行参数处理、主框架窗口的创建(负责将文档、主框架窗口和视图关联在一起)、文档模板的创建、文件菜单的处理、About对话框的创建和显示等。2)主框架窗口类CMainFrame——从MFC的CFrameWnd(SDI)或CMDIFrameWnd(MDI)类派生,对应的源文件为MainFrm.h和MainFrm.cpp。它是应用程序的界面(主窗口),包含(创建和管理)菜单栏、工具栏和状态栏,负责子框架窗口(MDI)或视图类(SDI)的创建。


2016-05-24
原文:3)子框架窗口类CChildFrame——从MFC的CMDIChildWnd类派生,只有MDI程序才有,对应的源文件为ChildFrm.h和ChildFrm.cpp。包含子框架窗口的标题栏和边框,负责视图类(SDI)的创建。4)文档类CtestDoc——从MFC的CDocument类派生,对应的源文件为TestDoc.h和TestDoc.cpp。负责文件读写和数据处理。5)视图类CtestView——一般从MFC的CView类派生,也可以从CScrollView等其他MFC视图类派生,对应的源文件为TestView.h和TestView.cpp。对应于框架窗口的客户区,负责数据的显示、图形的绘制和与用户的交互等。


2016-05-24
原文:CWinApp是基类,从它可以派生出一个Windows应用对象。每一个使用MFC的应用程序都必须也只能包含一个从CWinApp派生的应用程序对象。CWinApp实例化的应用程序对象是一个全局变量,在程序运行中该对象可以与其他对象相互协调,提供管理程序的功能,如初始化程序、生成窗口、同其他类对象进行消息传递等功能,当Windows调用WinMain()函数时,该对象已经有效了。当用户从CWinApp类派生一个应用类时,重载InitInstance成员函数,以建立用户的应用程序的主窗口框架


2016-05-24
原文:当用户使用CWinApp类时,应使用#include<afxwin.h>将头文件afxwin.h包含到源文件中。除了CWinApp类的成员函数外,MFC提供了以下的全局函数访问CWinApp对象以及其他的全程信息:1)AfxGetApp:取得指向CWinApp对象的指针。2)AfxGetInstanceHandle:取得当前应用程序实例的句柄。3)AfxGetResoureHandle:取得应用程序资源的句柄。4)AfxGetAppName:取得一指针,它指向包含应用程序名的字符串。相反,如果有一个指向CWinApp对象的指针,使用m_pszExename以取得应用程序的名称。


2016-05-24
原文:在编写文档/视图结构的应用程序时,CFrameWnd作为主窗口管理视图和文档对象。CFrameWnd类为了能很好地支持系统菜单和控制条(工具条、状态条等),定义了大量的成员函数和变量。当用户使用CFrameWnd类时,应使用#include<afxwin.h>将头文件afxwin.h包含到源文件中,


2016-05-24
原文:有三种方法来构造一个主框架窗口:1)用Create直接构造。2)用LoadFrame直接构造。3)用文件模板间接构造。在调用Create和LoadFrame前,必须用C++的new运算符在堆中构造一个CFrameWnd对象,并用AfxRegisterWndClass全程函数登记窗口类,为主窗口设置类风格和图标。LoadFrame比Create要求的参数要少,它从资源中检索大部分默认值,包括框架标题、图标、加速表、表格和菜单,由于要被LoadFrame获取,所有资源必须有相同的资源ID号(如IDR_MAINFRAME)。


2016-05-24
原文:CView类提供用户定义的视图类的基本功能。视图被链接到文件,并且成为文件和用户之间的中介。视图在显示屏或打印机上产生一个文件图像,并把用户的输入翻译成为对文件的操作。当用户使用CView类时,应使用#include<afxwin.h>将头文件afxwin.h包含到源文件中,


2016-05-24
原文:CView类是查看文档数据的应用程序视图的基类,在实际的应用中,往往还会使用CScrollView、CFormView、CRecordView和CEditView等视图类。CScrollView是具有滚动功能的视图的基类,从其派生的视图类可以自动实现滚动。CFormView用于实现基于对话模板资源的用户界面,CRecordView提供直接链接到ODBC记录集的表单视图,CEditView提供Windows标准编辑控件的视图。


2016-05-24
原文:CDocument类提供由用户定义的文件类的基本功能,支持对文件的标准操作,如建立、载入或存储文件。框架通过CDocument提供的接口管理文件。当用户使用CDocument类时,应使用#include<afxwin.h>将头文件afxwin.h包含到源文件


2016-05-24
原文:CDialog类用于在屏幕上显示对话框的基类。对话框有两种类型:模态型和无模态型。模态型对话框在应用程序继续之前必须由用户关闭;无模态型对话框允许用户在不取消或不移去对话框的情况下,显示其他对话框并返回到其他任务。当用户使用CDialog类时,应使用#include<afxwin.h>将头文件afxwin.h包含到源文件中,CDialog类的主要成员见表5-5。


2016-05-25
原文:CMenu类提供了生成、跟踪、更新和删除一个菜单的成员函数。当用户使用CMenu类时,应使用#include<afxwin.h>将头文件afxwin.h包含到源文件中,


2016-05-25
原文:CWinThread类是MFC用来封装线程的,包括UI线程和工作者线程。因此每个MFC程序至少使用一个CWinThread派生类。当用户使用CWinThread类时,应使用#include<afxwin.h>将头文件afxwin.h包含到源文件中


2016-05-25
原文:1. 下拉式菜单下拉式菜单一般显示在应用程序窗口的顶部,按照类别排列成一行,与某个类别相关的所有功能均排列在相应类别的下面。如果选中某个类别,其下就会弹出菜单,该菜单中有一系列具有相关功能的菜单命令可供用户选择。


2016-05-25
原文:2. 级联菜单级联菜单是下拉菜单的一个扩展。如果某个菜单命令的右侧有一个向右的黑三角符号,那么这个菜单命令就是一个级联菜单。级联菜单带有另一个子菜单,子菜单一般显示在所属菜单命令的右侧。这个子菜单与下拉式菜单相似,有一系列菜单命令可供用户选择。在此,需区别弹出式菜单和菜单命令。一般来说,单击后会出现下拉子菜单的菜单称为弹出式菜单,而其他菜单称为菜单命令。级联菜单也是弹出式菜单,它右侧出现的子菜单中的各个小菜单也称为菜单命令。


2016-05-25
原文:3. 快捷菜单快捷菜单是可以通过在应用程序区域中右击调出的一种很方便的菜单,也可称为弹出式菜单。由于该菜单的菜单命令依赖于被选中的对象或光标在工作区域内所指的位置,因此该菜单也称为上下文菜单。


2016-05-25
原文:对一个单文档的工程来说,菜单是在CxxxApp的InitInstance中产生的(xxx为工程名),产生代码如下:CsingleDocTemplate *pDocTemplate;pDocTemplate=new CsingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CxxxDoc),RUNTIME_CLASS(CMainFrame),//SDI主框架窗口RUNTIME_CLASS(CxxxView));AddDocTemplate(pDocTemplate);


2016-05-25
原文:其中IDR_MAINFRAME是菜单的ID,在资源面板里可以看到,很多资源的ID都是IDR_MAINFRAME,包括菜单、工具栏、加速键、图标和字符串表,因此一个ID可以标识多个资源。


2016-05-25
原文:在应用程序中创建并使用一个菜单,一般都应该遵循下面四个步骤:1)在工程中添加一个自定义的菜单资源。2)用菜单编辑器设计菜单。3)将菜单加入应用程序。4)为每个菜单命令添加消息映射。


2016-05-25
原文:菜单编辑器的功能有:1)创建菜单及菜单命令。2)创建菜单快捷键。3)定义加速键及快捷菜单。4)标记菜单。5)在菜单中加入菜单。6)启用及禁用菜单。7)移除与加载菜单。8)修改和控制系统菜单及用户自定义的菜单。


2016-05-25
原文:菜单可以有多级结构,即一个菜单项可以有多个子菜单,而一个子菜单又可以包含多个下一级的子菜单,依此类推。但在菜单实际设计时,菜单的级数一般以2~3级为宜,而且设计时还要注意一些菜单原则。例如,若单击某菜单项会弹出一对话框,那么在该菜单项文本后加上“…”;若菜单项需要助记符(带下划线的字符),则用括号将其括起来;对于顶层菜单项来说,当按住“Alt”键不放,再按助记符所对应的字符键时,对应的顶层菜单就会被打开;若子菜单项还有助记符,则只要按对应的字符键,则可执行该菜单命令;定义助记符时,只要在字符前面加上“&”符号即可;若某项菜单需要快捷键的支持,则一般将其列在相应菜单项文本之后。


2016-05-25
原文:MFC是通过使用CMenu类来生成菜单的,CMenu类生成的菜单有两种:Popup类型和非Popup类型。这两种类型又可以分为使用资源编辑器生成的菜单资源和不使用资源编辑器生成的菜单资源。对于非Popup类型的菜单,必须在创建后再粘贴到某个窗口上才会显示出来。Popup类型的菜单却不能粘贴到窗口上。CMenu类是从CObject类派生而来的,其数据成员m_hMenu为菜单句柄。构造函数CMenu()创建CMenu对象。


2016-05-25
原文:创建弹出式菜单CMenu类的成员函数较多,但建立弹出式菜单只需用到其中几个成员函数。(1)LoadMenu函数原型:BOOL LoadMenu (UINT nIDResource);其中nIDResource是菜单资源的ID号,在示例ex06_1中用的是IDR_POPMENU。(2)GetSubMenu函数原型:CMenu *GetSubMenu (int nPos) const;此函数用于得到子菜单的指针。nPos为层数,0为第一层子菜单、1为第二层子菜单、……依此类推。(3)TrackPopupMenu函数原型:BOOL TrackPopupMenu(UINT nFlags,int x,int y,


2016-05-25
原文:CWnd *pWnd,LPCRECT lpRect=0);其中nFlags为屏幕坐标属性和鼠标坐标属性。x,y均为屏幕坐标。lpRect即菜单所占的区域。如果lpRect为NULL,当用户在菜单以外的区域按鼠标键时,菜单会消失。屏幕坐标属性:·TPM_CENTERALIGN:横向将菜单以x居中。·TPM_LEFTALIGN:横向将菜单以x左对齐。·TPM_RIGHTALIGN:横向将菜单以x右对齐。鼠标按键属性(只在响应WM_CONTEXTMENU消息时有效):·TPM_LEFTBUTTON:连续按鼠标右键不会连续弹出菜单,鼠标右键不可用于选定菜单项。·TPM_RIGHTBUTTON:连续按鼠标右键会连续弹出菜单,鼠标右键可用于选定菜单项。


2016-05-25
原文:创建动态菜单需使用如下的菜单函数:(1)LoadMenu函数原型:BOOL LoadMenu(UINT nIDResource);其中nIDResource是菜单资源的ID号,这里用的是刚建立的IDR_POPMENU。(2)GetSubMenu函数原型:CMenu *GetSubMenu(int nPos)const;此函数用于得到子菜单的指针。nPos为层数,0为第一层子菜单、1为第二层子菜单、……依此类推。(3)InsertMenu函数BOOL InsertMenu(UINT nPosition,UINT nFlags,UINT_PTR nIDNewItem=0,


2016-05-25
原文:LPCTSTR lpszNewItem=NULL);其中,nPosition指定新菜单项将被插入其前面的菜单项,其含义由参数nFlags决定。nFlags指定控制参数nPosition的标志、新菜单项的内容、外观和性能。nIDNewItem指示新菜单的命令ID或者句柄。lpszNewItem指示新菜单的内容。


2016-05-25
原文:增加菜单void CMainFrame:OnDynAdd(){//TODO:在此添加命令处理程序代码CMenu m_addMenu,*m_pMainmenu;if(!m_addMenu.LoadMenu(IDR_DYN))//装入菜单资源{MessageBox(_T("动态菜单装入失败!"),_T("错误"),MB_OK|MB_ICONERROR);return;//如装入失败,显示消息框且返回}


2016-05-25
原文:CString str=_T("自己的动态菜单(&D)");//要增加的菜单项的标签m_pMainmenu=CMenu:FromHandle(m_wndMenuBar.GetDefaultMenu());//取得指向窗口菜单的CMenu对象的指针m_pMainmenu->InsertMenu(1,MF_POPUP|MF_BYPOSITION|MF_STRING,(UINT)m_addMenu.GetSubMenu(0)->m_hMenu,str);//将弹出式菜单插入到第n项菜单之前(菜单项从0开始计算)//addmenu.GetSubMenu(0)->m_hMenu是被装入菜单的第一个菜单项的弹出式菜单的菜单句柄m_wndMenuBar.CreateFromMenu(m_pMainmenu->GetSafeHmenu(),TRUE,TRUE);m_addMenu.Detach();//将资源菜单(IDR_MENU1)与CMenu对象分离DrawMenuBar();}//删除菜单void CMainFrame:OnDynDelete(){//TODO:在此添加命令处理程序代码CMenu *m_pMainmenu;CString str;m_pMainmenu=CMenu:FromHandle(m_wndMenuBar.GetDefaultMenu());//取得指向窗口菜单的CMenu


2016-05-25
原文:对象的指针for(int i=m_pMainmenu->GetMenuItemCount()-1;i>=0;i--)//取得菜单的项数{m_pMainmenu->GetMenuString(i,str,MF_BYPOSITION);//将指定菜单项的标签复制到指定的缓冲区。MF_BYPOSITION的解释见上if(str==_T("自己的动态菜单(&D)"))//如果是刚才我们增加的菜单项则删除{m_pMainmenu->DeleteMenu(i,MF_BYPOSITION);break;}}m_wndMenuBar.CreateFromMenu(m_pMainmenu->GetSafeHmenu(),TRUE,TRUE);DrawMenuBar();//重画菜单}


2016-05-25
原文:创建新工具栏1)在资源视图中,右击“.rc”文件&

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赤龙绕月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值