nichtmodalen Dialog mit CreateMutex schließen



  • Da hat der Copy&Paste-Teufel mal wieder zugeschlagen.
    Selber denken, besser sein.



  • Es ist leider sehr schwer etwas neu zu lernen ohne einen
    richtigen Lehrer oder Vorwissen. Ich habe zwar den
    Code übernommen, aber hatte auch gedacht dass sich
    dieses Mutex auf den aktuellen Dialog bezieht in dem
    es aufgerufen wird und folglich auch nur diesen schließt.

    Ich würde gerne besser werden und denke auch selbst 💡
    Nur grad am Anfang ist man auf Hilfe von den Leuten angewiesen,
    die es nunmal besser bzw. richtig können. Und das seid ihr für mich 🙂

    Ich habe bereits rausgefunden dass ich beim Aufruf gleich prüfen muss,
    ob das Fenster schon einmal erstellt wurde. Also noch im aufrufenden
    Hauptdialog. Den Aufruf mache ich so:

    CMYDIA* m_dia2;
    
        m_dia2= new CMYDIA;
        m_dia2->Create(IDD_DIALOG2);
        m_dia2->ShowWindow(SW_SHOWNORMAL);
    
    	 m_dia2->SetWindowPos(NULL, 870, 474, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
    

    Ich muss nun also noch herausbekommen ob dieser Button bereits einmal
    gedrückt wurde und, ob der Dialog2 evtl. bereits geschlossen wurde.
    Da liegt noch mein Problem, wie ich das prüfen kann.
    Schließen würde ich dann so:

    m_dia2->CloseWindow();
    

    Bin ich richtig davor, wenn ich mit FindWindow versuche das Dialogfenster
    von IDD_DIALOG2 anhand des Textes in der Titelleiste zu finden und ggf.
    zu beenden ?



  • So, ich habe es rausgefunden mit einigen Probierereien 😃

    Ich lege einen int an den ich auf 1 oder 0 setze und
    je nachdem rufe ich DestroyWindow auf.
    1=Fenster bereits einmal geöffnet, also schließen.
    0=Fenster nicht geöffnet, also noch öffnen.

    So schließe ich das Fenster dann, wenn mein int 1 ist:

    CWnd* fenster; 
    fenster=CWnd::FindWindow(NULL,"mein testfenster");    
    fenster->DestroyWindow();
    


  • Hm, ich würde es anders machen:
    Die Variable vom Typ CMYDIA nicht lokal und per new anlegen (wer löscht den Speicher denn dann wieder??), sondern als Membervariable im Hauptdialog.
    Und wenn es dann dazu kommt, den Dialog anzuzeigen, würde ich per ::IsWindow(m_dlgMyDia.GetSafeHwnd()) und vielleicht noch mit m_dlgMyDia.IsWindowVisible() überprüfen, ob der Dialog schon angezeigt wird und ihn dann nur anzeigen, wenn das nciht der Fall ist.

    Schöner wäre es natürlich, wenn du es anders machen würdest:
    CMYDIA eine Membervariable vom Typ des Hauptdialogs spendieren.
    Wenn man nun den Dialog aufruft wird der Button disabled und wenn man den Dialog schließt, dann enabled CMYDIA mit der Membervariable des Hauptdialogs den Button wieder. So kann man auf den Button nur klicken, wenn der Dialog nicht angezeigt wird.



  • Ich habe nun CMYDIA* m_dia2 als Membervariable im Hauptdialog
    angelegt und in OnInitDialog mit m_dia2= new CMYDIA; initialisiert.

    Was genau habe ich zuvor falsch gemacht ? Mülle ich mit meiner vorherigen
    Variante den Speicher zu, weil ich m_dia2 praktisch immer neu erstelle bei
    jedem weiteren Buttondruck ?



  • Exakt. Und genauso jetzt: Du gibst m_dia2 vermutlich niemals frei.
    Es ist auch absolut sinnlos m_dia als Zeiger zu erstellen -> lass es bleiben.



  • Dann hab ich es wohl doch noch nicht richtig verstanden, wie ich
    m_dia2 nun anlege 😞
    Ich konnte zwar bis jetzt nicht feststellen, dass ich den Speicher
    zumülle, aber würde es wenn schon richtig schreiben wollen, um eben dies
    im Fall der Fälle zu verhinden.

    Wie würde ein Freigeben von m_dia2 aussehen ? Release oder sowas ?
    Wie soll ich m_dia2 dann bekannt machen wenn nicht so wie jetzt.

    Tut mir wirklich leid euch mit solchen für euch banalen Sachen die
    Zeit zu rauben, nur blicke ich da noch nicht so schnell durch und bin
    für eure Hilfe hier wirklich dankbar 👍



  • wenn du mit new speicher anlegst, musst du ihn mit delete wieder löschen.

    Momentan machst du es ja so:
    CMYDIA *m_dia2 als Membervariable und dann ein new im OnInitDialog.
    Lass den Teil mit new im OnInitDialog ganz weg und leg die Membervariable so an:
    CMYDIA m_dia2;

    Dann musst du dich nciht mehr darum kümmern, dass der Speicher freigegeben wird.
    Ich empfehle dir übrigens ein Buch oder zumindest ein ausführliches Tutorial zum Thema C++.



  • Warum nicht mit new. Es fehl ja nur die Speicherfreigabe.
    Ohne Heap kann der Stack bald voll sein.



  • Öhm... Ich habe bisher noch keinen Fall gehabt, in dem ich meine Dialoge mit new hätte anlegen müssen, weil der Stack voll ist. Und so schnell wird der Stack acuh nicht voll.



  • Mach mal ein Programm mit ca. 80 Threads.
    Dann versuche noch ein Fenster zu erstellen.

    Auch wenn es nicht viele Fälle gibt wo der Stack zu klein wird sollte man die default 1 MB nur für das verwenden wofür man sie auch braucht.
    Man kann ja nicht wissen welche Strukturen die Klasse hat.
    Wird ein großes Programm mit allen Variablen und Daten immer nur auf den Stack gelegt kann es schonmal zu Problemen kommen.



  • Natürlich kann man wissen, welche Strukturen die Klasse hat. Man hat sie ja schließlich erstellt.
    Ich denke, wenn man weiß, wie groß ein Programm wird, muss man es nciht übertreiben. Mit deiner Argumentation dürfte man garnichts mehr auf dem Stack erstellen.


Anmelden zum Antworten