[英]mfc access to formview item from dialog box
在我的SDI應用程序中,我需要了解這種行為。 單擊FormView上的按鈕后,將打開一個CDialog。 當我按下CDialog上的OK按鈕時,我調用FormView的函數。 我不想關閉CDialog。 我嘗試使用無模式對話框來做到這一點,但是當我從對話框調用formview函數時,我無法訪問formview的控件,就像它丟失了hwnd一樣。 錯誤是無法讀取m_hwnd的內存,而hwnd是???。 這是我的代碼:打開無模式對話框:
CCampiDlg *m_pDialog = NULL;
HWND hCampi = NULL;
// Invoking the Dialog
m_pDialog = new CCampiDlg;
if (m_pDialog != NULL)
{
BOOL ret = m_pDialog->Create(m_pDialog->IDD, this);
if (!ret) //Create failed.
{
AfxMessageBox(_T("Error creating Dialog"));
}
m_pDialog->ShowWindow(SW_SHOW);
}
當我在對話框中按確定按鈕時,我會執行以下操作:
CEditorTxView pView;
box2 = (CEdit*)(GetDlgItem(IDC_CAMPI_BOX2));
box2->GetWindowTextW(campo);
pView.inserisciCampo(1, campo);
在CEditorTxView(CFormView)的inserisciCampo函數中,我必須使用控件txtCtrl進行操作,但是丟失了hwnd。 txtCtrl的聲明在CEditorTxView.h中
CTx1 txtCtrl;
並在DoDataExchange函數中對其進行初始化:
void CEditorTxView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TX1, txtCtrl);
}
有人可以幫助我嗎?
我可以在這里給您兩個答案:
對於第一個,您必須在對話框類中聲明一個指向視圖的指針,並在視圖的構造函數中對其進行初始化:
class CCampiDlg : public CDialog
{
public:
CCampiDlg(CEditorTxView* pView, CWnd*pParent = NULL) // Change declaration to add pointer to view
: m_pView(pView)
{
}
// ... Whatever
private:
CEditorTxView* m_pView;
}
現在在您的按鈕處理程序中:
CEdit* box2 = (CEdit*)(GetDlgItem(IDC_CAMPI_BOX2)); // Why not use a control variable?
box2->GetWindowTextW(campo);
m_pView->inserisciCampo(1, campo);
這應該可以滿足您的要求。 但是, 這是錯誤的方法 。
這種方法的問題在於對話框對父級的了解太多。 它知道它的類型為CEditorTxView
,並且有一個名為inserisciCampo
的成員,該成員需要一個數字和一些文本。
它不應該那么了解。 實際上,除了了解CView甚至CWnd類型之外,對此一無所知。
如果對話框了解該視圖,則不能將該對話框與其他視圖一起使用,並且該視圖每次更改其表示方式(例如,現在的文本框將來可能是組合框)時,對話框都必須進行相應的更改。
解決方案是向父母發送消息,說明發生了什么。 然后,父級(視圖)應該知道如何處理該事件。 例如:
class CCampiDlg : public CDialog
{
public:
CCampiDlg(CWnd*pParent = NULL) {}
protected:
OnOk()
{
CString campo;
c_CampiBox2.GetWindowText(campo);
GetParent()->SendMessage(UWM_CAMPO2_SET, 0, (LPARAM)&campo);
}
}
在視圖中:
// It can be ON_REGISTERED_MESSAGE:
ON_MESSAGE(UWM_CAMPO2_SET, OnCampo2Set)
//...
LRESULT CEditorTxView::OnCampo2Set(WPARAM, LPARAM lParam)
{
CString* s = (CString*) lParam;
inserisciCampo(1, *campo);
return 0;
}
現在,您已經將視圖和對話框解耦了。 對話框對視圖一無所知。 您可以更改其類型,更改表示形式,甚至使其成為對話框,而不必在對話框中進行任何更改。 如果您在其他地方需要相同的無模式對話框,只需將其放到那里,在父級中創建一個消息處理程序,然后瞧瞧!
有關更多說明和更好的示例,請查看以下文章:
在確定按鈕上,單擊下面的代碼正在運行:
CEditorTxView pView;
box2 = (CEdit*)(GetDlgItem(IDC_CAMPI_BOX2));
box2->GetWindowTextW(campo);
pView.inserisciCampo(1, campo);
請注意,您正在堆棧中創建新的pView,它不與任何窗口連接。 您實際上並不是在引用已經創建並啟動了充當父級對話框的視圖。 重新查看上面的代碼並嘗試獲取視圖:
如果無法使用,請嘗試以下代碼(Google可以)
CFrameWnd * pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd);
CView * pView = pFrame->GetActiveView();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.