1. 程式人生 > >手寫MFC應用程式流程---第二課

手寫MFC應用程式流程---第二課

手寫MFC應用程式流程的步驟:

1.建立 Win32 專案 -》空專案–》 修改屬性中 配置屬性-》常規-》MFC的使用,改為:在共享DLL中使用MFC(預設為使用標準Windows)
2.新增標頭檔案,cpp檔案

MFC視窗建立的流程:

  1. 標頭檔案中:
    建立兩個類: 應用程式類MyApp和框架類MyFrame
    MyApp : public CWinApp 而且裡面有一個虛擬函式 InitInstance函式,作為函式入口地址
    MyFrame:有一個建構函式
    -----------------------------重要----------------------------
    2).cpp中 //實際的執行流程為CPP中 A B 流程

    A. 定義一個唯一的應用程式類的全域性物件
    B. 程式入口函式功能: InitInstance
    a. 給框架類物件進行動態記憶體分配,建立一個框架類物件指標
    aa. 框架類物件的建構函式中進行建立視窗CWnd::Create
    b. 顯示視窗 CWnd::showWindow
    c.更新視窗 cWinTread::m_pMainWnd
    d.儲存框架類視窗物件指標 cWinTread::m_pMainWnd
    -----------------------------重要----------------------------

訊息對映機制的實現流程

1.DECLARE_MESSAGE_MAP() :
在標頭檔案的類的內部新增,表明在類中使用訊息對映機制,將訊息對映到函式中
2.BEGING_MESSAGE_MAP(派生類名, 基類名) : 開始訊息對映
ON_WM_LBUTTONDOWN( )//入口函式
ON_WM_PAINT()
END_MESSAGE_MAP() 結束訊息對映
3.在標頭檔案中宣告訊息處理函式
4.在cpp中實現訊息函式

程式碼:
標頭檔案中

#pragma once//防止標頭檔案多次包含,只調用一次

#include <afxwin.h>
//應用程式類
class MyApp : public CWinApp
{
public:
	//基類寫虛擬函式
	//派生類只是重寫
	//MFC應用程式入口函式
	virtual BOOL InitInstance();
};

//框架類

class MyFrame : public CFrameWnd
{
public:
	MyFrame();
	afx_msg void OnLButtonDown( UINT, CPoint ) ; //只在.h中建立宣告時,是不會響應函式的,必須在cpp的開始訊息對映的地方宣告一下
	afx_msg void OnPaint();
	DECLARE_MESSAGE_MAP();//宣告在一個類中使用訊息對映,把訊息對映到函式中,必須宣告//在類實現中,必須在 開始訊息對映和結束訊息對映的地方新增 對映入口 ON_WM_LBUTTONDOWN( )
};


cpp中

#include "mfcc.h"


//有且只要一個全域性的應用程式類物件
MyApp myApp;//如果不定義一個全域性物件時,在winmain.cpp中  有一個AfxGetApp()函式就是獲取應用程式的CWinAPP  物件的指標,此時返回的就是NULL 程式執行不了

BOOL MyApp::InitInstance()
{
	/*
	1.建立框架類物件
	2.顯示視窗
	3.更新視窗
	4.儲存框架類物件指標
	
	
	*/
	//使用new 建立類的動態記憶體時,會自動呼叫類的建構函式。。。
	MyFrame* myframe = new MyFrame;//new MyFrame()  new MyFrame 這兩個好像都行?

	//顯示視窗
	myframe->ShowWindow(SW_SHOW);

	//更新視窗
	myframe->UpdateWindow();

	//儲存框架類指標
	m_pMainWnd = myframe;//如果不儲存框架類物件指標,則視窗一閃而過
	//而且,還不能給 myframe 指標給delete掉,去掉也是一閃而過,那我啥時候給動態記憶體釋放呢?
	return TRUE;
}

BEGIN_MESSAGE_MAP(MyFrame,CFrameWnd)
ON_WM_LBUTTONDOWN( )
ON_WM_PAINT()
END_MESSAGE_MAP()
MyFrame::MyFrame()
{
	//CWnd類的成員函式 CFrameWnd繼承與CWnd
	//建立物件
	Create(NULL,TEXT("MFC"));//windows API時建立視窗需要用createwindow  而且還必須要先註冊視窗類,才能用createwindow
	//顯示框框
}
void MyFrame::OnLButtonDown( UINT, CPoint )
{
	MessageBox(TEXT("LLLD"));
}

void MyFrame::OnPaint()//必須加類說明符,否則會報錯:“this”: 只能用於非靜態成員函式內部
{
	CPaintDC dc(this);
	dc.TextOutW(30,30,TEXT("ACC"));
}

【總結】
【1】#pragma once :防止標頭檔案多次包含,只調用一次,,放在標頭檔案中。。。。。。。
【2】Create與CreateWindow的區別
CreateWindow是一個Windows API 函式,也是用來建立視窗的函式。
本文中如果使用CreateWindow 則必須的先註冊視窗類,在建立視窗。
如果使用MFC自己封裝好的視窗類在,則不用如此。

CFrameWnd::Create ,是MFC的CFrameWnd類的一個成員函式,用於建立和設定視窗,還函式已經把,初始化視窗的基本資訊,註冊視窗類封裝在了一起。
【3】用new 給類進行動態記憶體分配物件時,
MyFrame* myframe = new MyFrame;//new MyFrame() new MyFrame 這兩個好像都行?
MyFrame* myframe = new MyFrame();這兩個都可以

後者
【4】//有且只要一個全域性的應用程式類物件
MyApp myApp;//如果不定義一個全域性物件時,在winmain.cpp中 有一個AfxGetApp()函式就是獲取應用程式的CWinAPP 物件的指標,此時返回的就是NULL 程式執行不了
【5】執行時報錯:“this”: 只能用於非靜態成員函式內部
解決: OnPaint函式是在框架類函式中的,需要新增類作用域修飾符 MyFrame::
而且 CPaintDC必須只能在OnPaint()函式中使用
【6】在手動寫訊息對映時,如果在標頭檔案中聲明瞭訊息處理函式,在cpp中有了函式的實現,但沒有在 開始訊息對映和結束訊息對映的中間給出對映入口地址,則程式不會報錯,只不過不會執行此功能。
【7】MFC中文字一些操作都是CDC類 的派生類,,,

問題: 在應用程式類中InitInstance函式中,給框架類進行 動態記憶體分配時 使用new ,那什麼情況時候會使用delete 進行記憶體釋放呢???

MFC有三種訊息
標準訊息:滑鼠,鍵盤訊息
命令訊息:command 選單的操作,,,有自更新機制,自動更新,不用管
通告訊息: 控制元件產生的事件