天天看點

MFC對話框程式設計

1. 利用VisualC++建立一個對話框

2. 對話框類的繼承特性:

cobject

    ccmdtarget

     cwnd       //由cwnd派生,是一個視窗類

      cdialog     

在VC++ 中,一個視窗與一個C++類進行關聯,對話框的基類為CDialog 類。

對話框分為模态對話框與非模态對話框,模态對話框在應用程式能進行其它操作之前必須關閉,非模态的對話框允許不關閉對話框而進行應用程式操作.

MSDN中的說明:

This class is the base class used for displaying dialog boxes on the screen. Dialog boxes are of two types: modal and modeless. A modal dialog box must be closed by the user before the application continues. A modeless dialog box allows the user to display the dialog box and return to another task without canceling or removing the dialog box.

3. 建立對話框類

确定選中新添加的對話框,View ---> ClassWizard 建立一個基于CDialog 的類與本對話框關聯,輸入類名,檔案名,基類名,對話框ID , 此時,我們在工程中添加了一個類。

4. 建立對話框

a.模态對話框

利用DoModal()  //調用domodal()建立一個模态的對話框,它的傳回值是做為cdialog::enddailog成員函數的參數,這個參數用來關閉對話框 Calls a modal dialog box and returns when done. 

//Return Value:An int value that specifies the value of the nResult parameter that was passed to the CDialog::EndDialog member function, which is used to close the dialog box. The return value is –1 if the function could not create the dialog box, or IDABORT if some other error occurred, in which case the Output window will contain error information from GetLastError.

備注:cdialog::enddailog //用來關閉模态的對話框

用法:

為菜單項加入響應對話框

(1)建立一個對話框,輕按兩下該對話框,為該對話框建立一個類CTestDlg,基類為CDialog。

(2)在菜單中加入一個新的菜單項,然後用ClassWizard加入一個基于View類的Command指令函數,在該指令函數中寫入代碼:

CTestDlg dlg;

dlg.DoModal();

(3)在***View.Cpp開頭中加入#include “CTestDlg.h” ,再連結。

b.非模态對話框:

利用CDialog::Create()。

virtual BOOL Create(

   UINT nIDTemplate,  //對話框ID号

   CWnd* pParentWnd = NULL   //對話框父視窗C++對象指針); //Initializes the CDialog object. Creates a modeless dialog box and attaches it to the CDialog object.

注意:在調用Create()之後,必須調用ShowWindow()函數将其顯示出來,

BOOL ShowWindow(int nCmdShow ); //Sets the visibility state of the window

注意,在建立非模态對話框是,必須注意對話框對象的生命周期,因為在顯示對話框時,程式是一直在運作的,但是如果定義為局部的非模态對話框,在其生命周期結束之後就會被銷毀。

在***View.App類中,加入成員變量: CTestDlg dlg;

同上例,在菜單中加入一個新的菜單項,然後用ClassWizard加入一個基于View類的Command指令函數,在該指令函數中寫入代碼:

dlg.Create(IDM_Dialog1,this);

dlg.ShowWindow(SW_SHOW);

另一種方法,為對話框變量配置設定堆記憶體。

CTestDialog *pDlg=new CTestDialog();

pDlg->Create(IDD_DIALOG1,this);

pDlg->ShowWindow(SW_SHOW);

注意:在模态對話框中,點選OK按鈕,将銷毀對話框;在非模态對話框中,點選OK按鈕,隻是将對話框做為不可視處理,而不是銷毀。

非模 态對話框要覆寫其基類的OnOk()函數 ,在MSDN中的說明: If you implement the OK button in a modeless dialog box, you must override the OnOK member function and call DestroyWindow from within it. Don't call the base-class member function, because it calls EndDialog, which makes the dialog box invisible but does not destroy it.

5. 在對話框中建立動态按鈕:

例子:在對話框中加入一個按鈕,按下該按鈕,将自動建立一個新的按鈕

(1)在C***View類中加入一個成員變量:CButton m_btn;

(2)在對話框類中添加一個BOOL型成員變量m_bIsCreate,并且初始化為FALSE。

在對話框的按鈕中添加響應函數,加入代碼:

if(m_bIsCreate==FALSE)  //如果沒有建立

 {

  m_btn.Create("Mickor.Guo",BS_DEFPUSHBUTTON |WS_CHILD|WS_VISIBLE,

   CRect(0,10,100,30),this,123);

m_bIsCreate=TRUE;

 }

 else

  m_btn.DestroyWindow();  //消毀視窗

m_bIsCreate=FALSE;

//該if-else處理是為了防止重複按下該按鈕時,出現錯誤。還有另外一種處理方法,就是不用設定m_bIsCreate為成員變量,而是設定為靜态的局部變量,在if語句之間加上:static BOOL  m_bIsCreate=FALSE;

最直接的方法,運用m_hWnd句柄的情況來建立:

if(!m_btn.m_hWnd)  //如果沒有建立

備注(按鈕建立函數):

virtual BOOL CButton::Create(

   LPCTSTR lpszCaption,    //Specifies the button control's text.  按鈕文本

   DWORD dwStyle,  //按鈕樣式  Specifies the button control's style. Apply any combination of button styles to the button.

   const RECT& rect,  //按鈕位置與大小  Specifies the button control's size and position.

   CWnd* pParentWnd,  //父視窗指針

   UINT nID   //按鈕ID

);  //Creates the Windows button control and attaches it to the CButton object.

6. 靜态文本框程式設計:

CString str;

 if(GetDlgItem(IDC_NUMBER1)->GetWindowText(str),str=="Number1")

  GetDlgItem(IDC_NUMBER1)->SetWindowText("數字1");

函數說明:

a.   CWnd* GetDlgItem ( int nID ) const; //通過控件ID 獲得控件C++對象指針

//This method retrieves a pointer to the specified control or child window in a dialog box or other window. The pointer returned is usually cast to the type of control identified by nID. 

b.   void GetWindowText(CString& rString )const;  //獲得視窗文本

//This method copies the CWnd caption title into the buffer pointed to by lpszStringBuf or into the destination string rString. If the CWnd object is a control, the GetWindowText method copies the text within the control instead of copying the caption.   

c.   void SetWindowText( LPCTSTR lpszString );  //設定視窗文本

//This method sets the window title to the specified text. If the window is a control, the text within the control is set. This method causes a WM_SETTEXT message to be sent to this window.   

注意:逗号(",")運算符的應用

注意:在此之前,要設定靜态文本控件的Notify 屬性為真

7. EditBox 編輯框程式設計:

對話框控件的七種通路方式:

A.   GetDlgItem()->Get(Set)WindowText()

B.   GetDlgItemText()/SetDlgItemText()

C.   GetDlgItemInt()/SetDlgItemInt()

D.   将控件和整型變量相關聯

E.    将控件和控件變量相關聯

F.    SendMessage()

G.   SendDlgItemMessage()

例:為一個按鈕添加加法的功能,按下,則将第一個edit控件和第二個edit控件的值相加,結果輸出到第三個edit控件中。

方法1:利用GetWindowText()和SetWindowText()實作。

在按鈕響應函數中添加如下代碼:

int num1,num2,num3;

char ch1[10],ch2[10],ch3[10];

GetDlgItem(IDC_EDIT1)->GetWindowText(ch1,10);

GetDlgItem(IDC_EDIT2)->GetWindowText(ch2,10);

num1=atoi(ch1);

num2=atoi(ch2);

num3=num1+num2;

itoa(num3,ch3,10);

GetDlgItem(IDC_EDIT3)->SetWindowText(ch3);

方法2:利用GetDlgItemText()和SetDlgItemText()實作

函數說明:

int GetDlgItemText( int nID,  // 控件ID

LPTSTR lpStr,  //字元串數組

int nMaxCount  //最大的字元數

) const; //在一個視窗控件中讀取文本到字元數組中

//This method retrieves the title or text associated with a control in a dialog box. This method copies the text to the location pointed to by lpStr and returns a count of the number of bytes it copies.

void SetDlgItemText( 

int nID,  //控件ID

LPCTSTR lpszString );  //字元串

// 設定控件的文本内容   This method sets the caption or text of a control owned by a window or dialog box. SetDlgItemText sends a WM_SETTEXT message to the given control

用法 :可以将上面的代碼換成:

GetDlgItemText(IDC_EDIT1,ch1,10);

GetDlgItemText(IDC_EDIT1,ch2,10);

SetDlgItemText(IDC_EDIT3,ch3);

方法3:GetDlgItemInt()和SetDlgItemInt()實作

UINT GetDlgItemInt( 

BOOL* lpTrans = NULL,  //控件文本是否有非數字字元,當設為NULL 時,不進行報錯

BOOL bSigned = TRUE )  //是否為有符号數值

const; //獲得控件文本,并轉換成數值類型 The CWnd::GetDlgItemInt method retrieves the text of the control identified by the nID parameter. This method translates the text into an integer value by stripping any extra spaces at the beginning of the text and converting decimal digits. It stops the translation when it reaches the end of the text or encounters any nonnumeric character.

void SetDlgItemInt( 

UINT nValue,  //數值

BOOL bSigned = TRUE  //是否為有符号數值

); //把一個數值設定成控件文本  This method sets the text of a specified control in a dialog box to the string representation of a specified integer value. SetDlgItemInt sends a WM_SETTEXT message to the given control.

num1=GetDlgItemInt(IDC_EDIT1);

num2=GetDlgItemInt(IDC_EDIT2);

SetDlgItemInt(IDC_EDIT3,num3);

備注:

int atoi( const char *string ); // 把一個字元串轉為INT 類型的數值

char *_itoa(

   int value,  //要換的數值

   char *string,  //轉換成的字元串

   int radix  //數值的進制  2--36

); //把一個數值轉換成字元串

方法4:利用資料交換與較驗

  A. View ---> ClassWizard ---> Member Variables 在此界面添加資料成員與控件的資料關聯操作(即為各個控件添加成員變量),類名,控件名,資料成員名,資料類型,資料範圍等

  B. 這裡為3個EDIT控件設定3個成員變量:m_num1,m_num2,m_num3。此時,ClassWizard 在程式中添加了如下代碼:

     在該對話框類的頭檔案中: 

//{{AFX_DATA(CTestDialog)

 enum { IDD = IDD_DIALOG1 };

 int  m_num1;                 //可知添加了3個成員變量

 int  m_num2;

 int  m_num3;

 //}}AFX_DATA

在類的構造函數中,添加了3個成員變量的初始化:

C***Dlg::C***Dlg(……)

{…

 m_num1=0;

 m_num2=0;

 m_num3=0;

}

     在對話框類的DoDataExchange 函數中,将成員變量和控件進行了關聯:

//}}AFX_DATA_MAP(C***Dlg)

DDX_Text(pDX, IDC_EDIT1, m_num1);           

DDV_MinMaxInt(pDX, m_num1, 0, 100);

DDX_Text(pDX, IDC_EDIT2, m_num2);

DDX_Text(pDX, IDC_EDIT3, m_num3);

//}}AFX_DATA_MAP

 備注:MSDN中NOTE:

       virtual void DoDataExchange( CDataExchange* pDX ); 

     //This method is called by the framework to exchange and validate dialog data

C. 想要在程式中進行資料互動,必須調用 UpdateData() 函數

       BOOL UpdateData(BOOL bSaveAndValidate = TRUE ); //當參數為TRUE時,将控件的值傳給成員變量,當參數為FALSE時,将成員變量的值傳給控件

 //NOTE:This method initializes data in a dialog box, or retrieves and validates dialog data.Specifies a flag that indicates whether dialog box is being initialized (FALSE) or data is being retrieved (TRUE). 

在按鈕的指令實作函數中,加入如下代碼:

UpdateData();

m_num3=m_num1+m_num2;

UpdateData(FALSE);

方法5:通過控件對象進行資料互動與關聯

  A. 如同上面一樣,在 Add Member Variables 界面的Category 下拉清單框中,選擇Control ,進行控件關聯操作。(為EDIT1關聯m_edit1, 為EDIT2關聯m_edit2, 為EDIT3關聯m_edit3)

  B. 利用控件的成員函數進行操作,在按鈕指令實作函數中加入代碼:

m_edit1.GetWindowText(ch1,10);

m_edit2.GetWindowText(ch2,10);

m_edit3.SetWindowText(ch3);

方法6:通過Windows 消息進行資料互動

  A. 想要獲得一個控件文本,可以有以下四種方式:

       ::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);// 利用Win32函數SendMessage發送一個擷取文本的消息

       ::SendMessage(m_edit1.m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);//利用控件變量

       GetDlgItem(IDC_EDIT1)->SendMessage(WM_GETTEXT,10,(LPARAM)ch1);//直接用CWnd的成員函數SendMessage去發送消息

       m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)ch1);//利用控件變量的成員函數SendMessage去發送消息

  B. 設定控件文本可以:

     m_edit1.SendMessage(WM_SETTEXT,0,(LPARAM)ch1);

或::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_SETTEXT,0,(LPARAM)ch1);

在按鈕指令響應函數中,添加代碼:

m_edit1.SendMessage(WM_GETTEXT,10,(LAPRAM)ch1); 

m_edit2.SendMessage(WM_GETTEXT,10,(LPARAM)ch2);

m_edit3.SendMessage(WM_SETTEXT,0,(LPARAM)ch3);

 備注:

      LRESULT SendMessage(

        HWND hWnd,    //控件句柄

        UINT Msg,     //Windows 消息 , 這裡為WM_GETTEXT 獲得文本/WM_SETTEXT 設定文本

        WPARAM wParam, //WM_GETTEXT 時,為最大字元數量 ,WM_SETTEXT 時,要設為0

        LPARAM lParam  //要獲得或設定的文本

      ); //發送一個Windows 消息

方法7:利用SendDlgItemMessage()函數,直接給對話框子控件發送消息 

函數說明: 

LRESULT SendDlgItemMessage( 

        int nID,  //控件ID

        UINT message, 

        WPARAM wParam = 0, 

        LPARAM lParam = 0 

     ); //This method sends a message to a control. 參數同上

SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,10,(LAPRAM)ch1); 

SendDlgItemMessage(IDC_EDIT2,WM_GETTEXT,10,(LAPRAM)ch2); 

num3=num1+num2;;

SendDlgItemMessage(IDC_EDIT2,WM_SETTEXT,0,(LPARAM)ch3);