代码改变世界

MFC笔记(1)

2010-01-25 09:03  Clingingboy  阅读(897)  评论(1编辑  收藏  举报

   只为记忆更加深刻

如果程序变的不是非常枯燥乏味,学的人就会有兴趣很多,学ui就是一种.虽然学ui只是起步,但足够增加对学习的信心,也为后续打下基础.

有些人喜欢先探秘,比如先看深入浅出浅出MFC,我一直以来的想法是先学后用,如果连用都用不好,我想我也并不具备设计框架的能力.只有知道框架要做什么事情以后,自然自己心中会提出疑问.

Hello World程序

 

// Define a window class derived from CFrameWnd
class CHelloWindow : public CFrameWnd
{
public:
    CHelloWindow()
        { Create(NULL, _T("Hello World!"), WS_OVERLAPPEDWINDOW, rectDefault); }
};

#endif

// Define an application class derived from CWinApp
class CHelloApp : public CWinApp
{
public:
    virtual BOOL InitInstance()
    {
        m_pMainWnd = new CHelloWindow();
        m_pMainWnd->ShowWindow(SW_SHOWNA);
        m_pMainWnd->UpdateWindow();
        return TRUE;
    }
};

CHelloApp HelloApp;  // HelloApp's constructor initializes and runs the app


上面这段程序,实现了一个最简单的MFC程序,作为.net程序员,总是喜欢与.net中winfrom或者wpf进行比较.

CFrameWnd可以理解为窗体的基类

CWinApp 程序入口点,用于管理应用程序

virtual 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 
);

一个最简单的窗体需要在构造函数中调用Create方法用于创建和初始化窗体的一些参数,即必须提供基本窗体参数,c++具备函数默认参数功能,所以最简单的只需要提供两个参数即可,其他参数随着时间的增长自然会熟悉,不需要去强记.

c++风格的参数选择


在c#中,习惯于使用枚举进行同一项的参数选择,但c++则喜欢定义常量,当然其实其他语言也这么做,相对而言,个人认为枚举的做法更加优雅.所以看c++程序需要接受这种风格,而且将会大量出现

注意new

 

写c#程序new一个对象是非常正常的,c++的new就是申请内存,必须要删除掉的,没有GC,一看到new就要注意了。默认情况下,一个对象的初始化是不需要用new的,只需要声明,这是最大的区别,刚开始会看起来不习惯,看多了就好了,这是最大的注意点.

初始化程序


InitInstance方法提供了接口进行程序初始化,声明了一个窗体,并显示.

m_pMainWnd = new CHelloWindow();
m_pMainWnd->ShowWindow(SW_SHOWNA);
m_pMainWnd->UpdateWindow();


ShowWindow用于设定窗体初始化的状态,并不是真正Show,奇怪为何不命名SetShowWindowState这样的方法,让人误解.来看下参数的定义,均是这种风格.不查文档或者不熟悉源码,基本就不知道他们的存在…如果改成枚举就可以SW.xxxx了.很厌恶…

/*
 * ShowWindow() Commands
 */
#define SW_HIDE             0
#define SW_SHOWNORMAL       1
#define SW_NORMAL           1
#define SW_SHOWMINIMIZED    2
#define SW_SHOWMAXIMIZED    3
#define SW_MAXIMIZE         3
#define SW_SHOWNOACTIVATE   4
#define SW_SHOW             5
#define SW_MINIMIZE         6
#define SW_SHOWMINNOACTIVE  7
#define SW_SHOWNA           8
#define SW_RESTORE          9
#define SW_SHOWDEFAULT      10
#define SW_FORCEMINIMIZE    11
#define SW_MAX              11


UpdateWindow方法将会重绘窗体,呈现窗体.调用此方法将会触发ON_WM_PAINT消息.

注意c#很容易捕获一个事件,MFC与win32则称这些事件为消息,因为windows事件就是基于消息.所以两者概念上几乎是相同,说法不同,当然我更喜欢说事件.但不得不说消息:).

消息映射


在没有封装的情况下,默认捕获消息是用switch来判断的,很不方便,MFC通过消息映射机制来简化了这一操作.比如下面代码

BEGIN_MESSAGE_MAP( CMainWindow, CFrameWnd )
    //{{AFX_MSG_MAP( CMainWindow )
    ON_WM_PAINT()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()


BEGIN_MESSAGE_MAP和END_MESSAGE_MAP用于声明消息的触发回调方法,(.net则更简单,直接重写即可)然后重写方法

void CMainWindow::OnPaint()
{
    CRect rect;
    GetClientRect(rect);

    CPaintDC dc(this);

    dc.DrawText (_T ("Hello, MFC"), -1, rect,
        DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    
}

 

以上用GDI在窗体中间画了一段文字

对象获取方法


在.net中若获取一个对象则,直接调函数返回,如 IList list=object.GetList();

到了c++这里则变成 IList list;GetLisht(&list);这种风格也非常的多,这可能就是语言特性决定的做法.需要特别的注意.

 

这样一个简单的MFC程序就完成了

image