MFC 對話框編程 -- 總結 .


一、創建對話框對象

1.首先利用資源編輯器創建對話框資源,並針對該對話框資源定義一個對話框類:class   CTestDlg :  public CDialog

2.創建話話框對象

模態對話框的創建:

    如:

     CTestDlg    dlg;

     dlg.DoModal();

 

非模態對話框創建:

   如:

   CTestDlg    dlg;

   dlg.Create(IDD_DIALOG, this);

  

但這樣是得不到一個正常顯示的非模態對話框的。因為模態與非模態對話框的實現方式並不相同,這里我們還要注意幾點。

  1. 非模態對話框創建完成后是隱藏着的,必須調用ShowWindow來進行顯示。
  2. 對於模態對話框,當執行到DoModal 函數以創建對話框時,程序會暫停執行,直至模態對話框關閉。所以創建模態對話框可以采用局部對象。
    但是,對於非模態對話框,當執行Create函數時並不會暫停執行,當執行到大括號"}后Dlg局部對象被銷毀生命周期結束,於是異常出現了。
    解決方法有兩個:
        一、在View類中定義一個CTestDlg 成員變量。
        二、動態創建一個CTestDlg 變量,並重寫CTestDlg 類的 PostNcDestroy函數,在該函數里銷毀對象 delete    this;
  3. 無論創建的是模態對話框,還是非模態對話框,當我們單擊確定或取消按鈕后對話框都會消失。但這時低層的操作卻是不同的。
    對於模態對話框,此時對話框對象的確是被銷毀了,但對於非模態對話框,這時只是隱藏起來不再顯示。這需要我們自己調用DestoryWindow函數來進行銷毀工作。
    這時我們必須重寫 CTestDlg 的 OnOK 、 OnCancel 兩個函數(這兩個是基類CDialog的虛函數),在這兩個函數內調用DestroyWindow函數,並注意不再調用基類CDialog相應的函數。

正確地創建非模態對話框的代碼如下:

CTestDlg   *pDlg = new CTestDlg;
pDlg->Create(IDD_DIALOG, this);
pDlg->ShowWindow(SW_SHOW);   

同時,在CTestDlg 類的 PostNcDestroy函數中銷毀對象:delete   this;

 

二、動態創建按鈕

1. 在對話框類CTestDlg 中定義一個 CButton 類對象,作為其成員變量。

2. 在相應的消息處理中,調用 CButton類的Create函數創建按鈕。

要注意兩點:

  • 如果在調用CButton::Create創建按鈕時沒有指定WS_VISIBLE 風格,那么隨后一定要調用這個按鈕對象的ShowWindow函數,來將該按鈕顯示出來。
  • 為防止該CButton關聯多個按鈕,這里需要進行一些設置,如下:
    if (!m_btn.m_hwnd)
    {
          // CButton 對象m_btn 未關聯一個按鈕
          m_btn.Create(....);
    }
    else
    {
          // CButton 對象m_btn 已關聯一個按鈕
          其他操作...
    }
    當然,方法並不只這一種。但這是最漂亮的方法。

 

三、設置控件文本文字

1.下面列舉幾個用來設置控件文本文字的函數:

// 取得對話框中指定控件的窗口句柄。控件通過ID標識來指定
CWnd*         GetDlgItem( int nID ) const;
void CWnd::GetDlgItem( int nID, HWND* phWnd ) const;

// 取得窗口文本
int      GetWindowText( LPTSTR lpszStringBuf, int nMaxCount ) const;
void   GetWindowText( CString& rString ) const;

// 設置窗口文本
void  SetWindowText( LPCTSTR lpszString );

// 取得指定控件窗口文本。控件通過ID標識來指定
int    GetDlgItemText( int nID, LPTSTR lpStr, int nMaxCount ) const;
int    GetDlgItemText( int nID, CString& rString ) const;

// 設置指定控件窗口文本。控件通過ID標識來指定
void SetDlgItemText( int nID, LPCTSTR lpszString );

// 取得指定控件窗口文本,並轉化為UINT 類型返回。控件通過ID標識來指定
UINT GetDlgItemInt( int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE ) const;

// 設置指定控件窗口文本,由UINT類型轉化為字符 。控件通過ID標識來指定
void  SetDlgItemInt( int nID, UINT nValue, BOOL bSigned = TRUE );

2.可以為對話框控件關聯一個變量,在CTestDlg 類的DoDataExchange來完成數據的更新與交換。

這里我們需要重點說明 DoDataExChange 函數:
首先引用MSDN的一段解釋吧:Called by the framework to exchange and validate dialog data。意指框架調用此函數來改寫與確認對話框數據。

其實DoDataExChange函數主要是通過DDX_TEXT(....)  或 DDX_CONTROL(....) 來實現數據的實時關聯的。
我從我的MSDN中隨便拿來一個定義:

void AFXAPI DDX_Text( CDataExchange* pDX, int nIDC, BYTE& value );

其實這個要關聯的話也很簡單,沒有那么復雜。如下:

value = GetDlgItemInt(nIDC);
SetDlgItemInt(nIDC, value);


而DoDataExchange 函數是在UpdateData函數內部調用的。
該函數只有一個布爾型參數,它決定了數據傳送的方向:

  • 調用UpdateData(TRUE)    , 將數據從對話框的控件中傳送到對應的數據成員中。
  • 調用UpdateData(FALSE)  , 則將數據從數據成員中傳送給對應的控件。

UpdateData(FALSE) 是將變量的值傳到控件.
UpdateData(TRUE)  是從控件中取值到關聯的變量

 

四、對話框伸縮功能的實現

只關聯到兩個函數:

// 取得指定窗口邊框折尺寸

void GetWindowRect( LPRECT lpRect ) const;

// 設置指定窗口(控件)的位置同尺寸

BOOL SetWindowPos( const CWnd* pWndInsertAfter, intx, inty, int cx, intcy, UINTnFlags );

 

 

 

五、逃跑按鈕的實現

1. 創建一個基於對話框的MFC 程序,刪除原有的控件后,再添加兩個按鈕,更改兩按鈕名為"你能抓到我嗎?"

2.打開類視圖,定義一個新類CNewButton,這個新類的基類為CButton。並為此類添加一個成員變量:CNewButton   *m_pbtn;

3.打開資源視圖,分別為兩個按鈕創建兩個CNewButton類關聯變量:m_btn1, m_btn2;

4.在CXXXDlg中改寫其OnInitDialog函數。主要添加:

           m_btn1.m_pbtn = &m_btn2;

           m_btn2.m_pbtn = &m_btn1;

5.對於CNewButton 類,必定其OnMouseMove函數。主要添加:

           ShowWindow(SW_HIDE);

           m_pbtn->ShowWindow(SW_SHOW);

 

編譯,連接。 OK

 

六、屬性頁、屬性表單與向導的建立

1.創建屬性頁

打開資源編輯器,點擊Dialog 資源並在列出的選項中,選擇:IDD_PROPPAGE_LARGE。建立屬性頁資源。

之后,我們就可以其上添加其他控件來完善我們的屬性頁。關於屬性頁的完善操作我們在后面會談到。

屬性頁資源完善后,再為每一個屬性頁關聯一個類。

2.創建屬性表單

打開類視圖,添加新類CPropSheet,其基類為CPropertySheet。

之后再為其添加屬性頁類對象,並在其構造函數中利用AddPage函數將屬性頁添加到表單上。

3.消息響應

再主菜單的最后再增加一個菜單項,並為此菜單添加消息響應函數。

在此響應函數中創建屬性表單:

CPropSheet     propSheet(TEXT("屬性表單"));

propSheet.DoModal();

4.向導的創建

創建一個向導類型的對話框,應該遵循創建一個標准屬性表單的步驟來實現。

但在調用屬性表單對象的DoModal函數之前,應該先調用SetWizardMode函數,來聲明建立的是一個作為向導的屬性表單。

所以,應在DoModal函數之前添加如下代碼:

propSheet.SetWizardMode();

5.屬性頁的完善操作

首先我們要注意到屬性頁,在三個不同時期的關鍵性操作:

  1. 當屬性表單中的某屬性頁被選中,從而成為一個活動的頁面時,應用程序框架就會調用OnSetActive函數。
    OnSetActive 是其基類的一個虛函數,我們可以重寫這個函數並在其中進行一些操作。
  2. 假設當前我們處於屬性表單中的某屬性頁,當我們點擊下一步並將進入下一個屬性頁時,應用程序框架會調用OnWizardNext函數。
    OnWizardNext 是其基類的一個虛函數,我們可以重寫這個函數並在其中進行一些操作。
    類似的還有OnWizardBack 同 OnWizardFinish函數。
  3. 當一個屬性頁被創建時,會調用其OnInitDialog函數。
    我們可以在這個函數里對屬性頁中的控件進行一些操作。如為列表框或下拉框添加字符串等。

 

from:http://blog.csdn.net/ltag0110rtag/article/details/7369105


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM