SetFocus() Problem?



  • Huhu

    ich hab hier Registerkarten. Wenn ich die Klicke, soll ein Feld deaktiviert werden in einem anderem Dialog.

    Hab sowas schonmal gemacht und hat auch wunderbar geklappt. Doch bei den Registerkarten will er jetzt nun nicht mehr so, wie er soll.

    Also: hab das folgendermaßen gelöst:

    Dialog.h

    CWnd* pBoxOne;
    

    Dialog.cpp in der OnInitDialog

    pBoxOne = GetDlgItem(IDC_Kundenname);
    

    Dialog2.cpp
    [cpp]

    // Routine für Registerkartenwechsel
    void CTest::OnLButtonDown(UINT nFlags, CPoint point)
    {
    Pruefplaene Handle;
    Handle = new Pruefplaene;
    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();
    }
    }
    [/cpp]

    Er zeigt mir weder Fehler noch Warnungen an, wenn ich aber jetzt auf nen anderes Register klicke, bekomme ich ne Fehlermeldung mit Speicherproblemen!



  • MSS-Software schrieb:

    Pruefplaene* Handle;
    Handle = new Pruefplaene;
    Handle->pBoxOne->EnableWindow(FALSE);

    Er zeigt mir weder Fehler noch Warnungen an, wenn ich aber jetzt auf nen anderes Register klicke, bekomme ich ne Fehlermeldung mit Speicherproblemen!

    Du solltest dir dringend nochmal den Unterschied zwischen Klasse und Instanz klarmachen. Du erstellst da eine neue Instanz von Pruefplaene, und erwartest offenbar, dass du darüber die Steuerelement-Member einer ganz anderen Instanz von Pruefplaene beeinflussen kannst.



  • ja, das ist richtig

    aber wie kann ich denn dann von der einen Instanz die Steuerelemente verwenden?



  • Indem du der CTest-Instanz einen Zeiger oder eine Referenz auf die richtige Pruefplaene-Instanz mitgibst.



  • also müsste ich in der Header Datei, wo die CTest deklariert ist, die Header Datei der Pruefplaene includen und dann so:

    Pruefplaene* Handle;
    


  • MSS-Software schrieb:

    also müsste ich in der Header Datei, wo die CTest deklariert ist, die Header Datei der Pruefplaene includen und dann so:

    Pruefplaene* Handle;
    

    Wenn du damit einen Member von CTest meinst: Ja, das kannst du so machen. Bedenke aber, dass dir dieser Zeiger allein auch nicht weiterhilft. Du musst ihn auf die richtige Instanz von Pruefplaene setzen.



  • ja, genau das meine ich;

    hab ich auch jetzt so gemacht, aber Compiler meldet:

    error C2143: Syntaxfehler : Fehlendes ';' vor '*'

    error C2501: 'Pruefplaene' : Fehlende Speicherklasse oder Typspezifizierer

    error C2501: 'Handle' : Fehlende Speicherklasse oder Typspezifizierer



  • Hast du da zwei Headerdateien, die sich gegenseitig einbinden?

    Dann ersetze die Includedirektive in einer Datei durch eine Vorwärtsdeklaration der Klasse - für einen Zeiger reicht das - und setze die Includedirektive in die dazugehörige .cpp-Datei.



  • 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???


Log in to reply