Cấu trúc chương trình MFC trên Windows

Ứng dụng MFC đơn giản

Dưới đây là step để tạo project sử dụng MFC trên Visual Studio 2015.
Step 1: File -> New -> Project…
Step 2:
– Template: Visual C++ -> Win32
– Chọn Win32 Project
– Tên project: MFCApp1
– Đường dẫn lưu project: D:\C++\Project
– Click [OK]

Tạo project MFC trên Visual Studio
Tạo project MFC trên Visual Studio

Step 3: Click [Next]

Tạo project MFC trên Visual Studio
Tạo project MFC trên Visual Studio

Step 4:
– Application type: Windows application
– Additional options: Empty project
– Click [Finish]

Tạo application MFC trên Visual Studio
Tạo application MFC trên Visual Studio

Step 5: change setting trên Visual Studio để config project sử dụng MFC. Chọn “Use MFC in a Shared DLL”

Cấu hình cho project sử dụng MFC
Cấu hình cho project sử dụng MFC

Step 6: Tạo file MFCApp1.cpp

Tạo file .cpp
Tạo file .cpp

Step 7: Copy toàn bộ source code sau vào file MFCApp1.cpp

#include <afxwin.h>

class CMyFrame : public CFrameWnd
{
public:
    CMyFrame()
    {
        Create(NULL, _T("Simple MFC Application"));
    }
protected:
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
    DECLARE_MESSAGE_MAP()
};

class CExample : public CWinApp
{
    BOOL InitInstance()
    {
        CMyFrame *Frame = new CMyFrame();
        m_pMainWnd = Frame;
        Frame->ShowWindow(SW_NORMAL);
        Frame->UpdateWindow();
        return TRUE;
    }
};

// Map of Messages
BEGIN_MESSAGE_MAP(CMyFrame, CFrameWnd)
    ON_WM_CREATE()
    ON_WM_SHOWWINDOW()
END_MESSAGE_MAP()

CExample theApp;

// ON_WM_CREATE()
int CMyFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    // Create the window and make sure it doesn't return -1
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    // else is implied
    return 0;
}

// ON_WM_SHOWWINDOW()
void CMyFrame::OnShowWindow(BOOL bShow, UINT nStatus)
{
    CFrameWnd::OnShowWindow(bShow, nStatus);
    ShowWindow(SW_MAXIMIZE);
}

Giải thích:
Cấu trúc chương trình MFC gồm có 3 phần chính:
1. Frame class

class CMyFrame : public CFrameWnd
{
public:
    CMyFrame()
    {
        Create(NULL, _T("Simple MFC Application"));
    }
protected:
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
    DECLARE_MESSAGE_MAP()
};

Chúng ta tạo class CMyFrame kế thừa class CFrameWnd trong MFC và implement lại hàm tạo cho class CMyFrame.
Trong hàm tạo, hàm Create() được gọi để tạo frame cho application với title bar “Simple MFC Application”

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);

Định nghĩa các function xử lí message được gửi về từ hệ điều hành Windows.

2. Hàm Main

class CExample : public CWinApp
{
    BOOL InitInstance()
    {
        CMyFrame *Frame = new CMyFrame();
        m_pMainWnd = Frame;
        Frame->ShowWindow(SW_NORMAL);
        Frame->UpdateWindow();
        return TRUE;
    }
};
CExample theApp;

“trái tim” của ứng dụng MFC là object application base trên class MFC CWinApp.
Class CWinApp:
– Cung cấp message loop để lấy message từ HĐH gửi về
– Dispatch message tới application.
Để sử dụng class CWinApp, chúng ta cần include header AFXWIN.H. Để class application có quyền truy cập tới các object của ứng dụng, chúng ta cần khai báo biến theApp là global và phải là biến duy nhất của ứng dụng.
Ngoài ra, class CWinApp cung cấp rất nhiều function cơ bản như InitInstance(). Để tạo được application, chúng ta cần override phương thức này. Interface được khai báo trong file AFXWIN.H

virtual BOOL InitInstance();

Phương thức này được sử dụng để tạo ứng dụng. Nếu thành cồng, trả về TRUE hoặc giá trị khác 0. Nếu không tạo được application, trả về FALSE hoặc 0.

BOOL InitInstance()
{
    CMyFrame *Frame = new CMyFrame();
    m_pMainWnd = Frame;
    Frame->ShowWindow(SW_NORMAL);
    Frame->UpdateWindow();
    return TRUE;
}

Trong phương thức InitInstance(), chúng ta tạo object của class CMyFrame. Để application có thể sử dụng frame của class CMyFrame, chúng ta gán con trỏ m_pMainWnd (member của class CWinThread)

3. Message và Event
– Class CWinApp cung cấp 1 vòng lặp thông điệp(message loop). Nó là vòng lặp vô hạn, chạy trong suốt vòng đời của ứng dụng. Message loop là 1 cấu trúc đợi và phát các sự kiện hoặc các message trong chương trình. HĐH Windows giao tiếp sử dụng các message.

– Message là giá trị integer chỉ ra một sự kiện cụ thể. VD: Khi chúng ta click vào button, thay đổi kích thước cửa sổ hoặc đóng ứng dụng,…v.v. Thì sẽ có rất nhiều message được tạo ra. Các message này có thể không được xử lí đồng thời, mà các message này sẽ được đưa vào 1 hàng đợi thông điệp (message queue) và đợi để xử lí lần lượt từng message một.

class CMyFrame : public CFrameWnd
{
    ...
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
    DECLARE_MESSAGE_MAP()
};

Khai báo phương thức xử lí message trong frame và kết thúc bởi macro DECLARE_MESSAGE_MAP()

BEGIN_MESSAGE_MAP(CMyFrame, CFrameWnd)
    ON_WM_CREATE()
    ON_WM_SHOWWINDOW()
END_MESSAGE_MAP()

Tạo bảng message bắt đầu bởi macro ON_WM_CREATE() và kết thúc bởi ON_WM_SHOWWINDOW(). Macro ON_WM_CREATE() với 2 tham số đầu vào là tên class CMyFrame và tên class MFC CFrameWnd.
Khi object (cửa sổ) được tạo, frame gửi message WM_CREATE tới ứng dụng, phương thức OnCreate() được gọi.
Chú ý: message WM_CREATE sẽ không xuất hiện trong source code, nó bị ẩn đi framework MFC.

int CMyFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    // Create the window and make sure it doesn't return -1
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    // else is implied
    return 0;
}

Override phương OnCreate() của class CFrameWnd, trong phương thức CMyFrame::OnCreate(), gọi lại phương thức CFrameWnd::OnCreate(). Trả về -1, cửa sổ không được tạo. Trả về 0, nếu cửa sổ được tạo thành công.
Frame truyền tham số truyền struct LPCREATESTRUCT.

void CMyFrame::OnShowWindow(BOOL bShow, UINT nStatus)
{
    CFrameWnd::OnShowWindow(bShow, nStatus);
    ShowWindow(SW_MAXIMIZE);
}

Sau khi cửa sổ được tạo, frame gửi message WM_SHOWWINDOW, phương thức CMyFrame::OnShowWindow() được gọi để hiển thị cửa sổ. Cửa sổ hiện thị với maximum size với tham số SW_MAXIMIZE.

Kết quả:

Minh họa ứng dụng MFC đơn giản
Minh họa ứng dụng MFC đơn giản

MFC template project trên Visual Studio

Trên đây là cách tạo project MFC “thủ công” để các bạn hiểu được flow xử lí của framework MFC. Trên Visual Studio có support tạo project MFC bằng Wizard.
Kể từ bài viết sau chúng ta sẽ sử dụng MFC Wizard Template trong Visual Studio để tạo ứng dụng MFC. MFC Wizard template cũng không có gì ghê gớm cả, nó giúp developer tạo ra bộ khung của 1 chương trình MFC gồm có Frame class và hàm Winmain.
MFC Wizard Template trên Visual Studio gồm có:
– MFC Application
– MFC ActiveX Control
– MFC DLL
Để tạo ứng dụng GUI MFC, chúng ta sử dụng MFC Application template.

Be the first to comment

Leave a Reply