MFC: PropertySheet Datenaustausch zwischen zwei tabs



  • Hi,
    also ich hab eine propertypage(x) mit einem button, wenn man klickt öffnet sich ein neues propsheet mit 2 proppages.
    Die Daten von den den 2 proppages zu übernehmen is kein problem
    das mach ich halt in der funktion vom button(auf der propage(x)),
    mit if(propertySheet_1.DoModal() == IDOK).

    Aber wie kann ich jetz zwischen den zwei propertypages daten übergeben, während das propertysheet mit den zwei pages(2tabs) geöffnet ist? Das Objekt der Klasse wird ja in der klasse der (x) page erzeugt und in den anderen klassen kann ich ja nicht drauf zugreifen.

    Wenn ich das neuerzeugte propertysheet schließe wird ja die (propertySheet_1.DoModal() == IDOK) aufgerufen. Also wenn ich es schließe und neu öffne kann ich die daten übergeben aber halt nicht zwischendrin.

    kann ich da nicht if(propertySheet_1.m_Tab1.OnSelchangeCombo1()==true) machen oder so, halt ne abfrage ob etwas geändert wurde?
    Oder gibt es eine möglichkeit von einer anderen klasse auf das objekt zuzugreifen und die daten zu übergeben?

    MFG Peter


  • Administrator

    Also ich habe es nun 3 mal durchgelesen und verstehe es immer noch nicht zu 100% was du willst. Aber mal schauen:

    Du hast zwei Dialogs? Dialog1 und Dialog2. In Dialog1 erstellst du, wenn man auf einen Button klickt, Dialog2 und führst diesen Dialog2 per DoModal aus. Du willst nun während Dialog2 läuft auf Dialog1 zugreifen? Dann übergib doch Dialog2 einen Zeiger auf Dialog1 bevor du DoModal aufrufst. Dann kannst du zur Laufzeit von Dialog2 auf Dialog1 zugreifen. Wo liegt da ein Problem?

    Oder versteh ich was falsch?
    Grüssli



  • Du hast zwei Dialogs? Dialog1 und Dialog2. In Dialog1 erstellst du, wenn man auf einen Button klickt, Dialog2 und führst diesen Dialog2 per DoModal aus.

    Richtig

    Du willst nun während Dialog2 läuft auf Dialog1 zugreifen?

    Falsch.
    In Dialog2 besteht aus 2 tabs also registern und ich möchte im 1. tab was eintragen und wenn ich dann das 2. tab öffne (alles im 2.dialog) sollen daten aus dem 1.tab übernommen werden, das funktioniert aber erst wenn ich dialog2 mit ok schließe und im dialog 1 den 2. dialog erneut mit dem button aufrufe


  • Administrator

    Das sollte doch kein Problem sein. Du hast ja sicherlich ein Code von dieser Art beim ButtonClick:

    CPropertySheet Sheet("Irgendwas");
    CTab1 Tabdlg1;
    CTab2 Tabdlg2;
    
    // Hier kannst du doch einen Zeiger von Tabdlg1 an Tabdlg2 geben.
    Tabdlg2.SetPointer(&Tabdlg1);
    
    Sheet.AddPage(&Tabdlg1);
    Sheet.AddPage(&Tabdlg2);
    

    Die Funktionen und Namen sind natürlich frei erfunden. Und nun musst du halt nur noch in der CTab2 Klasse einen Behandlungscode einführen, wenn der Dialog aktiviert wird.

    Ich kenne mich jetzt zu wenig aus mit CPropertyPage, dass ich es auswendig sagen könnte, aber es gibt sicher irgendeine Message, welche aufgerufen wird, wenn der Dialog aktiviert wird. Und wenn es keine eigene hat, probier es halt mal mit WM_ACTIVATE oder sowas.

    Grüssli



  • Also jetzt mal anders:
    Ich hab eine dialogbasierende anwendung erstellt und hab in den Header- und Source-Dateien des Dialogs "CDialog" durch "CPropertySheet" ersetzt.
    Und hab Klassen, von CPropertyPage abgeleitet, ersteltt für jedes Dialogfeld und
    dort Membervariablen zugewiesen z.B. CWelcome,CPruef oder CNoten. Das PropertySheet wird im Wizard-Modus verwendet.

    dlg.h

    class CAbirechnerDlg : public CPropertySheet								//CDialog ersetzt duech CPropertySheet
    {
    // Konstruktion
    public:
    	CAbirechnerDlg(CWnd* pParent = NULL);	// Standard-Konstruktor
    	//Konstruktion von Objekten der PropertyPages//
    	CWelcome page1;
    	CPruef page2;
    	CNoten page3;
    

    dlg.cpp

    CAbirechnerDlg::CAbirechnerDlg(CWnd* pParent /*=NULL*/)
    	: CPropertySheet()	//Parameter der Elternklassen-Initialisierung geändert(CDialog->CPropertySheet())
    {
    	//{{AFX_DATA_INIT(CAbirechnerDlg)
    		// HINWEIS: Der Klassenassistent fügt hier Member-Initialisierung ein
    	//}}AFX_DATA_INIT
    	// Beachten Sie, dass LoadIcon unter Win32 keinen nachfolgenden DestroyIcon-Aufruf benötigt
    	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
        AddPage(&page1);
    	AddPage(&page2);
    	AddPage(&page3);
    	AddPage(&page4);
    	AddPage(&page5);
    	AddPage(&page6);
    	SetWizardMode();
    }
    

    Das Sind halt 6Seiten die man mit "weiter" durchschalten kann.
    wenn ich auf der 1. Seite(CWelcome) etwas eintrage, soll das auf der 2. Seite angezeigt werden(CPruef).

    Die Objekte der Klassen CWelcome und CPruef werden ja in der C...Dlg (s.o.)
    erstellt und ich möchte wenn ich die 2.seite anzeige (mich also in der Klasse CPruef und nicht C...Dlg befinde) auf die Werte, der in C...Dlg erstellten Objekte zugreifen.

    Also wie kann ich Daten bei PropertyPages austauschen, wenn diese nicht modal aufgerufen werden und in einer art wizard-modus verwendet werden?

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_core_property_sheets.3a_.exchanging_data.asp
    bringt mich ja nur weiter wenn ich ein propertysheet modal aufrufe


  • Administrator

    Ich weiss nicht wo dein Problem ist ... Ich habe oben die Lösung hingeschrieben. Ich habe es nun aber halt selber schnell gemacht. Nen 5 min Code hingeschrieben und getestet und funktioniert wunderbar. Ich poste mal meinen Code hier rein, damit vielleicht besser verstehst was ich meine:

    Ich habe halt nun keine Klasse von CPropertySheet abgeleitet, sondern sie einfach direkt genommen, kommt aber im Endeffet aufs gleiche hinaus.

    CPropertySheet cs("Title");
    CPageOne PageOne;
    CPageTwo PageTwo;
    
    PageTwo.SetPrevPage(&PageOne);
    
    cs.AddPage(&PageOne);
    cs.AddPage(&PageTwo);
    cs.SetWizardMode();
    cs.DoModal();
    

    CPageOne.h

    #pragma once
    
    // CPageOne dialog
    
    class CPageOne : public CPropertyPage
    {
    	DECLARE_DYNAMIC(CPageOne)
    
    public:
    	CPageOne();
    	virtual ~CPageOne();
    
    // Dialog Data
    	enum { IDD = IDD_PROPPAGE_ONE };
    
    protected:
    	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    
    	DECLARE_MESSAGE_MAP()
    private:
    	CString m_str;
    public:
    	virtual LRESULT OnWizardNext();
    	CString GetString() { return m_str; };
    };
    

    CPageOne.cpp

    // PageOne.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "testsplitter.h"
    #include "PageOne.h"
    #include ".\pageone.h"
    
    // CPageOne dialog
    
    IMPLEMENT_DYNAMIC(CPageOne, CPropertyPage)
    CPageOne::CPageOne()
    	: CPropertyPage(CPageOne::IDD)
    	, m_str(_T(""))
    {
    }
    
    CPageOne::~CPageOne()
    {
    }
    
    void CPageOne::DoDataExchange(CDataExchange* pDX)
    {
    	CPropertyPage::DoDataExchange(pDX);
    	DDX_Text(pDX, IDC_EDIT_INPUT, m_str);
    }
    
    BEGIN_MESSAGE_MAP(CPageOne, CPropertyPage)
    END_MESSAGE_MAP()
    
    // CPageOne message handlers
    
    LRESULT CPageOne::OnWizardNext()
    {
             // Überschriebene virtuelle Funktion.
    	UpdateData(TRUE);
    
    	return CPropertyPage::OnWizardNext();
    }
    

    CPageTwo.h

    #pragma once
    #include "PageOne.h"
    
    // CPageTwo dialog
    
    class CPageTwo : public CPropertyPage
    {
    	DECLARE_DYNAMIC(CPageTwo)
    
    public:
    	CPageTwo();
    	virtual ~CPageTwo();
    
    // Dialog Data
    	enum { IDD = IDD_PROPPAGE_TWO };
    
    protected:
    	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    
    	DECLARE_MESSAGE_MAP()
    private:
    	CString m_str;
    	CPageOne* m_pPageOne;
    
    public:
    	void SetPrevPage(CPageOne* pPage) { m_pPageOne = pPage; };
    	virtual BOOL OnSetActive();
    };
    

    CPageTwo.cpp

    // PageTwo.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "testsplitter.h"
    #include "PageTwo.h"
    #include ".\pagetwo.h"
    
    // CPageTwo dialog
    
    IMPLEMENT_DYNAMIC(CPageTwo, CPropertyPage)
    CPageTwo::CPageTwo()
    	: CPropertyPage(CPageTwo::IDD)
    	, m_str(_T(""))
    	, m_pPageOne(NULL)
    {
    }
    
    CPageTwo::~CPageTwo()
    {
    }
    
    void CPageTwo::DoDataExchange(CDataExchange* pDX)
    {
    	CPropertyPage::DoDataExchange(pDX);
    	DDX_Text(pDX, IDC_EDIT_OUTPUT, m_str);
    }
    
    BEGIN_MESSAGE_MAP(CPageTwo, CPropertyPage)
    END_MESSAGE_MAP()
    
    // CPageTwo message handlers
    
    BOOL CPageTwo::OnSetActive()
    {
             // Überschriebene virtuelle Funktion.
    	m_str = m_pPageOne->GetString();
    	UpdateData(FALSE);
    
    	return CPropertyPage::OnSetActive();
    }
    

    Und das funktioniert einwandfrei. Da ist ein Edit Feld im Ersten bereich, da gibt man was ein und da ist ein Edit Feld im zweiten Bereich. Wenn man in CPageOne auf Next klickt, dann wird beim CPageTwo die Eingabe ausgegeben.

    Und du kannst als Zeiger auch sonst irgend ein Dialog übergeben, dass doch scheiss egal. Du kannst auch den Pages einen Zeiger auf CPropertySheet übergeben um dessen Daten abzurufen. Ich weiss echt nicht was für ein Problem du hast. Das ist sowas von einfach. Du musst den einzelnen Seiten nur einen Zeiger übergeben auf die Klasse, in welchen die Objekte sind, welche du auf der Seite anzeigen willst.

    Hoffe ich konnte dir mit dem Code helfen.

    Grüssli



  • Danke!!!!!
    Das war ja eigentlich auch die erste idee mitm pointer auf die seite aber ich hab halt irgendwas falsch gemacht 😃
    Und mein Lehrer hat das auch nicht hinbekommen 😃
    Aber super das funktioniert wunderprächtig.


Anmelden zum Antworten