SetFocus() Problem?



  • 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



  • MSS-Software schrieb:

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

    Ist dir klar, dass diese Instanz wieder zerstört wird, wenn CCAQDlg::OnStammdatenPrfplne beendet ist? falls CreateTest keine blockierende Funktion ist - das vermute ich hier einfach mal - lebt dieses Objekt nicht besonders lange.



  • ja klar

    shit, da hab ich gar nicht dran gedacht

    sicher

    ok, wenn ich die Instanz anstatt im konstruktor nun wieder in der CreateTest erzeugen lasse, hab ich denn dann die Möglichkeit, innerhalb derselben Klasse auf diese Instanz in der Funktion zuzugreifen?



  • hab das dann mal so probiert:

    [cpp]
    void CTABPruefplaene::OnLButtonDown(UINT nFlags, CPoint point)
    {
    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();
    CreateTest()::Pruef_Auf->GetDlgItem(IDC_Kundenname)->EnableWindow(FALSE);

    }
    }

    void CTABPruefplaene::CreateTest()
    {
    Pruef_Auf = new Pruefplaene;
    Pruef_Auf->Create(IDD_Pruefplaene, this);
    Pruef_Auf->ShowWindow(SW_SHOWNORMAL);
    }
    [/cpp]

    Abder da sagt er mir, dass Pruef_Auf kein Element von Global namespace ist;

    hab dann versucht die Instanz ganz außerhalb der Funktionen zu erzeugen, wobei ich dann die Fehlermeldung bekomme:

    Fehlende Speicherklasse oder Typspezifiziere

    class Pruefplaene* kann nicht in int konvertiert werden



  • Lass mal das CreateTest():: weg. Was soll das überhaupt?



  • ich muss ja auf die Instanz zugreifen, die in CreateTest() erstellt wird, weil er mir ja sonst wieder nen speicherproblem macht



  • hmm, das Problem liegt woanders

    und zwar hab ich das ja so gemacht in der Routine, wo der Dialog aufgerufen wird:

    #include "TABPruefplaene.h"
    
    CTABPruefplaene Handle;
    Handle.CreateTest();
    

    dann hab ich aber mal den include in die Header Datei der dazugehörigen cpp datei gepackt und das ganze als Member erzeugt:

    CCAQDlg.h

    #include "TABPruefplaene.h"
    
    CTABPruefplaene Handle; //Member
    

    CCAQDlg.cpp

    Handle.CreateTest();
    

    So, das gibt ein wunderbares Phänomen:

    keine Fehler und keine Warnungen, aber er führt mir das Programm nicht aus!!!



  • MSS-Software schrieb:

    ich muss ja auf die Instanz zugreifen, die in CreateTest() erstellt wird, weil er mir ja sonst wieder nen speicherproblem macht

    Aber Pruef_Auf ist doch ein Member von CTABPruefplaene. Du musst nur dafür sorgen, dass CreateTest nur einmal, und vor OnLButtonDown, aufgerufen wird. Wenn das dann immer noch nicht funktioniert, hast du noch ein anderes Problem.

    Ohne dir zu nahe treten zu wollen: Ich habe (nicht zum ersten Mal) den Eindruck, dass du die elementaren Sprachmittel von C++ nicht verstehst. Du bastelst solange an deinem Code herum, bis der Compiler sich nicht mehr beschwert. Vor den dann auftretenden Laufzeitfehlern stehst du völlig hilflos da, weil du selbst nicht verstehst, was du da geschrieben hast. Ich rate dir (auch nicht zum ersten Mal), die Finger von der GUI-Programmierung zu lassen und dich mit den Grundlagen zu befassen.

    Du wirkst wie jemand, der versucht ein Haus zu bauen, ohne zu wissen, wie Türen oder Treppen funktionieren und an welchem Ende man eine Maurerkelle anfasst.



  • aber OnLButtonDown wird doch erst ausgeführt, wenn ich die Register wechsel; und um die Register wechseln zu können, muss der Dialog ja vorher erscheinen

    und CreateTest() repräsentiert ja den Dialog und somit wurde die doch auch vorher ausgeführt;

    aber das Problem ist, dass wenn ich die Instanz im konstruktor erzeuge, er mir den Dialog nicht öffnet und wenn ich die Instanz in CreateTest() erzeuge, ist diese Instanz nur für diese Funktion gültig sprich: logisch, wenn ich dann OnLButtonDown ausgeführt wird, dass er auf einen leeren Zeiger greift



  • ich hab jetzt mal son schnelltut gelesen mit klassen und Instanzen

    das war aber nur sehr allgemein beschrieben

    wo finde ich denn was, wie erklärt wird, wie ich die z.B. Übergebe oder drauf zugreife etc???

    hättest du da vielleicht noch was für mich?

    wär lieb von dir


Anmelden zum Antworten