Hi!
Ich möchte folgendes realisieren:
Wenn mein Programm mit dem Parameter /autorun gestartet wird, wird die Form beim Start sofort ausgeblendet. Das ist ja nicht schwer.
Wenn man die Anwendung jetzt ein zweites mal startet soll die bereits laufende Applikation sichtbar gemacht werden und das neue Programm sofort wieder beendet werden. Kann man so etwas machen?
Habe da mal etwas von Singletons oder so gehört, aber weiss nicht wie das funktioniert und ob man damit auch auf Methoden der älteren Instanz zugreifen kann.
thx,
m0m0
Hallo m0m0,
die halbe Miete hast du schon mal mit mehrere Programminstanzen verhindern?
Und die andere Hälfte mit: Dateiassoziation (statt die Argumente zu senden, benutzt du den ArgsReceiver einfach dazu, dass die erste Instanz sich mit BringToFront selbst wieder aktiviert).
herbivore
Hi!
Danke, das mit dem Verhindern mehrere Programminstanzen funktioniert.
Wie du das mit dem ArgsReceiver meinst versteh ich aber leider nicht.
m0m0
Hallo m0m0,
in dem Beispiel in Dateiassoziation wird die Klasse ArgsReceiver benutzt, um die Argumente der zweiten Instanz an die erste Instanz zu übergeben. Die zweite Inszanz ruft dazu die Methode SetNewArgs auf die aber (dank Remoting) in der ersten Instanz ausgeführt wird.
Du willst ja keine Argumente übergeben, sondern nur dass sich die erste Instanz wieder anzeigt. Dazu benutzt du den gleichen Mechanismus, nur dass die Klasse ArgsReceiver in SetNewArgs nicht die übergebenen Argumente verarbeitet (bekommt ja dann auch keine mehr), sondern einfach die erste (also die eigene) Instanz wieder anzeigt. Klasse und Methode kannst und solltest du natürlich entsprechend umbenennen.
Für das Anzeigen kannst du BringToFront verwenden, wenn das Fenster nicht minimiert ist. Sollte es minimiert sein, kannst du zusätzlich bzw. vorab den Form.WindowState auf Normal setzten.
herbivore
Hallo,
das hier ist so ziemlich genau das Problem, was ich gerade habe nur ohne Lösung 🙂
Also die Kommunikation hat geklappt, ich kann auch auf der ersten Instanz etwas machen. Bei mir schaut das so aus:
class RemoteObject : MarshalByRefObject
{
public void loadIt()
{
Program.MainWindow.BringToFront();
Program.MainWindow.LoadIt()
}
}
Wie gesagt, LoadIt() wird aufgerufen, aber BringToFront() macht nichts. Das Fenster ist nicht minimiert. Jemand eine Idee, woran das liegen kann?
Gruß
Mike
Also das Problem scheint wohl irgendwie zu sein, dass ich nicht Thread übergreifend auf die Elemente zugreifen kann. Weil jetzt wird sogar mal ne Exception geworfen. Und wie umgehe ich das Problem nun? 🙂
Gruß
Mike
Hm, ich hab nun was gefunden und das umgestrickt:
public void LoadIt(string test)
{
MainForm window = Program.MainWindow;
if (window.InvokeRequired)
{
Console.WriteLine("Invoke required");
MyCallback callback = new MyCallback(LoadIt);
window.Invoke(callback, new object[] { test });
}
else
{
if (window.WindowState == FormWindowState.Minimized)
{
window.WindowState = FormWindowState.Normal;
}
window.BringToFront();
}
}
Das komische ist, dass "Invoke required" nie ausgegeben wird. Hier war ich also wohl eher aufm Holzweg 🙁
Gruß
Mike
Das Invoke ist übrigens doch nicht überflüssig, die Ausgabe kam. Ich hab im falschen Programm geschaut 🙂 Geht aber trotzdem noch nicht. Habs noch mit Activate() probiert, aber das hat auch nicht geholfen.
Gruß
Mike
Hi nochmal,
so ich habs nun anders gemacht: Im RemoteObject habe ich eine Methode GetWindowHandle(). Die liefert mir das Handle des Hauptfensters zurück. Und anschließend rufe ich den Win32 Call SetForegroundWindow(handle) auf. Damit gehts jetzt.
Gruß
Mike
Bei mir nicht. (Sorry, dass ich nen neuen Thread aufgemacht habe. Mein Suchbegriff war beim ersten Mal wohl nicht allgemein genug gehalten.)
Die Anwendung, die meine Anwendung gestartet hat, bleibt im Vordergrund. Allem SetForegroundWindow zum Trotz. Alt+Tab geht aber.