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”文件,然后从快捷菜单中选择“添加资源”(如果“.rc”文件中有一个现有工具栏,则右击“工具栏”文件夹,并从快捷菜单中选择“插入Toolbar”即可)。2)在“添加资源”对话框中,选择“资源类型”列表中的“Toolbar”,然后单击“新建”。如果“Toolbar”资源类型旁边出现加号(+),表示工具栏模板可用。单击加号展开模板列表,选择一个模板,然后单击“新建”。2. 通过转换位图创建工具栏可以通过转换位图创建新工具栏,将位图的图形转换为工具栏的按钮图像。位图通常包含单个位图的若干按钮图像,每个按钮一个图像。图像可以为任意大小,默认图像高为15像素,宽为16像素。在图像编辑器中,从“图像”菜单中选择“工具栏编辑器”时,可以在“新建工具栏资源”对话框中指定按钮图像的大小。1)在图像编辑器中打开现有的位图资源(如果“.rc”文件中尚没有位图,则右击“.rc”文件,从快捷菜单中选择“导入”,定位到想添加到“.rc”文件中的位图,然后单击“打开”)。
2016-05-25
原文:2)从“图像”菜单中选择“工具栏编辑器”,出现“新建工具栏资源”对话框。可以更改图标图像的宽度和高度,以与位图匹配。然后将工具栏图像显示在工具栏编辑器中。3)若要完成转换,请使用“属性”窗口更改按钮的命令ID。键入新ID或从下拉列表中选择ID。
2016-05-25
原文:3. 创建、移动和编辑工具栏按钮在工具栏编辑器中可以轻松创建、移动、复制和编辑工具栏按钮。默认情况下,新按钮或空白按钮显示在工具栏的右端。在编辑该按钮之前可以移动它。当创建一个新按钮时,另一个空白按钮出现在被编辑按钮的右侧。保存工具栏时不保存空白按钮。(1)创建新的工具栏按钮在资源视图中展开资源文件夹(如Project1.rc)。展开“工具栏”文件夹,并选择要编辑的工具栏,为工具栏右端的空白按钮分配ID。可以通过在“属性”窗口中编辑“标识”属性来实现。例如,可能需要为工具栏按钮提供与菜单选项相同的ID。在这种情况下,使用下拉列表框选择菜单选项的ID。(2)移动工具栏按钮在工具栏视图窗口中,将要移动的按钮拖动到工具栏上的新位置。(3)删除工具栏按钮
2016-05-25
原文:选择工具栏按钮并将其拖出工具栏。(4)从工具栏中复制按钮按住“Ctrl”键,在“工具栏视图”窗口中,将按钮拖动到工具栏上的新位置或另一个工具栏上的某个位置。(5)在工具栏按钮之间插入间隔通常情况下,若要在按钮之间插入间隔,只需在工具栏中将它们彼此拖开即可。1)在后面没有间隔的按钮前插入间隔:向右或向下拖动按钮,直到与下一个按钮重叠大约一半。2)在后面有间隔的按钮前插入间隔并保持后面的间隔:拖动按钮,直到右边缘或下边缘刚好接触到下一个按钮或刚好与其重叠。3)在后面有间隔的按钮前插入间隔并消去后面的间隔:向右或向下拖动按钮,直到与下一个按钮重叠大约一半。(6)移除工具栏按钮之间的间隔1)若工具按钮前后均有间隔,拖动该工具按钮向右直到它接触相邻工具按钮,则此工具按钮前的间隔保留,工具按钮后的间隔消失。反之,若拖动该工具按钮向左直到它接触相邻的前一个工具按钮,则此工具按钮前面的间隔消失,后面的间隔仍保留。2)删除工具按钮间隔时,只要将间隔一端的工具按钮拖向间隔
2016-05-25
原文:另一端的工具按钮,直到与另一个按钮重叠一半以上即可。
2016-05-25
原文:CMFCToolBar对象的构造可通过两个函数实现。·CMFCToolBar类对象的创建函数Create,创建工具栏,并连接到工具栏对象。原型如下:virtual BOOL Create(CWnd *pParentWnd,DWORD dwStyle=AFX_DEFAULT_TOOLBAR_STYLE,UINT nID=AFX_IDW_TOOLBAR);参数说明如下:pParentWnd:指定一个工具栏所属的框架父窗口。dwStyle:指定工具栏的样式。nID:指定工具栏的ID。
2016-05-25
原文:状态栏窗口既不接受用户的输入也不产生命令消息,它的工作只是在程序控制窗口的下面显示文本。状态栏支持两种类型的文本窗口:消息行窗口和状态指示器窗口。如果要把状态栏用于应用程序专门的数据,就必须先禁用显示菜单指示和键盘状态的标准状态栏。
2016-05-25
原文:C++ 2010在MainFrm.cpp文件中产生静态的indicators数组,该数组定义了用于应用程序状态栏的窗口。indicators数组定义如下:static UINT indicators[]={ID_SEPARATOR,//状态行指示器ID_INDICATOR_CAPS,//大小写指示器ID_INDICATOR_NUM,//数字小键盘指示器ID_INDICATOR_SCRL,//滑动按键指示器};
2016-05-25
原文:CMFCStatusBar对象的构造可通过三个函数实现。·CMFCStatusBar类对象的创建函数Create,创建状态栏,并连接到状态栏对象。原型如下:BOOL Create(CWnd *pParentWnd,DWORD dwStyle=WS_CHILD|WS_VISIBLE|CBRS_BOTTOM,UINT nID=AFX_IDW_STATUS_BAR);参数说明如下:pParentWnd:指定一个状态栏所属的框架父窗口。dwStyle:指定状态栏的风格。其取值含义见表6-5。nID:指定子窗口的ID。
2016-05-25
原文:·CMFCStatusBar类对象扩展创建函数CreateEx,创建扩展样式状态栏,并连接到状态栏对象。原型如下:BOOL CreateEx(CWnd *pParentWnd,DWORD dwCtrlStyle=0,DWORD dwStyle=WS_CHILD|WS_VISIBLE|CBRS_BOTTOM,UINT nID=AFX_IDW_STATUS_BAR);参数说明如下:pParentWnd:指定一个状态栏所属的框架父窗口。dwCtlStyle:指定状态栏的扩展风格。dwStyle:指定状态栏的风格。nID:指定状态栏窗口的ID。
2016-05-25
原文:在资源视图中,选中“ex06_5.rc”,单击鼠标右键弹出快捷菜单,选择“资源符号”。在“资源符号”对话框中选择“新建”,在“新建符号”中输入新的状态栏标识“ID_MY_STATUS_BAR”,并接受默认值。6)为主框架类“CMainFrame”添加“视图”菜单中的“状态栏”命令,并添加处理消息。在类视图中选中“CMainFrame”,在该类的属性窗口中,选择“事件”,定位到“ID_VIEW_STATUS_BAR”,该ID为“视图”菜单下“状态栏”菜单的ID。展开该节点,在下方选择“COMMAND”为之添加消息,再选择“UPDATA_COMMAND_UI”,添加消息。添加的处理消息代码如下:void
CMainFrame:OnViewStatusBar(){//TODO:在此添加命令处理程序代码
2016-05-25
原文:m_wndStatusBar.ShowWindow((m_wndStatusBar.GetStyle()&WS_VISIBLE)==0);RecalcLayout();}void CMainFrame:OnUpdateViewStatusBar(CCmdUI *pCmdUI){//TODO:在此添加命令更新用户界面处理程序代码pCmdUI->SetCheck((m_wndStatusBar.GetStyle()&WS_VISIBLE)!=0);}
2016-05-25
原文:)定位到主框架类“CMainFrame”的头文件“MainFrm.h”中,添加函数原型。afx_msg void OnUpdateLeft(CCmdUI *pCmdUI);afx_msg void OnUpdateRight(CCmdUI *pCmdUI);8)修改状态栏按钮变量,使其为“public”。9)定位到主框架类“CMainFrame”的实现文件“MainFrm.cpp”,修改状态栏指示器数组如下:
2016-05-25
原文:static UINT indicators[]={ID_SEPARATOR,//状态行指示器ID_SEPARATOR,ID_INDICATOR_LEFT,ID_INDICATOR_RIGHT,};10)定位到主框架类“CMainFrame”的“OnCreate”,修改状态栏初始化代码如下:if(!m_wndStatusBar.Create(this,WS_CHILD|WS_VISIBLE|CBRS_BOTTOM,ID_MY_STATUS_BAR)||!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT))){TRACE0("未能创建状态栏\n");return-1;//未能创建}
2016-05-25
原文:11)定位到主框架类“CMainFrame”的实现文件“MainFrm.cpp”,在消息映射代码处添加下面的代码:BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)ON_WM_CREATE()ON_COMMAND(ID_VIEW_STATUS_BAR,&CMainFrame:OnViewStatusBar)ON_UPDATE_COMMAND_UI(ID_VIEW_STATUS_BAR,&CMainFrame:OnUpdateViewStatusBar)ON_UPDATE_COMMAND_UI(ID_INDICATOR_LEFT,OnUpdateLeft)ON_UPDATE_COMMAND_UI(ID_INDICATOR_RIGHT,OnUpdateRight)END_MESSAGE_MAP()
2016-05-25
原文:2)在主框架类“CMainFrame”的实现文件“MainFrm.cpp”的末尾添加如下代码:void CMainFrame:OnUpdateLeft(CCmdUI *pCmdUI){pCmdUI->Enable(:GetKeyState(VK_LBUTTON)<0);}void CMainFrame:OnUpdateRight(CCmdUI *pCmdUI){pCmdUI->Enable(:GetKeyState(VK_RBUTTON)<0);}
2016-05-25
原文:oid Cex06_5View:OnMouseMove(UINT nFlags,CPoint point){//TODO:在此添加消息处理程序代码和(或)调用默认值CString str;CMainFrame *pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;//得到主框架指针CMFCStatusBar *pStatus=(CMFCStatusBar*)pFrame->GetDescendantWindow(ID_MY_STATUS_BAR);//得到状态栏if(pStatus){str.Format(_T("x=%d"),point.x);pStatus->SetPaneText(0,str);//设置文本str.Format(_T("y=%d"),point.y);pStatus->SetPaneText(1,str);//设置文本}CView:OnMouseMove(nFlags,point);}
2016-05-25
原文:对话框分为模态对话框和非模态对话框。二者的区别在于当对话框打开时,是否允许用户进行其他对象的操作。1)模态对话框:模态对话框弹出后,独占了系统资源,用户只有在关闭该对话框后才可以继续执行,即不能在关闭对话框之前执行应用程序其他部分的代码。模态对话框一般要求用户做出某种选择。图7-1 CDialog类2)非模态对话框:非模态对话框弹出后,程序可以在不关闭该对话框的情况下继续执行,在转入应用程序其他部分的代码时不需要用户做出响应。非模态对话框一般用来显示信息,或者实时地进行一些设
2016-05-25
原文:EndDialog。该函数用于退出模态对话框。其原型为:void EndDialog(int nResult);
2016-05-25
原文:CDialog:UpdateData()函数的原型为:BOOL UpdateData(BOOL bSaveAndValidate=TRUE);返回值:如果操作成功,则返回非零值;否则返回0。如果bSaveAndValidate为TRUE,则返回非零值意味着已成功地使数据有效。参数bSaveAndValidate是指明要初始化对话框(FALSE)还是获取数据(TRUE)的标志。
2016-05-25
原文:if(m_pModallessDlg==NULL){m_pModallessDlg=new CDialogModalless;m_pModallessDlg->Create(IDD_MODALLESS_DIALOG,this);
2016-05-25
原文:if(m_pModallessDlg!=NULL){//释放空间delete m_pModallessDlg;}
2016-05-25
原文:/显示非模态对话框m_pModallessDlg->ShowWindow(SW_SHOW);
2016-05-25
原文:在Windows系统中提供了一些通用对话框,如“打印设置”对话框、“页面设置”对话框、“查找”对话框、文件对话框、“字体”对话框和“颜色”对话框等。这些是Windows系统中出现频率很大的对话框,将它们定义为通用对话框可以极大地减轻程序的复杂度,同时,MFC已经用类封装了这些通用对话框。一般来讲,要使用通用对话框,不需要派生新的类,因为MFC的基类已经提供了常用的功能。而且在对话框结束后,可以通过成员函数得到用户在对话框中的选择。
2016-05-25
原文:1. 文件对话框文件对话框为打开和保存文件提供了一个方便易用的接口,MFC的CFileDialog类对其进行了封装
2016-05-25
原文:CFileDialog类构造函数原型如下:explicit CFileDialog(BOOL bOpenFileDialog,LPCTSTR lpszDefExt=NULL,LPCTSTR lpszFileName=NULL,DWORD dwFlags=OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,LPCTSTR lpszFilter=NULL,CWnd *pParentWnd=NULL,DWORD dwSize=0,BOOL bVistaStyle=TRUE);其中:参数bOpenFileDialog指定文件对话框的类型。如果该值为TRUE,则创建文件“打开”对话框;如果为FALSE,则构造一个“另存为”对话框。参数lpszDefExt指定默认的文件扩展名,如果用户在对话框的“文件名”编辑框中不包含扩展名,则lpszDefExt定义的扩展名自动加到文件名后。默认为NULL,即不添加扩展名。参数lpszFileName用于初始
2016-05-25
原文:化显示在编辑框中的文件名,如果为NULL,则不显示。参数dwFlags用于定制对话框的一个或多个标志的组合。参数lpszFilter是一组成对的字符串,指定可以打开文件类型的过滤器。如果指定过滤器,则仅被选择的文件显示于文件列表框中。参数pParentWnd指向父窗口或所有者窗口。参数dwSize是OPENFILENAME结构体的大小。参数bVistaStyle表示只在Vista系统下使用。CFileDialog类有一个重要的OPENFILENAME类型成员变量m_ofn,该变量提供了对话框的结构信息,可以通过该变量完成对话框的定制。
2016-05-25
原文:“颜色”对话框提供了对颜色的方便选择,用户可以直观地在对话框中选择所需的颜色,也可以创建自定义的颜色。
2016-05-25
原文:MFC的CColorDialog类对“颜色”对话框进行了封装,在程序中可以使用带参数的构造函数创建“颜色”对话框,该函数原型如下:CColorDialog(COLORREF clrInit=0,DWORD dwFlags=0,CWnd *pParentWnd=NULL);其中:参数clrInit为默认选择的颜色,默认为黑色RGB(0,0,0)。参数dwFlags是定制对话框
2016-05-25
原文:外观的标志。参数pParentWnd指向父窗口或所有者窗口。CColorDialog类提供了一个CHOOSECOLOR结构类型的变量m_cc,方便用户对“颜色”对话框进行初始化。
2016-05-25
原文:使用CFindReplaceDialog类创建的“查找”与“替换”对话框
2016-05-25
原文:Create()函数原型如下:virtual BOOL Create(BOOL bFindDialogOnly,LPCTSTR lpszFindWhat,LPCTSTR lpszReplaceWith=NULL,DWORD dwFlags=FR_DOWN,CWnd *pParentWnd=NULL);其中:参数bFindDialogOnly为对话框类型,如果设置为TRUE,显示标准“查找”对话框,如果设置为FALSE,则显示“替换”对话框。参数lpszFindWhat指定要查找的字符串。参数lpszReplaceWith指定替换找到的字符串的默认字符串。参数dwFlags为标志位,可用一个或多个标志的组合来定制对话框,默认为FR_DOWN,指定查找方向是向下的。参数pParentWnd指向对话
2016-05-25
原文:框的父窗口或所有者窗口,此窗口是接收对话框中“查找/替换”信息的窗口,如果为NULL,则为调用此对话框主窗口。为使窗口能响应“查找/替换”请求,必须在父窗口框架中调用Windows API Register Window Message()函数对其进行注册,并使用ON_REGISTERED_MESSAGE消息映射宏处理注册的消息。消息映射完成后,就可以从框架窗口的回调函数中调用CFindReplaceDialog类成员函数进行“查找/替换”操作。
2016-05-25
原文:“字体”对话框为应用程序中的字体设置提供了良好的界面,MFC的CFontDialog类对其进行了封装。
2016-05-25
原文:“字体”对话框使用CFontDialog类中带参数的构造函数进行创建,函数原型如下:CFontDialog(LPLOGFONT lplfInitial=NULL,DWORD dwFlags=CF_EFFECTS|CF_SCREENFONTS,CDC * pDCPrinter=NULL,CWnd *pParentWnd=NULL);其中:参数lplfInitial为LPLOGFONT类型,可以设置打开对话框时的初始化字体属性。参数dwFlags指定选择字体标志组合。参数pdcPrinter指向选择字
2016-05-25
原文:体的打印机设备上下文。参数pParentWnd指向“字体”对话框的父窗口或所有者窗口。在CFontDialog类中,提供了一个重要的成员变量m_cf,返回时将字体信息保存在该变量中,可以通过它来取得字体信息。
2016-05-25
原文:“打印设置”对话框提供了对打印机接口的支持,用户可以通过该对话框选择已安装的打印机及相关设置
2016-05-25
原文:MFC的CPrintDialog类对“打印设置”对话框进行了封装,在程序中可以使用带参数的构造函数进行“打印设置”对话框的创建,该函数原型如下:CPrintDialog(BOOL bPrintSetupOnly,DWORD dwFlags=PD_ALLPAGES|PD_USEDEVMODECOPIES|PD_NOPAGENUMS|PD_HIDEPRINTTOFILE|PD_NOSELECTION,CWnd *pParentWnd=NULL);其中:参数bPrintSetupOnly指定显示标准的“打印”对话框,还是显示“打印设置”对话框。设置该参数为TURE,则显示标准“打印设置”对话框,如果为FALSE,则显示“打印”对话框。参数dwFlags是用于定制对话框设置的标志。参数pParentWnd是指向对
2016-05-25
原文:话框的父窗口或主窗口的指针。CPrintDialog类提供了一个变量m_pd,存储返回的打印信息。
2016-05-25
原文:“页面设置”对话框提供了一个可以方便地设置页面属性的用户界面,可以通过该对话框设置纸张、页边距、打印方向等,也可以用它来调用“打印设置”对话框。图7-24给出了标准“页面设置”对话框。MFC的CPageSetupDialog类对“页面设置”对话框进行了封装,在程序中可以使用带参数的构造函数进行“页面设置”对话框的创建,该函数原型如下:CPageSetupDialog(DWORD dwFlags=PSD_MARGINS|PSD_INWININIINTLMEASURE,CWnd *pParentWnd=NULL);其中:参数dwFlags是用来定制对话框设置的标志。参数pParentWnd是指向对话框的父窗口或主窗口的指针。
2016-05-25
原文:CPageSetupDialog类提供了一个PAGESETUPDIALOG结构的成员变量m_psd,用户可以通过成员变量m_psd更改打印机设置。
2016-05-25
原文:静态控件包括静态文本(Static Text)和图片(Picture)控件,前者用来显示文本,后者可以显示位图、图标、矩形和图元文件,并且显示图片可以不必考虑图片的重绘。静态控件不能接收用户的输入。
2016-05-25
原文:创建一个静态控件可以使用Create成员函数:virtual BOOL Create(LPCTSTR lpszText,DWORD dwStyle,const RECT&rect,CWnd *pParentWnd,UINT nID=0xffff);其中dwStyle将指明该窗口的风格,除了子窗口常用的风格WS_CHILD、WS_VISIBLE外,可以针对静态控件指明专用的风格。1)SS_CENTER、SS_LEFT和SS_RIGHT:指明字符显示的对齐方式。
2016-05-25
原文:2)SS_GRAYRECT:显示一个灰色的矩形。3)SS_NOPREFIX:指明风格,对于字符“&”将直接显示,否则“&”将作为转义符不显示,而在其后的字符将有下划线。如果需要直接显示“&”必须使用“&&”表示。4)SS_BITMAP:显示位图。5)SS_ICON:显示图标。6)SS_CENTERIMAGE:图像居中显示。利用成员函数SetWindowText/GetWindowText,可设置/得到控件当前显示的文本;利用成员函数SetIcon/GetIcon,可设置/得到控件当前显示的图标;利用成员函数SetBitmap/GetBitmap,可设置/得到控件当前显示的位图。
2016-05-25
原文:多行编辑框行号从0开始,除了最后一行外,每一行的结尾处都有一对回车换行符(用\r\n表示)作为换行标志,在屏幕上不可见。
2016-05-25
原文:创建一个编辑框可以使用Create成员函数:virtual BOOL Create(DWORD dwStyle,const RECT&rect,CWnd *pParentWnd,UINT nID);其中dwStyle将指明该窗口的风格,除了子窗口常用的风格WS_CHILD、WS_VISIBLE外,可以针对编辑框指明专门的风格。1)ES_AUTOHSCROLL、ES_AUTOVSCROLL:指明输入文字超出显示范围时自动滚动。2)ES_CENTER、ES_LEFT和ES_RIGHT:指定对齐方式。3)ES_MULTILINE:指明
2016-05-25
原文:是否允许多行输入。4)ES_PASSWORD:指明是否为密码输入框,如果指明该风格则输入的文字显示为“*”。5)ES_READONLY:指明是否为只读。6)ES_UPPERCASE、ES_LOWERCASE:显示大写/小写字符。利用成员函数SetWindowText/GetWindowText,可以设置/获取控件当前显示的文本。通过GetLimitText/SetLimitText可以获取/设置在编辑框中输入的字符数量。由于在输入时用户可能选择某一段文本,所以通过void CEdit:GetSel(int&nStartChar,int&nEndChar)可获取用户选择的字符范围,通过调用void
CEdit:SetSel(int nStartChar,int nEndChar,BOOL bNoScroll=FALSE)可以设置当前选择的文本范围,如果指定nStartChar=0,nEndChar=-1,则表示选中所有的文本。void ReplaceSel(LPCTSTR lpszNewText,BOOL bCanUndo=FALSE)可以将选中的文本替换为指定的文字。此外编辑框还有一些与剪贴板有关的功能:void Clear(),删除选中的文本;void Copy(),可将选中的文本送入剪贴板;void
Paste(),将剪贴板中内容插入到当前编辑框中光标位置;void Cut(),相当于Copy和Clear结合使用。
2016-05-25
原文:以下为编辑框的几种常用消息映射宏:1)ON_EN_CHANGE:编辑框中文字更新后产生。2)ON_EN_ERRSPACE:编辑框无法分配内存时产生。3)ON_EN_KILLFOCUS/ON_EN_SETFOCUS:在编辑框失去/得到输入焦点时产生。
2016-05-25
原文:创建按钮:virtual BOOL Create(LPCTSTR lpszCaption,DWORD dwStyle,const RECT&rect,CWnd *pParentWnd,UINT nID);其中lpszCaption是按钮上显示的文字,dwStyle为按钮风格,除了Windows风格可以使用外(如WS_CHILD|WS_VISIBLE|WS_BORDER),还有按钮专用的一些风格。1)BS_AUTOCHECKBOX:检查框,按钮的状态会自动改变。2)BS_AUTORADIOBUTTON:圆形选择按钮,按钮的状态会自动改变。3)BS_AUTO3STATE:允许按钮有三种状态,即选中、未选中和未定。4)BS_CHECKBOX:检查框。5)BS_DEFPUSHBUTTON:默认普通按钮。6)BS_LEFTTEXT:左对齐文字。
2016-05-25
原文:7)BS_OWNERDRAW:自绘按钮。8)BS_PUSHBUTTON:普通按钮。9)BS_RADIOBUTTON:圆形选择按钮。10)BS_3STATE:允许按钮有三种状态,即选中、未选中和未定。另外,rect为窗口所占据的矩形区域。pParentWnd为父窗口指针。nID为该按钮的ID值。获取/改变按钮状态:对于检查框和圆形按钮可能有两种状态,即选中和未选中。如果设置了BS_3STATE或BS_AUTO3STATE风格就可能出现第三种状态:未定,这时按钮显示灰色。通过调用int CButton:GetCheck()得到当前是否被选中,返回0指明未选中,1指明选中,2指明未定。调用void
CButton:SetCheck(int nCheck)设置当前选中状态。处理按钮消息:要处理按钮消息需要在父窗口中进行消息映射,映射宏为ON_BN_CLICKED(id,memberFxn),id为按钮的ID值,就是创建时指定的nID值。处理函数原型为afx_msg void memberFxn()。
2016-05-25
原文:创建一个列表窗口可以使用Create成员函数:virtual BOOL Create(DWORD dwStyle,const RECT&rect,CWnd *pParentWnd,UINT nID);其中dwStyle将指明该窗口的风格,除了子窗口常用的风格WS_CHILD、WS_VISIBLE外,可以针对列表框指明专门的风格。1)LBS_MULTIPLESEL:指明列表框可以同时选择多行。2)LBS_EXTENDEDSEL:可以通过按下“Shift/Ctrl”键选择多行。3)LBS_SORT:所有的行按照字母顺序进行排序。在列表框生成后需要向其中加入或删除行,可以利用:1)int
AddString(LPCTSTR lpszItem)添加行。2)int DeleteString
2016-05-25
原文:(UINT nIndex)删除指定行。3)int InsertString(int nIndex,LPCTSTR lpszItem)将行插入到指定位置。4)void ResetContent()可以删除列表框中所有行。5)int GetCount()得到当前列表框中行的数量。如果需要获取/设置当前被选中的行,可以调用int GetCurSel()/int SetCurSel(int iIndex)。如果指明了选择多行的风格,就需要先通过调用int GetSelCount()得到被选中的行的数量,然后通过int
GetSelItems(int nMaxItems,LPINT rgIndex)得到所有选中的行,参数rgIndex为存放被选中行的数组。通过调用int
2016-05-25
原文:GetLBText(int nIndex,LPTSTR lpszText)得到列表框内指定行的字符串。此外通过调用int FindString(int nStartAfter,LPCTSTR lpszItem),可以在当前所有行中查找指定的字符串的位置,nStartAfter指明从哪一行开始进行查找。int SelectString(int nStartAfter,LPCTSTR lpszItem)可以选中包含指定字符串的行。以下为列表框的几种常用消息映射宏:1)ON_LBN_DBLCLK:鼠标双击。2)ON_EN_ERRSPACE:列表框无法分配内存时产生。3)ON_EN_KILLFOCUS/ON_EN_SETFOCUS:在列表框失去/得到输入焦点时产生。4)ON_LBN_SELCHANGE:选择的行发生改变。使用以上几种消息映射的方法,可以定义原型为afx_msg
void memberFxn()的函数,并且定义形式如ON_Notification(id,memberFxn)的消息映射。如果在对话框中使用列表框,类向导会自动列出相关的消息,并能自动产生消息映射代码。
2016-05-25
原文:组合框(Combo Box)可看做一个编辑框或静态文本框与一个列表框的组合,当前选择的项将显示在组合框的编辑框或静态文本框中。可以创建如下3种类型的组合框:1)简单:创建包括编辑框和列表框的简单组合框,其中编辑框控件用来接受用户的输入。2)下拉框:默认值,创建下拉组合框。该类型与简单组合框类似,仅当用户单击编辑框控件右侧的下拉箭头时组合框的列表框部分才显示。3)下拉列表:该类型类似于下拉样式,只是使用静态文本框代替编辑框控件显示列表框中的当前选择。可以设定Data属性,指定初始值用来填充控件的数据,用分号
2016-05-25
原文:分隔项。创建一个组合窗口可以使用Create成员函数:virtual BOOL Create(DWORD dwStyle,const RECT&rect,CWnd *pParentWnd,UINT nID);其中dwStyle将指明该窗口的风格,除了子窗口常用的风格WS_CHILD、WS_VISIBLE外,可以针对组合框指明专门的风格。1)CBS_DROPDOWN:下拉式组合框。2)CBS_DROPDOWNLIST:下拉式列表组合框,但是编辑框内不能进行输入。3)CBS_SIMPLE:编辑框和列表框同时被显示。4)LBS_SORT:所有行按照字母顺序进行排序。由于组合框内包含了列表框,所以列表框的功能组合框都能够使用。此外编辑框的功能也能够使用,如可以利用:1)DWORD
GetEditSel()/BOOL SetEditSel(int
2016-05-25
原文:StartChar,int nEndChar)获取或设置编辑框中被选中的字符位置。2)BOOL LimitText(int nMaxChars)设置编辑框中可输入的最大字符数。编辑框的剪贴板功能Copy、Clear、Cut和Paste都可以使用。以下为组合框的几种常用消息映射宏:1)ON_CBN_DBLCLK:鼠标双击。2)ON_CBN_DROPDOWN:列表框被弹出。3)ON_CBN_KILLFOCUS/ON_CBN_SETFOCUS:在列表框失去/得到输入焦点时产生。4)ON_CBN_SELCHANGE:列表框中选择的行发生改变。5)ON_CBN_EDITUPDATE:列表框中内容被更新。使用以上几种消息映射的方法,可以定义原型为afx_msg
void memberFxn()的函数,并且定义形式如ON_Notification(id,memberFxn)的消息映射。如果在对话框中使用组合框,Class Wizard会自动列出相关的消息,并能自动产生消息映射代码。
2016-05-25
原文:分组框控件(Group Box)常常用于合理地组合一组控件,如组合Radio Button和Check Box控件,显示一个框架,其上有一个标题。分组框的用法简单,把它拖放到窗口上,再把所需的控件拖放到分组框中即可(但其顺序不能颠倒,不能把分组框放在已有的控件上面)。其结果是父控件是分组框,不是窗口,所以在任意时刻,可以选择多个Radio Button。但在分组框的子控件中,一次只能选择一个Radio Button。父控件和子控件的关系:把一个控件放在窗口上时,窗口就是该控件的父控件,所以该控件是窗口的一个子控件。而把一个分组框放在窗口上时,它就成为窗口的一个子控件。分组框本身可以包含控件,所以它就是这些控件的父控件,其结果是移动Group
Box时,其中的所有控件也会随之移动。把控件放在分组框上的另一个结果是可以改变其中所有控件的某些属性,方法是在分组框上设置这些属性。例如,如果要禁用分组框中的所有控件,只需把分组框的Enabled属性设置为False即可。
2016-05-25
原文:滚动条(Scroll Bar)通常用于定位之类的操作,分为垂直滚动条和水平滚动条。在滚动条内有一个滚动框,用来表示当前的值。单击滚动条,可以使滚动框移动一页或一行,也可以直接拖动滚动框,滚动条一般不会单独使用。创建一个滚动条可以使用Create成员函数:virtual BOOL Create(DWORD dwStyle,const RECT&rect,CWnd *pParentWnd,UINT nID);其中,dwStyle将指明该窗口的风格,除了子窗口常用的风格WS_CHILD、WS_VISIBLE外,可以针对滚动条指明专门的风格:1)SBS_VERT风格,将创建一个垂直的滚动条。2)SBS_HORZ风格,将创建一个水平的滚动条。在创建滚动条后需要调用void
SetScrollRange(int nMinPos,int nMaxPos,BOOL bRedraw=TRUE)设置滚动范围。int GetScrollPos()/int SetScrollPos()可用来获取和设置当前滚动条的位置。void ShowScrollBar(BOOL bShow=TRUE)用来显示/隐藏
2016-05-25
原文:滚动条。BOOL EnableScrollBar(UINT nArrowFlags=ESB_ENABLE_BOTH)用来设置滚动条上箭头是否为允许状态。nArrowFlags可取以下值:1)ESB_ENABLE_BOTH:两个箭头都为允许状态。2)ESB_DISABLE_LTUP:上/左箭头为禁止状态。3)ESB_DISABLE_RTDN:下/右箭头为禁止状态。4)ESB_DISABLE_BOTH:两个箭头都为禁止状态。
2016-05-25
原文:如果需要在滚动条位置被改变时得到通知,需要在父窗口中定义对消息WM_VSCROLL/WM_HSCROLL的映射。方法为:在父窗口类中重载。·afx_msg void OnVScroll(UINT nSBCode,UINT nPos,CScrollBar *pScrollBar)·afx_msg void OnHScroll(UINT nSBCode,UINT nPos,CScrollBar *pScrollBar)所使用的消息映射宏为:ON_WM_VSCROLL()、ON_WM_HSCROLL(),在映射宏中不需要指明滚动条的ID,因为所有滚动条的滚动消息都由同样的函数处理。在OnHScroll/OnVScroll中的第三个参数会指明当前滚动条的指针,第一个参数表示滚动条上发生的动作,可取以下值:1)SB_TOP/SB_BOTTOM:已滚动到顶/底部。2)SB_LINEUP/SB_LINEDOWN:向上/下滚动一行。3)SB_PAGEDOWN/SB_PAGEUP:向上/下滚动一页。4)SB_THUMBPOSITION/SB_THUMBTRACK:滚动条拖动到某一位置,参数nPos指明当前位置(参数nPos在其他的情况下是无效的)。
2016-05-25
原文:5)SB_ENDSCROLL:滚动条拖动完成(用户松开鼠标)。
2016-05-26
原文:旋转按钮控件(Spin Button Control)又称为上下控件(Up Down Control),其主要功能是利用一对标有相反方向箭头的小按钮,通过单击该按钮,在一定范围内改变当前的数值。旋转按钮控件的当前值通常显示在一个称为伙伴窗口(Buddy Window)的控件中,可以是一个编辑框等。
2016-05-26
原文:与其他控件一样,可以通过设置旋转按钮的风格控制其显示外观。其风格如下:1)UDS_HORZ:旋转按钮是水平方向的。2)UDS_VERT:旋转按钮是垂直方向的。3)UDS_ALIGNLEFT:旋转按钮位于伙伴窗口的左侧。4)UDS_ALIGNRIGHT:旋转按钮位于伙伴窗口的右侧。5)UDS_AUTOBUDDY:把旋转按钮的伙伴窗口设置为对话框中的顺序控件。6)UDS_SETBUDDYINT:当旋转按钮当前值改变时,自动改变伙伴窗口标题所显示的数值。7)UDS_NOTHOU
2016-05-26
原文:SANDS:取消显示的数字中每三位间的“,”分隔符。8)UDS_WRAP:旋转按钮的当前值超出最大(最小)值时自动回绕到最小(最大)值。9)UDS_ARROWKEYS:可以让用户用光标键来改变当前值。旋转按钮也可以不在伙伴窗口的任何一侧。如果位于伙伴窗口的一侧,应适当减少伙伴窗口的宽度以容纳旋转按钮。
2016-05-26
原文:CSpinButtonCtrl:Create()函数建立旋转按钮控件对象并绑定对象,旋转按钮控件类Create的调用格式如下:virtual BOOL Create(DWORD dwStyle,const RECT&rect,CWnd *pParentWnd,UINT nID);
2016-05-26
原文:其中:·参数dwStyle用来确定旋转按钮控件的风格。·参数rect用来确定旋转按钮控件的大小和位置。·参数pParentWnd用来确定父窗口指针。·参数nID用来确定旋转按钮的控件符ID值。旋转按钮控件的类属性包括设置加速键SetAccel、取得加速键GetAccel、设置基数SetBase、取得基数GetBase、设置伙伴窗口SetBuddy、取得伙伴窗口GetBuddy、设置当前位置SetPos、取得当前位置GetPos、设置上限下限值SetRange和取得上限下限值GetRange等。
2016-05-26
原文:进度条控件(Progress Control)主要用来进行数据读写、文件拷贝和磁盘格式化等操作时的工作进度提示情况,如安装程序等,伴随工作进度的进展,进度条的矩形区域从左到右利用当前活动窗口标题栏的颜色不断填充。进度条控件在MFC类库中的封装类为CProgressCtrl,通常仅作为输出类控件,所以其操作主要是设置进度条的范围和当前位置,并不断地更新当前位置。进度条的范围用来表示整个操作过程的时间长度,当前位置表示完成情况的当前时刻。SetRange()函数用来设置范围,初始范围为0~100;SetPos()函数用来设置当前位置,初始值为0;SetStep()函数用来设置步长,初始步长为10;StepIt()函数用来按照当前步长更新位置;OffsetPos()函数用来直接将当前位置移动一段距离。如果范围或位置发生变化,那么进度条将自动重绘进度区域及时反映
2016-05-26
原文:当前工作的进展情况。CProgressCtrl:Create()函数建立进度条控件对象并绑定对象。Create的调用格式如下:virtual BOOL Create(DWORD dwStyle,const RECT&rect,CWnd *pParentWnd,UINT nID);其中:·参数dwStyle用来确定进度条控件的风格。·参数rect用来确定进度条控件的大小和位置。·参数pParentWnd用来确定进度条父窗口指针。·参数nID用来确定进度条控件的控件符ID值。进度条控件的类属性包括设置进度条最大最小控件范围SetRange、设置进度条当前位置SetPos、设置进度条当前位置偏移值OffsetPos和设置进度条控件增量值SetStep。
2016-05-26
原文:滑块控件(Slider Control)也称为轨道条控件,其主要是通过用一个带有轨道和滑标的小窗口以及窗口上的刻度,让用户选择一个离散数据或一个连续的数值区间。通过鼠标或键盘进行数据的选择操作,滑块既可以是水平方向的,也可以是垂直方向的。滑块控件的风格如下:1)TBS_HORZ:滑块是水平方向的。2)TBS_VERT:滑块是垂直方向的。3)TBS_LEFT:滑块位于窗口左侧。4)TBS_RIGHT:滑块位于窗口右侧。5)TBS_TOP:滑块位于窗口顶部。
2016-05-26
原文:6)TBS_BOTTOM:滑块位于窗口底部。7)TBS_BOTH:滑块位于窗口两侧。8)TBS_AUTOTICKS:滑块具有刻度,默认。9)TBS_NOTICKS:滑块不具有刻度。滑块的刻度条在每一个数值位置显示一个刻度标记,如果在滑块上显示某一数值选择区间,则应使用风格TBS_ENABLESELRANGE,此时选择区间是一个小的三角形符号。另外,使用风格TBS_NOTHUMB会使滑标消隐起来。CSliderCtrl:Create函数建立滑块控件对象并绑定对象:virtual BOOL Create(DWORD
dwStyle,const RECT&rect,CWnd *pParentWnd,UINT nID);其中:·参数dwStyle用来确定滑块控件风格。·参数rect用来确定滑块控件的大小和位置。·参数pParentWnd用来确
2016-05-26
原文:定滑块控件的父窗口指针。·参数nID用来确定滑块控件的控件符ID值。滑块控件对象的类属性包括取得滑块大小GetLineSize、设置滑块大小SetLineSize、取得滑块页大小GetPageSize、设置滑块页大小SetPageSize、取得滑块最大位置GetRangeMax、取得滑块最小位置GetRangeMin、取得滑块范围GetRange、设置滑块最小位置SetRangeMin、设置滑块最大位置SetRangeMax、设置滑块范围SetRange、取得滑块当前位置GetSelection、设置滑块当前位置SetSelection、取得滑块当前位置GetPos和设置滑块当前位置SetPos等。滑块控件的操作方法包括清除滑块当前选择ClearSel、验证滑块当前位置是否在最大最小位置之间VerifyPos和清除当前刻度标志ClearTics。
2016-05-26
原文:属性页控件可以在一个窗口中添加不同的页面,然后在页选择发生改变时得到通知。MFC中使用CTabCtrl类来封装属性页控件的各种操作。通过调用Create函数创建一个窗口,声明如下:virtual BOOL Create(DWORD dwStyle,const RECT&rect,CWnd *pParentWnd,UINT nID);dwStyle中可以使用以下一些属性页控件的专用风格:
2016-05-26
原文:1)TCS_BUTTONS:使用按钮来表示页选择位置。2)TCS_MULTILINE:分行显示页选择位置。3)TCS_SINGLELINE:只使用一行显示页选择位置。在控件创建后必须向其中添加页面才可以使用,此外CTabCtrl类还提供了一些函数用于获取/修改控件的状态。int GetCurSel()/int SetCurSel(int nItem)用于获取/设置当前被选中的页位置;BOOL DeleteItem(int nItem)/BOOL DeleteAllItems()用于删除指定/所有页面;void
Remove-Image(int nImage)用于删除某页选择位置上的图标。属性页控件的消息映射同样使用ON_NOTIFY宏,形式如下:ON_NOTIFY(wNotifyCode,id,memberFxn)。wNotifyCode为通知代码,id为产生该消息的窗口ID,memberFxn为处理函数,函数的原型:void On×××Tab(NMHDR * pNMHDR,LRESULT * pResult),其中pNMHDR为一数据结构,在具体使用时需要转换成其他类型的结构。
2016-05-26
原文://设置属性页的页面TCITEM item;item.mask=TCIF_TEXT;item.pszText=_T("第一页");m_tabctrl.InsertItem(0,&item);item.pszText=_T("第二页");m_tabctrl.InsertItem(1,&item);//把对话框对象与对话框控件、属性页控件相关联m_dlg1.Create(IDD_DIALOG1,&m_tabctrl);m_dlg2.Create(IDD_DIALOG2,&m_tabctrl);//设置初始化位置CRect
r;m_tabctrl.GetClientRect(&r);m_dlg1.SetWindowPos(NULL,10,30,r.right-20,r.bottom-80,SWP_SHOWWINDOW);m_dlg2.SetWindowPos(NULL,10,30,r.right-20,r.bottom-40,SWP_HIDEWINDOW);return TRUE;//除非将焦点设置到控件,否则返回TRUE}
2016-05-26
原文:在MFC中CImageList类封装了图像列表控件的功能,图像列表是一个具有相同大小的图像(可以是不同类型)的集合,主要用于应用程序中大规模图标的存储,该控件是不可见的。通常与CListBox、CComboBox、CComboBoxEx以及CTabCtrl一起使用,为它们提供图标资源。图像的每个集合中均以0为图像索引基数,可以把这些图标看成是以数组方式存储的,图像列表通常由大图标或位图构成,其中包含位图模式。实际上,所有在同一个图像列表中的图标都被存储在一个屏幕设备的位图中。可以向CImageList对象中添加位图和图标资源,添加图像的方法有两种:资源可以是程序中资源文件的资源,也可以直接从外部文件调入。1)从程序的资源文件中添加图标和位图图像,代码如下所示://创建一个CImageList类的指针变量
2016-05-26
原文:CImageList *pImageList;pImageList=new CImageList();pImageList->Create(32,32,ILC_COLOR32,0,4);//添加图标,图标可以随图像列表大小自动拉伸pImageList->Add(AfxGetApp()->LoadIcon(IDI_ICON1));pImageList->Add(AfxGetApp()->LoadIcon(IDI_ICON2));//添加位图,并使黑色为透明色,如果图像列表大小和位图大小不一致可能会导致添加失败CBitmap
bmp;bmp.LoadBitmap(IDB_BITMAP1)pImageList->Add(&bmp,RGB(0,0,0));bmp.DeleteObject();bmp.LoadBitmap(IDB_BITMAP2)pImageList->Add(&bmp,RGB(0,0,0));
2016-05-26
原文:)从外部文件中添加图标和位图图像,代码如下所示:HBITMAP hBitmap;CBitmap *pBitmap;CString FilePathName="e:\TIME.bmp";pBitmap=new CBitmap;//从文件导入位图hBitmap=(HBITMAP)LoadImage(AfxGetInstanceHandle(),FilePathName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);pBitmap->Attach(hBitmap);m_pImageList->Add(pBitmap,RGB(0,0,0));
2016-05-26
原文:这样一个图像列表就创建好了,并且已经添加了图像,接下来就可以在其他控件中使用其中的图像了。通常需要调用控件SetImageList(m_pImageList),将当前图像列表设置为引用图像源。列表控件提供了对Windows列表功能操作的基本方法,操作一个列表控件的基本方法为:创建列表控件→创建列表控件所需要的图像列表→向列表控件添加表列和表项→对列表进行各种操作,主要包括查找、排序、删除、显示方式、排列方式以及各种消息处理功能等;最后撤销列表控件。列表控件CListCtrl的Create函数格式如下:virtual
BOOL Create(DWORD dwStyle,const RECT&rect,CWnd * pParentWnd,UINT nID);
2016-05-26
原文:其中,参数dwStyle用来确定列表控件的风格;rect用来确定列表控件的大小和位置;pPar-entWnd用来确定列表控件的父窗口,通常是一个对话框;nID用来确定列表控件的标识。其中列表控件的风格可以是下列值的组合:1)LVS_ALIGNLEFT:用来确定表项的大小图标以左对齐方式显示。2)LVS_ALIGNTOP:用来确定表项的大小图标以顶部对齐方式显示。3)LVS_AUTOARRANGE:用来确定表项的大小图标以自动排列方式显示。4)LVS_EDITLABELS:设置表项文本可以编辑,父窗口必须设有LVN_ENDLABELEDIT风格。5)LVS_ICON:用来确定大图标的显示方式。6)LVS_LIST:用来确定列表方式显示。7)LVS_NOCOLUMNHEADER:用来确定在详细资料方式时不显示列表头。8)LVS_NOLABELWRAP:用来确定以单行方式显示图标的文本项。9)LVS_NOSCROLL:用来屏蔽滚动条。10)LVS_NOSORTHEADER:用来确定列表头不能用做按钮功能。
2016-05-26
原文:11)LVS_OWNERDRAWFIXED:在详细列表方式时允许自绘窗口。12)LVS_REPORT:用来确定以详细资料即报告方式显示。13)LVS_SHAREIMAGELISTS:用来确定共享图像列表方式。14)LVS_SHOWSELALWAYS:用来确定一直显示被选中表项方式。15)LVS_SINGLESEL:用来确定在某一时刻只能有一项被选中。16)LVS_SMALLICON:用来确定小图标显示方式。17)LVS_SORTASCENDING:用来确定表项排序时是基于表项文本的升序方式。18)LVS_SORTDESCENDING:用来确定表项排序时是基于表项文本的降序方式。列表控件的操作方法包括插入一个新的表项InsertItem、删除一个表项DeleteItem、排序表项SortItems、测试列表的位置HitTest、重绘表项RedrawItems、插入一个表列InsertColumn、删除一个表列DeleteColumn、编辑一个表项文本EditLabel和重绘一个表项DrawItem等。
2016-05-26
原文:树形控件可以用于树形的结构,其中有一个根结点(Root),下面有许多子结点,而每个子结点上又允许有一个或多个或没有子结点。MFC中使用CTreeCtrl类封装树形控件的各种操作,通过调用Create函数创建一个窗口,声明如下:virtual BOOL Create(DWORD dwStyle,const RECT&rect,CWnd *pParentWnd,UINT nID);dwStyle中可以使用以下一些树形控件的专用风格:1)TVS_HASLINES:在父/子结点之间绘制连线。2)TVS_LINESAT
2016-05-26
原文:ROOT:在根/子结点之间绘制连线。3)TVS_HASBUTTONS:在每一个结点前添加一个按钮,用于表示当前结点是否已被展开。4)TVS_EDITLABELS:结点的显示字符可以被编辑。5)TVS_SHOWSELALWAYS:在失去焦点时也显示当前选中的结点。6)TVS_DISABLEDRAGDROP:不允许拖拽。7)TVS_NOTOOLTIPS:不使用ToolTip显示结点的字符。在树形控件中每一个结点都有一个句柄(HTREEITEM),同时添加结点时必须提供该结点的父结点句柄(其中Root结点只有一个,既不可以添加也不可以删除),利用HTREEITEM
InsertItem(LPCTSTR lpszItem,HTREEITEM hParent=TVI_ROOT,HTREEITEM hInsertAfter=TVI_LAST)可以添加一个结点,lpszItem为显示的字符,hParent代表父结点的句柄,当前添加的结点会排在hInsertAfter表示的结点的后面,返回值为当前创建的结点的句柄。为树形控件结点前添加图标,就必须先调用CTreeCtrl类的成员函数CImageList *SetImageList(CImageList *pImageList),指明当前控件所使用
2016-05-26
原文:的图像列表(ImageList),nImageListType为TVSIL_NORMAL。在调用完成后,控件中使用的图片以设置的ImageList中图片为准。然后调用HTREEITEM InsertItem(LPCTSTR lpszItem,int nImage,int nSelectedImage,HTREEITEM hParent=TVI_ROOT,HTREEITEM hInsertAfter=TVI_LAST)添加结点,其中参数nImage为结点没被选中时所使用图片序号,nSelectedImage为结点被选中时所使用图片序号。此外CTreeCtrl类还提供了一些函数,用于获取/修改控件的状态:1)HTREEITEM
GetSelectedItem()将返回当前选中的结点的句柄。2)BOOL SelectItem(HTREEITEM hItem)将选中指定结点。3)BOOL GetItemImage(HTREEITEM hItem,int&nImage,int&nSelectedImage)/BOOL SetItemImage(HTREEITEM hItem,int nImage,int nSelectedImage)用于获取/修改某结点所使用的图标索引。4)CString GetItemText(HTREEITEM hItem)/BOOL
SetItemText(HTREEITEM hItem,LPCTSTR lpszItem)
2016-05-26
原文:用于获取/修改某结点的显示字符。5)BOOL DeleteItem(HTREEITEM hItem)用于删除某一结点,BOOL DeleteAllItems()将删除所有结点。此外如果想遍历树可以使用下面的函数:1)HTREEITEM GetRootItem():获取根结点。2)HTREEITEM GetChildItem(HTREEITEM hItem):获取子结点。3)HTREEITEM GetPrevSiblingItem/GetNextSiblingItem(HTREEITEM hItem):获取指定结点的上/下一个兄弟结点。4)HTREEITEM
GetParentItem(HTREEITEM hItem):获取父结点。树形控件的消息映射使用ON_NOTIFY宏,形式如下:ON_NOTIFY(wNotifyCode,id,mem berFxn)。wNotifyCode为通知代码,id为产生该消息的窗口ID,memberFxn为处理函数,该函数的原型:void On×××Tree(NMHDR *pNMHDR,LRESULT *pResult),其中pNMHDR为一数据结构,在具体使用时需要转换成其他类型的结构。对于树形控件可能的取值和对应的数据结构为:·TVN_SELCHANGED:在所选中的结点发生改变后发送,
2016-05-26
原文:所用结构为NMTREEVIEW。·TVN_ITEMEXPANDED:在某结点被展开后发送,所用结构为NMTREEVIEW。·TVN_BEGINLABELEDIT:在开始编辑结点字符时发送,所用结构为NMTVDISPINFO。·TVN_ENDLABELEDIT:在结束编辑结点字符时发送,所用结构为NMTVDISPINFO。·TVN_GETDISPINFO:在需要获取某结点信息时发送(如获取结点的显示字符),所用结构为NMTVDISPINFO;
2016-05-26
原文:图形设备接口(Graphics Device Interface,GDI)是Windows操作系统的传统图形子系统,负责与设备无关的图形绘制,Win32 API为应用程序提供了丰富的绘图函数和功能,MFC对它们进行了C++类封装
2016-05-26
原文:每次需要重绘窗口时(如程序启动、窗口大小改变、全部或部分窗口重现、程序员调用函数RedrawWindow或Invalidate/UpdateWindow),应用程序框架都会调用CWnd消息响应成员函数(即应用程序框架通过覆盖CWnd的成员函数)来绘制窗口客户区。
2016-05-26
原文:在Windows中,绘图都是在当前的映射模式(Map Mode)下(坐标系中)进行的。而当前映射模式可以用CDC类的成员函数SetMapMode来设置。1. 默认映射模式映射模式影响所有的图形和文本绘制函数,它定义(将逻辑单位转换为设备单位所使用的)度量单位和坐标方向,Windows总是用逻辑单位来绘图。
2016-05-26
原文:可使用CDC类的成员函数GetMapMode和SetMapMode来获得和设置当前映射模式:int GetMapMode()const;//返回当前的映射模式virtual int SetMapMode(int nMapMode);//返回先前的映射模式
2016-05-26
原文:其中,in为英寸,1 in=2.54 cm;twips(缇)是一种打印标准单位;isotropic(各向同性的)指x与y方向的单位相同;anisotropic(各向异性的)则是指x与y方向的单位不同。
2016-05-27
原文:对所有非MM_TEXT映射模式,有如下重要规则:1)CDC类的成员函数(如各种绘图函数)具有逻辑坐标参数。2)CWnd类的成员函数(如各种响应函数)具有设备坐标参数(如鼠标位置point)。3)位置的测试操作(如CRect的PtInRect函数)只有使用设备坐标时才有效。4)长期使用的值应该用逻辑坐标保存(如窗口滚动后保存的设备坐标就无效了)。因此,为了使应用程序能够正确工作,除MM_TEXT映射模式外,其他映射模式都需要进行单位转换。Windows的GDI负责逻辑坐标和设备坐标之间的转换,这可以调用CDC类的成员函数LPtoDP和DPtoLP来进行,其函数原型为:void
LPtoDP(LPPOINT lpPoints,int nCount=1)const;
2016-05-27
原文:void LPtoDP(LPRECT lpRect)const;void LPtoDP(LPSIZE lpSize)const;void DPtoLP(LPPOINT lpPoints,int nCount=1)const;void DPtoLP(LPRECT lpRect)const;void DPtoLP(LPSIZE lpSize)const;
2016-05-27
原文:GDI支持大多数流行的图像文件格式,如BMP、GIF、JPEG、TIFF和PNG等。下面先来介绍这些图像文件,然后再说明Image和Bitmap类支持的特性。1. 图像文件格式简介图像文件是描绘一幅图像的计算机磁盘文件,其文件格式不下数十种。这里仅介绍BMP、GIF、JPEG、TIFF和PNG等图像文件格式。(1)BMP文件格式BMP图像文件格式是Microsoft为其Windows环境设置的标准图像格式。一个Windows的BMP位图实际上是一些与显示像素相对应的位阵列,它有两种类型:一种称为GDI位图,另一种是DIB(Device-Independent
Bitmap)位图。GDI位图包含了一种与Windows的GDI模块有关的Windows数据结构,该数据结构是与设备有关的,故此位图又称为DDB(Device-Dependent Bitmap)位图。当用户的程序取得位图数据信息时,其位图显
2016-05-27
原文:示方式视显示卡而定。由于GDI位图的这种设备依赖性,当位图通过网络传送到另一台PC,很可能就会出现问题。DIB比GDI位图有更多编程优势,例如它自带颜色信息,从而使调色板管理更加容易,且任何运行Windows的机器都可以处理DIB,并通常以后缀为.bmp的文件形式被保存在磁盘中或作为资源存在于程序的EXE或DLL文件中。
2016-05-27
原文:(2)GIF文件格式图形交换格式(Graphics Interchange Format,GIF)主要用于CompuServe网络图形数据的在线传输和存储。GIF提供了足够的信息并很好地组织了这些信息,使得许多不同的输入输出设备能够方便地交换图像,它支持24位彩色,由一个最多256种颜色的调色板实现,图像的大小最多是64K×64K个像素点。GIF的特点是LZW压缩、多图像和交错屏幕绘图。
2016-05-27
原文:(3)JPEG文件格式国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合成立的“联合照片专家组”JPEG(Joint Photographic Experts Group)于1991年3月提出了ISO CD 10918号建议草案“多灰度静止图像的数字压缩编码”(通常简称为JPEG标准)。这是一个适用于彩色和单色多灰度或连续色调静止数字图像的压缩标准,它包括无损压缩和基于离散余弦变换和Huffman编码的有损压缩两个部分。前者不会产生失真,但压缩比很小;后一种算法进行图像压缩时,信息虽有损失但压缩比可以很大。例如压缩20~40倍时,人眼基本上看不出失真。JPEG图像文件也是一种像素格式的文件格式,但它比BMP等图像文件要复杂许多。所幸的是,GDI的Image类提供了对JPEG文件格式的支持,从而不需要对JPEG格式有太多的了解就能处理该格式的图像。
2016-05-27
原文:4)TIFF文件格式TIFF(Tagged Image File Format,标志图像文件格式)最早是由Aldus公司于1986年推出的,它对从单色到24位真彩色的任何图像都有很好的支持,而且在不同的平台之间的修改和转换十分容易。与其他图像文件格式不同的是,TIFF文件中有一个标记信息区用来定义文件存储的图像数据类型、颜色和压缩方法。
2016-05-27
原文:(5)PNG文件格式PNG(Portable Network Graphic,可移植的网络图像)文件格式是由Thomas Boutell、Tom Lane等人提出并设计的,它是为了适应网络数据传输而设计的一种图像文件格式,用于取代格式较为简单、专利限制严格的GIF图像文件格式。而且,这种图像文件格式在某种程度上甚至还可以取代格式比较复杂的TIFF图像文件格式。它的特点主要有:压缩效率通常比GIF要高、提供Alpha通道控制图像的透明度、支持Gamma校正机制用来调整图像的亮度等。需要说明的是,PNG文件格式支持三种主要的图像类型:真彩色图像、灰度级图像和颜色索引数据图像。JPEG只支持前两种图像类型,而GIF虽然可以利用灰度调色板补偿图像的灰度级别,但原则上它仅仅支持第三种图像类型。
2016-05-27
原文:2. Image和Bitmap类GDI的Image类封装了对BMP、GIF、JPEG、PNG、TIFF、WMF(Windows元文件)和EMF(增强WMF)图像文件的调入、格式转换以及简单处理的功能。而Bitmap类是从Image类继承的一个图像类,它封装了Windows位图操作的常用功能。例如,Bitmap:SetPixel和Bitmap:GetPixel分别用来对位图进行读写像素操作,从而可以为图像的柔化和锐化处理提供一种可能。
2016-05-27
原文:3. DrawImage方法DrawImage是GDI的Graphics类显示图像的核心方法,它的重载函数有许多个。一般常用的重载函数有:Status DrawImage(Image *image,INT x,INT y);Status DrawImage(Image *image,const Rect&rect);Status DrawImage(Image *image,const Point *destPoints,INT count);Status DrawImage(Image *image,INT
x,INT y,INT srcx,INT srcy,INT srcwidth,INT srcheight,Unit srcUnit);其中(x,y)用来指定图像image显示的位置,这个位置与image图像的左上角点相对应。rect用来指定被图像填充的矩形区域,destPoints和count分别用来指定一个多边形的顶点和顶点个数。若count为3,则表示该多边形是一个平行四边形,另一个顶点由系
2016-05-27
原文:统自动给出。此时,destPoints中的数据依次对应于源图像的左上角、右上角和左下角的顶点坐标。srcx、srcy、src-width和srcheight用来指定要显示的源图像的位置和大小,srcUnit用来指定所使用的单位,默认时使用PageUnitPixel,即用像素作为度量单位。
2016-05-27
原文:DC是Windows为设备无关的图形绘制而定义的一种数据结构,包含了一组图形对象和关联属性以及若干影响输出的图形模式和绘图参数。所有的GDI绘图操作,都是采用DC中的当前图形对象作为绘图工具,并且都是在DC中的当前图形模式下使用当前的绘图参数进行的。
2016-05-27
原文:Windows的图形对象(Graphic Object)包括画线状图的画笔、绘制和填充面状图的画刷、用于显示图像及复制和滚动部分屏幕的位图、定义可用颜色的调色板、用于裁剪和其他操作的区域、用于绘制和画图操作的路径以及用于输出文字的字体等
2016-05-27
原文:图形模式(Graphics Mode)用于确定颜色如何混合、输出在何处出现、输出如何缩放等
2016-05-28
原文:CDC类是MFC对DC结构及其相关绘图和状态设置函数的C++类封装。CDC是CObject的直接派生类,CDC类自己也有若干派生类,其中包括:窗口客户区DC所对应的CClientDC类、OnPaint和OnDraw消息响应函数的输入参数中使用的CPaintDC类、图元文件对应的CMetaFileDC类和整个窗口所对应的CWindowDC类
2016-05-28
原文:1. 获得DC在OnDraw函数中应该使用输入参数(CDC类对象的指针)pDC,在其他函数中则可调用从CWnd类继承的成员函数GetDC来获得当前窗口(如客户区)DC的指针,该函数的原型为:CDC *GetDC();注意,每次从OnDraw函数的输入参数或调用GetDC所获得的DC,都是一个全新的临时默认DC,具有默认的绘图环境和设置。它不能用类变量来长期保存,而且原来选入的各种GDI对象全都被作废,原来设置的各种状态也失效,一切都必须从头再来。2. 释放DC因为Windows限制可用DC的数量,所以DC属于稀缺的公用资源。因此,对每次获得的DC,在使用完成后必须立即释放。从OnDraw函数的输入参数pDC获得的DC,在该函数运行结束后,系统会自动释放。但由GetDC所获得的DC,则必须自己来手工释放,这可以通过调用从CWnd类继承的成员函数ReleaseDC来完成。该函数的原型为:
2016-05-28
原文:int ReleaseDC(CDC * pDC);//成功返回非0
2016-05-28
原文:例如:void CDrawView:OnLButtonUp(UINT nFlags,CPoint point){CDC * pDC=GetDC();//获取DC…//设置参数、绘制图形ReleaseDC(pDC);//释放DCCView:OnLButtonUp(nFlags,point);}
2016-05-29
原文:3. 安全DC句柄可以用CDC类的成员函数GetSafeHdc来获取DC所对应窗口(如客户区)的安全DC句柄,该函数的原型为:HDC GetSafeHdc();与用GetDC函数所得到的临时DC不同,该安全DC句柄在窗口存在期间内一直是有效的。例如,可先定义类变量HDC m_hDC,再在适当的地方给它赋值m_hDC=GetDC()->GetSafeHdc(),然后就可以放心地使用了。还可以使用CDC类的成员函数Attach将一个空CDC对象与此安全DC句柄连接在一起,该函数的原型为:BOOL Attach(HDC
hDC);//成功返回非0
2016-05-29
原文:4. 屏幕DC可以以NULL为输入参数,调用全局的API函数GetDC获取屏幕DC的句柄:HDC GetDC(HWND hWnd);例如:HDC hdc=:GetDC(NULL);//获取屏幕DC的句柄Ellipse(hdc,0,0,150,100);//用API函数在屏幕左上角画一椭圆
2016-05-29
原文:也可以利用CDC类的成员函数Attach,将屏幕DC的句柄选入自定义的CDC类中来构造屏幕CDC类的对象。例如:HDC hdc=:GetDC(NULL);//获取屏幕DC的句柄CDC sDC;//定义屏幕DC(空)对象sDC.Attach(hdc);//粘上屏幕DC句柄sDC.Ellipse(0,0,150,100);//在屏幕左上角画一椭圆
2016-05-29
原文:库存对象是由操作系统维护的用于绘制屏幕的常用对象,包括库存画笔、画刷、字体等。使用SelectStockObject函数可以直接选择库存对象,修改系统默认值。
2016-05-29
原文:CPen *PenOld,PenNew;CBrush *BrushOld,BrushNew;//选用库存黑色画笔PenOld=(CPen*)pDC->SelectStockObject(BLACK_PEN);//画一个矩形外框pDC->Rectangle(100,100,300,300);//选用库存浅灰色画刷BrushOld=(CBrush*)pDC->SelectStockObject(LTGRAY_BRUSH);//填充矩形内部pDC->Rectangle(100,100,300,300);//关联GDI库存对象PenNew.CreateStockObject(WHITE_PEN);pDC->SelectObject(&PenNew);//在矩形内画了两条白色对角线pDC->MoveTo(100,100);pDC->LineTo(300,300);pDC->MoveTo(100,300);pDC->LineTo(300,100);//恢复系统默认的GDI对象pDC->SelectObject(PenOld);pDC->SelectObject(BrushOld);}
2016-05-29
原文:1. 画笔(CPen)创建CPen类画笔对象的方法有如下两种:(1)使用非默认构造函数创建初始画笔CPen(int nPenStyle,int nWidth,COLORREF crColor);其中:1)nPenStyle为画笔的风格,
2016-05-29
原文:2)nWidth为画笔的宽度,与映射模式有关,使用默认映射时为像素数,若nWidth=0,则不论什么映射模式,画笔宽都为一个像素。3)crColor为画笔的颜色值。默认的画笔为单像素宽的黑色实心笔。例如:CPen *pGrayPen=new CPen(PS_SOLID,0,RGB(128,128,128));CPen grayPen(PS_SOLID,0,RGB(128,128,128));
2016-05-29
原文:2)使用成员函数CreatePen(该函数可多次使用)创建画笔BOOL CreatePen(int nPenStyle,int nWidth,COLORREF crColor);可先用CPen类的默认构造函数创建一个空画笔对象,然后再调用CreatePen创建具有新内容的画笔,例如:CPen grayPen;grayPen.CreatePen(PS_SOLID,0,RGB(128,128,128));
2016-05-29
原文:不过在用CreatePen创建新画笔之前,必须先调用DeleteObject函数删除画笔对象的内容。该函数是CPen的基类CGDIObject的成员函数,下面是它的原型:BOOL DeleteObject();
2016-05-29
原文:2. 将画笔选入DC因为在GDI中,所有(被封装在CDC类中的)绘图函数都是使用DC中的当前绘图工具(包括画笔和画刷等)进行绘图的,为了能使用我们自己所创建的画笔对象来绘图,就必须先将它选入DC(以代替原来DC中的画笔,而成为DC的当前画笔),这可以通过调用设备上下文类CDC的成员函数SelectObject来完成:CPen * SelectObject(CPen *pPen);该函数的返回值为指向原来画笔对象的指针(一般将其保存下来,供下次选出新画笔时使用)。例如:Cpen *pOldPen=pDC->SelectObject(&pen);另外,Windows中有一些已经预定义好了的画笔对象(见表8-5),可用CDC类的另一成员函数SelectStockObject将其中的画笔选入DC,例如:
2016-05-29
原文:pDC->SelectStockObject(BLACK_PEN);该函数的原型为:virtual CGdiObject *SelectStockObject(int nIndex);其中,DC画笔为单像素宽的单色实心画笔,默认为黑色,是从Windows NT/2000开始新引进的,可用于直接设置画笔颜色。
2016-05-29
原文:3. 绘制线状图在将画笔对象选入DC后,就可以调用CDC类中的绘图函数,使用DC中的当前画笔对象来画线状图及面状图的边线。如果不创建和选入画笔对象,则使用的是DC中的默认画笔,为单像素宽的实心黑色画笔。Windows中的线状图有直线、折线、矩形和(椭)圆(弧)等。
2016-05-29
原文:. 删除画笔不能直接删除仍在DC中的画笔对象,必须先将它从DC中释放出来后才能删除。释放的方法是装入其他的画笔对象(一般是重新装入原来的画笔对象)。例如:pDC->SelectObject(pOldPen);删除画笔对象的方法有如下几种:1)删除画笔内容:调用画笔类CDC的成员函数DeleteObject删除画笔的当前内容(但是未删除画笔对象,以后可再用成员函数CreatePen在画笔对象中继续创建新的画笔内容)。例如:pen.DeleteObject();
2016-05-29
原文:2)删除画笔对象:使用删除运算符delete将画笔对象彻底删除。例如:delete&pen;
2016-05-29
原文:3)自动删除:若画笔对象为局部变量,则在离开其作用域时,画笔对象会被系统自动删除。
2016-05-29
原文:CDC * pDC=GetDC();//获取DCCPen pen,*pOldPen;//定义画笔对象和指针//创建10单位宽的绿色实心画笔pen.CreatePen(PS_SOLID,10,RGB(0,255,0));pOldPen=pDC->SelectObject(&pen);//选入绿色画笔pDC->Rectangle(10,10,100,100);//画矩形pDC->SelectObject(pOldPen);//选出绿色画笔pen.DeleteObject();//删除绿色画笔//创建单像素宽的红色虚线画笔:pen.CreatePen(PS_DASH,0,RGB(255,0,0));pOldPen=pDC->SelectObject(&
2016-05-29
原文:en);//选入红色画笔pDC->MoveTo(10,10);pDC->LineTo(100,100);//画直线ReleaseDC(pDC);//释放DC
2016-05-29
原文:对Windows NT/2000及以上的版本,如果只需修改单像素宽实心画笔的颜色,则可以不用反复创建和选入新画笔,而使用CDC类的成员函数SetDCPenColor,来直接设置位于绘图环境DC中DC画笔的当前颜色,其函数原型为:COLORREF SetDCPenColor(COLORREF crColor);//返回原颜色值不过需要在先调用CDC类的成员函数SelectStockObject将DC画笔选入DC之后,才能使用SetDCPenColor函数来设置DC中画笔的新颜色。例如:pDC->SelectStockObject(DC_PEN);//选入DC画笔pDC->SetDCPenColor(RGB(255,0,0));//设置成红色与SetDCPenColor所对应的获取DC画笔当前颜色的CDC类成员函数为:
2016-05-29
原文:COLORREF GetDCPenColor()const;
2016-05-29
原文:在Windows中,面状图必须用画刷(brush)来填充,所以面色是由画刷颜色来确定的。MFC中的画刷类为CBrush(它也是CGDIObject的派生类),画刷的创建与使用步骤与画笔相似。1. 构造函数CBrush类有4个构造函数,分别用于创建空画刷、实心画刷、条纹画刷和图案画刷:1)CBrush():创建一个画刷的空对象。2)CBrush(COLORREF crColor):创建颜色为crColor的单色实心画刷。3)CBrush(int nIndex,COLORREF crColor):创建风格由nIndex指定且颜色为crColor的条纹(hatch)画刷,其中nIndex可取条纹风格(Hatch
Styles)值见表8-6和图8-6。
2016-05-29
原文:4)CBrush(CBitmap *pBitmap):创建位图为pBitmap的图案画刷。2. 创建函数与构造函数相对应,CBrush类有多个创建不同类型画刷的成员函数,如:BOOL CreateSolidBrush(COLORREF crColor);//创建(单色)实心画刷BOOL CreateHatchBrush(int nIndex,COLORREF crColor);//创建条纹画刷BOOL CreatePatternBrush(CBitmap *pBitmap);//创建图案画刷
2016-05-29
原文:4. 选入画刷与画笔一样,也可以用函数SelectObject或SelectStockObject将自定义画刷或预定义画刷选入DC中,供绘面状图时使用。如果未选入任何画刷,则系统会使用DC中默认的白色实心画刷来绘图。5. 例子下面是一个创建、选入并使用自定义实心画刷的简单例子代码段:CDC * pDC=GetDC();CBrush brush(RGB(0,255,0));pDC->SelectObject(&brush);pDC->Rectangle(10,10,200,150);ReleaseDC(pDC);
2016-05-29
原文:6. 设置DC画刷颜色对Windows NT/2000及以上的版本,如果只需修改实心画刷的颜色,而不改变画刷的种类和风格,则可以不用反复创建和选入新画刷,而使用CDC类的成员函数SetDCBrushColor来直接设置DC画刷的颜色,如下所示:COLORREF SetDCBrushColor(COLORREF crColor);//返回原颜色值与设置DC画笔类似,也需要先调用CDC类的成员函数SelectStockObject将DC画刷选入DC后,才能使用SetDCBrushColor函数来设置DC中画刷的颜色。例如:pDC->SelectStockOb
2016-05-29
原文:ect(DC_BRUSH);//选入DC画刷pDC->SetDCBrushColor(RGB(255,0,0));//设置成红色与SetDCBrushColor对应的获取DC中画刷颜色的成员函数为:COLORREF GetDCBrushColor()const;
2016-05-29
原文:为了设置在绘制文本的前景像素时使用的颜色,调用CDC:SetTextColor函数,定义如下:COLORREF SetTextColor(COLORREF CrColor):为了设置在绘制文本的背景像素时使用的颜色,调用CDC:SetBkColor函数,定义如下:COLORREF SetBkColor(COLORREF CrColor):
2016-05-29
原文:. 设置文本显示属性CDC类还提供了设置文本显示属性的函数,如下:1)SetBkMode和GetBkMode:设置和获得背景模式。2)SetTextAlign和GetTextAlign:设置和获得文本对齐方式。3)SetTextJustification和SetTextCharaterExtra:调整文本。文本背景模式的默认设置是OPAQUE,这就要求GDI用户使用背景颜色。可修改设置为TRANSPARENT,要求GDI用户在绘制文本时不要使用背景色。函数的格式为:int CDC:SetBkMode(int
nBkmode);SetBkMode()函数设置当前的背景模式值,nBkmode表示背景模式,只有两种取值:O-PAQUE和TRANSPARENT。
2016-05-29
原文:int CDC:GetBkMode()const;GetBkMode()函数返回当前使用的背景模式。文本对齐方式描述了文本坐标(x,y)和文本框之间的关系。默认设置将文本与文本坐标右下方对齐。可使用SetTextAlign()函数设置文本对齐方式,函数格式为:UINT SetTextAlign(UINT nFlags);nFlags为下列标志的组合,同列中的各标志之间相互排斥,只能从一列中取一种标志,第一行为系统的默认设置值。
2016-05-29
原文:如果准备将不同字体、不同字号的文本混合显示在一行,使用Y轴默认设置TA_TOP将产生奇怪的现象,这时应该更改Y轴默认设置为TA_BOTTOM。SetTextJustification()和SetTextCharaterExtra()函数用于设置两种文本属性——文本调整和文本额外间隔。这两种属性能够帮助填补文本行。填补文本行是为了生成WYSIWYG(所见即所得)输出效果。在大多数情况下,它意味着显示屏幕输出变形,以模仿打印输出的效果。SetTextJustification()函数能够指定添加到各个间隔字符的像素数。如果需要更多的填充,则应调用SetTextCharaterExtra()函数,将额外的像素添加到各个字符(而不是间隔字符)。
2016-05-29
原文:3. 设置字体字体是一组复杂的图形图像,大小和设计都是统一的,用于表示字符数据。字体通常由磅值、名称和风格标识,如8磅粗体Arial的风格。处理字体的最简单方法是使用GDI的常备字体,如要自己设置显示字体的风格则需要创建一个CFont对象,具体步骤如下:1)定义CFont对象。2)调用CreateFont()函数创建字体。3)将创建的字体对象选入DC,并保存前一个被选入DC的字体对象。CreateFont()函数包括大量参数,具体解释如下。① 参数。BOOL CreateFont(int nHeight,//字体所需高度,为0时使用默认值int
nWidth,//字符的宽度值,为0时表示设备的纵横比匹配可用字体的纵横比int nEscapement,//字体转义,指定转义矢量和X轴的夹角int norientation,//字体方向,指定
2016-05-29
原文:字符基线和X轴的夹角(以0.1为单位)int nWeight,//字体厚度,常用取值有FW_NORMAL,FW-REGULAR和FW_BOLDBYTE bItalic,//是否斜体,布尔值BYTE bUnderline,//是否带有下划线,布尔值BYTE cStrikeOut,//是否带有删除线,布尔值BYTE nCharSet,//使用的字符集,常用取值有ANSI SHARSET、DEFAULT_CHARSET、SYBOL_CHARSET、HIFTJIS_CHARSET、OEM_CHARSETBYTE
nOutPrecision,//输出精度BYTE nCl土pPrecision,//剪切精度BYTE nQuality,//输出质量BYTE nPitchAndFamily,//字符间距和字符族LPCTSTR 1pszFacename//字体的名称);② 返回值。如果创建成功,返回非0值;否则返回0值。
2016-05-29
原文:4. 格式化文本(1)确定后继文本坐标函数原型:CSize GetTextExtent(LPCTSTR LpszString,int nCount);功能:获得所选字体中指定字符串的宽度和高度。说明:lpszString是字符串指针,nCount表明所包括的字符数,返回值CSize是包含两个成员的结构,cx是字符串的宽度,cy是字符串的高度。(2)确定换行时文本坐标GetTextMetric()函数用来计算两行文本之间的间隔。当然可以使用GetTextExtent()函数返回值中字符串的高度来决定两行文本之间的间隔,但这种方式并不精确。文本中行之间的间隔包括两部分:字符单元高度和外部行距大
2016-05-29
原文:小。这两部分内容都包含在TEXTMETRIC数据结构中。调用GetTextMetric()函数可以获得当前字体的TEXTMETRIC结构的数据,并计算文本行的间隔:TEXTMETRIC tm;pDC->GetTextMetriea(&tm);int LineHeight=tm.tmHeight+tm.tmExternalLeading;数据类型TEXTMETRIC的定义如下:typedef struct tagTEXTMETRIC{/*tm*/int tmHeight;int tmAscent;int
tmDescent;int tmInternalLeading;int tmExternalLeading;int tmAveCharWidth;int tmMaxCharWidth;int tmWeight;BYTE tmItalic;BYTE tmUnderlined;BYTE tmStruckOut;BYTE tmFirstChar;BYTE tmLastChar;BYTE tmDefaultChar;
2016-05-29
原文:BYTE tmBreakChar;BYTE tmPitchAndFamily;BYTE tmCharSet;int tmOverhang;int tmDigitizedAspectX;int tmDigitizedAspectY;}TEXTMETRIC;
2016-05-30
原文:5. 文本输出函数(1)TextOut()函数函数原型:BOOL CDC:TextOut(int x,int y,const CString&str);功能:在屏幕的指定位置用当前设定的颜色、字体、对齐方式输出文本。说明:其中,x、y是输出位置的坐标,str是要输出的文本串。在输出文本之前,应先设置输出文本串的颜色、字体及对齐方式。(2)TabbedTextOut()函数与TextOut()功能相似,唯一的差别是可以为支持制表符而定义一组制表位。(3)DrawText()函数函数原型:int CDC:DrawText(const
CString&str,LPRECT 1pRect,UINT nFormat);
2016-05-30
原文:功能:在一个区域中显示并格式化文本。说明:函数正确执行后返回文本行的高度,str是要输出的文本,1pRect是指定矩形输出区域,nFormat是格式常量。
2016-05-30
原文:Cex08_3Doc *pDoc=GetDocument();ASSERT_VALID(pDoc);if(!pDoc)return;//TODO:在此处为本机数据添加绘制代码int y,x;CString outstr[4];outstr[0]="第一行黑色的使用系统字体的文本串";outstr[1]="第二行红色自定义字体文本串";outstr[2]="第三行蓝色文本串";outstr[3]="最后一行大号字,加下划线的斜体文本串";x=0;y=0;//输出第一行pDC->SetTextColor(RGB(0,0,0));//设置黑色前景色pDC->TextOut(x,y,outstr[0]);//输出outstr[0]
2016-05-30
原文://输出第二行TEXTMETRIC tm;pDC->GetTextMetrics(&tm);//获得当前字体的TEXTMETRIC结构的数据//计算文本行的间隔,获得第二行的高度位置y=y+tm.tmHeight+tm.tmExternalLeading;CFont NewFont1;NewFont1.CreateFont(30,20,0,0,//创建自定义字体——黑体FW_HEAVY,false,false,false,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,_T("黑体"));CFont
*PoldFont;PoldFont=pDC->SelectObject(&NewFont1);//设置自定义字体,保存系统字体pDC->SetTextColor(RGB(255,0,0));//设置红色前景色pDC->TextOut(x,y,outstr[1]);//输出outstr[1]//输出第三行文本串pDC->GetTextMetrics(&tm);//获得当前字体的TEXTMETRIC结构的数据pDC->SetTextColor(RGB(0,0,255));//设置蓝色前景色
2016-05-30
原文:y=y+tm.tmHeight+tm.tmExternalLeading;pDC->TextOut(x,y,outstr[2]);//输出outstr[2]//在第三行文本串之后重新以绿色输出第三行文本串pDC->GetTextMetrics(&tm);//获得当前字体的TEXTMETRIC结构的数据pDC->SetTextColor(RGB(0,255,0));//设置绿色前景色CSize strSize=pDC->GetTextExtent(outstr[2]);x+=strSize.cx;//计算第二行的宽度,获得第三行的位置pDC->TextOut(x,y,outstr[2]);//输出outstr[2]//输出第四行文本串pDC->GetTextMetrics(&tm);//获得当前字体的TEXTMETRIC结构的数据x=0;//重置第四行的横向起点//计算第二、三行的高度,获得第四行的位置,20*行间间隔y=y+tm.tmHeight+20*tm.tmExternalLeading;CFont
NewFont2;NewFont2.CreateFont(60,20,0,0,//创建自定义字体——大号字FW_NORMAL,true,true,false,ANSI_CHARSET,OUT_DEFAULT_PRECIS,
2016-05-30
原文:CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,_T("大号字"));pDC->SelectObject(&NewFont2);//设置自定义字体pDC->SetTextColor(RGB(155,155,155));//设置灰色前景色pDC->TextOut(x,y,outstr[3]);//输出outstr[3]pDC->SelectObject(PoldFont);//还原系统字体
2016-05-30
原文:Windows中,位图是GDI对象,它像字体、画刷、画笔和其他GUI对象一样具有相当高的处理级别。我们可以用绘图程序创建位图,把它们作为资源嵌入应用程序的EXE文件,并用简单的函数加载它们;也可以使用GDI函数随意创建位图,把它们绘制到内存中的虚拟显示平面上。一旦创建了位图,就可以通过几个简单的函数调用把它显示在屏幕上或复制到打印机上了。
2016-05-30
原文:在程序中,可利用CBitmap类的LoadBitmap函数来加载位图资源:CBitmap bmp;//定义位图对象bmp.LoadBitmap(IDB_BITMAP1);//加载位图资源为了支持位图,GDI还提供了Bitmap类,Bitmap类是建立在抽象的Image类基础上的,如果创建了一个位图并将它存储为一个文件,可以将文件的路径传递给这个类的构造函数,如下所示:public:Bitmap(String *filename);
2016-05-30
原文:一旦准备好图片,为了将它呈现给用户,可以调用Graphics:DrawImage()方法。根据所有可能的需要,这个方法重载了很多版本,其中的一个版本使用如下的语法:public:void DrawImage(Image *img,Point point);第一个参数是一个先前已经初始化了的位图对象,第二个参数规定了图片将画在什么位置,这个位置对应于图片的左上角。
2016-05-30
原文:。DIB位图区别于GDI位图的本质特性如下:1)包含创建DIB位图设备上的颜色格式信息。2)包含创建DIB位图设备上的分辨率信息。3)包含创建DIB位图设备上的调色板信息。4)包含用以将调色板的红、绿、蓝(RGB)颜色元素映像到DIB图像中的像素的位图数组。5)包含数据压缩标志,它指示哪种数据压缩方案用于压缩磁盘文件。
2016-05-30
原文:1. GDI位图的使用GDI的Image类封装了对BMP、GIF、JPEG、PNG、TIFF、WMF(Windows元文件)和EMF(增强WMF)图像文件的调入、格式转换以及简单处理的功能。而Bitmap是从Image类继承的一个图像类,它封装了Windows位图操作的常用功能。在CBitmap类的对象中,包含了一种与Windows的GDI模块有关的Windows数据结构BITMAP,该结果是与设备有关的,应用程序可以得到GDI位图数据的一个备份,但其中位图的安排完全依赖于显示设备。在同一台机器中,我们可以将GDI位图在不同的应用程序中任意地传送,但由于GDI位图对设备的依赖性,因此通过磁盘或调制解调器对它们进行传送没有太大的意义。
2016-05-30
原文:GDI位图是由保存位图数据的BITMAP结果定义的,BITMAP定义如下:typedef struct tagBITMAP{//bmLONG bmType;//位图类型LONG bmWidth;//以像素表示的位图宽度LONG bmHeight;//以像素表示的位图高度LONG bmWidthBytes;//每条扫描线的字节数WORD bmPlanes;//在位图中的颜色面数WORD bmBitsPixel;//描述像素颜色所需位数LPVOID bmBits;//指向构成图像数
2016-05-30
原文:据的字符值数组的指针}BITMAP;
2016-05-30
原文:一是调用LoadBitmap成员函数装入程序资源中的位图数据,如下:CBitmap m_Bitmap;m_Bitmap.LoadBitmap(IDB_BITMAP1);
2016-05-30
原文:二是调用成员函数CreateCompatibleBitmap生成空位图,运行程序时再绘制所要的图形。如下:CBitmap m_Bitmap;CClient DC dc(this);m_Bitmap.CreateCompatibleBitmap(&dc,32,32);
2016-05-30
原文:函数CreateCompatibleBitmap的&dc参数是设备环境对象的地址,生成的位图将与这个对象相联系的设备兼容,后两个参数分别是位图的宽度和高度,单位是像素。调用CreateCompatibleBitmap时,Windows保留一块内存给位图。这个位图中存放的像素值最初是未定的,必须用绘图函数生成所要的图形。但在位图内画图前,要生成与位图相联系的设备环境对象,这就是内存设备环境对象。为了生成内存设备环境对象,先要声明CDC类的实例,再调用CDC的成员函数CreateCompatibleDC,例如:CClient
DC dc(this);CDC MemDC;m_Bitmap.CreateCompatibleBitmap(&dc,32,32);MemDC.CreateCompatibleDC(&dc);
2016-05-30
原文:函数CreateCompatibleDC的参数是设备环境对象的地址。接着调用CDC的成员函数SelectObject将位图对象选入内存设备环境对象,例如:MemDC.SelectObject(&m_Bitmap);现在可以对内存设备环境对象调用CDC绘图函数在位图内绘制所要的图形了。
2016-05-30
原文:MFC的CDC类提供了三个传送图形数据块的灵活而有效的函数:PatBlt、BitBlt和StretchBlt。生成图形时可用这些函数,复制图形数据块和用简单或复杂的方法修改图形数据(如传递颜色或翻转图形)时也用这些函数。这些函数可用于将图形数据从同一设备显示表面的一个位置复制到另一个位置,也可用于在不同设备间或设备与位图间复制图形数据。通过CDC类的成员函数PatBlt画矩形区。PatBlt函数使用当前选入指定设备环境中的刷子(简称当前刷)绘制给定的矩形区域在位操作环境中,当前刷通常指当前图案。尽管也可通过调用CDC:FillRect用当前图案填充区域,但PatBlt函数更加灵活,其原型如下:BOOL
PatBlt(int x,int y,int nWidth,int nHeight,DWORDdwRop);
2016-05-30
原文:前两个参数指定所画矩形区左上角的逻辑坐标,后两个参数按逻辑单位指定这个区的宽和高,DWORDdwRop参数是光栅操作码。光栅操作码给PatBlt提供了灵活性,它指定图案中的每个像素与目标地点的当前像素的组合方式,产生最后的目标像素颜色。BitBlt函数可以把图形数据块从一个位置传送到另一位置,源位置和目标位置可以在同一设备(或位图)上,也可以在不同设备上,其原型如下:BOOL BitBlt(int x,int y,int nWidth,int nHeight,CDC *pSrcDC,int xSrc,int
ySrc,DWORD dwRop);前两个参数指定传送目标位置左上角的逻辑坐标,紧接着两个参
2016-05-30
原文:数指定传送的数据块逻辑尺寸。第5个参数pSrcDC是源设备环境对象的指针,第6、7个参数xSrc和ySrc是源设备中位图的左上角逻辑坐标,最后一个参数dwRop是光栅操作码。BitBlt将图形数据块从一个与第5个参数pSrcDC表示的环境对象相联系的设备复制到与调用函数的环境对象相联系的设备上。StretchBlt是这三个位操作函数中最灵活的,它可用于完成BitBlt能完成的所有操作,还可以在传送时改变数据块的大小和将块翻转(水平、垂直或双向),其原型如下:BOOL StretchBlt(int x,int
y,int nWidth,int nHeight,CDC *pSrcDC,int xSrc,int ySrc,int nSrcWidth,int nSrcHeight,DWORD dwRop);StretchBlt除了比BitBlt多了两个指明源位图宽和高的参数外,其他同BitBlt一样。这样StretchBlt可用于指定源块和目标块的大小,而BitBlt只能指定一个块的大小。如果目标大小小于源大小则图形压缩,如果目标大小大于源大小则图形扩大,如果nWidth和nSrcWidth的符号不同则目标图形是源图的水平镜像。同样,如果nHeight和nSrcHeight符号相反,则目标图形是源图的垂直镜像。
2016-05-30
原文:DIB(DeviceIndepentent Bitmap)位图是另外一种格式的位图。如果要将位图保存在文档中,以便其他机器能够对它进行读取,则必须使用与设备无关的格式——DIB格式。它完全解决了位图传送问题,任何运行Windows的机器都可以对DIB进行处理,通常以后缀为BMP的文件形式保留在磁盘中,当BMP文件从磁盘文件中读出来以后,通常被转成GDI位图,但必要的时候程序可直接利用DIB格式进行工作。DIB格式可支持单色、16色及256色位图,也支持24位彩色位图。为了节省磁盘空间,DIB格式还可对16色和256色位图进行压缩。(1)BMP文件内的DIB的结构BMP图像文件结构可分为三部分:表头、调色板和图像数据。只有全彩色BMP图像文件内没有调色板数据,其余不超过256种颜色的图像文件都必须设定调色板信息,即使是单色BMP图像文件也不例外。1)BMP表头数据。Windows把BMP图像文件表头细分为两组数据结构:BITMAPFILEHEADER和BITMAPINFOHEADER,如果还需要调色板数据,则放在表头之后,两组数据结构的内容如下:typedef
struct tagBITMAPFILEHEADER{//位图文件头结构的定义
2016-05-30
原文:WORD bfType;//指定文件类型,必须是BMPDWORD bfSize;//双字节为单位指定文件的大小WORD bfReserved1;//保留,必须为0WORD bfReserved2;//保留,必须为0DWORD bfOffBits;//从位图文件头开始到位图数据段的字节总数,即字节偏移量}BITMAPFILEHEADER;typedef struct tagBITMAPINFOHEADER{//位图信息头结构的定义DWORD biSize;//指定该结构所需的字节数LONG biWidth;//以像素为单位指定位图的宽度LONG
biHeight;//指定位图的高度,若为负值,该位图原点在左上角,高为biHeight的绝对值WORD biPlanes;//为目标设备指定位面数,该值必须置为1WORD biBitCountDWORD biCompression;//为一个压缩位图指定压缩类型DWORD biSizeImage;//指定图像大小,若不压缩位图,可将该值置为0LONG biXPelsPerMeter;//以像素点/米为单位指定位图的目标设备的水平分辨率LONG biYPelsPerMeter;//以像素点/
2016-05-30
原文:米为单位指定位图的目标设备的垂直分辨率DWORD biClrUsed;//指定该位图实际使用的颜色表中的颜色索引数DWORD biClrImportant;//指定显示该位图所需的最重的颜色索引数}BITMAPINFOHEADER;
2016-05-30
原文:2)调色板数据。Windows将BMP图像文件的调色板数据结构命名为RGBQUAD,该结构描述组成某颜色的红、绿、蓝相对强度值。其数据结构如下:typedef struct tagRGBQUAD{//rgbqBYTE rgbBlue;//指定颜色中蓝色的强度值BYTE rgbGreen;//指定颜色中绿色的强度值BYTE rgbRed;//指定颜色中红色的强度值BYTE rgbReserved;//保留,必须为0}RGBQUAD;还有一个重要的数据结构BITMAPINFO,该结构由前面介绍的BITMAPINFOHEADER和RGBQUAD结构组成,它提供了Windows对DIB的大小和颜色的完整定义。因此也可这样说,DIB位图由两个不同的部分组成:描述
2016-05-30
原文:位图大小和颜色的BITMAPINFO结构和定义位图像素的字节数组,BITMAPINFO的结构如下:typedef struct tagBITMAPINFO{//bmiBITMAPINFOHEADER bmiHeader;RGBQUAD bmiColors[1];}BITMAPINFO;
2016-05-30
原文:编写DIB类由于MFC未提供DIB类,用户在使用DIB时将面临繁重的Windows API编程任务。幸运的是,Visual Studio提供了一个较高层次的API,简化了DIB的使用,主要包括:1)SetDiBitToDevice:该函数可以直接在显示器或打印机上显示DIB位图,没有任何缩放。2)StretchDIBits:该函数可以类似于StretchBlt的方式显示DIB位图。3)GetDIBits:该函数可以使用分配的内存从GDI位图中构造一个DIB位图。4)CreateDIBItmap:该函数可以从DIB位图中创建GDI位图。5)CreateDIBSection:可以创建一个特殊的DIB,它返回一个GDI位图句柄。该函数提供了DIB和GDI位图的最好特征,可
2016-05-30
原文:以直接访问DIB的内存,如果有了位图句柄和内存设备环境,还可以调用GDI函数在DIB中画图。6)ReadDIBFile:把DIB文件读入内存。7)SaveDIB:把DIB保存到文件中。8)CreateDIBPalette:从DIB中创建一个逻辑调色板。9)PaintDIB:显示DIB。10)DIBWidth:返回DIB的宽度。11)DIBHeight:返回DIB的高度。
2016-05-30
原文:下面就CDib类中关键成员函数做简要介绍:CDib():默认构造函数,创建一个空的DIB对象。~CDib():析构函数,释放所有分配的DIB内存。DIB段构造函数CDib(CSize size,int nBitCount):如果需要调用CreateDIBSection函数创建DIB段,可以使用该构造函数。它的参数决定了DIB的大小和颜色数目。该函数可以分配信息头内存,不能分配图像内存。AttachMapFile(const LPCWSTR strPathname,BOOL bShare):以读模式打开内存映射文件,并将其与CDib对象进行关联。
2016-05-30
原文:AttachMemory(LPVOID lpvMem,BOOL bMustDelete,HGLOBAL hGlobal):将内存中的DIB与已有的CDib对象关联。Compress(CDC * pDC,BOOL bCompress/*=TRUE*/):转换已有的DIB为GDI位图,然后生成一个新的压缩的或不压缩的DIB。CopyToMapFile(const LPCWSTR strPathname):创建一个新的内存映射文件,并将现有的CDib对象数据复制到该文件的内存,释放以前分配的所有内存,关闭现有的所有内存映射文件。CreateBitmap(CDC
* pDC):从已有的DIB中创建GDI位图,由Compress函数调用。CreateSection(CDC * pDC/*=NULL*/):通过调用CreateDIBSection函数来创建一个DIB段,图像内存将不被初始化。Draw(CDC * pDC,CPoint origin,CSize size):通过调用StretchDIBits函数将CDib对象输出到显示器(或打印机)。Empty():释放已分配的内存,必要时关闭映射文件。GetDimensions():返回以像素表示的DIB位图的宽度和高度。GetSizeHeader():返回信
2016-05-30
原文:息头文件中的字节数及与之相连的颜色表。GetSizeImage():返回DIB位图中的字节数(不包括信息头文件和颜色表)。MakePalette():读取已存在的颜色表,创建一个Windows调色板。Read(CFile * pFile):将DIB位图从文件读入到CDib对象。ReadSection(CFile * pFile,CDC * pDC/*=NULL*/):从BMP文件中读取信息首部,调用CreateDIBSection来分配图像内存,然后将图像读入该内存。SetSystemPalette(CDC
* pDC):对于不存在颜色表的CDib对象,可以调用该函数为该对象创建一个逻辑调色板。Write(CFile * pFile):把DIB从CDib对象写进文件中。下面是CDib类的源程序代码://dib.cpp#include "stdafx.h"#include "dib.h"#ifdef_DEBUG#define new DEBUG_NEW#undef THIS_FILE
2016-05-30
原文:static char THIS_FILE[]=__FILE__;#endifIMPLEMENT_SERIAL(CDib,CObject,0);CDib:CDib(){m_hFile=NULL;m_hBitmap=NULL;m_hPalette=NULL;m_nBmihAlloc=m_nImageAlloc=noAlloc;Empty();}CDib:CDib(CSize size,int nBitCount){m_hFile=NULL;m_hBitmap=NULL;m_hPalette=NULL;m_nBmihAlloc=m_nImageAlloc=noAlloc;Empty();ComputePaletteSize(nBitCount);m_lpBMIH=(LPBITMAPINFOHEADER)newchar[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries];m_nBmihAlloc=crtAlloc;m_lpBMIH->biSize=sizeof(BITMAPINFOHEADER);m_lpBMIH->biWidth=size.cx;
2016-05-30
原文:m_lpBMIH->biHeight=size.cy;m_lpBMIH->biPlanes=1;m_lpBMIH->biBitCount=nBitCount;m_lpBMIH->biCompression=BI_RGB;m_lpBMIH->biSizeImage=0;m_lpBMIH->biXPelsPerMeter=0;m_lpBMIH->biYPelsPerMeter=0;m_lpBMIH->biClrUsed=m_nColorTableEntries;m_lpBMIH->biClrImportant=m_nColorTableEntries;ComputeMetrics();memset(m_lpvColorTable,0,sizeof(RGBQUAD)*m_nColorTableEntries);m_lpImage=NULL;//数据为空}CDib:~CDib(){Empty();}CSize
CDib:GetDimensions(){if(m_lpBMIH==NULL)return CSize(0,0);return CSize((int)m_lpBMIH->biWidth,(int)m_lpBMIH->biHeight);}BOOL CDib:AttachMapFile(const LPCWSTR strPathname,BOOL bShare)
2016-05-30
原文:{//如果我们打开同一个文件两次,Windows将把它看成是两个不同的文件//在#palette entries>biClrUsed处不能使用BMP文件工作HANDLE hFile=:CreateFile(strPathname,GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);ASSERT(hFile!=INVALID_HANDLE_VALUE);DWORD dwFileSize=:GetFileSize(hFile,NULL);HANDLE
hMap=:CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);DWORD dwErr=:GetLastError();if(hMap==NULL){AfxMessageBox(_T("Empty bitmap file"));return FALSE;}LPVOID lpvFile=:MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);ASSERT(lpvFile!=NULL);if(((LPBITMAPFILEHEADER)lpvFile)->bfType!=0x4d42){
2016-05-30
原文:AfxMessageBox(_T("Invalid bitmap file"));DetachMapFile();return FALSE;}AttachMemory((LPBYTE)lpvFile+sizeof(BITMAPFILEHEADER));m_lpvFile=lpvFile;m_hFile=hFile;m_hMap=hMap;return TRUE;}BOOL CDib:CopyToMapFile(const LPCWSTR strPathname){//复制DIB到一个新文件,释放前面的指针//如果你前面使用了CreateSection,HBITMAP将为NULL(而且无用)BITMAPFILEHEADER
bmfh;bmfh.bfType=0x4d42;//‘BM‘bmfh.bfSize=m_dwSizeImage+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries+sizeof(BITMAPFILEHEADER);//bfSize的意思是位图的大小bmfh.bfReserved1=bmfh.bfReserved2=0;bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries;
2016-05-30
原文:HANDLE hFile=:CreateFile(strPathname,GENERIC_WRITE|GENERIC_READ,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);ASSERT(hFile!=INVALID_HANDLE_VALUE);int nSize= sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries+ m_dwSizeImage;HANDLE
hMap=:CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,nSize,NULL);DWORD dwErr=:GetLastError();ASSERT(hMap!=NULL);LPVOID lpvFile=:MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);ASSERT(lpvFile!=NULL);LPBYTE lpbCurrent=(LPBYTE)lpvFile;memcpy(lpbCurrent,&bmfh,sizeof(BITMAPFILEHEADER));//file
headerlpbCurrent+=sizeof(BITMAPFILEHEADER);LPBITMAPINFOHEADER lpBMIH=(LPBITMAPINFOHEADER)lpbCurrent;memcpy(lpbCurrent,m_lpBMIH,sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries);lpbCurrent+=sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries;memcpy(lpbCurrent,m_lpImage,m_d
2016-05-30
原文:wSizeImage);//字节图片DWORD dwSizeImage=m_dwSizeImage;Empty();m_dwSizeImage=dwSizeImage;m_nBmihAlloc=m_nImageAlloc=noAlloc;m_lpBMIH=lpBMIH;m_lpImage=lpbCurrent;m_hFile=hFile;m_hMap=hMap;m_lpvFile=lpvFile;ComputePaletteSize(m_lpBMIH->biBitCount);ComputeMetrics();MakePalette();return
TRUE;}BOOL CDib:AttachMemory(LPVOID lpvMem,BOOL bMustDelete,HGLOBAL hGlobal){//假设接近BITMAPINFOHEADER,颜色,图片//颜色表的长度可以为0Empty();m_hGlobal=hGlobal;if(bMustDelete==FALSE){m_nBmihAlloc=noAlloc;}
2016-05-30
原文:else{m_nBmihAlloc=((hGlobal==NULL)?crtAlloc:heapAlloc);}try{m_lpBMIH=(LPBITMAPINFOHEADER)lpvMem;ComputeMetrics();ComputePaletteSize(m_lpBMIH->biBitCount);m_lpImage=(LPBYTE)m_lpvColorTable+sizeof(RGBQUAD)*m_nColorTableEntries;MakePalette();}catch(CException
*pe){AfxMessageBox(_T("AttachMemory error"));pe->Delete();return FALSE;}return TRUE;}UINT CDib:UsePalette(CDC * pDC,BOOL bBackground/*=FALSE*/){if(m_hPalette==NULL)return 0;HDC hdc=pDC->GetSafeHdc();:SelectPalette(hdc,m_hPalette,bBackground);return:RealizePalette(hdc);
2016-05-30
原文:}BOOL CDib:Draw(CDC * pDC,CPoint origin,CSize size){if(m_lpBMIH==NULL)return FALSE;if(m_hPalette!=NULL){:SelectPalette(pDC->GetSafeHdc(),m_hPalette,TRUE);}pDC->SetStretchBltMode(COLORONCOLOR);:StretchDIBits(pDC->GetSafeHdc(),origin.x,origin.y,size.cx,size.cy,0,0,m_lpBMIH->biWidth,m_lpBMIH->biHeight,m_lpImage,(LPBITMAPINFO)m_lpBMIH,DIB_RGB_COLORS,SRCCOPY);return
TRUE;}HBITMAP CDib:CreateSection(CDC * pDC/*=NULL*/){if(m_lpBMIH==NULL)return NULL;if(m_lpImage!=NULL)return NULL;//如果图片不存在可以只完成这个m_hBitmap=:CreateDIBSection(pDC->GetSafeHdc(),(LPBITMAPINFO)m_lpBMIH,
2016-05-30
原文:DIB_RGB_COLORS,(LPVOID*)&m_lpImage,NULL,0);ASSERT(m_lpImage!=NULL);return m_hBitmap;}BOOL CDib:MakePalette(){//用DIB的颜色表制作一个逻辑调色板palette(m_hPalette)//这个调色板将会在绘制DIB之前被选择并且实现if(m_nColorTableEntries==0)return FALSE;if(m_hPalette!=NULL):DeleteObject(m_hPalette);LPLOGPALETTE
pLogPal=(LPLOGPALETTE)new char[2*sizeof(WORD)+m_nColorTableEntries *sizeof(PALETTEENTRY)];pLogPal->palVersion=0x300;pLogPal->palNumEntries=m_nColorTableEntries;LPRGBQUAD pDibQuad=(LPRGBQUAD)m_lpvColorTable;for(int i=0;i<m_nColorTableEntries;i++){pLogPal->palPalEntry[i].peRed=pDibQuad->rgbRed;pLogPal->palPalEntry[i].peGreen=pDibQuad->rgbGreen;pLogPal->palPalEntry[i].peBlue=pDibQuad->rgbBlue;
2016-05-30
原文:pLogPal->palPalEntry[i].peFlags=0;pDibQuad++;}m_hPalette=:CreatePalette(pLogPal);delete pLogPal;return TRUE;}BOOL CDib:SetSystemPalette(CDC * pDC){//如果DIB还没有一个颜色表,我们可以使用系统的halftone调色板if(m_nColorTableEntries!=0)return FALSE;m_hPalette=:CreateHalftonePalette(pDC->GetSafeHdc());return
TRUE;}HBITMAP CDib:CreateBitmap(CDC * pDC){if(m_dwSizeImage==0)return NULL;HBITMAP hBitmap=:CreateDIBitmap(pDC->GetSafeHdc(),m_lpBMIH,CBM_INIT,m_lpImage,(LPBITMAPINFO)m_lpBMIH,DIB_RGB_COLORS);ASSERT(hBitmap!=NULL);return hBitmap;
2016-05-30
原文:}BOOL CDib:Compress(CDC * pDC,BOOL bCompress/*=TRUE*/){if((m_lpBMIH->biBitCount!=4)&&(m_lpBMIH->biBitCount!=8))return FALSE;if(m_hBitmap)return FALSE;HDC hdc=pDC->GetSafeHdc();HPALETTE hOldPalette=:SelectPalette(hdc,m_hPalette,FALSE);HBITMAP hBitmap;//临时的if((hBitmap=CreateBitmap(pDC))==NULL)return
FALSE;int nSize=sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries;LPBITMAPINFOHEADER lpBMIH=(LPBITMAPINFOHEADER)new char[nSize];memcpy(lpBMIH,m_lpBMIH,nSize);//新的头部if(bCompress){switch(lpBMIH->biBitCount){case 4:lpBMIH->biCompression=BI_RLE4;break;case
8:lpBMIH->biCompression=BI_RLE8;break;
2016-05-30
原文:default:ASSERT(FALSE);}//用null数据指针调用GetDIBits得到压缩DIB的大小if(!:GetDIBits(pDC->GetSafeHdc(),hBitmap,0,(UINT)lpBMIH->biHeight,NULL,(LPBITMAPINFO)lpBMIH,DIB_RGB_COLORS)){AfxMessageBox(_T("Unable to compress this DIB"));//可能是使用颜色表的问题:DeleteObject(hBitmap);delete[]lpBMIH;:SelectPalette(hdc,hOldPalette,FALSE);return
FALSE;}if(lpBMIH->biSizeImage==0){AfxMessageBox(_T("Driver can‘t do compression"));:DeleteObject(hBitmap);delete[]lpBMIH;:SelectPalette(hdc,hOldPalette,FALSE);return FALSE;}else{m_dwSizeImage=lpBMIH->biSizeImage;
2016-05-30
原文:}}else{lpBMIH->biCompression=BI_RGB;//decompress//来自位图宽度和高度的图片大小的位数信息DWORD dwBytes=((DWORD)lpBMIH->biWidth *lpBMIH->biBitCount)/32;if(((DWORD)lpBMIH->biWidth *lpBMIH->biBitCount)%32){dwBytes++;}dwBytes*=4;m_dwSizeImage=dwBytes *lpBMIH->biHeight;//no compressionlpBMIH->biSizeImage=m_dwSizeImage;}//第二个GetDIBits调用制作DIBLPBYTE
lpImage=(LPBYTE)new char[m_dwSizeImage];VERIFY(:GetDIBits(pDC->GetSafeHdc(),hBitmap,0,(UINT)lpBMIH->biHeight,lpImage,(LPBITMAPINFO)lpBMIH,DIB_RGB_COLORS));TRACE("dib successfully created-height=%d\n",lpBMIH->biHeight);:DeleteObject(hBitmap);Empty();
2016-05-30
原文:m_nBmihAlloc=m_nImageAlloc=crtAlloc;m_lpBMIH=lpBMIH;m_lpImage=lpImage;ComputeMetrics();ComputePaletteSize(m_lpBMIH->biBitCount);MakePalette();:SelectPalette(hdc,hOldPalette,FALSE);TRACE("Compress:new palette size=%d\n",m_nColorTableEntries);return TRUE;}BOOL
CDib:Read(CFile * pFile){Empty();int nCount,nSize;BITMAPFILEHEADER bmfh;try{nCount=pFile->Read((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER));if(nCount!=sizeof(BITMAPFILEHEADER)){return FALSE;}if(bmfh.bfType!=0x4d42){return FALSE;}nSize=bmfh.bfOffBits-size
2016-05-30
原文:of(BITMAPFILEHEADER);m_lpBMIH=(LPBITMAPINFOHEADER)new char[nSize];m_nBmihAlloc=m_nImageAlloc=crtAlloc;nCount=pFile->Read(m_lpBMIH,nSize);//info hdr&color tableComputeMetrics();ComputePaletteSize(m_lpBMIH->biBitCount);MakePalette();m_lpImage=(LPBYTE)new char[m_dwSizeImage];nCount=pFile->Read(m_lpImage,m_dwSizeImage);//image
only}catch(CException *pe){AfxMessageBox(_T("Read error"));pe->Delete();return FALSE;}return TRUE;}BOOL CDib:ReadSection(CFile * pFile,CDC * pDC/*=NULL*/){//新功能从磁盘读取BMP并且创建一个DIB//允许从磁盘修改位图//1. 读取文件头部得到hdr+color表的大小信息
2016-05-30
原文://2. 读取hdr获得图像的大小信息和颜色表//3. 基于头部参数创建DIB//4. 将图像读入内存并分配CreateDibSectionEmpty();int nCount,nSize;BITMAPFILEHEADER bmfh;try{nCount=pFile->Read((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER));if(nCount!=sizeof(BITMAPFILEHEADER)){return FALSE;}if(bmfh.bfType!=0x4d42){return
FALSE;}nSize=bmfh.bfOffBits-sizeof(BITMAPFILEHEADER);m_lpBMIH=(LPBITMAPINFOHEADER)new char[nSize];m_nBmihAlloc=crtAlloc;m_nImageAlloc=noAlloc;nCount=pFile->Read(m_lpBMIH,nSize);//hdr信息和颜色表if(m_lpBMIH->biCompression!=BI_RGB){return FALSE;}
2016-05-30
原文:ComputeMetrics();ComputePaletteSize(m_lpBMIH->biBitCount);MakePalette();UsePalette(pDC);m_hBitmap=:CreateDIBSection(pDC->GetSafeHdc(),(LPBITMAPINFO)m_lpBMIH,DIB_RGB_COLORS,(LPVOID*)&m_lpImage,NULL,0);ASSERT(m_lpImage!=NULL);nCount=pFile->Read(m_lpImage,m_dwSizeImage);//image
only}catch(CException *pe){AfxMessageBox(_T("ReadSection error"));pe->Delete();return FALSE;}return TRUE;}BOOL CDib:Write(CFile * pFile){BITMAPFILEHEADER bmfh;bmfh.bfType=0x4d42;//"MB"int nSizeHdr=sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries;bmfh.bfSize=0;bmfh.bfReserved1=bmfh.bfReserved2=0;bmfh.bfOffBits=sizeof(BITMAPFILEHE
2016-05-30
原文:ADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries;try{pFile->Write((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER));pFile->Write((LPVOID)m_lpBMIH,nSizeHdr);pFile->Write((LPVOID)m_lpImage,m_dwSizeImage);}catch(CException *pe){pe->Delete();AfxMessageBox(_T("write
error"));return FALSE;}return TRUE;}void CDib:Serialize(CArchive&ar){DWORD dwPos;dwPos=ar.GetFile()->GetPosition();TRACE("CDib:Serialize--pos=%d\n",dwPos);ar.Flush();dwPos=ar.GetFile()->GetPosition();TRACE("CDib:Serialize--pos=%d\n",dwPos);if(ar.IsStoring()){Write(ar.GetFile());
2016-05-30
原文:}else{Read(ar.GetFile());}}//帮助功能void CDib:ComputePaletteSize(int nBitCount){if((m_lpBMIH==NULL)||(m_lpBMIH->biClrUsed==0)){switch(nBitCount){case 1:m_nColorTableEntries=2;break;case 4:m_nColorTableEntries=16;break;case 8:m_nColorTableEntries=256;break;case
16:case 24:case 32:m_nColorTableEntries=0;break;default:ASSERT(FALSE);}
2016-05-30
原文:}else{m_nColorTableEntries=m_lpBMIH->biClrUsed;}ASSERT((m_nColorTableEntries>=0)&&(m_nColorTableEntries<=256));}void CDib:ComputeMetrics(){if(m_lpBMIH->biSize!=sizeof(BITMAPINFOHEADER)){TRACE("Not a valid Windows bitmap--probably an OS/2 bitmap\n");//抛出一个新的CException例外}m_dwSizeImage=m_lpBMIH->biSizeImage;if(m_dwSizeImage==0){DWORD
dwBytes=((DWORD)m_lpBMIH->biWidth *m_lpBMIH->biBitCount)/32;if(((DWORD)m_lpBMIH->biWidth *m_lpBMIH->biBitCount)%32){dwBytes++;}dwBytes*=4;m_dwSizeImage=dwBytes *m_lpBMIH->biHeight;//no compression}
2016-05-30
原文:m_lpvColorTable=(LPBYTE)m_lpBMIH+sizeof(BITMAPINFOHEADER);}void CDib:Empty(){//在DIB的任何地方都支持清除操作DetachMapFile();if(m_nBmihAlloc==crtAlloc){delete[]m_lpBMIH;}else if(m_nBmihAlloc==heapAlloc){:GlobalUnlock(m_hGlobal);:GlobalFree(m_hGlobal);}if(m_nImageAlloc==crtAlloc)delete[]m_lpImage;if(m_hPalette!=NULL):DeleteObject(m_hPalette);if(m_hBitmap!=NULL):DeleteObject(m_hBitmap);m_nBmihAlloc=m_nImageAlloc=noAlloc;m_hGlobal=NULL;m_lpBMIH=NULL;m_lpImage=NULL;m_lpvColorTable=NULL;m_nColorTableEntries=0;m_dwSizeImage=0;m_lpvFile=NULL;
2016-05-30
原文:m_hMap=NULL;m_hFile=NULL;m_hBitmap=NULL;m_hPalette=NULL;}void CDib:DetachMapFile(){if(m_hFile==NULL)return;:UnmapViewOfFile(m_lpvFile);:CloseHandle(m_hMap);:CloseHandle(m_hFile);m_hFile=NULL;}
2016-05-30
原文:在WM_CREATE消息中,程序从资源区中装入所有的图标和光标资源,装入图标是用LoadI-con函数来完成的:invoke LoadIcon(hInstance,lpIconName)if eaxmov hIcon,eaxendif
2016-05-30
原文:hInstance参数指定实例句柄,表示图标资源定义在哪个可执行文件中。lpIconName参数指定图标资源的名称,它就是资源文件中定义的图标ID值,如果调用成功的话,函数返回图标句柄。除了可以装入资源文件中定义的图标资源之外,当参数hInstance为NULL的时候,用LoadIcon还可以用预定义的lpIconName参数装入Windows预定义的图标
2016-05-30
原文:装入光标的函数有两个。装入在资源中定义的光标的函数是LoadCursor,它的语法与LoadI-con几乎一样:invoke LoadCursor(hInstance,lpCursorName)if eaxmov hCursor,eaxendif
2016-05-30
原文:另一个光标装入函数是LoadCursorFromFile,这个函数从磁盘光标文件中装入光标:invoke LoadCursorFromFile(lpCursorFileName)if eaxmov hCursor,eaxendif
2016-05-30
原文:要在标题栏中设置图标可以用向窗口发送WM_SETICON消息的办法实现:invoke SendMessage(hWnd,WM_SETICON,ICON_BIG,hIcon)
2016-05-30
原文:消息的wParam参数可以是ICON_BIG或ICON_SMALL,用来指定图标的分辨率为32×32还是16×16。要将窗口的光标设置为新的光标不能使用WM_SETCURSOR,这个消息是通知窗口重新刷新光标而不是让它设定指定的光标。Windows中的SetCursor函数可以用来设置窗口光标,但这只能将新的光标维持很短一段时间,因为当Windows向窗口重新发送WM_SETCURSOR消息的时候,光标就会被设置为原来的样子,所以SetCursor并不能用来永久地改变窗口的光标。
2016-05-30
原文:如果要改变窗口的光标,正确的办法是用SetClassLong函数改变窗口类的属性,这个函数的使用方法如下:invoke SetClassLong(hWnd,nIndex,dwNewLong)SetClassLong函数用来改变窗口类的属性,所以可以改变类中的光标设定,hWnd用来指定用这个类建立的某个窗口句柄,nIndex参数指定要改变窗口类的哪个属性,可以指定为GCL_HBRBACKGROUND、GCL_HCURSOR、GCL_HICON、GCL_HMODULE、GCL_MENUNAME、GCL_STYLE或GCL_WNDPROC等,它们分别表示要改变窗口类的背景色、光标、图标、
2016-05-30
原文:hInstance、菜单、风格或窗口过程地址,可以用SetClassLong函数来改变一个窗口类的几乎所有属性,程序中可通过SetClassLong函数将窗口的光标在不同的光标句柄之间切换:invoke SetClassLong(hWnd,GCL_HCURSOR,hCur1或hCur2)
2016-05-30
原文:如果应用程序要将显示结果在打印机上打印出来,OnDraw函数便担负着双重的任务:如果正在显示,OnPaint函数便调用OnDraw,并且设备环境是显示器环境;如果正在打印,OnDraw由另一个CView虚函数OnPrint调用,用一个打印机设备环境作为参数。每打印一整页,便调用一次OnPrint函数。在打印预览模式下,OnDraw函数实际上是指向CPreviewDC对象的一个指针,不管是打印还是预览,OnPrint和OnDraw函数都起着同样的作用。
2016-05-30
原文:CView:OnPrint函数原型:virtual void OnPrint(CDC * pDC,CPrintInfo *pInfo);其中,pDC为指向打印机设备环境的指针,pInfo为指向打印信息的对象(CPrintInfo结构)的指针,该信息包括纸张尺寸、当前页码和最大页码。框架调用CView:OnPrint函数以打印或预览文档的一页。对于要被打印的每一页,框架在调用OnPrepareDC成员函数之后立即调用CView:OnPrint函数。要被打印的页是在pInfo指向的CPrintInfo结构的m_nCurPage成员中指定的。默认调用
2016-05-30
原文:OnDraw函数并将打印机设备环境传递给CView:OnPrint函数。下面是重载的OnPrint函数的基本结构:void CMyView:OnPrint(CDC * pDC,CPrintInfo *pInfo){OnDraw(pDC);}
2016-05-30
原文:CView:OnPrepareDC函数原型:virtual void OnPrepareDC(CDC * pDC,CPrintInfo *pInfo=NULL);其中,pDC为指向设备环境的指针,用于画出文档的图像。pInfo为指向CPrintInfo结构的指针,如果OnPrepareDC是为打印或打印预览调用的,则该结构描述了当前打印任务,m_nCurPage成员指定了要打印的页数。如果OnPrepareDC是为屏幕显示而调用的,则这个参数为NULL。在为屏幕显示而调用OnDraw成员函数或者为打印或打印预览每一页而调用OnPrint成员函数之前,框架调用CView:OnPrepareDC函数。如果CView:OnPrepareDC函数是为屏幕显示而调用的,则CView:OnPrepareDC函数的默认实现不做任何操作。CView:OnPrepareDC函数在派生类中(例如在CScrollView中)被重载,以调整设备环境的属性,因此,在重载代码的开始部分总应该调用基类的实现。
2016-05-30
原文:如果CView:OnPrepareDC函数是为打印而调用的,默认的实现检查保存在pInfo参数中的页面信息。如果没有指定文档的长度,OnPrepareDC假定文档只有一页,并且在打印完一页以后停止打印循环。这个函数通过将结构的m_bContinuePrinting成员设为FALSE来结束打印循环。如果具有以下的原因,则应重载OnPrepareDC函数:1)要为指定的页面调整设备环境的属性。例如,如果想要设置设备环境的映射模式或者其他特征,则应在这个函数中完成这些操作。2)要实现打印时的分页。通常应当在打印开始时利用OnPreparePrinting成员函数来指定文档的长度。但是,如果并不准确地知道文档的长度(例如,当打印数据库中未知数量的记录时),则应重载OnPrepareDC函数,以在打印时检测是否到了文档的末尾。如果已经没有文档需要打印了,将CPrintInfo结构的m_bContinuePrinting成员设为FALSE。3)要按页发送打印机的转义序列码。要在OnPrepareDC中发送转义序列码,则应调用pDC成员的Escape成员函数。
2016-05-30
原文:当一个打印任务开始的时候,应用程序框架调用两个CView函数:OnPreparePrinting和OnBeginPrinting(如果选择了Printing和Print Preview选项的话,AppWizard生成OnPreparePrinting、OnBeginPrinting和OnEndPrinting),在显示Print对话框之前,会调用第一个函数OnPreparePrinting。如果知道第一页和最后一页的页码,可以在OnPreparePrinting中调用CPrintInfo:SetMinPage和CprintInfo:SetMaxPage。传递到这些函数的页码会出现在Print对话框中,以便用户改变。在Print对话框退出之后,会调用第二个函数OnBeginPrinting。如果重载OnBeginPrinting函数名,便可以创建整个打印任务中都需要的GDI对象,如字体。如果只创建一次字体而不是对每页都重新创建的话,程序会运行得更快
2016-05-30
原文:一些。在打印任务的末尾,当最后一页打印完成后,就会调用CView类的函数OnEndPrinting。重载这个函数可以删除在OnBegin
2016-05-30
原文:MFC提供了对数据库编程的强大支持。对于数据库的访问,MFC提供了两组类:ODBC(Open Database Connectivity)和DAO(Database Access Object)。利用这两个功能强大的类,用户可以方便地开发出基于ODBC或DAO的数据库应用。MFC的ODBC类对较复杂的ODBC API进行了封装,提供了简化的调用接口,从而方便了数据库应用程序的开发。程序员不必了解ODBC API和SQL的具体细节,利用ODBC类即可完成对数据库的大部分操作。MFC的ODBC类主要包括:1)CDatabase类:主要功能是建立与数据源的连接。2)CRecordset类:该类代表从数据源选择的一组记录(记录集),程序可以选择数据源中的某个表作为一个记录集,也可以通过对表的查询得到记录集,还可以合并同一数据源中多个表的列到一个记录集中。通过该类可对记录集中的记录进行滚动、修改、增加和删除等操作。
2016-05-30
原文:3)CRecordView类:提供了一个表单视图与某个记录集直接相连,利用对话框数据交换机制(DDX)在记录集与表单视图的控件之间传输数据。该类支持对记录的浏览和更新,在撤销时会自动关闭与之相联系的记录集。4)CFieldExchange类:支持记录字段数据交换(DFX),即记录集字段数据成员与相应的数据库的表的字段之间的数据交换。该类的功能与CDataExchange类的对话框数据交换功能类似。5)CDBException类:代表ODBC类产生的异常。CDatabase针对某个数据库,负责连接数据源;CRecordset针对数据源中的记录集,负责对记录的操作;CRecordView负责界面;CFieldExchange负责CRecordset与数据源的数据交换。
2016-05-30
原文:BOOL CtestDlg:IsOpenODBC()//判断数据库是否打开的实现函数{int bol=0;CDatabase odbc;TRY{odbc.Open(_T("test"),FALSE,FALSE,_T("ODBC;UID=sa"));return TRUE;}CATCH_ALL(e)//捕捉数据库打开异常{return FALSE;}END_CATCH_ALL}
2016-05-30
原文:void CtestDlg:OnBnClickedSelect(){CDatabase myMdb;myMdb.Open(_T("test"),FALSE,FALSE,_T("ODBC;UID=sa"));//打开数据库连接//数据库已打开……CRecordset tmpRS(&myMdb);//从数据源选择记录集tmpRS.Open(CRecordset:forwardOnly,_T("SELECT *FROM data"));//通过查询语句打开一个数据集CString szResult;while(!tmpRS.IsEOF())//判断是否为最后一条记录{tmpRS.GetFieldValue(_T("name"),szResult);//获取记录值,并用列表显示m_List.AddString(szResult);tmpRS.MoveNext();}tmpRS.Close();myMdb.Close();//TODO:在此添加控件通知处理程序代码}
2016-05-30
原文:void Cdata:button1(){CDatabase myMdb;myMdb.Open(_T("test"),FALSE,FALSE,_T("ODBC;UID=sa"),TRUE);MessageBox(AfxGetMainWnd()->m_hWnd,_T("数据库管理ODBC开启成功。"),_T("数据库管理"),MB_OK);Cdata tmpRS(&myMdb);if(!tmpRS.Open())MessageBox(AfxGetMainWnd()->m_hWnd,_T("连接失败"),_T("错误信息"),MB_OK);if(!tmpRS.CanAppend())MessageBox(AfxGetMainWnd()->m_hWnd,_T("不能添加记录到数据库"),_T("错误信息"),MB_OK);tmpRS.AddNew();//清空记录,准备向数据库中添加记录tmpRS.m_name=_T("dahua");tmpRS.m_number=_T("5555");tmpRS.m_score=100;tmpRS.Update();//更新记录
2016-05-30
原文:tmpRS.Close();//只要有打开就应该对应关闭记录集myMdb.Close();//和ODBC连接,清空占用的系统资源}
2016-05-30
原文:void CtestDlg:OnBnClickedDelete(){CDatabase m_dbCust;CString sql=_T("delete *from data");m_dbCust.Open(_T("test"),FALSE,FALSE,_T("ODBC;UID=sa"));m_dbCust.ExecuteSQL(sql);//执行Cdatabase的成员函数ExecuteSQL实现指定SQL语句的功能m_dbCust.Close();//TODO:在此添加控件通知处理程序代码}
图: