?? visual c++ mfc +=+
字號:
// 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);
}
主要修改了三個方面:
1. CButtonWindow的類說明現在包含了一個新的成員函數和一個新的表示消息映射的宏。HandleButton函數是正常的C++函數,它通過afx_msg標簽確定為消息處理函數。該函數需要一些特殊的約束,例如,它必須是void型并且它不能接收任何參數。DECLARE_MESSAGE_MAP宏建立了消息映射。函數和宏都必須是public型的。
2. HandleButton函數作為成員函數以同樣的方式來建立。在該函數中,我們調用了Windows API中的MessageBeep函數。
3. 用宏來建立消息映射。在代碼中,你可以看見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 <afxwin.h>
#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函數,并且該函數必須接收三個參數。OnSize函數必須是消息映射所屬類的成員函數,并且該函數必須用afx_msg來說明(正如上面在CButtonWindow的定義中所見到的一樣)。
如果你查看MFC文檔,就會發現CWnd中有近100名為“On...”的函數。CWnd::OnSize是其中之一。所有這些函數都在消息映射中有形如ON_WM_對應的標簽。例如,ON_WM_SIZE對應OnSize。ON_WM_入口不接收任何參數,如ON_BN_CLICKED一樣。參數是假設的并自動傳遞給相應的如OnSize的“On...”函數。
重復一遍,因為它很重要: OnSize函數總是與消息映射中的ON_WM_SIZE入口想對應。你必須命名處理函數OnSize, 并且它必須接收三個參數。不同的函數的參數會有所不同。
上面的代碼中在OnSize函數自身的內部,有三行代碼修改了按鈕在窗口中的尺寸。你可以在該函數中輸入任何你想要的代碼。
調用GetClientRect是為了恢復窗口用戶區域的新尺寸。該矩形會被縮小,并調用按鈕的MoveWindow函數。MoveWindow是從CWnd繼承來的,改變尺寸和移動子窗口是在一步完成的。
當你執行上面改變窗口大小的程序時,你就會發現按鈕自己能正確地改變大小。在代碼中,變尺寸事件他國消息映射中的OnSize函數而產生一調用,它調用MoveWindow函數來改變按鈕的大小。
窗口消息
查看MFC文檔,你可以看到主窗口處理的各種各樣的CWnd消息。有些與我們上面介紹的類似。例如,ON_WM_MOVE消息是當用戶移動窗口時發送的消息,ON_WM_PAINT消息是當窗口的任何部分需要重畫時發出的。至今為止,我們的所有程序,重畫工作都是自動完成的,因為是控制自己來負責其外觀。如果你自己使用GDI命令來在用戶區域中繪制,應用程序就應負責重畫工作。因此ON_WM_PAINT就變得重要了。
還有一些發送給窗口的事件消息更深奧。例如,你可以使用ON_WM_TIMER消息與SetTimer函數來使接收預先設置的時間間隔。下面的代碼給出了該過程。當你運行該代碼時,程序會每隔1秒鐘鳴笛一聲。你可以用其它更有用的功能來代替鳴笛。
// button4.cpp
#include <afxwin.h>
#define IDB_BUTTON 100
#define IDT_TIMER1 200
// 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);
afx_msg void OnTimer(UINT);
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);
}
// A message handler function
void CButtonWindow::OnTimer(UINT id)
{
MessageBeep(-1);
}
// Th
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -