Hallo Sascha und André,
erstmal artigst Danke für die Antworten!
Post by André MinhorstPost by Sascha TrowitzschPost by unknownkann mir jemand den Trick verraten, wie ich einen Benutzer aus der
Datenbank rausschmeiße (bzw. dessen FE schließe), wenn bei dem gerade eine
Msgbox aktiv ist?
AXP/03/07
Access schließt sich, aber die Msgbox bleibt offen.
Tja, VBA ist nunmal noch aktiv, bzw. wartet auf die Beendigung der Msgbox. Davor
geht nichts. Modal ist modal.
Man könnte den Prozess wohl bloß killen, aber das ist es sicher nicht, was du
möchtest.
Bliebe die einzige Lösung, von einem anderen Prozess aus das
Msgbox-#32770-Fenster zu verhandlen und den Button OK per SendMessage zu
klicken.
Über Automation oder aus der DB selbst heraus fällt mir nix ein.
Aus der Datenbank heraus: Formular mit Timer, dass das Meldungsfenster
unter bestimmten Bedingungen, die regelmäßig geprüft werden, mit
1. Bedingung setzen: DB soll geschlossen werden, setze irgendeine
Boolean-Variable innerhalb der Datenbank auf True. Das müsste aber von
außerhalb passieren, weil Du die Datenbank ja wohl auch von außerhalb
schließen willst. Vielleicht eine öffentliche Variable des Formulars mit
dem Timer?
Das passiert über einen Tabelleneintrag im Backend, den der Admin
entsprechend für Wartungsarbeiten setzen kann. Wird dann von den FEs über
einen Timer abgefragt.
Post by André Minhorst2. Meldungsfenster identifizieren: Bei der testgetriebenen Entwicklung
habe ich vor dem Öffnen eines Meldungsfensters den Fenstertitel in eine
globale Variable geschrieben. Den lese ich dann aus, identifiziere das
Fenster mit FindWindow, hole es mit SetForegroundWindow nach vorne und
setze dann Sendkeys ab. Interessant wäre bei Dir wahrscheinlich, die
Taste des Meldungsfensters zu treffen, die keinen Schaden anrichtet. Das
kann man je Meldungsfenster vielleicht auch noch vor dem Öffnen in eine
globale Variable schreiben und dann per Sendkeys erst den Fokus auf die
richtige Schaltfläche setzen und dann anklicken. Bedeutet zwar mehr
Programmieraufwand, wäre dann aber so zuverlässig, wie Vorgänge mit
SendKeys eben sein können. ;-)
Mit dem Fenstertitel versagt es bei mir, da unterschiedliche Dialoge mit
unterschiedlichen Titeln offen sein können (Msgbox, Inputbox, FileDialog
etc.). Glücklicherweise gehören sie alle zur Klasse #32770 und zudem
exisitieren accessseitig keine weiteren derartiger Fenster.
Habe es jetzt vorerst so gelöst, daß ich vom Startformular ggf. ein
Meldungsformular aufrufe, von wo aus nach Ablauf einer Gnadenfrist für den
Nutzer die Close-Prozedur gestartet wird.
Dadrin werden zunächst alle Fenster mit EnumThreadWindows durchgelaufen und
ein SendMessage WM_Close auf die Klassen #32770 abgesetzt. Das funktioniert
schonmal für die Windows-Dialoge, die in der Regel ja unterschiedliche
Fenstertitel haben.
War das nicht erfolgreich (IsWindow) handelt es sich um eine Msg- oder
Inputbox.
In dem Fall durchlaufe ich nochmal deren ChildWindows, um den richtigen
Button zu erwischen, auf den dann ein Sendmessage BM_Click abgesetzt werden
kann. Diesen wiederum identifiziere ich über die ID (GetWindowLong).
Man kann das wie vorgeschlagen natürlich sicherer über eine Variable lösen,
aber ich habe deutlich mehr als 500 Messageboxen und am Montag
Abgabetermin. Ggf. wäre aber eh der konsequente Einsatz eigener
Message-Formulare einfacher.
Wie auch immer das Finden des richtigen Buttons ist wirklich der
Knackpunkt, da hierdurch ja eventuell weitere Aktionen angeleiert werden.
Glücklicherweise ist es bei mir so, daß alle Buttons, auf die geklickt
werden muß, etweder OK, Abbrechen oder Nein sind. Diese haben immer die IDs
2, 3(2) und 7 (hoffentlich ;-))
Ein weiteres Problem war noch das Schließen der Applikation. Ein
Application.Quit läßt den Prozess offen. Ein
Application.Closecurrentdatabase schließt aber zumindest die aktuelle
Datenbank, naja.
--
Grüßle vom Bodensee
Jörg Ostendorp
Access-FAQ: www.donkarl.com