科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件剖析MFC六大关键技术之初始化过程

剖析MFC六大关键技术之初始化过程

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

我并不认为MFC减轻了程序员们的负担,MFC出现的目的虽然似乎是为了让程序员不用懂得太多就可以进行视窗编程.

作者:liyi268 来源:blog 2007年10月19日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
转了一个大圈,我们仿佛又回到了SDK编程的开始。但现在我们现在能清楚地知道,表面上MFC与SDK编程截然不同,但实质上MFC只是用类的形式封装了SDK函数,封装之后,我们在WinMain()函数中只需要几行代码,就可以完成一个窗口程序。我们也由此知道了应如何去封装应用程序类(CWinApp)和主框架窗口类(CFrameWnd)。下面把上开始设计这两个类。

  为了简单起见,我们忽略这两个类的基类和派生类的编写,可能大家会认为这是一种很不负责任的做法,但本人觉得这既可减轻负担,又免了大家在各类之间穿来穿去,更好理解一些(我们在关键的地方作注明)。还有,我把全部代码写在同一个文件中,让大家看起来不用那么吃力,但这是最不提倡的写代码方法,大家不要学哦!

#include <windows.h>
HINSTANCE hInstance;

class CFrameWnd
{
 HWND hwnd;
 public:
  CFrameWnd(); //也可以在这里调用Create()
  virtual ~CFrameWnd();
  int Create(); //类就留意这一个函数就行了!
  BOOL ShowWnd();
};
class CWinApp1
{
 public:
  CFrameWnd* m_pMainWnd;//在真正的MFC里面
  //它是CWnd指针,但这里由于不写CWnd类
  //只要把它写成CFrameWnd指针
  CWinApp1* m_pCurrentWinApp;//指向应用程序对象本身
  CWinApp1();
  virtual ~CWinApp1();
  virtual BOOL InitInstance();//MFC原本是必须重载的函数,最重要的函数!!!!
  virtual BOOL Run();//消息循环
};
CFrameWnd::CFrameWnd(){}
CFrameWnd::~CFrameWnd(){}

int CFrameWnd::Create() //封装创建窗口代码
{
 WNDCLASS wndcls;
 wndcls.style=0;
 wndcls.cbClsExtra=0;
 wndcls.cbWndExtra=0;
 wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
 wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);
 wndcls.hIcon=LoadIcon(NULL,IDC_ARROW);
 wndcls.hInstance=hInstance;
 wndcls.lpfnWndProc=DefWindowProc;//默认窗口过程函数。
 //大家可以想象成MFC通用的窗口过程。
 wndcls.lpszClassName="窗口类名";
 wndcls.lpszMenuName=NULL;
 RegisterClass(&wndcls);

 hwnd=CreateWindow("窗口类名","窗口实例标题名",WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL);
 return 0;
}

BOOL CFrameWnd::ShowWnd()//显示更新窗口
{
 ShowWindow(hwnd,SW_SHOWNORMAL);
 UpdateWindow(hwnd);
 return 0;
}

/////////////
CWinApp1::CWinApp1()
{
 m_pCurrentWinApp=this;
}
CWinApp1::~CWinApp1(){}
//以下为InitInstance()函数,MFC中要为CWinApp的派生类改写,
//这里为了方便理解,把它放在CWinApp类里面完成!
//你只要记住真正的MFC在派生类改写此函数就行了。
BOOL CWinApp1::InitInstance()
{
 m_pMainWnd=new CFrameWnd;
 m_pMainWnd->Create();
 m_pMainWnd->ShowWnd();
 return 0;
}

BOOL CWinApp1::Run()//////////////////////封装消息循环
{
 MSG msg;
 while(GetMessage(&msg,NULL,0,0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 return 0;
} //////////////////////////////////////////////////////封装消息循环

CWinApp1 theApp; //应用程序对象(全局)

int WINAPI WinMain( HINSTANCE hinst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
 hInstance=hinst;
 CWinApp1* pApp=theApp.m_pCurrentWinApp;
 //真正的MFC要写一个全局函数AfxGetApp,以获取CWinApp指针。
 pApp->InitInstance();
 pApp->Run();
 return 0;
}

  代码那么长,实际上只是写了三个函数,一是CFrameWnd类的Create(),第二个是CWinApp类的InitInstance()和Run()。在此特别要说明的是InitInstance(),真正的MFC中,那是我们跟据自己构造窗口的需要,自己改写这个函数。

  大家可以看到,封装了上面两个类以后,在入口函数WinMain中就写几行代码,就可以产生一个窗口程序。在MFC中,因为WinMain函数就是固定的那么几行代码,所以MFC绝对可以帮我们自动完成(MFC的特长就是帮我们完成有规律的代码),所以我们创造MFC应用程序的时候,看不到WinMain函数。

  写到这里,MFC六大关键技术之一:MFC程序的初始化过程(模拟),就差不多写完了。回头看一下,居然写了八千多字,原本以为写完六大关键技术也不用写那么多字,现在还觉得庆幸的是不把文档、视类牵连进去,否则更不知写到何时。

  还有五大关键技术没有写,我还应该写下去吗?上面写了八千多字,都是我一个字一个字地敲进去,每个例子都是自己生硬地想出来。用了十多个小时,换来的可能更多是论坛中朋友们的漫骂,讥讽!

  但我觉得还是值得的,我一向认为VC没有敌人,只有朋友,放眼周围,发觉学VC的朋友越来越少,也没有发现多少招收VC程序员的地方。记得读大学的时候,我遇到一位搞美术的师兄,本来同行如敌国(我曾经搞过美术)。师兄美术功底很好,但他从来没有在学校获过美术一等奖,原因评奖的不懂得欣赏他的作品。我的出现,他深刻地体会到了:多一个朋友,会少一分孤独!有时觉得学习VC的朋友是英雄(但我不是英雄,因为我学VC多年来无甚突破),是值得尊敬的人物,大家交流一下,纠正一下自己的错误,真是一种福份……
 

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章