簡體   English   中英

MFC從對話框訪問FormView項目

[英]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);
}

有人可以幫助我嗎?

我可以在這里給您兩個答案:

  1. 如何執行您要問的事情(從無模式對話框訪問CFormView控件)
  2. 如何解決您的基本問題(將無模式對話框中的更改傳達給所有者視圖)

對於第一個,您必須在對話框類中聲明一個指向視圖的指針,並在視圖的構造函數中對其進行初始化:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM