Delphi: Fremdes Programm schließen

Hallo,

ich will den Task vom InterntExplorer schließen. Mit der Message WM_CLOSE bekomme ich fremde Fenster zu, jedoch nicht das vom IE. Da höre ich nur ein DING und sonst leider nichts.

Für einen Tip, der funktioniert spendiere ich diesmal eine Vollversion des fertigen Programms.

Das sollt etwa so gehe (leider nur VB, aber in Delphi sieht die API ja auch nicht viel anders aus…):

 Public Const INFINITE = &HFFFF
 Public Const PROCESS\_ALL\_ACCESS = &H1F0FFF 
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpCaption As Any) As Long
Declare Function PostMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal InheritHandle As Long, ByVal dwProcessID As Long) As Long
Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Declare Function IsWindow Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long

Public Sub CloseAppClass(Optional AppClass As String = "IEFrame")
Dim Lg As Long, lngRes As Long, hwnd As Long, hProcess As Long, s As String, idProc As Long
 hwnd = GetDesktopWindow()
 hwnd = GetWindow(hwnd, GW\_CHILD)
 Do While hwnd 0
 s = String(255, 0)
 Lg = GetClassName(hwnd, s, Len(s)) ' Class holen
 If Lg \> 0 Then
 If left(s, Lg) = AppClass Then
 lngRes = PostMessage(hwnd, WM\_CLOSE, 0&, 0&amp:wink:
 lngRes = GetWindowThreadProcessId(hwnd, idProc)
 hProcess = OpenProcess(PROCESS\_ALL\_ACCESS, 0, idProc)
 lngRes = TerminateProcess(hProcess, 0&amp:wink:
 End If
 End If
 hwnd = GetWindow(hwnd, GW\_HWNDNEXT)
 Loop
End Sub

Reinhard

…was er damein wohl meint, ist dass du mit FindWindow ein Handle auf das Main-Window der fremden Applikation anforderst und ihr darüber eine WM_CLOSE Message schickst :smile:

…was er damein wohl meint, ist dass du
mit FindWindow ein Handle auf das
Main-Window der fremden Applikation
anforderst und ihr darüber eine WM_CLOSE
Message schickst :smile:

Wie bitte? Wer meint was? Ich glaube, ich hab’ Sebastian schon richtig verstanden - das WM_CLOSE klappt halt beim IE nicht (vermutlich, weil das Fensterhandling beim IE anders als bei klassischen Windows-Anwendungen ist).

Reinhard

…was [er] damein wohl meint

er=du

Dies VB-Zeug versteht ja niemand :stuck_out_tongue:

In Delphi wär’s z.B. so:

unit CloseApp;

interface

uses WinTypes;

procedure CloseAppFromInst(HInst: THandle);

implementation

uses WinProcs, Messages;

{ Callback function that has each top-level window passed to it. }
{ Return true to continue enumerating, false to stop. }
function EnumWindowsProc(Handle: HWND; Info: Pointer): boolean;
{$IFDEF WIN32} stdcall; {$ELSE} export; {$ENDIF}
begin
Result := TRUE; { continue enumeration }
{ Does this app have the same instance as what we are looking for? }
{$IFDEF WIN32}
if GetWindowLong(Handle, GWL_HINSTANCE) = LongInt(Info) then begin
{$ELSE}
if GetWindowWord(Handle, GWW_HINSTANCE) = LongInt(Info) then begin
{$ENDIF}
PostMessage(Handle, WM_CLOSE, 0, 0); { Close the app }
Result := FALSE; { stop enumerating windows, we are done. }
end;
end;

procedure CloseAppFromInst(HInst: THandle);
begin
EnumWindows(@EnumWindowsProc, LongInt(HInst));
end;

end.

Es geht doch nicht um den Code, sondern um den Algorithmus - und der ist von der Programmiersprache unabhängig, also nochmal ganz langsam:

PostMessage WM_CLOSE

funktioniert nicht beim IExplorer - ob jetzt in Delphi oder in VB. (Ausserdem sind die Sprachunterschiede zwischen VB und Delphi eigentlich nicht so gross, dass man nicht mit ein bisschen gutem Willen aus meinem Beispielprogramm ersehen könnte, wie’s gemeint ist.)

Reinhard

als Weihnachtsgeschenk ;o)

var HW: HWND;
P: PChar;
Lg: Integer;
IDProc: Integer;
hProcess: THandle;
begin
GetMem(P,255);
IDProc:=0;
HW:=GetDesktopWindow;
HW:=GetWindow(HW,GW_Child);
while HW0 do
begin
lg:=GetClassName(HW,P,255);
if lg>0 then
begin
if Copy(P,1,lg)=‚IEFrame‘ then
begin
PostMessage(hw, wm_Close,0,0);
getWindowThreadProcessID(HW,@idProc);
hProcess:=OpenProcess(Process_All_Access,False,idProc); // False bitte prüfen! Bin nicht sicher ob in VB 0=False oder -1=False!!!
TerminateProcess(hProcess,0);
end;
end;
HW:=GetWindow(HW,GW_HWNDNEXT);
end;
Dispose§;
end;

Ich kommentiere das jetzt mal nicht weiter, sondern wünsche allen Insassen dieses Threads - und natürlich auch allen anderen - ein frohes Fest…

Reinhard

So, vielen Dank für die vielen Antworten!!!
Das mit IEFRAME funktioniert tatsächlich einwandfrei!
Super!

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]