?? visual c++ mfc 簡明教程.txt
字號:
class CButtonApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};
// Create an instance of the application class
CButtonApp ButtonApp;
// Declare the main window class
class CButtonWindow : public CFrameWnd
{
CButton *button;
public:
CButtonWindow();
afx_msg void HandleButton();
DECLARE_MESSAGE_MAP()
};
// The message handler function
void CButtonWindow::HandleButton()
{
MessageBeep(-1);
}
// The message map
BEGIN_MESSAGE_MAP(CButtonWindow, CFrameWnd)
ON_BN_CLICKED(IDB_BUTTON, HandleButton)
END_MESSAGE_MAP()
// The InitInstance function is called once
// when the application first executes
BOOL CButtonApp::InitInstance()
{
m_pMainWnd = new CButtonWindow();
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
// The constructor for the window class
CButtonWindow::CButtonWindow()
{
CRect r;
// Create the window itself
Create(NULL,
"CButton Tests",
WS_OVERLAPPEDWINDOW,
CRect(0,0,200,200));
// Get the size of the client rectangle
GetClientRect(&r);
r.InflateRect(-20,-20);
// Create a button
button = new CButton();
button->Create("Push me",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
r,
this,
IDB_BUTTON);
}
主要修改了三個方面:
CButtonWindow的類說明現在包含了一個新的成員函數和一個新的表示消息映射的宏。HandleButton函數是正常的C++函數,它通過afx_msg標簽確定為消息處理函數。該函數需要一些特殊的約束,例如,它必須是void型并且它不能接收任何參數。DECLARE_MESSAGE_MAP宏建立了消息映射。函數和宏都必須是public型的。
HandleButton函數作為成員函數以同樣的方式來建立。在該函數中,我們調用了Windows API中的MessageBeep函數。
用宏來建立消息映射。在代碼中,你可以看見BEGIN_MESSAGE_MAP宏接收兩各參數。第一個指定了使用消息映射的類的名稱。第二個是基類。然后是ON_BN_CLICKED宏,接受兩個參數控制的ID和該ID發送命令消息時所調用的函數。最后,消息映射用END_MESSAGE_MAP來結束。
當用戶單擊按鈕時,它向其包含該按鈕的父窗口發送了一個包含其ID的命令消息。那是按鈕的缺省行為,這就是該代碼工作的原因。按鈕向其父窗口發送消息,是因為它是子窗口。父窗口截取該消息并用消息映射來確定所要調用的函數。MFC來安排,只要指定的消息一出現,相應的函數就會被調用。
ON_BN_CLICKED消息是CButton發送的唯一感興趣的消息。它等同于CWnd中的ON_COMMAND消息,只是一個更簡單方便的同義詞而已。
改變大小的消息
在上面的代碼中,由于有了消息映射,從CFrameWnd繼承來的應用程序窗口認出按鈕有按鈕產生的單擊消息并響應之。加入消息映射的ON_BN_CLICKED宏指定了按鈕的ID和窗口在接收到來自按鈕的命令消息時應調用的函數。因為只要用戶單擊了按鈕,按鈕就會自動把其ID發送父窗口,這樣才能允許代碼正確地處理按鈕事件。
作為該應用程序的主窗口的框架窗口自己也有傳遞消息的能力。大約有100不同的消息可用,它們都是從CWnd類繼承來的。從MFC幫助文件中瀏覽CWnd類的成員函數,你就會看到所有的這些消息。查看所有以“On”開頭的成員函數。
你可能已經注意到了,至今為止所有的代碼都不能很好地處理尺寸變化。當窗口變化大小時,窗口的框架會做相應的調整,但是窗口中調的內容仍原處不動。可以通過處理尺寸變化的事件來更好的處理這一問題。任何窗口發送的消息之一就是變尺寸消息。該消息是當改變形狀時發出的。我們可以使用該消息來控制框架中子窗口的大小,如下所示:
// button3.cpp
#include
#define IDB_BUTTON 100
// Declare the application class
class CButtonApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};
// Create an instance of the application class
CButtonApp ButtonApp;
// Declare the main window class
class CButtonWindow : public CFrameWnd
{
CButton *button;
public:
CButtonWindow();
afx_msg void HandleButton();
afx_msg void OnSize(UINT, int, int);
DECLARE_MESSAGE_MAP()
};
// A message handler function
void CButtonWindow::HandleButton()
{
MessageBeep(-1);
}
// A message handler function
void CButtonWindow::OnSize(UINT nType, int cx,
int cy)
{
CRect r;
GetClientRect(&r);
r.InflateRect(-20,-20);
button->MoveWindow(r);
}
// The message map
BEGIN_MESSAGE_MAP(CButtonWindow, CFrameWnd)
ON_BN_CLICKED(IDB_BUTTON, HandleButton)
ON_WM_SIZE()
END_MESSAGE_MAP()
// The InitInstance function is called once
// when the application first executes
BOOL CButtonApp::InitInstance()
{
m_pMainWnd = new CButtonWindow();
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
// The constructor for the window class
CButtonWindow::CButtonWindow()
{
CRect r;
// Create the window itself
Create(NULL,
"CButton Tests",
WS_OVERLAPPEDWINDOW,
CRect(0,0,200,200));
// Get the size of the client rectangle
GetClientRect(&r);
r.InflateRect(-20,-20);
// Create a button
button = new CButton();
button->Create("Push me",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
r,
this,
IDB_BUTTON);
}
為了理解上面的代碼,從窗口的消息映射開始。你會發現入口ON_WM_SIZE。該入口表示消息映射是對來自CButtonWindow對象的變尺寸消息發生響應。變尺寸消息是當用戶改變窗口的大小時產生的。該消息來自窗口本身,而不是作為ON_COMMAND消息由按鈕向其父窗口發送的。這是因為窗口框架不是子窗口。
要注意的是消息映射中的ON_WM_SIZE入口沒有參數。你在MFC文檔中CWnd類,消息映射中的ON_WM_SIZE入口總是調用OnSize函數,并且該函數必須接收三個參
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -