Lesson6: 對話框編程

1. Windows應用程序工作的基本流程是從用戶那裏得到數據,經過相應的處理之後,現把處理結果輸出到屏幕,打印機或者綿輸出設備。這就需要用到Windows應用程序的用戶接口對話框。對話框就是一個窗口,它不僅可以接收消息,而且還可以被移動和關閉,甚至可以在它的客戶區中進行繪圖。相當於一個窗口,在它上面能夠旋轉各種標準控件和擴展控件。都是由CWnd類派生來

 

2. 對話框的類型:模態(Model)對話框非模態(Modeless)對話框

(1)模態對話框:指當其顯示時,程序會暫停執行,直到關閉這個模態對話框後,才能繼續執行程序中其它任務。

         當一個模態對話框打開時,用戶只能與該對話框進行交互,而其它用戶界面對象接收不到輸入信息

(2)非模態對話框:當其顯示時,允許執行程序中其它任務,而不用關閉這個對話框

MFC中,對資源的操作通常都是通過一個與資源相關的類來完成。對話框資源對應CDialog基類。

 

3.  在對話框資源界面,選擇[View]->[ClassWizard]菜單命令,(也可以新建的對話框資源上雙擊鼠標左鍵),選擇一個基類,創建關於它的類。其中一般有兩個函數一個是構造函數(可用於初始化成員變量),另外一個是DoDataExchange主要用來完成對話框數據的交換和校驗,要想在其它窗口的事件中顯示該對話框就涉及到創建對話框的模式(模態與非模態)

(1)模態對話框的創建

創建模態對話框要調用CDialog類的成員函數:DoModel(),創建一個模態對話框,其返回值作爲CDialog類的另一個成員函數:EndDialog的參數,後者的功能就是關閉模態對話框。

Void CMyboleView::OnDialog(){
    CTestDlg dlg;//視類中源文件要包含這個類的頭文件
     dlg.DoModal();//創建一個模態對話框,
}

(2)非模態對話框的創建

需要利用CDialog類的Create成員函數

BOOL Create(LPCTSTR lpszTemplateName, CWnd* pParaentWnd = NULL);

BOOL Create(UINT nIDTemplate, Cwnd* pParentWnd = NULL);

lpszTemplateName對話框模板的名稱,nIDTemplate對話框模板的IDpParentWnd對話框的父窗口,如果是NULL則父窗口就是主應用程序窗口

注意:當創建非模態對話框時,還需要調用ShowWindow函數顯示對話框,而模態的不需要

Void CMyboleView::OnDialog(){
     CTestDlg *pDlg = new CTestDlg;//定義成指針,在堆上分配內存(或定義爲全局變
                                            //量,在堆上分配的內存如不主動銷燬則與程序生命週期一樣,
      pDlg->Create(IDD_DIALOG1, this);//創建一個非模態對話框,使用對話框ID,
                                              //父窗口是調用OnDalog函數的窗口
      pDlg->ShowWindow(SW_SHOW);//顯示窗口
}

 

4.  動態添加Button

void CDlg::OnBtnAdd() 
{
   if (!IsCreated/*m_btn.h_Wnd*/)//也可使用m_btn對象中的成員變量判斷句柄是否有值
   {
     m_btn.Create("New", BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,
              CRect(0, 0, 100, 100), this, 123);//在對話框上動態添加一個按鈕
      IsCreated = TRUE;//判斷是否已經創建了按鈕,是的話銷燬,現點擊可再重新創建
   }
   else
  {
     m_btn.DestroyWindow();//銷燬窗口,因爲按鈕也是從CWnd繼承來
      IsCreated = FALSE;
  }
}

5. 控件的訪問     

獲取對話框上的項目指針:GetDlgItem()

獲取窗口信息:GetWindowText()

更改窗口信息:SetWindowText()

直接取得對指定話框上項目的信息:GetDlgItemText() 想當於GetDlgItem()GetWindowText()合用。

同理有SetDlgItemText() 相當於GetDlgItem()SetItemText() 合用。

GetDlgItemInt(),SetDlgItemInt()等等,S/GetDlgItemInt()可以處理有符號的整數。

字符到數組的轉換:atoi() 轉換一個類型到指定類型時,用 類型的第一個字母 to 指定類型的一個字母。

在DoExchange函數裏,放置以DDX_爲前綴的函數,來關聯一個控件和變量,DDV_爲前綴的函數,用來校驗一個控件內容。DDX_(對話框數據交換)   DDV_(對話框數據校驗)

注意,在用數據變量關聯控件的方式時,千萬注意要使用UpdateData()!

也可以用一個控件變量關聯一個控件,用它的成員函數,來對控件進行操作,例如:CEDIT.GetWindowText()

SendMessage()的用法,比較好用,注意,發送消息,是控件向系統發送,由系統處理。

SendDlgItemMessage()

 SendMessage(),Windows程序都基於消息的,爲了獲取或設置窗口的文本,只要知道獲取或設置窗口文本的消息,就可以通過SendMessage來發送這條消息,從而獲取或設置控件的文本。獲取窗口文本的消息是WM_GETTEXT發送該消息後,系統將把指定窗口的文本複製到調用者提供的一個緩存中,在這個消息兩個附加參數中,wParam指定將複製的字符數據,lParm就是調用者提供的用來保存窗口文本的緩存地址。WM_SETTEST消息wParam參數沒用,值爲0,lParam參數指定用來設置文本字符串地址;SendDlgItemMessage()

幾種控件操作的代碼:

void CTestDlg::OnBtnAdd() 
{
        //點擊後創建一個新的按鈕
//      if (!m_btn)
//      {
//         m_btn.Create("新按鈕", BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD, CRect(0, 0, 100, 20), this, 123);
//      }
//      if (!m_btn.m_hWnd)
//      {
//         m_btn.Create("新按鈕", BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD, CRect(0, 0, 100, 20), this, 123);
//      }
//      else{
//         m_btn.DestroyWindow();
//      }
         /*對話框控件訪問方式
         (1):GetDlgItem()->G(S)etWidowText()方式
         */
         /*int num1, num2, num3;
         char ch1[10], ch2[10], ch3[10];
 
         GetDlgItem(IDC_NUM1)->GetWindowText(ch1, 10);
         GetDlgItem(IDC_NUM2)->GetWindowText(ch2, 10);
 
         num1 = ::atoi(ch1);
         num2 = ::atoi(ch2);
         num3 = num1 + num2;
 
         ::itoa(num3, ch3, 10);
 
         GetDlgItem(IDC_NUM3)->SetWindowText(ch3);
         */
         /*對話框控件訪問方式
         (2):G(S)etDlgItemInt()方式
         */
         /*int num1, num2, num3;
         num1 = GetDlgItemInt(IDC_NUM1, NULL, TRUE);
         num2 = GetDlgItemInt(IDC_NUM2, NULL, TRUE);
 
         num3 = num1 + num2;
         SetDlgItemInt(IDC_NUM3, num3, TRUE);
         */
 
         /*對話框控件訪問方式
         (3):G(S)etDlgItemText()方式
         */
         /*int num1, num2, num3;
         char ch1[10], ch2[10], ch3[10];
         
         GetDlgItemText(IDC_NUM1, ch1, 10);
         GetDlgItemText(IDC_NUM2, ch2, 10);
         
         num1 = ::atoi(ch1);
         num2 = ::atoi(ch2);
         num3 = num1 + num2;
         
         ::itoa(num3, ch3, 10);
         
         SetDlgItemText(IDC_NUM3, ch3);
         */
         
         /*對話框控件訪問方式
         (4):將控件和整型變量相關聯,然後調用UpdateData(TRUE)初始化或校驗數據,在操作完成後調用UpdateData(FALSE);實現對話框數據初始化
         */
         /*注意,該方法有數據校驗的功能,在添加變量時可以指定數據值的範圍
         UpdateData(TRUE);//獲取編輯框中的數據
         m_num3 = m_num2 + m_num1;//數據操作(+)
         UpdateData(FALSE);//初始化編輯框3中的數據,即將變量中的數據顯示到控件中
         */
         /*對話框控件訪問方式
         (5):將控件和控件變量相關聯,然後調用控件變量的G(S)etWindowext方法
         */
         /*int num1, num2, num3;
         char ch1[10], ch2[10], ch3[10];
         
         m_cNum1.GetWindowText(ch1, 10);
         m_cNum2.GetWindowText(ch2, 10);
         
         num1 = ::atoi(ch1);
         num2 = ::atoi(ch2);
         num3 = num1 + num2;
         
         ::itoa(num3, ch3, 10);
         
         SetDlgItemText(IDC_NUM3, ch3);
         */
         /*對話框控件訪問方式
         (6):SendMessage(),平臺SDK的函數,發送WM_GETTEXT/WM_SETTEXT消息
         */
         /*int num1, num2, num3;
         char ch1[10], ch2[10], ch3[10];
         ::SendMessage(GetDlgItem(IDC_NUM1)->m_hWnd, WM_GETTEXT, 10, (LPARAM)ch1);
         ::SendMessage(GetDlgItem(IDC_NUM2)->m_hWnd, WM_GETTEXT, 10, (LPARAM)ch2);
 
         num1 = ::atoi(ch1);
         num2 = ::atoi(ch2);
         num3 = num1 + num2;
         
         ::itoa(num3, ch3, 10);
         ::SendMessage(GetDlgItem(IDC_NUM3)->m_hWnd, WM_SETTEXT, 10, (LPARAM)ch3);
         GetDlgItem(IDC_NUM1)->SendMessage(WM_GETTEXT, 10, (LPARAM)ch1);
         */
         
         /*對話框控件訪問方式
         (8):SendDlgItemMessage()
         */
         int num1, num2, num3;
         char ch1[10], ch2[10], ch3[10];
         SendDlgItemMessage(IDC_NUM1, WM_GETTEXT, 10, (LPARAM)ch1);
         SendDlgItemMessage(IDC_NUM2, WM_GETTEXT, 10, (LPARAM)ch2);
         num1 = ::atoi(ch1);
         num2 = ::atoi(ch2);
         num3 = num1 + num2;
         
         ::itoa(num3, ch3, 10);
         
         SendDlgItemMessage(IDC_NUM3, WM_SETTEXT, 0, (LPARAM)ch3);
         SendDlgItemMessage(IDC_NUM3, EM_SETSEL, 0, -1);
         GetDlgItem(IDC_NUM3)->SetFocus();
//      GetDlgItem(IDC_NUM1)->GetWindowText(ch1, 10);
//      GetDlgItem(IDC_NUM2)->GetWindowText(ch2, 10);
//      num1 = ::atoi(ch1);
//      num2 = ::atoi(ch2);
//      num3 = num1 + num2;
//      itoa(num3, ch3, 10);
//      GetDlgItem(IDC_NUM3)->SetWindowText(ch3);
 
//      CString str1, str2, str3;
//      int num1, num2, num3;
//      GetDlgItem(IDC_NUM1)->GetWindowText(str1);
//      GetDlgItem(IDC_NUM2)->GetWindowText(str2);
//      num1 = ::atoi(str1);
//      num2 = ::atoi(str2);
//      num3 = num1 + num2;
//      str3.Format("%d", num3);
//      GetDlgItem(IDC_NUM3)->SetWindowText(str3);
 
//      UpdateData();
//      m_num3 = m_num1 + m_num2;
//      UpdateData(FALSE);
}


 說明:

(1)itoa函數:將整型轉換成字符

(2)atoi函數:將字符轉換成整型

(3)SendMessage函數:要使用SDK函數,前面加::表示全局函數,第一個參數句柄可以先獲取控件句柄然後再取出其m_hWnd窗口句柄變量,如果控件綁定變量,使用變量的SendMessage函數則不需要句柄值

 

6. 伸縮對話框

改變窗口的大小Wnd::SetWindowPos()對話框從父類繼承來的函數。

判斷一個矩形是否爲空:IsRectEmpty(),IsRectNull()

前者是判斷矩形面積是否爲空,後者是判斷矩形的四個座標值是否爲0,不關心是否能做爲一個矩形。

·····SetWindowPos()改變窗口的大小和Z次序的排列。 ·····

 

7. 焦點的問題

SetFocus()

SetWindowLong

::GetNextWindow()

::GetWindow()

::GetNextDlgTabItem()

CWnd::GetWindow()

CWnd::GetNextWindow

CWnd::GetNextDlgTabItem()

缺省OK按鈕的IDIDOK,

VC++環境下打開對話框資源編輯器,選擇[Layout]->[Tab order]可以查看和調整對話框上控件的tab順序;

 

8. 在用變量來更新控件值,更新控件數據與獲取控件數據都要注意一點:

    無論是獲取數據還是更新窗口上的數據都是要進行數據交換,要使用UpdateData函數,

Void CTestDlg::OnBtnAdd(){
    UpdateData();//使控件變量獲取控件上的數據
     m_num3 = m_num1 + m_num2;//三個變量都是綁定控件的,對應控件中的值
     UpdateData(FALSE);//函數默認參數爲TRUE,要更新控件數據設置爲FALSE
}

9. 如何改變按鈕的字體?在對話框的屬性中改變字體的屬性即可

 

10. 逃跑按紐的實現

 (1)CButton派生一個類,CWeixinBtn

 (2)IDC_EDIT1關聯成員變量m_btn1,類型爲CWeixinBtn,注意要包含頭文件。

 (3)CWeixinBtn中加一個指針成員變量CWeixinBtn *pWeixinBtn,然後將其地址初始化。

 (4)在新類中增加鼠標移動的消息處理。

 

11.屬性表單

 (1)插入屬性頁資源。Insert->new Resource->Dialog

 (2)當選擇Classwizard菜單時,系統提示是否爲創建新的類,我們將其從CPropertyPage派生!這樣可以爲方便爲其

           增加消息響應函數。

 (3)插入新的從CPropertySheet派生的類,在類中增加3CPropertyPage的實例。

 (4)view中增加菜單項,當點擊時顯示屬性表單,出現中文亂碼,修改CPropertyPage屬性爲中文,另外將其字體

           設爲宋體。

 (5)CPropertyPage中設置SetWizardButtons可將其屬性改爲上一步、完成!

 (6)IDC_RADIO1關聯成員變量,需要先設置Group屬性才行。另外別忘記調用UpdateData().

 (7)CPropertyPage增加虛函數,OnWizardNext,如果用戶點擊下一步時,不想讓他進入下一步,剛返回-1

 (8)將用戶的選擇輸出到屏幕上,此時可以在View中增加幾個成員變量,用來接收用戶選擇的數據。

注意: memset()的用法! memset(m_bLike,0,sizeof(m_bLike));將所指定長度設置爲0

          ZeroMemory(m_bLike, sizeof(m_bLike));同上效果

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章