Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Fremde Anwendung (+ Message Box Dialog) "sanft" beenden (https://www.delphipraxis.net/89209-fremde-anwendung-message-box-dialog-sanft-beenden.html)

Thomas233 27. Mär 2007 14:04


Fremde Anwendung (+ Message Box Dialog) "sanft" be
 
Hi,

ich habe ein Problem mit einer fremden Anwendung die ich schliessen will. Leider konnte ich weder in diesem Forum noch bei Google einen Lösungsweg finden.

Problemstellung:
Ein fremdes Programm soll durch mein Programm "sanft" (d.h. kein unsanftes terminieren des Prozesses bzw. vermeiden eines Datenverlustes beim Beenden wg. kritischer Daten) beendet werden.

Bisheriger Stand:
Ich hole mir das Win32-Handle des entsprechenden Programmfensters und schicke dem fremden Programm mit meinem Programm eine WM_CLOSE-Nachricht per Winapi-Befehl SendMessage().
Das Programm reagiert auch darauf, jedoch mit einer Sicherheitsabfrage ob es wirklich geschlossen werden soll (eine Messagebox).

Das Problem:
Diese Sicherheitsabfrage blockiert nun das gesamte Programm welches beendet werden soll. Leider hat die Messagebox natürlich kein Handle sodass ich keine WM_CLOSE Nachricht daran schicken kann. Ausserdem habe ich schon versucht einen Enter-Tastendruck zu simulieren per SendInput() welcher die Messagebox eigentlich (zumindest wenn man es manuell macht) mit "Ja" beantworten müsste. Desweiteren habe ich dem Programm eine weitere WM_CLOSE Nachricht geschickt und gehofft, hat jedoch auch nicht geholfen.

Würde mich über einen Tipp sehr freuen !

Danke !

Mfg.
Thomas Tschofenig

RavenIV 27. Mär 2007 14:10

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
Such mal hier im Forum nach "Taste senden" oder "tastendruck simulieren" oder so ähnlich.
Damit kann man einer Anwendung einen Tastendruck rüberbeamen.

EWeiss 27. Mär 2007 14:13

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
Versuchs mal mit der API GetForegroundWindow
entweder bekommst ein Handle der Messagebox oder nicht!.

Alternativ dazu

Zitat:

GetActiveWindow
GetForegroundWindow
GetFocus
GetTopWindow(GetFocus)
musst halt versuchen ..


Man kann immer versuchen, per Sendkeys ein Alternate F4 zu schicken.
Das Fenster muss natuerlich vorher aktiviert werden. Die meisten Fenster (incl. Messageboxen) reagieren darauf.

gruss

SirThornberry 27. Mär 2007 15:20

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
es ist eine MessageBox die kein Handle hat? Kannst du einen Screenshot davon zeigen? wenn es eine Messagebox ist gibt es auf jeden fall auch ein Handle.

EWeiss 27. Mär 2007 15:47

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
Zitat:

Zitat von SirThornberry
es ist eine MessageBox die kein Handle hat? Kannst du einen Screenshot davon zeigen? wenn es eine Messagebox ist gibt es auf jeden fall auch ein Handle.

Nein nicht unbedingt!
Bei Office zum beispiel werden die Messageboxen gezeichnet bzw... sind Bilder
Daher gibt es da auch kein Handle da es keine Fenster gibt.

gruss Emil

LizardKaiser 27. Mär 2007 15:51

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
hast du das mal mit Spy++ überprüft?

Thomas233 27. Mär 2007 16:57

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
Liste der Anhänge anzeigen (Anzahl: 1)
Soviel ich bisher gelesen habe ist es nicht möglich eine Messagebox per Handle und WM_CLOSE zu schliessen da diese für Windows Dialoge ohne Handle bzw. Dialoge die zu einem anderen Handle gehören darstellen (intern dürften sie natürlich auch ein eigenes Handle haben, da kommt man aber sicher nicht ran).

Hier mein Versuch eines Tastendruckes:

Delphi-Quellcode:
procedure CloseAppFromInst(HInst: THandle);
var
  Inp: TInput;
  I: Integer;
begin
  //Fenster fokussieren
  PostMessage(HInst, WM_ACTIVATEAPP, 0, 0);
  PostMessage(HInst, WM_SHOWWINDOW, 0, 0);

  //Schliessen Nachricht
  PostMessage(HInst, WM_CLOSE, 0, 0);

  Inp.Itype := INPUT_KEYBOARD;
  Inp.ki.wVk := VK_RETURN;
  Inp.ki.dwFlags := 0;
  SendInput(1, Inp, SizeOf(Inp));

  keybd_event(VK_RETURN,0,0,0);
end;
Habs auch schon mit SendInput() versucht, kam aber auch nichts dabei heraus !

EWeiss 27. Mär 2007 17:28

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
Meine Vorschläge mal überdacht?
Schick doch einfach mal ein F4 an die Messagebox
nachdem du sie in den Vordergrund und Focustiert hast.

Eigentlich müßte dann da der OK Button den Focus hat der Dialog schließen.
Frage mich auch warum du das Handle vom process holst.

Das liefert dir die API GetForegroundWindow .. Quasi das Handle der MessageBox

gruss

LizardKaiser 27. Mär 2007 17:33

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
wieso denn nicht

- hDlg := FindWindow('#32770', 'titel der msgBox');
- if handle der fremden anwendung == GetParent(hDlg):
- hBtn = FindWindow('Button', 'OK');
- SendMessage(hBtn, BM_CLICK, 0, 0)

ohne gewähr und pseudiger pseudocode, vllt. klappts ja (bei BM_CLICK bin ich mir allerdings nicht so sicher)

EWeiss 27. Mär 2007 17:38

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
Zitat:

Zitat von LizardKaiser
wieso denn nicht

- hDlg := FindWindow('#32770', 'titel der msgBox');
- if handle der fremden anwendung == GetParent(hDlg):
- hBtn = FindWindow('Button', 'OK');
- SendMessage(hBtn, BM_CLICK, 0, 0)

ohne gewähr und pseudiger pseudocode, vllt. klappts ja (bei BM_CLICK bin ich mir allerdings nicht so sicher)

hmm kapier das nicht!
warum so umständlich wenn wie schon erklärt GetForegroundWindow das Handle liefert
ohne FindWindow , GetwindowText und.. und.. und.


Zitat:

1. GetForegroundWindow
Diese Funktion ermittelt den Fensterhandle des Fensters welches sich im Vordergrund (am Anfang der Z-Order) befindet.
Zitat:

2. GetFocus
Diese Funktion ermittelt den Fensterhandle des Fensters welches im aktuellen Thread den Focus besitzt.
Zitat:

3. GetTopWindow
Diese Funktion ermittelt den Fensterhandle des Kindfensters welches den Focus besitzt oder sich im Vordergrund befindet.
gruss

LizardKaiser 27. Mär 2007 18:22

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
Ich wollte ja nur eine Alternativlösung posten :gruebel:

EWeiss 27. Mär 2007 18:32

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
Zitat:

Zitat von LizardKaiser
Ich wollte ja nur eine Alternativlösung posten :gruebel:

Jo sorry!
Muss ja auch keine meiner lösungen benutzt werden.
Sind lediglich auch nur vorschläge.

gruss

Thomas233 30. Mär 2007 16:44

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
So, hab jetzt alles mal durchprobiert.

U.a. die ganzen Get***-Methoden um an das Messagebox-Handle zu kommen. Half aber auch nicht da ich entweder das falsche Handle bekam oder das anschliessende Senden der WM_CLOSE Nachricht nichts bewirkt hat (mit dem richtigen Handle).

Dann hab ich es mit einem simulierten Alt+F4 probiert, das bringt aber auch nichts da sich dann nicht das Programm schliesst sondern nur die Messagebox (Programm läuft normal weiter).

Nun habe ich meinen Code ein bisschen umgebaut und es mit einem simulierten Return/Enter probiert, geht aber auch nicht (Messagebox bleibt regungslos stehen):

Delphi-Quellcode:
var
  Inp: array of TInput;
  I: Integer;
begin
  PostMessage(HInst, WM_ACTIVATEAPP, 0, 0);
  PostMessage(HInst, WM_SHOWWINDOW, 0, 0);
  PostMessage(HInst, WM_CLOSE, 0, 0);

  SetLength(Inp,2);

  Inp[0].Itype := INPUT_KEYBOARD;
  Inp[0].ki.wScan:=MapVirtualKey(VK_RETURN, 0);
  Inp[0].ki.wVk := VK_RETURN;
  Inp[0].ki.dwFlags := 0;

  Inp[1].Itype := INPUT_KEYBOARD;
  Inp[1].ki.wScan:=MapVirtualKey(VK_RETURN, 0);
  Inp[1].ki.wVk := VK_RETURN;
  Inp[1].ki.dwFlags := KEYEVENTF_KEYUP;

  SendInput(2, Inp[0], SizeOf(Inp[0]));
Ich kriegs einfach nicht hin.

Ich erinne mich aber u.a. das bei manchen Treiberinstallationen die ganzen Meldungen welche z.b. Windows Xp ausgibt (Windows zertifizierter Treiber usw.) vom Installationsprogramm manchmal selbst "bedient" werden. Das sieht man am besten daran wenn z.b. der Dialog "Treiber suchen" auftaucht, welcher dann vom Installationsprogramm wie von Geisterhand bedient wird (man sieht wie zwischen den einzelnen Schritten weiter gesprungen wird mit einem Klick auf "Weiter") um dann den Treiber zu installieren.
DAS bräuchte ich auch für mein Problem !

Danke trotzdem !

Mfg.
Thomas

EWeiss 30. Mär 2007 17:43

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
Zitat:

Dann hab ich es mit einem simulierten Alt+F4 probiert, das bringt aber auch nichts da sich dann nicht das Programm schliesst sondern nur die Messagebox
Wenn du schon soweit warst mußt du doch nur noch die Anwendung schließen.
Oder gehen dann Teile des Programms verloren ?
Abspeichern usw..

Werd mir mal ProgDVD anschauen und sehen was sich da machen läßt.
Aber nur wenn es Freeware ist .. kaufen will ich es deshalb nicht unbedingt

Gruss Emil

Luckie 30. Mär 2007 18:05

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
1. GetForeGroundWindow muss nicht die MessageBox sein.
2. Alt + F4 auf eine Messagebox angewand entspricht der Schaltfläche "Abbrechen".
3. MessageBoxen, die nur "Ja", "Nein" kennen, lassen sich nicht mit WM_CLOSE schliessen.

Thomas233 31. Mär 2007 13:21

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
Hi,

@Emil: Letzterer Beitrag beantwortet bereits deine Frage. Das Programm brauchst du übrigens nicht ausprobieren, den Screenshot habe ich nur als Beispiel genommen (will anderes Programm ansteuern).

@Luckie:
Zitat:

Zitat von Luckie
3. MessageBoxen, die nur "Ja", "Nein" kennen, lassen sich nicht mit WM_CLOSE schliessen.

Ja aber mit was denn dann ??

Danke !

Lg,
Thomas

Luckie 31. Mär 2007 13:31

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
Zitat:

Zitat von Thomas233
@Luckie:
Zitat:

Zitat von Luckie
3. MessageBoxen, die nur "Ja", "Nein" kennen, lassen sich nicht mit WM_CLOSE schliessen.

Ja aber mit was denn dann ??

In dem man auf eine der beiden Schaltflächen klickt. Ob nun selber mit der Maus oder mit ein paar Zeien Code ist unerheblich.

Thomas233 2. Apr 2007 11:49

Re: Fremde Anwendung (+ Message Box Dialog) "sanft"
 
Geht aber beides bei mir so nicht (manuell u. simulierter Tastendruck). Für einen Mausklick bräuchte ich dann erstmal die Koordinaten des OK-Buttons (kommt man wahrscheinlich auch ran, is aber sicherlich nicht ganz so unkompliziert).

Naja, hat sich aber zum Glück eh schon wieder erledigt, die Sicherheitsabfrage lässt sich nähmlich tatsächlich im Programm ausschalten (gut versteckt in den Optionen). Kam erst auf die Idee durch letzteren Beitrag. Dafür schliesse ich das Prog jetzt ganz gerne mal absolut ungewollt.

Danke trotzdem für die versuchte Hilfestellung !

Ich markiere es mal als nicht mehr offene Frage, wenn aber jemand noch eine Lösung findet oder ein ähnliches Prob hat...

Danke + Sorry !

Mit freundlichen Grüßen,
Thomas Tschofenig


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:50 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz