MFC学习_MFC入门

MFC
原作者姓名 zhoujiamurong

#include < afxwin.h >

class  sample: public  CFrameWnd
{
public :
    sample()
    {
        
this -> Create(NULL, " 我的第一次 " );
        
this -> MessageBox( " sample中调用 " , " sample中调用 " ,MB_OK);
    }
};

class  App: public  CWinApp
{
public :
    BOOL InitInstance();
    BOOL ExitInstance();
};

BOOL App::InitInstance()
{
    MessageBox(
0 , " InitInstance中调用 " , " InitInstance中调用 " ,MB_OK);
    sample
*  s = new  sample;
    m_pMainWnd
= s;
    s
-> ShowWindow(SW_SHOWDEFAULT);
    
return  TRUE;
}
BOOL App::ExitInstance()
{
    MessageBox(
0 , " ExitInstance中调用 " , " ExitInstance中调用 " ,MB_OK);
    
return  TRUE;
}

App a;

关键字

介绍
(原创) 一个最简单的例子,来讲诉MFC

读者评分 137 评分次数 37

正文
该文章为学习了C和C++以及有SDK编程基础的,但还未学习MFC的人员使用,我们开始使用一个基本的内容开始:

全部的代码如下:

#include <afxwin.h>

class sample:public CFrameWnd
{
public:
sample()
{
Create(NULL,"MFC Window");
MessageBox("My MFC Window","CFrame constructor",MB_OK);
}
};

class App:public CWinApp
{
public:
BOOL InitInstance();
BOOL ExitInstance();
};

BOOL App::InitInstance()
{
MessageBox(0,"My MFC Window","InitInstance",MB_OK|MB_ICONASTERISK);
sample *obj;
obj=new sample;
m_pMainWnd=obj;
obj->ShowWindow(SW_SHOWMAXIMIZED);
return TRUE;
}

BOOL App::ExitInstance()
{
MessageBox(0,"My Window","ExitInstance",MB_OK|MB_ICONHAND);
return TRUE;
}

App a;

你只需将以上代码拷贝下来,在VC++6.0编译器,建一个Window32工程,使用MFC链接库编译即可

具体步骤:打开VC++6.0,点击主菜单File(文件)-〉New(新建) 弹出一个对话框,我们选择

win32 Application(win32应用程序),再工程文本框给她起一个名字MyMFC,点击确定。在确认

信息的对话框里点确定。这样我们就建了一个win32 应用程序这样一个类型的工程。下面我们在

这个工程里建一个C++文件。点击菜单File(文件)-〉New(新建) 弹出一个对话框,选择

C++ source文件(C++源文件),再文件文本框里给他起个名字MyMFC,点击确定,这是我们将上面

的代码拷入,编译链接。你会发现有3个错误。

nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
Debug/MyMFC.exe : fatal error LNK1120: 2 unresolved externals

那么,这是因为没有使用MFC类库。我们现在导入。点击菜单(project)工程-〉setting设置,弹

出一个对话框,有一个下拉列表框,里面是Not Using MFC,我们把她改为Using MFC in a

Static Library,点击确定,再编译,运行,那么有这样一个窗体出现。下面是该程序的解释。


在以上的程序中,只使用了两个类CFrameWnd 和CWinApp,我们先看第一个类:

class sample:public CFrameWnd
{
public:
sample()
{
Create(NULL,"MFC Window");
MessageBox("My MFC Window","CFrame constructor",MB_OK);
}
};

第一个类sample继承了CFrameWnd类,CFrame类是MFC类库中的一个类,用它来代表窗体框架,我们先用sample类继承它,在构造函数调用了Create这个函数,在Create这个函数时调用的CFrameWnd类中的函数,使MFC写好的函数,CFrameWnd中封装了CreateWindow这个API函数为它的成员函数Create(),他们的参数都是像似的。但你会问,CreateWindow有11个参数,而这里的Create函数只用了两个参数,应为这里的Create有两个参数为必选参数,后面的参数有默认值

由MSDN的定义可以看出

BOOL Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle = WS_OVERLAPPEDWINDOW, const RECT& rect = rectDefault, CWnd* pParentWnd = NULL, LPCTSTR lpszMenuName = NULL, DWORD dwExStyle = 0, CCreateContext* pContext = NULL );

后面的参数都带有一个等号和一个默认的值。

我们再看在看第二个类,继承CWinApp类的App类。

class App:public CWinApp
{
public:
BOOL InitInstance();
BOOL ExitInstance();
};

在这个类中仅仅重写了两个函数,一个InitInstance(),一个ExitInstance(),这个类是控制整个应用程序的,所以称为CWinApp类,是不可或缺的一个类。而且要运行程序,要将该类实例化。实例化会自动调用构造函数,并调用InitInstance()这个函数(调用该函数是MFC写好的),因为该函数是一个虚函数,所以我们实例化继承CWinApp类的App类时,会自动调用App::InitInstance()(如果不明白,请复习c++的虚函数),这样就开始了一个应用程序实例的进程。来到的App::InitInstance()函数

BOOL App::InitInstance()
{
MessageBox(0,"My MFC Window","InitInstance",MB_OK|MB_ICONASTERISK);
sample *obj;
obj=new sample;
m_pMainWnd=obj;
obj->ShowWindow(SW_SHOWMAXIMIZED);
return TRUE;
}

在这个函数,首先法一个消息框出来,使用MessageBox函数,然后声明一个sample类的指针obj,第三行,为该obj分配内存,即实例化,类的实例化要调用构造函数的初始化,程序的控制点到达sample类的sample函数,

sample()
{
Create(NULL,"MFC Window");
MessageBox("My MFC Window","CFrame constructor",MB_OK);
}

这里才创建窗体,并且有一个消息框出现,然后程序的控制点回到 App::InitInstance()的m_pMainWnd=obj;位置

这一块是个难点,刚开始学的时候,我不明白m_pMainWnd,你从哪里来,来了干什么。

他从类CWinThread里来,他的定义为 CWnd* m_pMainWnd;

他凭什么直接用?class CWinApp : public CWinThread 因为MFC中的CWinApp类继承于CWinThread子类中用父类的成员变量,儿子用老爸的钱,当然可以拉,所以他可以直接用

他有什么用,我们看

sample *obj;
obj=new sample;

这两个是在InitInstance()这个成员函数声明的,也就是说,这个函数结束了,这个指针变量必然要析构,而这个指针是代表窗体框架的,这个指针释放了,那么,窗体也跟着消失了,所以,我们要把这个地址留下来,就给了m_pMainWnd这个指针了,他是在线程类中的,有线程他就在,程序结束了,没线程了,他也消失了,窗体框架也就结束了。

到现在我们还只是在内存中,创建了一个窗体,没有显示出来,那么

obj->ShowWindow(SW_SHOWMAXIMIZED);

通过这一句,用指针调用类的成员函数,在CFrameWnd中,还封装了ShowWindow这个API函数,用法和API函数一样。

在return TRUE;这句之后该函数结束。

程序进入了运行状态,在关闭程序的时候,会调用

ExitInstance()这个函数,该函数仅仅输出一个消息框就结束了。那么这个简单的MFC程序就讲到这里了。 

 

MFC 消息 映射
原作者姓名 zhojiamurong

#include < afxwin.h >

// 定义sample继承MFC中的CFrameWnd类,该类代表了窗体框架
class  sample: public  CFrameWnd
{
public :
    sample()
    {
        
// 调用CFrameWnd中的Create函数,创建窗体
         this -> Create(NULL, " 我的第一次 " );
        
this -> MessageBox( " sample中调用 " , " sample中调用 " ,MB_OK);
    }
    
// 添加消息处理函数
    
// 左键按下事件的方法
     void  OnLButtonDown(UINT,CPoint)
    {
        ::MessageBox(
0 , " 您点击了鼠标左键 " , " 您点击了鼠标左键 " ,MB_OK);
    }
    
// 消息映射的申明
    DECLARE_MESSAGE_MAP()
};

// 消息映射
BEGIN_MESSAGE_MAP(sample,CFrameWnd)
    
// 左键按下事件
    ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

// 定义App继承CWinApp类,该类控制整个应用程序
class  App: public  CWinApp
{
public :
    
// 应用程序初始化函数
    BOOL InitInstance();
    
// 应用程序结束函数
    BOOL ExitInstance();
};

// 重写InitInstance函数
BOOL App::InitInstance()
{
    MessageBox(
0 , " InitInstance中调用 " , " InitInstance中调用 " ,MB_OK);
    sample
*  s = new  sample;
    m_pMainWnd
= s;
    s
-> ShowWindow(SW_SHOWDEFAULT);
    
return  TRUE;
}
// 重写ExitInstance函数
BOOL App::ExitInstance()
{
    MessageBox(
0 , " ExitInstance中调用 " , " ExitInstance中调用 " ,MB_OK);
    
return  TRUE;
}

App a;

关键字

介绍
(原创)继续实例讲解MFC,本节将讲述消息映射

读者评分 94 评分次数 22

正文
MFC入门(二)消息映射
原创  作者:zhoujiamurong  
(仅供vchelp网站使用,如需转载请联系zhoujiamurong@163.com)
上一篇
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1339
      第一篇文章,在短短四五天当中,访问量就达到了1000,我还收到了网友的来信,

我很感动,也很自豪。这也激起我的写作的欲望。如果还不了解MFC的朋友,请先看上

一篇。我继续来写MFC的学习文章。我们上一节已经讲述了MFC的两个基本类

CWinApp类和CFrameWnd类,一个应用程序类和框架类。我们在这一节利用已有的程

序,来完成一个鼠标的响应事件。在MFC里面,它提供了一种叫做消息映射的机制,来

完成事件的处理。
       首先,在VC++中,将事件称为消息。我们要响应一个事件,我们就要写一个函数来

响应这个事件。那么,比如,我们点击了一下窗体,那么我们要响应这个点击事件,我

们要给这个事件写一个函数来响应他。这样有很多的事件,也就有很多对应的函数。那

么,我们怎么知道哪个事件和哪个函数相关联呢?
    在SDK的编程中,我们使用WndProc函数来统一处理消息,然后使用switch-case语句

,来区别每个消息,在每个case里面来处理事件。使用一个常量(例如WM_COMMAND

)来区别到底是哪个消息。MFC将SDK的这些switch-case封装成了宏,那么什么是宏。

可能很多人都学过,我在这里只提一下。
#define A 100
void main()
{
    printf("%d",A);
}
再这个程序中,我们就把100这个常量封装成了A,我们就可以使用宏 A来代替100。我们

回到正题,在MFC中提供了四个宏
DECLARE_MESSAGE_MAP
BEGIN_MESSAGE_MAP
END_MESSAGE_MAP
ON_COMMAND
因为这几个宏是嵌套宏定义,要展开很复杂,我个人研究了几天,有兴趣可以看一下我

的博客( http://blog.csdn.net/zhoujiamurong/ ),我们现在只用了解一下就可以了。
第一个宏DECLARE_MESSAGE_MAP是BEGIN_MESSAGE_MAP和
END_MESSAGE_MAP的申明,就是在类里面声明一些函数。

BEGIN_MESSAGE_MAP
END_MESSAGE_MAP这两个是函数的实现,那么在这个函数的实现是用

ON_COMMAND这个宏来定义具体的消息和消息对应的函数。那我们继续使用上一次我

们做的程序,我们在其中添加消息映射

#include <afxwin.h>

class sample:public CFrameWnd
{
public:
sample()
{
Create(NULL,"MFC Window");
MessageBox("My MFC Window","CFrame constructor",MB_OK);
}
void OnLButtonDown(UINT,CPoint)//添加的消息处理函数
{
    ::MessageBox(NULL,"ddd","dd",MB_OK);
}

DECLARE_MESSAGE_MAP()//消息映射的申明

};

BEGIN_MESSAGE_MAP(sample,CFrameWnd)
//这个宏填写两个参数,一个子类,一个父类
  ON_WM_LBUTTONDOWN()//左键按下的事件
END_MESSAGE_MAP()//结束宏
class App:public CWinApp
{
public:
BOOL InitInstance();
BOOL ExitInstance();

};



BOOL App::InitInstance()
{
MessageBox(0,"My MFC Window","InitInstance",MB_OK|MB_ICONASTERISK);
sample *obj;
obj=new sample;
m_pMainWnd=obj;
obj->ShowWindow(SW_SHOWMAXIMIZED);
return TRUE;
}

BOOL App::ExitInstance()
{
MessageBox(0,"My Window","ExitInstance",MB_OK|MB_ICONHAND);
return TRUE;
}

App a;
那么,这些消息映射的宏和函数的名字是固定的,因为这些是常用的系统消息。有这样

的名字的函数和宏会自己关联,我们将上述程序再运行一下,加深映象,这一节我们先讲

到这里。 

 

#include < afxwin.h >
#include 
" resource.h "

// 定义sample继承MFC中的CFrameWnd类,该类代表了窗体框架
class  sample: public  CFrameWnd
{
public :
    sample()
    {
        
// 调用CFrameWnd中的Create函数,创建窗体
        
// 定义一个矩形的位置及大小,作为窗体的位置及大小
        CRect mywindow( 0 , 0 , 200 , 200 );
        
this -> Create(NULL,                 // 注册类,MFC将注册类封装,我们填写NULL
             " 我的第一次 " ,                 // 窗体名,窗体标题
            WS_OVERLAPPEDWINDOW,         // 窗体风格
            mywindow,                     // 引用矩形mywindow作为窗体的大小及为
            NULL,                         /* 父窗体为空 */
            MAKEINTRESOURCE(IDR_MENU1),    
// 使用MAKEINTRESOURCE这个宏来包装我们的菜单ID
             0 ,                             // 窗体扩展风格
            NULL                         // 框架窗体的视图和文档信息,一般填NULL
            );
        
this -> MessageBox( " sample中调用 " , " sample中调用 " ,MB_OK);
    }
    
// 添加消息处理函数
    
// 左键按下事件的方法
     void  OnLButtonDown(UINT,CPoint)
    {
        ::MessageBox(
0 , " 您点击了鼠标左键 " , " 您点击了鼠标左键 " ,MB_OK);
    }
    
// 消息映射的申明
    DECLARE_MESSAGE_MAP()
};

// 消息映射
BEGIN_MESSAGE_MAP(sample,CFrameWnd)
    
// 左键按下事件
    ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

// 定义App继承CWinApp类,该类控制整个应用程序
class  App: public  CWinApp
{
public :
    
// 应用程序初始化函数
    BOOL InitInstance();
    
// 应用程序结束函数
    BOOL ExitInstance();
};

// 重写InitInstance函数
BOOL App::InitInstance()
{
    MessageBox(
0 , " InitInstance中调用 " , " InitInstance中调用 " ,MB_OK);
    sample
*  s = new  sample;
    m_pMainWnd
= s;
    s
-> ShowWindow(SW_SHOWDEFAULT);
    
return  TRUE;
}
// 重写ExitInstance函数
BOOL App::ExitInstance()
{
    MessageBox(
0 , " ExitInstance中调用 " , " ExitInstance中调用 " ,MB_OK);
    
return  TRUE;
}

App a;

 

关键字 MFC 资源
原作者姓名 zhoujiamurong

介绍
原创 用一个实例介绍如何使用资源,如何讲资源文件和源文件关联

读者评分 116 评分次数 28

正文
MFC入门(三)资源
原创  作者:zhoujiamurong  
(仅供vchelp网站使用,如需转载请联系zhoujiamurong@163.com)
上两篇
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1339
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1343
  我先申明一下,以免很多网友可能误会我,在VC方面我也是刚脱贫还未致富,我写这些
文章就是因为我脱贫的时候太艰辛,希望大家能够共同富裕。
  上两节我们讲了一个简单的MFC的程序,和消息映射宏的用法,我们这一节将讲述资源
文件,在将资源文件之前,我们看一下VC++的文件简介,那我们看下面这一张图。(来
自<<深入浅出MFC>>侯大师)

说明 res1.jpg


    这张图清楚的描述了VC++的文件系统,他们是分为两条线的一个是源文件,一个是资源文件。
    先讲第一条线—源文件,.c或者.cpp文件,在加入了头文件.H文件后,就进入编译器工具。
    再讲第二条线—资源文件,有最上面的三个工具,对话框工具编辑对话框文件.dlg,图片编辑器编辑图片(.bmp)、光标(.cur)、图标(.ico)文件,字体编辑器编辑字体文件(.FON)(但是字体我没有看到哪里可以用,请高人指点)。所有的资源文件合成一个文件.RC文件,即资源文件,我们可以想到,这资源文件和我们的源文件怎么关联呢?那么唯一相关联的是.H文件,这个头文件就是我们等一下要用的resource.h这个文件。
    .c或者.cpp文件和头文件编译成.obj文件,而.rc文件和头文件编译成.res文件,.obj和库文件和.res文件连结成可执行文件。
    大家可能都看烦了,下面来上机创建一个资源文件,即菜单,为我们上两节的程序加一个菜单。先打开我们的上两节的程序的工程,然后,新建—〉在打开的对话框里,我们自动会在文件选项卡里,我们选择Resource Script选项,在文件文本框中填写一个文件名,自己起一个名字。那么,我们就给我们的工程加了一个资源文件。在弹出的窗体,点击右键,在谈出的菜单中点击Insert菜单---〉Menu--〉新建.,在弹出得菜单编辑器,我们双击主菜单,弹出的属性框中,填写菜单标题 如:我的菜单.回车后,我们就建立了一个菜单资源文件。我们可以看到,这个资源编辑器是WYSIWYG(What you see is what you get所见及所得)界面,我只简单介绍一下:
   资源编辑器创建的资源会自动的生成resource.h这个头文件,我们刚才也讲了,这个头文件是资源文件和源代码文件的一个桥梁,所以我们在源代码例一定要#include “resource.h”,我们在创建子菜单的时候会发现,有一个资源ID号要你填写(自己起一个名字,不要重复),那么这个资源号就是我们在源代码里要引用的。
    我们已经添加了菜单,我们运行程序,发现菜单并没有出现,因为我们的菜单并没有和我们的某一个窗体相关联。那么如何关联?
    我们回忆我们在写SDK程序是我们是如何加菜单的。我们使用CreateWindow这个API函数来创建窗体,同时也关联菜单(当然,也可以在注册类里关联),我们知道MFC就是对API的封装后,CreateWindow当然也被封装了,他被封装成了很多类的Create方法,其中就有CFrameWnd。我们在Sample 类里继承了CFrameWnd,我们右键点击 Sample 构造函数里的Create方法,在弹出的菜单里点击Goto Define of Create,在弹出的菜单点确定。我们来到了Create方法的定义
BOOL Create(LPCTSTR lpszClassName,//注册类,MFC将注册类封装,我们填写NULL
     LPCTSTR lpszWindowName,//窗体名,窗体标题
     DWORD dwStyle = WS_OVERLAPPEDWINDOW,//窗体风格
     const RECT& rect = rectDefault,//窗体的矩形区域
     CWnd* pParentWnd = NULL,        // 父窗体指针
     LPCTSTR lpszMenuName = NULL,  //窗体的菜单
     DWORD dwExStyle = 0,//窗体扩展风格
     CCreateContext* pContext = NULL);//框架窗体的视图和文档信息,一般填NULL

    那我们看到前面两个参数,没有等号,说明他们是必选的参数,后面是可选的,在可选的参数里面有一个窗体的菜单,他的类型是LPCTSTR,我们看这个类型有一个方法,分开看,首先L是long ,P是指针,CT是Const常量 ,STR是字符串,也就是一个指向常量字符串的长指针。我们打开MSDN看这个方法的参数如何填写,在MSDN的索引中添Create回车,在弹出的主题中选择CFrameWnd::Create,我们找到菜单这个参数的解释

lpszMenuName
Identifies the name of the menu resource to be used with the window. Use MAKEINTRESOURCE if the menu has an integer ID instead of a string. This parameter can be NULL.

我们看到我们要使用MAKEINTRESOURCE这个宏来包装我们的菜单ID,其他的参数我们用默认的。
我们就填好了参数:

Create(NULL,"MFC Window",WS_OVERLAPPEDWINDOW,rectDefault,NULL,MAKEINTRESOURCE(IDR_MENU1),0,NULL);
不要忘记在前面加上#include "resource.h",在运行程序就会发现菜单。全部程序如下(不包括资源文件)

#include <afxwin.h>
#include "resource.h"
class sample:public CFrameWnd
{
public:
  sample()
  {
  Create(NULL,"MFC Window",WS_OVERLAPPEDWINDOW,rectDefault,NULL,MAKEINTRESOURCE(IDR_MENU1),0,NULL);
  MessageBox("My MFC Window","CFrame constructor",MB_OK);
  }
  void OnLButtonDown(UINT,CPoint)//添加的消息处理函数
  {
    ::MessageBox(NULL,"ddd","dd",MB_OK);
  }

  DECLARE_MESSAGE_MAP()//消息映射的申明

};

BEGIN_MESSAGE_MAP(sample,CFrameWnd)
//这个宏填写两个参数,一个子类,一个父类
  ON_WM_LBUTTONDOWN()//左键按下的事件
END_MESSAGE_MAP()//结束宏
class App:public CWinApp
{
public:
BOOL InitInstance();
BOOL ExitInstance();

};



BOOL App::InitInstance()
{
MessageBox(0,"My MFC Window","InitInstance",MB_OK|MB_ICONASTERISK);
sample *obj;
obj=new sample;
m_pMainWnd=obj;
obj->ShowWindow(SW_SHOWMAXIMIZED);
return TRUE;
}

BOOL App::ExitInstance()
{
MessageBox(0,"My Window","ExitInstance",MB_OK|MB_ICONHAND);
return TRUE;
}

App a; 

关键字 MFC
原作者姓名 zhoujiamurong

介绍
这一节,介绍工具条和状态栏

读者评分 97 评分次数 24

正文
MFC入门(四) 工具条和状态栏
原创  作者:zhoujiamurong  
(仅供vchelp网站使用,如需转载请联系zhoujiamurong@163.com)
上三篇
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1339
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1343
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1347
    这几天我比较忙,我的女朋友再就业,我公司也很多事,不过看到大家的评论,我很高兴,我会坚持写下去。(声明一下:有网友发信过来问问题,我只能尽量回复,我的个人精力有限,请大家谅解)到目前为止,可能大家还在纳闷,我为什么不讲一下向导,我在这里强调一下,请大家先不要碰向导,看完了手写的MFC之后,再学向导才比较好,因为向导不是给初学者用的。如同大家如果精通SDK编程,那我讲的都是废话,你看一下就会了,如同汇编高手学习C语言,看一下语法就可以了。这里强调一下基础的作用,关于SDK网友很关心,因为有些朋友没有学习过这方面的内容,我现在没有时间写这方面的文章,不过大家可以看一下《Windows程序设计》。下面我们来看一下今天要学的内容,上几章我们完成了一个程序的窗体,响应消息和菜单资源,我们来为我们的程序添加一点有用的东西。
工具条和状态栏
在这里要用要用到两个类工具条类CToolBar和状态栏类CstatusBar,关于类这一块我不讲了,大家自己看C++的书,用法一样,不过VC++的MFC里面有过程和类混合在一起。
   首先,讲一下工具条,它是一个条型的窗体,为什么这么说呢?我们看一下CToolBar类,我们打开一个MFC的工程,在工具主菜单里有一个子菜单—来源浏览器,点击他,弹出一个对话框,如果是英文版用快捷键Alt+F12.在对话框中输入CToolBar,在下面的列表框中选择Base Class And Members(基类和成员),点击确定.弹出一个窗体,在左边的树行控件中,我们把他的基类全部点开.如下图:
说明 b.bmp
我们可以看到他是继承于CWnd这个类的,而CWnd这个类就是窗体类,也就是说工具条类的爷爷就是窗体,所以我们说他就是一个窗体类型的东东.其实,我们大部分用的类都是窗体,可以这么说,在VC中万事万物皆窗体,我们再看一下状态栏,他的祖先也就是基类是什么:
说明 c.bmp
我们看到他们是同宗同源的。我们了解了这个类,我们知道在一个类实例化之前,她是没有任何作用的,所以我们要定义和实例化这两个类。我们继续上次的程序。在里面加这两个类的定义和实例化。
#include <afxwin.h>
#include <afxext.h>//MFC扩展类的头文件,也就是类的定义
#include "resource.h"
class sample:public CFrameWnd
{
public:
CToolBar t;//实例化工具条类
CStatusBar s;//实例化状态条类
  sample()
  {
  Create(NULL,"MFC Window",WS_OVERLAPPEDWINDOW,rectDefault,NULL,MAKEINTRESOURCE(IDR_MENU1),0,NULL);
  MessageBox("My MFC Window","CFrame constructor",MB_OK);
  }
  void OnLButtonDown(UINT,CPoint)//添加的消息处理函数
  {
    ::MessageBox(NULL,"ddd","dd",MB_OK);
  }

  DECLARE_MESSAGE_MAP()//消息映射的申明

};

BEGIN_MESSAGE_MAP(sample,CFrameWnd)
//这个宏填写两个参数,一个子类,一个父类
  ON_WM_LBUTTONDOWN()//左键按下的事件
END_MESSAGE_MAP()//结束宏
class App:public CWinApp
{
public:
BOOL InitInstance();
BOOL ExitInstance();

};



BOOL App::InitInstance()
{
MessageBox(0,"My MFC Window","InitInstance",MB_OK|MB_ICONASTERISK);
sample *obj;
obj=new sample;
m_pMainWnd=obj;
obj->ShowWindow(SW_SHOWMAXIMIZED);
return TRUE;
}

BOOL App::ExitInstance()
{
MessageBox(0,"My Window","ExitInstance",MB_OK|MB_ICONHAND);
return TRUE;
}

App a;
添加了三句话,我们运行一下,发现并没有效果。其实,在实例化后,我们仅仅是可以使用这两个类了,我们还要调用这两个类的方法才行。在调用之前,我们在讲一下理论知识。    
  工具条:一个条形的窗体,里面有很多的按钮,而且每个按钮对应一个图片。也就是说我们在创建一个工具条时要有按钮,图片准备好,在VC中一个工具条只有一个条形的图片,它负责提供所有的按钮图片,这个条形的图片被切割成大小为15*16的一个一个的小图片,给对应的按钮。我们首先要创建一个工具条窗体(Create方法),然后加载一个的位图(使用LoadBitmap方法),还要创建几个按钮(使用SetButtons方法),图片和按钮的关联是自动的。
状态条:一个条形的窗体,里面有很多的窗格,就是格子,我们要创建一个窗体(Create方法),在窗体上创建很多窗格(SetIndicators方法).
下面问题来了,VC的困惑不光在如何写代码,更多的时候不知道写在哪里。这样的原因是因为我们没有了解MFC的流程,不过我们可以想象一下,主窗体没有建的时候,我们不可以建工具条和状态条,皮之不存,毛将焉附?也就是在主窗体建成后,我们再建工具条和状态条。所以,我们在OnCreateClient这个方法里面写,不过要注意这个函数是框架的一部分,不要试图去调用它,她是在创建窗体时框架自动调用的。

#include <afxwin.h>
#include <afxext.h>//MFC扩展类的头文件,也就是类的定义
#include "resource.h"



class sample:public CFrameWnd
{
public:
  CToolBar t;//实例化工具条类
  CStatusBar s;//实例化状态条类

  sample()
  {
  Create(NULL,"MFC Window",WS_OVERLAPPEDWINDOW,rectDefault,NULL,MAKEINTRESOURCE(IDR_MENU1),0,NULL);
  MessageBox("My MFC Window","CFrame constructor",MB_OK);
  }
  void OnLButtonDown(UINT,CPoint)//添加的消息处理函数
  {
    ::MessageBox(NULL,"ddd","dd",MB_OK);
  }

  BOOL OnCreateClient(CREATESTRUCT *c,CCreateContext *p)
  {
   UINT tool[]={ID_DISPLAY_UP,ID_DISPLAY_DOWN,ID_DISPLAY_LEFT,ID_DISPLAY_RIGHT};
   UINT stat[]={0,ID_INDICATOR_NUM,ID_INDICATOR_CAPS};
      //工具条创建
      t.Create(this,WS_VISIBLE|WS_CHILD|CBRS_TOP|CBRS_FLYBY);
      //工具条加载图片
      t.LoadBitmap(IDB_BITMAP1);
      //设置按钮
      t.SetButtons(tool,4);
      
      //状态条创建
      s.Create(this);
      //状态条设置窗格
      s.SetIndicators(stat,3);
      return TRUE;

  }
  DECLARE_MESSAGE_MAP()//消息映射的申明

};

BEGIN_MESSAGE_MAP(sample,CFrameWnd)
//这个宏填写两个参数,一个子类,一个父类
    ON_WM_LBUTTONDOWN()//左键按下的事件
END_MESSAGE_MAP()//结束宏
class App:public CWinApp
{
public:
BOOL InitInstance();
BOOL ExitInstance();

};



BOOL App::InitInstance()
{
MessageBox(0,"My MFC Window","InitInstance",MB_OK|MB_ICONASTERISK);
sample *obj;
obj=new sample;
m_pMainWnd=obj;
obj->ShowWindow(SW_SHOWMAXIMIZED);
return TRUE;
}

BOOL App::ExitInstance()
{
MessageBox(0,"My Window","ExitInstance",MB_OK|MB_ICONHAND);
return TRUE;
}

App a;

这里面的代码有两句没有讲
UINT tool[]={ID_DISPLAY_UP,ID_DISPLAY_DOWN,ID_DISPLAY_LEFT,ID_DISPLAY_RIGHT};
UINT stat[]={0,ID_INDICATOR_NUM,ID_INDICATOR_CAPS};
这是因为我们要使用工具条必须要知道,用户到底点的是哪个按钮,所以,我们用一个数组标识她们,这两个数组里面的宏,必须要有对应的资源。我看到我们的工具条都是灰色的,因为,我们没有写消息映射给他们,状态栏也不可使用,必须要添加String Table才可以用。我们下次再讲。
示例:说明 文章.rar
下一节
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1358
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1375 

关键字 MFC 工具条 状态栏
原作者姓名 zhoujiamurong

介绍
继续介绍工具条和状态栏

读者评分 64 评分次数 16

正文
MFC入门(五)  工具条和状态条(下)
原创  作者:zhoujiamurong  
(仅供vchelp网站使用,如需转载请联系zhoujiamurong@163.com)
前几章
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1339
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1343
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1347
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1353

大家都在催我继续写,我真得很想写快点,不过我写这一篇文章得3-4个小时。我不希望大家看了不懂,或者没学到什么东西。写该系列文章,另一个原因就是想还Vchelp站长闻怡洋和雷神的人情,我在学VC很困难的时候,学习了雷神的文章和教程和闻站长的教程.有了很好的学习效果,在市面上很多的书籍一上来就是向导,很多人就是看不明白而放弃学VC。我希望大家也不要放弃,我又将我的这点烂文章,发到www.gameres.com 网站去了.( http://blog.gameres.com/show.asp?BlogID=636&column=0 )希望有更多的人来学习VC,也希望大家有什么体会和心得或发现也能够写出来大家共享J.
下面我接着上一节的内容来讲,我们已经将工具条和状态条的外观画好,现在要为这个工具条和状态栏加上响应,也就是消息映射和处理函数,
我们先将一些无关紧要的消息框去掉。然后添加消息映射,
  ON_COMMAND(ID_DISPLAY_UP,    up)
  ON_COMMAND(ID_DISPLAY_DOWN,down)
  ON_COMMAND(ID_DISPLAY_LEFT,left)
  ON_COMMAND(ID_DISPLAY_RIGHT,right)
消息映射宏ON_COMMAND接两个参数,第一个是资源ID号,第二个是响应函数的名字。我们要在sample类里面加上这些函数
void up()
  {
      ::MessageBox(0,"up","消息",MB_OK);
  }
  void down()
  {
      ::MessageBox(0,"down","消息",MB_OK);
  }
  void left()
  {
      ::MessageBox(0,"left","消息",MB_OK);
  }
  void right()
  {
      ::MessageBox(0,"right","消息",MB_OK);
  }
我们再运行一下程序,我们发现工具条变靓了,因为有了消息映射,所以工具条和菜单都从无效变成有效了。
下面,我们想在状态栏里显示鼠标的坐标。翻译成计算机的语言,也就是说,在鼠标移动的时候,我们获得鼠标的坐标,将这个坐标(整型)转换成字符串,然后,将这个字符串赋值给状态栏的一个窗格。
下面我们来实现它,首现我们要在状态栏添加一个网格,更改代码
UINT stat[]={0,ID_INDICATOR_NUM,ID_INDICATOR_CAPS};

UINT stat[]={0,0,ID_INDICATOR_NUM,ID_INDICATOR_CAPS};
再更改,
s.SetIndicators(stat,3);

s.SetIndicators(stat,4);
我们就添加了一个窗格,我们还要为鼠标移动添加消息映射,使用MFC定义好的宏ON_WM_MOUSEMOVE(),直接放到消息映射里面就可以了,下面添加消息映射的处理函数
void OnMouseMove(UINT nFlags, CPoint point) 通过这个函数我们可以得到两个参数:
uFlags 和 point ,这两个参数.我们在MSDN种查到对这两个参数的描述:
nFlags
Indicates whether various virtual keys are down. This parameter can be any combination of the following values:
指示哪些键被按下。这个参数可以是以下值的任意组合:
·    MK_CONTROL   Set if the CTRL key is down.  //CTRL键
·    MK_LBUTTON   Set if the left mouse button is down.//鼠标左键
·    MK_MBUTTON   Set if the middle mouse button is down.//鼠标中键
·    MK_RBUTTON   Set if the right mouse button is down.//鼠标右键
·    MK_SHIFT   Set if the SHIFT key is down. //SHIFT键
point
Specifies the x- and y-coordinate of the cursor. These coordinates are always relative to the upper-left corner of the window.
指示光标的坐标。这个光标是相对于窗体的左上角的。
这是我们要找的参数就是point,那么这个参数是CPoint 类型的,我们再查CPoint 类型,如何查呢?一种查MSDN,另一种在工程中,右键点击CPoint这个文字,出来的右键菜单中,点击goto the definition of CPoint 。我们看到了MFC的源码,CPoint本身是一个类,但是它是继承于一个结构的(tagPOINT)。我们看它的原始定义:
typedef struct tagPOINT
{
    LONG  x;
    LONG  y;
} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;
所以,我们就认为point 是一个结构。我们就把它当结构来用。我们已经得到了这个坐标(point.x,point.y),但是,它们都是长整型的,我们要把它转换成字符串。转换要使用一个类CString。这是字符串类,当然有转换函数。添加一下代码
      CString str;//这是我们最後要赋值的字符串;
      CString str_x;//X坐标
      CString str_y;//Y坐标
      str_x.Format("%d",point.x);//转换point.x到str_x
      str_y.Format("%d",point.y); //转换point.y到str_y
      str+="X: ";
      str+=str_x;
      str+="    ";
      str+="Y: ";
      str+=str_y;//以上是连接字符串到str中
      s.SetPaneText(1,str,TRUE);//最后赋值给窗格
      str_x.Empty();//下面是释放空间
      str_y.Empty();
      str.Empty();
我们再运行一下程序,我们晃动鼠标,观察状态栏的变化。是不是和画图软件的状态栏有点象。
下一步,我们添加String Table。再资源中添加,添加一个ID_INDICATOR_CAPS,标题自己定,在添加一个ID_INDICATOR_NUM,标题自己定。
再运行,我们按下num lock 或者 Caps lock键,看一下状态栏的变化,我们就建立了这样一个小程序
下一篇,我们讲GDI,使用GDI来创建一个小的程序.
http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1375  

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值