Kommunikation zwischen CView und nichtmodalen Dialog

mogul1983

Grünschnabel
Ich habe folgendes Problem:

Ich möchte aus einem nicht modalen Dialog Werte an die Ansichtsklasse schicken. Nach langem suchen und probieren bin ich noch immer nicht auf einen grünen Zweig gekommen. Ich habe schon versucht Nachrichten mit SendMessage() an die Ansichtsklasse zu schicken was aber nicht funktioniert hat. Jetzt habe ich ich es wie unten beschrieben probiert, aber das funktioniert auch nicht.

Ich habe meiner Ansichtsklasse CtestView einen Zeiger des Typs CNoModal (nicht modales Fenster) spendiert und dann in OnInitialUpdate mit new initialisiert:


Code:
CtestView.h:

class CNoModal;

class CtestView : public CFormView
{
	CNoModal *dlg;
protected:
....
}

.cpp
...
void CtestView::OnInitialUpdate()
{
	
	CFormView::OnInitialUpdate();
	GetParentFrame()->RecalcLayout();
	ResizeParentToFit();
	
        dlg = new CNoModal;

}
...
void CtestView::OnDlg() 
{
	UpdateData(TRUE);
	dlg->m_zahl=this->m_zahl;                 //Aktuellen Wert dem Dialog mitteilen
	dlg->Create(IDD_NOMODAL,NULL);
}

Mit OnDlg() wird das drücken eines Buttons abgearbeitet. Darin erzeuge ich den Dialog mit Creat. Was auch alles super klappt.

Jetzt zu meinem nicht modalen Dialog. Hier habe ich einen Variable der Ansichtsklasse definiert um dann einen Zeiger auf diese zu haben.

Code:
// NoModal.h : Header-Datei
//

/////////////////////////////////////////////////////////////////////////////
// Dialogfeld CNoModal
class CtestView; 

class CNoModal : public CDialog
{
// Konstruktion
public:
	CNoModal(CWnd* pParent = NULL);   // Standardkonstruktor
	CtestView *m_pView;
	OnInitDialog();

// Dialogfelddaten
	//{{AFX_DATA(CNoModal)
	enum { IDD = IDD_NOMODAL };
	int		m_zahl;
	//}}AFX_DATA


// Überschreibungen
	// Vom Klassen-Assistenten generierte virtuelle Funktionsüberschreibungen
	//{{AFX_VIRTUAL(CNoModal)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV-Unterstützung
	//}}AFX_VIRTUAL

// Implementierung
protected:

	// Generierte Nachrichtenzuordnungsfunktionen
	//{{AFX_MSG(CNoModal)
	afx_msg void OnApply();
	afx_msg void OnNehme();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

***************************************************************************************

// NoModal.cpp: Implementierungsdatei
//

#include "stdafx.h"
#include "Dialogetest.h"
#include "NoModal.h"
#include "MainFrm.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// Dialogfeld CNoModal 


CNoModal::CNoModal(CWnd* pParent /*=NULL*/)
	: CDialog(CNoModal::IDD, pParent)
{	
	//{{AFX_DATA_INIT(CNoModal)
	m_zahl = 0;
	//}}AFX_DATA_INIT
	m_pView = NULL;
}


CNoModal::OnInitDialog()
{
	CMainFrame* pMainFrame=(CMainFrame*)GetParentFrame();
	m_pView= (CtestView*)pMainFrame->GetActiveView();
	UpdateData(FALSE);
}

void CNoModal::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CNoModal)
	DDX_Text(pDX, IDC_ZAHL, m_zahl);
	DDV_MinMaxInt(pDX, m_zahl, 0, 10);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CNoModal, CDialog)
	//{{AFX_MSG_MAP(CNoModal)
	ON_BN_CLICKED(IDC_NEHME, OnNehme)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// Behandlungsroutinen für Nachrichten CNoModal 

void CNoModal::OnNehme() 
{
        UpdateData(TRUE);
	m_pView->m_zahl=m_zahl; Hier

}

OnNehme() wird wieder durch einen Buttonklick aufgerufen.

Jetzt sagt mir der Compiler an der Stelle Hier:
error C2027:Verwendung des undefinierten Typs "CtestView"
Siehe Deklaration von 'CtestView'

Ich komme einfach nicht weiter. Ist diese Methode der Kommunikation zwischen Ansicht und nicht modalen Dialog richtig? Wie kann ich den Programmierfehler beheben? Gibt es eine bessere Möglichkeit diese Kommunikation zu lösen?

Für Verbesserungen und Vorschläge bin offen.

Ich hoffe es kann mir jemand bei diesem Problem helfen.

Mfg mogul

[EDIT] Habe die falsche Klassenbezeichnung abgeändert
 
Zuletzt bearbeitet:
Hallo,

mich verwirrt etwas die Verwendung der zwei Klassenbezeichnungen "CDialogetestView" und "CtestView". Könntest du das mal genauer erklären?

Gruß
MCoder
 
Hi,

Leider sagt der gepostete Code nicht viel über die Klassen aus.
Mir fallen aber zwei Dinge auf:
1. in der DialogetestView.cpp solltest du die TestView.h includieren. Woher soll der Compiler sonst wissen, worum es sich handelt? Dann sollte der Fehler ausgeräumt sein.
2. Du rufst Create mit dem Standard-Konstruktor auf. Woher soll der Dialog einen gültigen Zeiger auf die View des Parent bekommen? Du solltest nach der Erzeugung des Dialogs einen Zeiger auf das Parent-Fenster holen und darüber einen Zeiger auf dessen View.

Mfg

langer
 
Sorry das mit der CDialogetestView ist falsch. Also ich habe den Klassennamen für den Post hier nur abgeändert. CDialogetestView == CtestView :)

Das Programm lässt sich ja auch übersetzten wenn ich die Zeile
Code:
m_pView->m_zahl=m_zahl;
weg lasse.

@langer1801:

Dein zweiter Punkt hört sich nach dem richtigen Weg an. Aber wie mache ich das:

Du solltest nach der Erzeugung des Dialogs einen Zeiger auf das Parent-Fenster holen und darüber einen Zeiger auf dessen View.

Danke schön schon mal im Vorraus
 
Hi,

dass sich das Programm übersetzen laßt, wenn du die Zeile wegläßt, ist klar. Wenn du aber wie geschrieben die Header-Datei der View includierst, sollte es auch mit der Zeile gehen.

Und einen gültigen Zeiger kannst du erhalten, indem du OnInitDialog überschreibst:
Code:
CNoModal::OnInitDialog()
{
	CMainFrame* pMainFrame=(CMainFrame*)GetParentFrame();
	m_pView=(CTestView*)pMainFrame->GetActiveView();
}

Mfg

langer
 
Also ich habe jetzt die OnInitDialog überschieben und die Definition auch in die NoModal.h geschieben. Aber jetzt kommt der Fehler:

Verwendung des undefinierten Typs "CMainFrame".

PS: Die Headerdatei TestView.h ist auch schon über TestView.cpp eigefügt. Das macht ja schon der Assistent.
 
Zuletzt bearbeitet:
Hi, wenn du eine andere Klasse in deiner Klasse verwendest, mußt du dem Compiler diese bekannt machen, indem du deren Header includierst.
Also mußt du in NoModal.cpp
Code:
#include "MainFrm.h"
einfügen.

Mfg

langer
 
Okay da hätte ich auch selbst drauf kommen können.

Jetzt habe ich aber wieder das selbe Problem wie am Anfang:

error C2027: Verwendung des undefinierten Typs "CDialogetestView"

auch wieder an der selben Stelle hier:
Code:
m_pView->m_zahl=m_zahl;

Ich habe oben mal den Quelltext vollständig gepostet. Vielleicht liegt ja wo anderst der Fehler.

Gibt es vielleicht eine bessere Lösung für nicht modale Dialoge?
 
Hi,

diese Header hast du in deine NoModal.cpp eingebunden:
Code:
#include "stdafx.h"
#include "Dialogetest.h"
#include "NoModal.h"
#include "MainFrm.h"

Es fehlt also der Header DialogetestView.h, deshalb meckert der Compiler. Allerdings hätte ich eher auf die Fehlermeldung "undefinierter Typ CTestView" getippt, da ich in deinem Quelltext keine Klasse CDialogetestView sehen kann. Ich würde deshalb
Code:
#include "TestView.h"
einfügen.

Und eine andere Methode, nichtmodale Dialoge zu erzeugen, gibt es nicht. Allerdings kannst du nichtmodale Dialoge nur über den Standard-Konstruktor erzeugen, deine selbst definierten Konstruktoren können nicht funktionieren, da du da nicht auf das Template zugreifst. Und dir Kommunikation mit dem Eltern-Fenster erfolgt eben über den Zeiger auf das Eltern-Fenster (MainFrm) und von da in die gewünschte Klasse.

Mfg

langer
 
Zurück