Auf Tastendruck zwischen Formularen rumswitchen
-
Hallo,
wie kann ich es realisieren das ich mittels Tastendruck zwischen Formularen rumswitchen kann?
Ich hab ein paar Formulare, 4 an der Zahl und jeder dieser 4 Forms ist ein Hotkey zugeteilt. Die Formulare werden dynamisch erzeugt wenn man den jeweiligen Hotkey drückt.
Mein Problem ist, dass, wenn ich z.B. Form1 mit Hotkey1 aufrufe, danach Hotkey2 für Form2, ich das bestehende Form1 nicht geschlossen kriege. Hierfür hab ich eine Variable genommen die sozusagen als eine Art FormID herhalten soll. Jedes der Formulare hat dann eine ID und wird in dieser Variable gespeichert und dann abgefragt. Wenn ein Formular dann erzeugt wird, wird die Variable auf den entsprechenden Wert gesetzt damit ich ermitteln kann welches Formular gerade aktiv ist um dann in der Lage zu sein das Form zu schliessen bevor das nächste erzeugt wird.
Ich hab allerdings auch noch nicht rausgefunden wie ich mit Boardmitteln rausfinden kann ob das Form überhaupt schon gibt, da die "Lösung" mit der Variable nur bedingt gut gelöst ist, abgesehen davon gehts eh nicht wirklich bzw. nur halb.
Also um das Beispiel von oben nochmal zu verdeutlichen:
- Programm wird gestartet
- ich drücke F5 und Form1 wird erzeugt
- wenn ich F6 drücke für Form2, will ich davor Form1 schliessenDie absolut einfallsloseste Idee die ich hatte, ging soweit das ich im entsprechenden Formular einen Timer genutzt habe, der eine Variable abgefragt hat und dann Close aufgerufen. Allerdings besteht das Form1 dann immer noch, dazu ist das zweite Form auch offen (ist ja gewollt), nur wenn ich das dann schliesse geht dann das andere auch zu (was normal schon hätte zu sein sollen).
Kann mir jemand einen Tip geben wie ich das machen kann? Ich scheitere nur daran das bestehende Form zu schliessen bevor das nächste erzeugt wird.
Ich hab irgendwo einen üblen Denkfehler drin

Danke!
-
- wenn ich F6 drücke für Form2, will ich davor Form1 schliessen
Wenn du Form1 schliesst, beendest du das ganze Programm, wenn ich mich recht entsinne. Arbeite doch einfach mit TForm::Hide()!
-
carstenbauer schrieb:
- wenn ich F6 drücke für Form2, will ich davor Form1 schliessen
Wenn du Form1 schliesst, beendest du das ganze Programm, wenn ich mich recht entsinne. Arbeite doch einfach mit TForm::Hide()!
Ja, aber ich hab Form1 nur als Beispiel genommen wegen Hotkey1 etc. Und Hide ist mehr als schlecht, da die Fenster funktionen ausführen bzw. auf Hotkeys reagieren, diese würden dann sonst kollidieren. Daher müssen diese ZU sein.
-
Zeig doch mal Deinen Quellcode zum Erzeugen und Schließen der Forms.
Die Variante mit dem angesprochenen Hide() scheint mir auf die Schnelle und ohne Deinen Programmhintergrund zu kennen auch die bessere. Kannst Du die Hotkeys/Funktionen nicht deaktivieren?
Gruss
-
Deklaration Hotkeys (unnötig aber der vollständigkeit halber)
RegisterHotKey(NULL,5,MOD_CONTROL,116); // CTRL+F5 RegisterHotKey(NULL,6,MOD_CONTROL,117); // CTRL+F6 RegisterHotKey(NULL,7,MOD_CONTROL,118); // CTRL+F7 RegisterHotKey(NULL,8,MOD_CONTROL,119); // CTRL+F8 RegisterHotKey(NULL,9,MOD_CONTROL,120); // CTRL+F9 RegisterHotKey(NULL,10,MOD_CONTROL,121); // CTRL+F10Hotkey Abfrage für die einzelnen Forms: (reduziert auf 2 Fenster zum testen)
void __fastcall TfrmMain::HotKeyMessage(tagMSG &Msg, bool &Handled) { if (Msg.message == WM_HOTKEY) { if (Msg.wParam == 5) { frmBotMacro->Close(); frmEE= new TfrmEE(Application); frmEE->ShowModal(); delete frmEE; } if (Msg.wParam == 6) { frmEE->Close(); frmBotMacro= new TfrmBotMacro(Application); frmBotMacro->ShowModal(); delete frmBotMacro; } } }Die IF-Orgie will ich noch umändern auf switch, aber ich glaube nicht das dies was daran ändern würde das das erste Form trotzdem noch angezeigt wird wenn das zweite offen ist.
€dit
Die Abfrage der Variable hab ich raugenommen weil ich was anderes probieren wollte, der Code oben ist der von gerade eben.
So hats davor ausgesehen (grob)
void __fastcall TfrmMain::HotKeyMessage(tagMSG &Msg, bool &Handled) { if (Msg.message == WM_HOTKEY) { if (Msg.wParam == 5) { if (BotMode == 1) { frmBotMacro->Close(); } else if (BotMode != 1) { BotMode = 2; frmEE= new TfrmEE(Application); frmEE->ShowModal(); delete frmEE; } } } }Zusatz: BotMode wurde beim starten der Anwendung auf 0 gesetzt = kein Formular offen. Das letzte Beispiel von oben ist nicht gnaz korrekt, aber ist jetzt nur sinngemäss gemeint da ich den richtigen Code schon gelöscht habe.
Gemeint war es so:
Wenn Hotkey1 für Fenster1 gedrückt wurde, wird die Variable BotMode auf 1 gesetzt. Dann frage ich, wenn ich den nächsten Hotkey drücke diese Variable ab um zu wissen welches Form gerade offen ist, dieses wird dann geschlossen (gut, es sollte !
), dann wird das 2te Fenster geöffnet und die Variable auf 2 gesetzt. (wie oben schon geschrieben ist BotMode nur eine Hilfsvariable).Ich hoffe, dass nun jeder verstanden hat was ich möchte. Ich habs nicht so mit erklären

-
Ist doch klar, dass die aufrufende Form offen bleibt. Du nutzt schließlich ShowModal(). Versuche es mal mit Show(). Schlage am besten mal den Unterschied dieser zwei Methoden in der Hilfe nach.
Gruss
-
Rostfrei[] schrieb:
Ist doch klar, dass die aufrufende Form offen bleibt. Du nutzt schließlich ShowModal(). Versuche es mal mit Show(). Schlage am besten mal den Unterschied dieser zwei Methoden in der Hilfe nach.
Gruss
Tja... mit Show wird das Formular aber automatisch wieder geschlossen sobald es aufgerufen wird.
-
Is doch auch klar. Schließlich gibst Du doch das Forumular direkt nach dem Anzeigen wieder frei.
... frmBotMacro->Show(); // Anzeigen delete frmBotMacro; // Löschen ...Schau Dir mal den Ablauf mit dem Debugger an.
-
So, es klappt jetzt schon mal wenn Form1 erstellt wurde damit es von Form2 geschlossen werden kann, aber nicht andersrum.
Gibt es eine Funktion mit der ich Prüfen kann ob ein Formular bereits besteht? Ich hab mit (if bla->Visible) aber das geht nicht da ich eine Schutzverletzung bekomme, was ja dann auch Logisch ist wenn das Formular nicht existiert. Über Google hab ich leider nichts gefunden was mir weiterhilft und in der Onlinehlife auch nicht

Scheinbar gibt es zumindest keine Funktion. Wie kann ich das den am besten anstellen?
€dit
So ich habs nun hinbekommen für ZWEI Forms, wenn aber ein drittes dazu kommt gibts wieder Schutzverletzung

-
um herauszubekommen ob es ein bestimmtes Formular schon gibt kannst du die Eigenschaften Forms,CustomForms,ActiveForm und/oder ActiveCustomForm von TScreen verwenden
alternativ kannst du den Zeiger auf das Form nach dem Löschen auch auf NULL setzten und die If-Abfrage ändern:
delete bla; //Löschen bla = NULL; ... if (bla) //Abfrage ob vorhanden
-
Linnea schrieb:
alternativ kannst du den Zeiger auf das Form nach dem Löschen auch auf NULL setzten und die If-Abfrage ändern:
delete bla; //Löschen bla = NULL; ... if (bla) //Abfrage ob vorhandenSo klappts astrein *freu* danke!
Aber wieso wird erst wenn man das Form auf NULL setzt (bla = NULL) false zurück geliefert und nicht schon dann wenn das Form gelöscht wurde? Normal sollte das doch dann bereits false sein wenn es gelöscht wird oder nicht? Weil das Form wird doch normal aus dem Speicher gelöscht.
-
Hallo
Du hast den Unterschied zwischen Pointern und Instanzen nicht verstanden.
Nehmen wir mal an du hast einen Pointer namens bla. Mit new erstellst du eine neue Instanz von TBla auf dem Heap und weist deren Adresse dem Pointer zu.
Wenn du jetzt delete auf den Pointer bla anwendest, wird die Instanz TBla gelöscht. Es wird aber nicht die Adresse in bla auf 0 zurückgesetzt! Denn es könnte ja dutzende Pointer geben die auf diese Instanz gezeigt haben. Der Compiler weiß nicht welche Pointer auf eine Instanz zeigen. Der Pointer wird ungültig, jede Referenzierung der Adresse wird automatisch ein unerlaubter Speicherzugriff. Du must also manuell in deiner Programmlogik dafür sorgen das ungültige Pointer nicht mehr verwendet werden oder eben neu besetzt werden.bis bald
akari
-
Danke
