PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wie kann ich alle anderen Fenster schließen?



Miaaa
06.02.2004, 17:32
Tach. Ich habe versucht, mit Delpi6 einen Befehl hinzubekommen, der alle anderen zur Zeit laufenden Fenster beendet. Ich poste mal:

unit Unit21;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, MPlayer, StdCtrls;

type
PFindWindowStruct = ^TFindWindowStruct;
TFindWindowStruct = record
Caption: string;
ClassName: String;
WindowHandle: THandle;
end;

type
TForm21 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form21: TForm21;
function FindAWindow(caption: string; ClassName: string): THandle;
function EnumWindowsProc(hWindow: hWnd; lParam: LongInt): boolean; stdcall;

implementation

{$R *.dfm}

procedure TForm21.Button1Click(Sender: TObject);
begin
Close;
end;

function EnumWindowsProc(hWindow: hWnd; lParam: LongInt): boolean; stdcall;
var lpBuffer: PChar;
WindowCaptionFound: boolean;
ClassNameFound: boolean;
begin
GetMem(lpBuffer, 255);
result:=true;
WindowCaptionFound:=false;
ClassNameFound:=false;
try
if GetWindowText(hWindow, lpBuffer,255)>0 then
if Pos(PFindWindowStruct(lParam).Caption, StrPas(lpBuffer))>0
then WindowCaptionFound:=true;
if PFindWindowStruct(lParam).ClassName='' then
ClassNameFound:=true
else if GetClassName(hWindow, lpBuffer, 255)>0 then
if Pos(PFindWindowStruct(lParam).ClassName, StrPas(lpBuffer))>0
then ClassNameFound:=true;
if (WindowCaptionFound and ClassNameFound) then begin
PFindWindowStruct(lParam).WindowHandle:=hWindow;
result:=false;
end;
finally
FreeMem(lpBuffer, sizeof(lpBuffer^));
end;
end;

function FindAWindow(caption: string; ClassName: string): THandle;
var WindowInfo: TFindWindowStruct;
begin
with WindowInfo do begin
caption:=caption;
className:=ClassName;
WindowHandle:=0;
EnumWindows(@EnumWindowsProc,LongInt(@WindowInfo));
result:=WindowHandle;
end;
end;

procedure TForm21.FormShow(Sender: TObject);
var TheWindowHandle: THandle;
begin
TheWindowHandle:=FindAWindow('');
if TheWindowHandle=0 then
ShowMessage('Window not found!')
else
BringWindowToTop(TheWindowHandle);

TheWindowHandle := FindWindow(NIL,'');
if TheWindowHandle<>0 then PostMessage(TheWindowHandle, wm_close, 1, 1);
end;

end.


Schwierigkeiten gibt es bei diesem Code wiefolgt: In der Vorletzten Zeile vor dem Letzten 'end;' ( TheWindowHandle := FindWindow(NIL,''); ) muss hinter NIL,' die Bezeichnung des Fensters das geschlossen werden soll. Ich brauche also noch eine Befehlszeile, die mir sagt wieviele Fenster überhaupt geöffnet sind (Sooft lass' ich den Code dann ablaufen, damit jedes Fenster geschlossen wird) und eine Befehlzeile die mir die Namen/ den Namen des Fensters mitteilt (Damit diese Namen dann in shortstrings gespeichert werden können, welche dann hinter NIL eingetragen werden können). Wenn ihr eventuell auch eine nicht ganz so aufwendige Methode kennt: Immer lasst es mich wissen!

Hoffe, ihr könnt miaaa helfen!

Ach ja, um diesen Code auszuprobieren braucht ihr bloß eine Unit 21 mit dazugehörigem Formular, auf dem ein Button namens Button1 ist. (Zur Zeit passiert aber noch gar nichts, ausser wenn ein Fenster geöffnet ist, das KEINEN Namen hat :) )

Ineluki
06.02.2004, 17:53
ich kapiere irgendwie nicht ganz, wieso du das so kompliziert machst @_@

EnumWindowPoc sollte doch eigentlich automatisch einmal fuer JEDES Top-Level Fenster aufgerufen werden, wenn du EnumWindows aufrufst ...

Wenn du nun alle Fenster schliessen willst, ausser dem von deinem eigenen programm haette ich das vielleicht so versucht ...



function EnumWindowsProc(hWindow: hWnd; donotclose: LongInt): boolean;stdcall;
begin
if hWindow<>THandle(donotclose) then PostMessage(hWindow, wm_close, 1, 1);
result:=true;
end;

procedure Form1.Button1Click(Sender: TObject);
begin
//Wir nehmen mal an, durch das Klicken auf den Button ist das Fenster im Vordergrund, das ich nicht schliessen will
EnumWindows(EnumWindowsProc,GetForegroundWindow);
end;


den Code hab ich nicht getestet ... aber sollte das nicht genau das machen, was du machen wolltest ? .. Alle Fenster ausser dem Aktiven schliessen ?

alternativ koenntest du auch folgendes probieren, wenn du nicht unbedingt den aktuellen prozess offen halten willst ...



Procedure Button1Click(Sender:TObject);
begin
PostMessage(HWND_BROADCAST, wm_close, 1, 1);
end;


Gruss Ineluki

Miaaa
07.02.2004, 19:27
Wie gesacht (odda nicht gesagt :) ), bin ich noch ein ziemlicher Anfänger (um Weihnachten habe ich das erste Mal mit Delphi6 geproggt) und kenne mich deshalb mit vielen 'Kurzbefehlen' nicht so aus. Aber Thanke, Ineluki!http://www.multimediaxis.de/images/smilies/old/sm_12.gif

Master of Disaster
08.02.2004, 05:25
Wenn du mit dem Windows API herumspielst wird ein Stöbern im Platform SDK auf support.microsoft.com sicher nicht schaden. Borland liefert mit Delphi normalerweise eine uralte Version der Hilfe des SDKs mit (<=Win95!), da sich aber seither einiges getan hat, würde ich mir an deiner Stelle mal die neuere Version anschaun.