图表解释 绿字:函数学习 红字:注意事项 黑字:正文内容
1.MFC是微软基础类库,它对windowsAPI函数进行了封装,简化了开发过程。
2.windows应用程序与控制台程序的区别:第一点:控制台应用程序是“黑屏的”,而windows应用程序是基于“窗口的”;第二点,控制台应用程序的核心内容是与操作系统无关;而windows应用程序是跟操作系统密切相关的。
3.WinMain函数是程序的入口,相当于main函数,在WinMain中,完成了6件事情:设计窗口类,注册窗口类,创建窗口,显示窗口,更新窗口,进入消息循环(这也是窗口程序的产生机制)。在设置窗口类中,指明消息处理函数,并把这个重要的信息在注册窗口时告诉操作系统,而在消息循环,每当我的应用程序收到了消息,都会把这个消息投递到这个应用程序的消息队列中,然后程序依次从中取走消息,并把消息告诉操作系统,操作系统调用消息处理函数来响应这些消息。
4.MFC消息映射的两种实现机制:
(1)使用虚函数:在基类中对每个消息处理函数定义一个虚函数,在派生类中可以重写这些函数。但是,这种方法是不可取的,因为我们知道,虚函数时要通过虚函数表来实现的,而在MFC如此繁杂的继承派生体系中,为每一个类增加一个虚函数表会大大增加整个程序的开销,而且扫描虚函数表会消耗很多的时间。
(2)采用消息映射表。对于每个可以接收和处理消息的类,定义一个消息和消息函数的静态对照表。当有消息到来时,只要扫描这个表就可以判断这个类是否能够处理该消息。如果子类找不到消息响应函数,则交给基类处理。
5.函数:
(1)使用SetPixel来为某一像素设置颜色,使用GetPixel来获取某一点的颜色。
(2)使用MoveToEx来移动到某一点,使用LineTo来从当前点画到指定点。
(3)FillRect函数来使用刷子,这个函数接受两个参数,第一个参数是指向矩形的指针,第二个参数是指向刷子的指针。该函数也是用来画矩形的
(4)刷子还有一种构造函数,接受指向位图的指针:CBrush( CBitmap* pBitmap );我们可以新建一幅位图,然后通过装载位图,使用位图构造刷子
(5)CreateSolidCaret实现创建插入符,创建完成后使用ShowCaret显示插入符。
(6)字体:在SDK下,我们使用GetTextMetrics函数,而在MFC下,我们使用的是经过封装的这个函数,使用的方法是大同小异的:定义一个TEXTMETRIC类型的变量,将它的地址传给GetTextMetrics,然后系统的一些字体之类的信息就会储存在变量中了。
6.画图相关的1个重要的概念是DC(设备描述表、设备上下文),还有对应的句柄HDC
7.菜单:整个菜单上的那些“文件”、“编辑”、“查看”等等内容,称为“顶层菜单”,双击它们,你会发现它们没有ID,而且它们是“弹出”(POPUP属性)的,它们不能响应命令;而点击子菜单的“打开”、“新建”等内容,可以响应命令这些内容称为菜单项。即顶层菜单不能响应命令,菜单项可以响应命令。
8.消息:
(1)标准消息:WM开头的,除了WM_COMMAND之外的消息都是标准消息。从CWnd派生来的类都能接受这种消息。
(2)命令消息:WM_COMMAND,它们是由菜单、工具栏等发出的消息。不同消息通过wParam来区别,从CCmdTarget类派生出来的的类都能相应这些消息。
(3)通告消息:由控件产生。它们也是WM_COMMAND消息,从CCmdTarget类派生出来的的类都能相应这些消息。
9.函数:
(1)获取菜单:CWnd的成员函数GetMenu来获得。这个函数返回一个指向CMenu类的指针。CMenu是MFC封装的关于菜单的类,其中有一个成员函数GetSubMenu来获得子菜单,找到子菜单以后,通过CheckMenuItem来给菜单加上标记,这个函数就可以用两种办法访问菜单项,具体如下:
GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_CHECKED | MF_BYPOSITION );
GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW,MF_CHECKED | MF_BYCOMMAND);
在CheckMenuItem第一种方法使用的是序号:在第二个参数中表明MF_BYPOSITION ,第一个参数填上序号即可,注意是从0开始的;当第二个参数选择MF_BYCOMMAND时,第一个参数就要使用ID号了
(2)添加默认菜单项:这也是通过CMenu的成员函数SetDefaultItem来完成的。而这个函数也是既可以使用ID,也可以使用序号使用,默认情况下,使用ID访问: · GetMenu()->GetSubMenu(0)->SetDefaultItem(ID_FILE_NEW);
· GetMenu()->GetSubMenu(0)->SetDefaultItem(0,TRUE);
注意,就是子菜单中的分隔符也占了一个序号,一个子菜单只能设置一个默认菜单项
(3)给菜单加上图标:SetMenuItemBitmaps 函数
m_bitmap.LoadBitmap(IDB_BITMAP1);
GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps ( ID_FILE_NEW , MF_BYCOMMAND , &m_bitmap , &m_bitmap );
(4)获取菜单图标长度:GetSystemMetrics(SM_CXMENUCHECK)
(5)禁用菜单项:EnableMenuItem
GetMenu()->GetSubMenu(0)->EnableMenuItem (1,MF_BYPOSITION | MF_DISABLED);
(6)移除和装载菜单:SetMenu。他接受一个指向CMenu的指针,如果把这个指针设为NULL,就可以移除菜单:SetMenu(NULL);
如果想装载菜单,可以:
CMenu menu;
menu.LoadMenu(IDR_MAINFRAME);
SetMenu(&menu);
注意:看起来就没有问题了,但是我们很容易就会发现,因为这里的menu是一个局部变量,所以程序执行完以后就析构了。所以程序在运行时会出问题。按照我们以前的习惯,可以将menu定义为成员变量。其实还有一种解决办法:使用CMenu的成员函数Detach 。他将菜单句柄与菜单对象分离,这样当菜单对象menu的生命周期结束以后,不会销毁那个本来是由菜单句柄管理,但现在已经从菜单句柄身上分离出去的那个菜单,而这个菜单会在窗口被关闭时自动销毁。