SetFocus() Problem?



  • abu abu abu

    gaaaaaaanz langsam *ggg*

    also das mit den 2 Header Datein könnte hinkommen

    die header datei, wo CTest drin deklariert ist, bindet die Header Datei von Pruefplaene ein

    und die Pruefplaene Header Datei bindet wieder die Header ein, wo CTest deklariert ist und demnach zufolge included sich die Pruefplaene Header Datei selber nochmal beim includen der anderen



  • Kurze Anmerkung zwischendurch: Schau mal da http://www.c-plusplus.net/forum/viewtopic-var-t-is-103523.html, vielleicht blickst du dann besser durch, warum das mit new nicht klappen konnte. 🙂



  • MSS-Software schrieb:

    die header datei, wo CTest drin deklariert ist, bindet die Header Datei von Pruefplaene ein

    und die Pruefplaene Header Datei bindet wieder die Header ein, wo CTest deklariert ist

    Das ist ein Problem. Die Include-Guards sorgen dafür, dass es nicht zu einer Endlos-Include-Rekursion kommt. Aber trotzdem steht hinterher zwangsläufig eine Klassendeklaration vor der anderen. Das kannst du nur durch eine Vorwärtsdeklaration einer der Klassen lösen.

    #include "pruefplaene.h"

    in test.h ersetzt du durch

    class Pruefplaene;

    Dafür schreibst du

    #include "pruefplaene.h"

    in test.cpp.



  • ja geil

    das wusste ich noch gar nicht

    danke

    compilieren tut er;

    aber jetzt kommt genau das, was du meintest mit der richtigen Instanz, er spuckt nämlich wieder Speicherfehler aus

    hab mir das Tut einen vorher auch grad durchgelesen; ja, is richtig, dass es dann auch nicht funzen kann;

    aber wie erkenn ich jetzt, welche die richtige Instanz ist??



  • MSS-Software schrieb:

    aber wie erkenn ich jetzt, welche die richtige Instanz ist??

    Das kannst du nur selbst wissen. Irgendwo in deinem Code erstellst du doch die Instanz von Pruefplaene, die das Fenster repräsentiert, auf das du zugreifen willst. Jetzt musst du den Zeiger in deiner Instanz von CTest auf die Adresse dieser Instanz von Pruefplaene setzen.



  • jo

    die wird in CAQDlg.h deklariert

    CDialog* Pruef_Auf;
    

    und in CAQDlg.cpp erstellt

    Pruef_Auf = new Pruefplan;
    Pruef_Auf->Create(IDD_Pruefplaene,NULL);
    Pruef_Auf->ShowWindow(SW_SHOW);
    

    somit habe ich jetzt in der Test.cpp folgendes gemacht

    #include "CAQDlg.h"
    
    Pruef_Auf = new Handle;
    Handle->pBoxOne->EnableWindow(FALSE);
    

    Daraufhin bekomme ich 103 Fehler und der erste ist, das Pruef_Auf nicht bekannt sein soll
    ->nicht deklarierter Bezeichner



  • MSS-Software schrieb:

    die wird in CAQDlg.h deklariert

    CDialog* Pruef_Auf;
    

    Ist das ein Member einer Klasse oder eine globale Variable?

    somit habe ich jetzt in der Test.cpp folgendes gemacht
    ...

    Pruef_Auf = new Handle;
    Handle->pBoxOne->EnableWindow(FALSE);
    

    Entscheide dich. Ist Handle ein Klassenname oder eine Variable? In der ersten Zeile benutzt du es als Klasse, in der zweiten als Zeiger. Es kann nicht beides sein.

    Zu welchem Zweck versuchst du da, eine neue Instanz zu erstellen?



  • zu 1:

    das ist eine Member

    zu 2:

    Handle soll die Instanz von CTest sein

    Wie du schon geschrieben hast, muss ich ja jetzt der Instanz von CTest die richtige Instanz von Pruefplaene zuweisen



  • MSS-Software schrieb:

    das ist eine Member

    Das heißt, die Adresse der "richtigen" Instanz von Pruefplaene ist ein Member einer anderen Klasse (ich vermute mal CAQDlg). Du musst diesen Zeiger (oder einen Zeiger oder eine Referenz auf die Instanz von CAQDlg, die diesen Zeiger beinhaltet) irgendwie dahin bringen, wo du die Instanz von CTest erstellst.

    Gibt es eigentlich irgendein System dahinter, welche Klasse einen Zeiger auf eine andere als Member hat? Ich vermute nämlich so langsam, dass du ein ernstes Designproblem hast. Oder gar kein Design.

    Handle soll die Instanz von CTest sein

    Ich dachte, pBoxOne wäre ein Member von Pruefplaene, nicht von CTest 😕



  • ich mach ma alles von vorne:

    Aufgabe: ich möchte, wenn ich eine Registerkarte klicke, sich ein Editfeld deaktiviert!

    Der Dialog, in dem sich die Registerkarten auch befinden, wird wie folgt aufgerufen:

    CAQDlg.h

    class CCAQDlg : public CDialog
    {
    // Konstruktion
    public:
    	CCAQDlg(CWnd* pParent = NULL);	// Standard-Konstruktor
    	CDialog* Pruef_Auf;
    

    CAQDlg.cpp

    #include "Pruefplaene.h"
    
    void CCAQDlg::OnStammdatenPrfplne() 
    {
    	// TODO: Code für Befehlsbehandlungsroutine hier einfügen
    	Pruef_Auf = new Pruefplaene;
    	Pruef_Auf->Create(IDD_Pruefplaene,NULL);
    	Pruef_Auf->ShowWindow(SW_SHOWNORMAL);
    }
    

    in der Header Datei, für den neuen Dialog, habe ich folgendes als Member gemacht:

    Pruefplaene.h

    CWnd* pBoxOne;
    

    das wird dann in der dazugehörigen cpp Datei bei OnInitDialog initialisiert

    Pruefplaene.cpp

    pBoxOne = GetDlgItem(IDC_Kundenname);
    

    so, da ich ja jetzt in die Klasse für die Registerkarten muss, habe ich bei der Header Datei dieser Klasse folgendes gemacht:

    TABPruefplaene.h

    class Pruefplaene;
    
    Pruefplaene* Handle; //Member
    

    und in der dazugehörigen cpp Datei dieses hier:

    TABPruefplaene.cpp

    #include "CAQDlg.h"
    #include "Pruefplaene.h"
    
    void CTABPruefplaene::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    	Handle = new Pruef_Auf;
    	Handle->pBoxOne->EnableWindow(FALSE);
    	CTabCtrl::OnLButtonDown(nFlags, point);
    	if (m_aktuelleSeite != GetCurFocus())
    	{
    		m_tabellenSeite[m_aktuelleSeite]->ShowWindow(SW_HIDE);
    		m_aktuelleSeite = GetCurFocus();
    		m_tabellenSeite[m_aktuelleSeite]->ShowWindow(SW_SHOW);
    		m_tabellenSeite[m_aktuelleSeite]->SetFocus();
    	}
    }
    


  • ich bin schon die ganze zeit am überlegen, wie ich auf diese instanz zugreife

    aber mir fällt bei gott nichts ein



  • kann man nicht die Instanz per Funktion übergeben?

    irgendwie so nach dem Motto:

    Pruef_Auf = new Pruefplaene;
    Pruef_Auf = Create(IDD_Pruefplaene);
    Pruef_Auf = ShowWindow(SW_SHOW);
    Uebergabe(Pruef_Auf);
    

    Und diese Funktion wäre dann in der CPP deklariert, wo ich die Instanz auch brauche.

    void Uebergabe (??? Instanz)
    {
         Handle = Pruef_Auf;    //Global deklariert in der CPP als Typ ???
    }
    

    Die ??? deshalb, weil ich noch nicht wirklich drüber nachgedacht habe, was das für ein Typ sein könnte.

    Im weiteren Programm würde ich das dann so anwenden:

    Handle.pBoxOne->EnableWindow(FALSE);
    

    Theoretisch möglich???



  • was für einen Datentyp müsste ich da denn nehmen?

    Also Pruef_Auf hat folgende deklaration:

    Pruefplaene Pruef_Auf; //Member in der Header
    
    Pruef_Auf = new Pruefplaene;
    


  • MSS-Software schrieb:

    was für einen Datentyp müsste ich da denn nehmen?
    Also Pruef_Auf hat folgende deklaration:

    Pruefplaene Pruef_Auf; //Member in der Header
    
    Pruef_Auf = new Pruefplaene;
    

    new gibt dir einen Zeiger zurück. Das sind aber absolute Grundlagen.

    MSS-Software schrieb:

    Pruef_Auf = new Pruefplaene;
    Pruef_Auf = Create(IDD_Pruefplaene);
    Pruef_Auf = ShowWindow(SW_SHOW);
    Uebergabe(Pruef_Auf);
    

    Und diese Funktion wäre dann in der CPP deklariert, wo ich die Instanz auch brauche.

    Existiert denn zu diesem Zeitpunkt schon die Instanz der Klasse, an die du den Zeiger übergeben musst?

    Dein Hauptproblem liegt nicht in der Organisation der .h und .cpp-Dateien und der Includedirektiven. Du konzentrierst deine Lösungsansätze darauf, was wo deklariert wird, und wer was includet. Dein Programm ist aber kein statisches Gebilde. Dass die Deklaration einer Klasse an einer bestimmten Stelle im Code bekannt ist, stellt den Compiler zufrieden. Aber die Lebenszeit und den Zugriff auf deine Instanzen musst du selbst koordinieren. Dein Hauptproblem ist die fehlende Übersicht darüber, wann und wo eine Instanz von welcher Klasse angelegt wird, und wo du diese Instanz wieder brauchst. Du könntest möglicherweise Referenzen statt Zeigern benutzen, denn die musst du initialisieren.

    Oder wie wäre es, wenn du eine Singleton-Klasse anlegst, die die ganzen Zeiger auf deine Dialoge speichert und bei Bedarf wieder rausgibt? Das wäre zumindest mal ein System:

    [cpp]
    Pruef_Auf = new Pruefplaene;
    Merker::Instance().SetPruef(Pruef_Auf);
    [/cpp]

    // später, da, wo du es brauchst:
    Merker::Instance().GetPruef().pBoxOne->EnableWindow(FALSE);
    

    Ansonsten würde ich dir empfehlen, das ganze Thema Klassen und Instanzen an einem viel einfacheren Projekt noch mal gründlich durchzuarbeiten. Diese Flickschusterei bringt dich langfristig nicht weiter.



  • ja, da hast du recht

    hast du denn mal nen Link oder so zu einem guten Tut?

    von welcher Basisklasse sollte dieser Merker denn sein?



  • MSS-Software schrieb:

    hast du denn mal nen Link oder so zu einem guten Tut?

    Auf http://www.c-plusplus.net gibt's eine Menge gute Links. 😉



  • ich hab jetzt mal völlig neu gedacht

    ich mache jetzt nur noch eine Instanz, die ich da erstelle, wo ich sie auch brauche

    hab das jetzt so gelöst:

    Aufruf.cpp

    #include "TABPruefplaene.h"
    

    [cpp]
    void CCAQDlg::OnStammdatenPrfplne()
    {
    // TODO: Code für Befehlsbehandlungsroutine hier einfügen
    CTABPruefplaene::Create();
    }
    [/cpp]

    TABPruefplaene.h

    class Pruefplaene;    //als class gemacht, wegen der Header Probleme
    

    [cpp]
    class CTABPruefplaene : public CTabCtrl
    {
    // Konstruktion
    public:
    CTABPruefplaene();
    int m_aktuelleSeite;
    int m_Seitennummern;
    CDialog* m_tabellenSeite[4];
    Pruefplaene Pruef_Auf;*
    ....
    ....
    ....
    static afx_msg void Create();
    [/cpp]

    TABPruefplaene.cpp

    void CTABPruefplaene::Create()
    {
    	Pruef_Auf = new Pruefplaene;
    	Pruef_Auf->Create(IDD_Pruefplaene);
    	Pruef_Auf->ShowWindow(SW_SHOW);
    }
    

    Jetzt hab ich die Instanz auch da, wo ich sie brauche. Nun tut siche aber ein anderes kleines Problem auf, was ich nicht so ganz verstehe:

    Compiler meldet:

    error C2597: Ungueltige Referenz auf ein Datenelement 'CTABPruefplaene::Pruef_Auf' in einer statischen Member-Funktion

    error C2227: Der linke Teil von '->Create' muss auf Klasse/Struktur/Union zeigen

    error C2227: Der linke Teil von '->ShowWindow' muss auf Klasse/Struktur/Union zeigen



  • hab jetzt aus der Statischen Member eine normale gemacht

    void CreateTest();
    

    und den Aufruf so:

    CTABPruefplaene Handle;
    Handle.CreateTest();
    

    funzt jetzt

    Jetzt habe ich folgen Anweisung noch in den Konstruktor geschrieben:

    Pruef_Auf = new Pruefplaene;
    

    Soll den Sinn haben, dass ich diese Instanz für die ganze Klasse zur Verfügung habe. Ich krieg auch keine Fehler und nicht, aber sobald ich auf den Link klicke, der den Dialog öffnen soll, schließ sich auf einmal das ganze Programm.



  • MSS-Software schrieb:

    und den Aufruf so:

    CTABPruefplaene Handle;
    Handle.CreateTest();
    

    Kannst du denn einfach so eine Instanz von CTABPruefplaene erstellen? Ist das auch eine Klasse, die ein Fenster repräsentiert? Hast du nicht vielleicht schon irgendwo eine Instanz dieser Klasse?



  • ja, das ist die Instanz, die vorher den Dialog repräsentiert hat

    ich hab die ursprüngliche entfernt und da halt neu angelegt

    wenn ich

    Pruef_Auf = new Pruefplaene;
    

    mit in die Funktion schreibe, die Create(IDD_....) usw macht, funzt das ja wunderbar, nur sobal ich die in den Kunstruktor packe nicht mehr


Anmelden zum Antworten