弄了好久,今天終於把在VC中的對話框類之間傳遞參數的問題解決了,很開心,記錄如下:
1.
我所建立的工程是一個基於MFC對話框的應用程序,一共有三個對話框,第一個對話框為主對話框,所對應的類為CTMDDDlg類。在主對話框上我放置了一個標簽頁(Tab Control)控件,其實現的功能是當單擊標簽提示A時進入頁面A,即對話框A(所對應的類為CDialogChild1),單擊B時進入對話框B(CDialogChild2)。
整個工程的框架已經設計好了,在對話框A和對話框B上放置了許多控件,現在我想實現這樣一種功能(當然,好像好多人都想實現這種功能),當單擊對話框A中的一個按鈕控件時,對話框B中的一個按鈕處於不可用狀態,再單擊一下,則變為可用。
要實現這種功能,關鍵在於使得對話框A中可以找到指向對話框B的指針,這樣才能找到對應的按鈕。
實現方法如下(在不使用全局變量的前提下):
(1)在CDialogChild1中單擊右鍵,添加一個CDialogChild2*類型的對話框指針變量,記為MyDlg2,訪問類型為public;
(2)找到CTMDDDlg類,在相應的OnInitDialog()函數中添加以下代碼:
BOOL CTMTDDDlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here TCITEM item; item.mask = TCIF_TEXT; item.pszText = "A"; m_TabCtrl.InsertItem (0,&item); item.pszText = "B"; m_TabCtrl.InsertItem (1,&item); m_Tab1.Create (IDD_DIALOG1,&m_TabCtrl); m_Tab2.Create (IDD_DIALOG2,&m_TabCtrl); m_Tab1.m_MyDlg2 = &m_Tab2; //以下設置使得初始化狀態顯示第一頁標簽頁 CRect r;//客戶窗口的坐標 m_TabCtrl.GetClientRect (&r); m_Tab1.SetWindowPos (NULL,10,20,r.right -20,r.bottom -40,SWP_SHOWWINDOW); m_Tab2.SetWindowPos (NULL,10,20,r.right -20,r.bottom -40,SWP_HIDEWINDOW ); return TRUE; // return TRUE unless you set the focus to a control }
注意,上面的 m_Tab1.m_MyDlg2 = &m_Tab2; 這行代碼是我們新添加的,
原來的OnInitDialog()函數中的代碼是為了實現標簽控件且初始化兩個對話框的(m_Tab1和m_Tab2分別是對話框A和對話框B所對應的對話框控件變量)。
注意,這里要添加的一行代碼必須放在m_Tab1和m_Tab2實例化之后,即Create函數之后
(3)有了m_MyDlg2指針后,我們就可以很隨意地在對話框類CDialogChild1中訪問對話框CDialogChild2中的成員變量了:
m_MyDlg1->GetDlgItem(IDC_BTN_A)->EnableWindow(); 呵呵,而最開心的事情是這里沒有用到全局變量。
2.以上方法的確可以解決我所遇到的問題,不過后來經過嘗試,又有了以下方法:(兩個類中均有其父類指針變量,通過父類指針訪問-》子類變量.子類成員函數)
(1)首先在對話框A和B中分別添加一個成員變量 CTMTDDDlg* m_MyDlg
(2)在OnInitDialog()當中添加以下代碼:
m_Tab1.m_MyDlg = this;
m_Tab2.m_MyDlg = this;
注意,以上代碼仍然添加在m_Tab1和m_Tab2生成之后
(3)有了m_MyDlg指針之后,我們就可以在對話框CDialogChild1和對話框CDialogChild2中使用m_MyDlg來訪問它的成員變量m_Tab1和m_Tab2,從而訪問它們的成員控件了:
m_MyDlg->m_Tab2.GetDlgItem(IDC_CHECK_A)->EnableWindow();
或者 m_MyDlg->m_Tab1.GetDlgItem(IDC_CHECK_A)->EnableWindow();
3.
現在介紹第三種方法,也是最簡單的方法,
使用GetParentOwner()來獲取該子窗口的擁有(owner)窗口的指針,然后訪問另外一個子窗口,比如在對話框A的cpp文件中加入以下代碼: ((CTMTDDDlg*)GetParentOwner())->m_Tab2.GetDlgItem(IDC_CHECK_A)->EnableWindow();
//由於GetParentOwner()返回的是一個CWnd類型的指針,需要進行強制轉換 這樣以來就可以實現我們需要的功能了。