Datenaustausch zw. verschiedenen Dialogfenstern [MFC]

Xcalibur

Grünschnabel
hy!

ich hab eine SDI-Anwendung mit dem MFC-Assistenten erstellt.Die Ansicht ist abgeleitet von CFormView und dient bei mir nur zum AUfrufen anderer Dialogfenster, über die dann z.b. Daten eingegeben, bearbeitet usw. werden können.

Ich hab bis jetzt 2 Dialoge, einen zum Daten eingeben und einen, der ein ListControl-Feld enthält, in dem die eingegbenen Daten erscheinen sollen.

Mein Problem ist jetzt aber, wie ich aus dem 1. Dialog (zum Daten eingeben) auf die Steuerelemente des anderen Dialogs zugreifen kann?

Probier da jetzt schon seit gestern mittag alle möglichkeiten aus, die mir einfallenb, aber ich kriegs nich hin :(

hab auch versucht objekte der klassen global zu deklarieren, funktioniert nicht :(

ich hoffe ihr könnt mir helfen, das problem hab ich immer wieder wenn ich ein programm schreiben will...

danke schonmal und ciao
 
Hi,

generell hat ein Dialog bei den Membervariablen eines anderen Dialos nix zu suchen (OOP - Kapselung!); ich für meinen Teil mache die Membervariablen IMMER private. Das erklärt allerdings Dein Problem nicht, sondern verschärft es...

Grundsätzlich sind Dialoge für mich "Dumme Kisten", die nix wissen außer dass sie leben (und selbst da bin ich mir manchmal nicht sicher...) Den Austausch zwischen verschiedenen Boxen mache ich normalerweise über die "darüberliegende" Klasse (z.B. das Hauptfenster, das beide Dialoge erzeugt - der holt sich die Daten über Memberfunktionen aus einem Dialog und stellt sie mit Memberfunktionen in den anderen Dialog).

Alles in allem ist das Vorgehen aber eine "Ermessensfrage" und eher philosophisch zu betrachten...

G.
 
hy!

danke für deine antwort!

bei den MFC bekommt ja jeder neu erstellte Dialog automatisch seine eigne Header- und Quellcodatei, deswegwen ist das mit der Verwaltung vom Hauptfenster aus auch nicht so einfach, weil ich ja von dort aus auch nicht auf die Variablen zugreifen kann,oder?

ich habs bis jetzt folgendermaßen gelöst:

ich deklarier in der .cpp datei des einen dialogs globale Variablen, die mit den Daten aus den Editfeldern gefüllt werden.
Diese globalen Variablen ruf ich dann über extern in der .cpp des andern Dialogs auf und deklarier nen pointer, der auf die adresse dieser externen Variable zeigt.

Ist das ok so? Oder gibts irgendwelche Probleme damit, schlechter Stil oder sonst was?
Bin grad erst dabei, das Lesen der Daten zu implementieren, das funktioniert (bis jetzt zumindest ;) ) ziemlich gut

Da fällt mir grad ein, eigentlich wärs besser wenn ich die globalen variablen in der ersten .cpp durch pointer auf die editfelder ersetz, besonders im hinblick aufs daten in die editfelder schreiben(und noch dazu würd ich mir ne initalisierung sparen).

ciao
 
Hi,

jetzt wird's philosophisch...

ich habe zu lange OOP unterrichtet als dass ich mich über die "Gesetze" hinwegsetzen kann. Globale Variablen lehne ich z.B. strikt ab, weil sie bei zunehmender Größe des Programms leicht zu unauffindbaren Fehlern führen; die quasi unmögliche Wiederverwendung ist das nächste Problem.
Nur als Anfrage: Kennst Du "Getter" und "Setter"? Du kannst sehr wohl auf Variablen "darunterliegender" Klassen zugreifen, wenn diese den Zugriff über Getter und Setter erlauben (also Funktionen, die nichts anderes tun als "Variable schreiben" und "Variable lesen") - damit bleibt die Kapselung erhalten und globale Variablen sind auch nicht nötig.

Aber nochmal. das fällt für mich schon unter Programmier-Philosophie...

G.
 
ich bin noch anfänger und hab deshalb auch noch keine richtige philosophie ;)

Set bzw. Get-Methoden (ich denk mal, dass du die meinst?!) kenn ich natürlich schon, aber ich kenn leider keine mit der ich die Steuerelemente eines Dialogs verändern kann.

Ich ruf meine Dialogfenster mit folgendem Aufruf ausm Hauptfenster auf:

Code:
// AddItem ist ein von CDialog abgeleitetes Dialogfenster

AddItem dlg;
dlg.DoModal();

Da ich im Hauptdialog dann ja nur "dlg" von dem neuen dialog hab, muss es da ja irgendeine methode geben, mit der ich die steuerelemtne beeinflussen kann. hab sie mir mal durchgeschaut, aber leider keine gefunden.
Da mir die Idee mit dem Set und Get und dem daten verwalten im Hauptfenster (ggf. eigene Klasse) gut gefällt, würd ich gerne wissen wie das funktioniert.

Kannst du mir ne Funktion bzw. Codeschnipsel geben?

€: hab die Set/GetDlgItemText ´funktionen gefunden, mal ausprobieren :)

ciao
 
Zuletzt bearbeitet:
Du wirst keine Get/Set-Methoden finden, weil Du die selbst schreiben musst... :)

Die Idee dahinter ist einfach, dass Du nicht direkt auf Membervariablen zugreifst, weil das Änderungen erschwert und das Finden von Fehlern in größeren Projekten fast unmöglich macht.

Als kleines Beispiel (ungetestet, d.h. direkt hier reingeschrieben):

Gegeben sei eine Dialogbox, die in einem Edit-Element (m_Edit) einen Text anzeigt, der von "irgendwoher" gesetzt werden können soll. Dann könntest Du in der Dialogbox-Klasse folgende Funktion einbauen:

class CMyDialog
{
public:
void SetText(const char *str) {m_Edit.SetWindowText(str);}
// ...
};

Die Funktion kannst Du dann jederzeit von irgendwoher aufrufen:

CMyDialog dlg;
// Erzeugung etc.
dlg.SetText("Hallo");

An dem Beispiel ist auch ganz gut erkennbar, was die Kapselung auf längere Sicht bringt: Sollte sich die Darstellung einmal ändern und nicht mehr in einem Edit-Element angezeigt werden, musst Du nur die SetText()-Funktion ändern und nicht alle Zugriffe auf die Variable, die im Programm vorkommen.

Hoffe, das hilft. Wenn nicht, melde Dich einfach.

G.
 
danke für den tipp!

habs kurz ausprobiert und funktioniert wunderbar ;)
muss jetzt leider in die schule bis halb 6, danach werd ich mich dann wieder dransetzen und mich dann nochmal melden...


ciao

p.s.: hast du icq oder bist du in irgendeinem IRC-Chan öfters anzutreffen?
wenn ja, schicks mir deine UIN oder den Chan+Network mal per PN... danke :)
 
Sybaris hat gesagt.:
Du wirst keine Get/Set-Methoden finden, weil Du die selbst schreiben musst... :)

Die Idee dahinter ist einfach, dass Du nicht direkt auf Membervariablen zugreifst, weil das Änderungen erschwert und das Finden von Fehlern in größeren Projekten fast unmöglich macht.

Als kleines Beispiel (ungetestet, d.h. direkt hier reingeschrieben):

Gegeben sei eine Dialogbox, die in einem Edit-Element (m_Edit) einen Text anzeigt, der von "irgendwoher" gesetzt werden können soll. Dann könntest Du in der Dialogbox-Klasse folgende Funktion einbauen:

class CMyDialog
{
public:
void SetText(const char *str) {m_Edit.SetWindowText(str);}
// ...
};

Die Funktion kannst Du dann jederzeit von irgendwoher aufrufen:

CMyDialog dlg;
// Erzeugung etc.
dlg.SetText("Hallo");

An dem Beispiel ist auch ganz gut erkennbar, was die Kapselung auf längere Sicht bringt: Sollte sich die Darstellung einmal ändern und nicht mehr in einem Edit-Element angezeigt werden, musst Du nur die SetText()-Funktion ändern und nicht alle Zugriffe auf die Variable, die im Programm vorkommen.

Hoffe, das hilft. Wenn nicht, melde Dich einfach.

G.


Hallo
in mein Program funktioniert es nicht :confused:
Ich habe ein TabCtrl mit zwei Unergeondete nicht Modale Dialogs mit jeweils eine Klasse CSeite1 und CSeite2
1. Ich habe in CSeite2 ein CEdit m_Edit;
2. in CSeite2 habe ich die Methode SetText definiert und deklariert
3. auf der CSeite1 versuche ich mit dem Aufruf der Methode mit ein Button und gebe ein String und bekomme diese Fehler:

Debug Aserrtion Faild:
Line 229

Bitte um Hilfe
 
Hi,
was steht denn in Line 229?
Wie hast du denn dein Tab-Ctr erzeugt?
Wenn du dein Tab-Control von PropertySheet/PropertyPage abgeleitet hast, funktioniert die Datenübergabe etwas anders. Du mußt dir aus der Seite, von der du auf eine andere zugreifen willst, mit
Code:
CPropertySheet* mySheet=GetParent();
einen Zeiger auf das PropertySheet holen. Von dort bekommst du mit
Code:
CPropertyPage*myPage=mySheet.GetPage(int nPage);
einen Zeiger auf die gewünschte Seite und kannst dann den Austausch durchführen.

Mfg

langer
 
Danke fur deine Hilfe!

Ich habe Folgendes meine TabCtrl und Dialogs erzeugt:

1. erst habe ich Dialog mit MFC erstellt diese hat folgned einstellung:
a1. IDD_BIT_DIALOG
b1. Still "Kontextmenu"
c1. Sichtbar
2. dann habe ich aus der Steuerelment Leiste ein TabCtrl über den Dialog gezogen
a2. IDC_TAB1
b2. Sichtba, Tapstop, Gruppe, HifID sind True
c2. Eine member variable mit Klassenassistent erstellt DynTabCtrl m_dynTabCtrl;
d2. aus dem Netz die Datei DynTabCtrl inclusive header runtergeladen und an den Project gehängt.
3. Dann zwei Dialos mit folgende einstellung erstellt: Beide sind nicht modal
a3.IDD_SEITE1 und IDD_SEITE2
b3. Still "Untergeornet"
c3. Rand "Keine"

Dialodsklassen werden mit jeweils CSeite1 und CSeite2 erstellt
so erzeuge ich mein Dialogs:
Code:
BOOL CBITDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Hinzufügen des Menübefehls "Info..." zum Systemmenü.

	// IDM_ABOUTBOX muss sich im Bereich der Systembefehle befinden.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{	
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Symbol für dieses Dialogfeld festlegen. Wird automatisch erledigt
	//  wenn das Hauptfenster der Anwendung kein Dialogfeld ist
	SetIcon(m_hIcon, TRUE);			// Großes Symbol verwenden
	SetIcon(m_hIcon, FALSE);		// Kleines Symbol verwenden
	
	// ZU ERLEDIGEN: Hier zusätzliche Initialisierung einfügen
	m_pDlg1 = new CSeite1();
	m_pDlg2 = new CSeite2();
	m_dynTabCtrl.InsertItem(m_pDlg1,"Search", IDD_SEITE1);
	m_dynTabCtrl.InsertItem(m_pDlg2,"Connection", IDD_SEITE2);

	return FALSE;  // Geben Sie TRUE zurück, außer ein Steuerelement soll den Fokus erhalten
}

in der Dialogs Klasse habe ich ein Pointer definiert:

Header von CSeite1

Code:
class CSeite1 : public CDialog
{
// Konstruktion
public:
	CSeite1(CWnd* pParent = NULL);   // Standardkonstruktor

// Dialogfelddaten
	//{{AFX_DATA(CSeite1)
	enum { IDD = IDD_SEITE1 };
	CListCtrl	m_cListCtrl;
	CButton	m_Search;
	CButton	m_LoadButton;
	CString	m_EditOpen1;
	CButton	m_Radio1;
	CString	m_EditOpen2;
	CString	m_sResults;
	CString	m_cSearch;
	//}}AFX_DATA


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

// Implementierung
protected:

	// Generierte Nachrichtenzuordnungsfunktionen
	//{{AFX_MSG(CSeite1)
	afx_msg void OnRadio1();
	afx_msg void OnRadio2();
	afx_msg void OnFileopen1();
	afx_msg void OnFileopen2();
	afx_msg void OnSelectbutton();
	afx_msg void OnChangeEdit1();
	afx_msg void OnChangeEdit2();
	virtual BOOL OnInitDialog();
	afx_msg void OnLoad();
	afx_msg void OnChangeSearchEdit();
	afx_msg void OnGo();
	virtual void OnOK();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
private:
	CSeite2* Dlg2;
	CWnd* m_pParentDlg1;
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein.

#endif // AFX_SEITE1_H__15FFF85D_5C78_427B_9A2D_87FEFBB3A8E4__INCLUDED_

Header von CSeite2

Code:
#if !defined(AFX_SEITE2_H__F3427A06_AA5A_4A9D_BD46_707718AA7BAD__INCLUDED_)
#define AFX_SEITE2_H__F3427A06_AA5A_4A9D_BD46_707718AA7BAD__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Seite2.h : Header-Datei
//

/////////////////////////////////////////////////////////////////////////////
// Dialogfeld CSeite2 

class CSeite2 : public CDialog
{
// Konstruktion
public:
	void SetText(const char *str);
	CSeite2(CWnd* pParent = NULL);   // Standardkonstruktor

// Dialogfelddaten
	//{{AFX_DATA(CSeite2)
	enum { IDD = IDD_SEITE2 };
	CEdit	m_Edit;
	CString	m_Edit1;
	//}}AFX_DATA


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

// Implementierung
protected:

	// Generierte Nachrichtenzuordnungsfunktionen
	//{{AFX_MSG(CSeite2)
	afx_msg void OnUpdateEdit1();
	afx_msg void OnChangeEdit1();
	virtual BOOL OnInitDialog();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
private:
	CWnd* m_pParentDlg2;
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein.

#endif // AFX_SEITE2_H__F3427A06_AA5A_4A9D_BD46_707718AA7BAD__INCLUDED_

um dein vorherige Tip zu testen habe ich nach dein Vorgabe gehadelt
ich habe eine OK Button auf der Seite1 erzeugt und wenn ich darauf drücke wir SetText in CSeite2 aufgerufen

Code:
void CSeite1::OnOK() 
{
	// TODO: Zusätzliche Prüfung hier einfügen
	
	CSeite2* dlg2 = new CSeite2();
	dlg2->SetText("Connection12");
	CDialog::OnOK();

}

Implementierung in CSeite2

void CSeite2::SetText(const char *str)
{
m_Edit.SetWindowText(str);
m_Edit1 = str;
// wenn ich hier UpdateData(...) aurufen bekommer ich weitere Assertion
}

Fehlermeldungen:

HTML:
eladene Symbole für "C:\Dokumente und Einstellungen\Hamid\Desktop\BIT\Debug\BIT.exe"
"C:\WINDOWS\system32\ntdll.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
"C:\WINDOWS\system32\kernel32.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
Geladene Symbole für "C:\WINDOWS\system32\MFC42D.DLL"
Geladene Symbole für "C:\WINDOWS\system32\MSVCRTD.DLL"
"C:\WINDOWS\system32\gdi32.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
"C:\WINDOWS\system32\user32.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
"C:\WINDOWS\system32\advapi32.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
"C:\WINDOWS\system32\rpcrt4.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
Geladene Symbole für "C:\WINDOWS\system32\MFCO42D.DLL"
Geladene Symbole für "C:\WINDOWS\system32\MSVCP60D.DLL"
"C:\WINDOWS\system32\mfc42loc.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
"C:\WINDOWS\system32\comctl32.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
"C:\WINDOWS\system32\uxtheme.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
"C:\WINDOWS\system32\msvcrt.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
"C:\WINDOWS\system32\msctf.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
"C:\WINDOWS\system32\SynTPFcs.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
"C:\WINDOWS\system32\version.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
"C:\WINDOWS\system32\shlwapi.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
"C:\WINDOWS\system32\apphelp.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
Thread 0xFA4 wurde mit Code 0 (0x0) beendet.
Thread 0x730 wurde mit Code -1073741819 (0xC0000005) beendet.
Das Programm "C:\Dokumente und Einstellungen\Hamid\Desktop\BIT\Debug\BIT.exe" wurde mit  Code -1073741819 (0xC0000005) beendet.

Ich höffe mit diese Information kann man heraus finden was ich nicht richtig mache :(

mfg. Drei
 
Zuletzt bearbeitet:
Zurück