Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Minimieren/Schließen einer Anwendung verhindern (https://www.delphipraxis.net/53358-minimieren-schliessen-einer-anwendung-verhindern.html)

DarkLord0 14. Sep 2005 21:25


Minimieren/Schließen einer Anwendung verhindern
 
Hallo,

Ich bin dabei mit Delphi 6 ein Programm zu schreiben, das ein anderes Programm öffnet, maximiert und seinem Fenster den Fokus erteilt. Bis dahin kein Problem, aber ich suche jetzt eine Möglichkeit, zu verhindern, dass dieses Fenster geschlossen oder minimiert (oder in einen anderen Zustand als maximiert versetzt) wird oder auch nur ein anderes Fenster (das nicht zu demselben Programm gehört) den Fokus erhält. Ich möchte also, dass der User ganz auf dieses Programm beschränkt ist (habe auch die Taskleiste ausgeblendet). Ich habe mit der Suchfunktion einen Ansatz gefunden, mit globalen Hooks alle Fensternachrichten abzufangen (und ggf. Schließen/Minimieren - Befehle "unschädlich" zu machen), aber ich hoffe es gibt auch noch eine einfachere Lösung! Ich habe versucht, dem betreffenden Fenster mit einem Timer immer wieder den Fokus zu geben, es zu maximieren etc., aber das halte ich für eine sehr unschöne Lösung. Würde mich über effizientere Ansätze freuen

TheMiller 14. Sep 2005 21:28

Re: Minimieren/Schließen einer Anwendung verhindern
 
Schau dir mal die Application-Event-Kompo an. Da steht "OnMinimize". Da trägst du einfach FormX.Restore ein...

TheMiller 14. Sep 2005 22:00

Re: Minimieren/Schließen einer Anwendung verhindern
 
Achso, und setze bei der Eigenschaft Formx.OnCloseQuery die Variable CanClose:=False. Sorry für die Kürze der Antwort, muss aber weg.

Luckie 14. Sep 2005 23:55

Re: Minimieren/Schließen einer Anwendung verhindern
 
@DJ-SPM: Ich galueb, er will das bei dem Fenster erreichen dessen Programm er startet. Also nicht bei seinem, sonder bei einem fremden Fenster.

DarkLord0 14. Sep 2005 23:57

Re: Minimieren/Schließen einer Anwendung verhindern
 
Zitat:

Zitat von Luckie
@DJ-SPM: Ich galueb, er will das bei dem Fenster erreichen dessen Programm er startet. Also nicht bei seinem, sonder bei einem fremden Fenster.

So ist es :)

tigerman33 15. Sep 2005 09:50

Re: Minimieren/Schließen einer Anwendung verhindern
 
Ich denke dann wirst du um das Abfangen der Nachrichten nicht drumrum kommen

//edit
:idea: Idee:
Ist es eigentlich möglich, über das Handle an das Fenster ranzukommen, in ein Delphi-Form zu "typecasten" und darin dann die eventhandler zu überschreiben?

TheMiller 15. Sep 2005 15:07

Re: Minimieren/Schließen einer Anwendung verhindern
 
OK, dann habe ich das falsch verstanden und bin somit aus dem Rennen ;)

DarkLord0 17. Sep 2005 20:10

Re: Minimieren/Schließen einer Anwendung verhindern
 
Zitat:

Zitat von tigerman33
:idea: Idee:
Ist es eigentlich möglich, über das Handle an das Fenster ranzukommen, in ein Delphi-Form zu "typecasten" und darin dann die eventhandler zu überschreiben?

Das wäre allerdings ein eleganter Weg, sollte es funktionieren. Vielleicht könnte sich ja mal jemand dazu äußern, der sich damit auskennt (ich weiß nämlich nicht wie ich das konkret durch code umsetzen sollte).

alzaimar 17. Sep 2005 21:48

Re: Minimieren/Schließen einer Anwendung verhindern
 
Du kannst das Fensterhandle herausbekommen, aber das reicht dir nicht: Nur weil Du die Adresse von jemanden hast, kannst du die Person ja auch nicht abgreifen.

Schreib Dir einen globalen Messagehook, wenn ein WM_CLOSE oder WM_QUERYENDSESSION an das betreffende Fenster geschickt wird, fängst Du das einfach ab. Aber Vorsicht! So ein Hook bremst ungemein und kann dein Windows zum Absturz bringen.

Olli 17. Sep 2005 21:53

Re: Minimieren/Schließen einer Anwendung verhindern
 
Zitat:

Zitat von alzaimar
[...] und kann dein Windows zum Absturz bringen.

Ist mir noch nie untergekommen! Zumindest nicht mit einem Fensterhook auf der NT-Plattform. Sicher, über 9x/Me brauchen wir hier nicht erst reden, aber wo ist dir das denn untergekommen? Oder ist für dich "unbenutzbar" bereits das gleiche wie "abgestürzt"?

tigerman33 18. Sep 2005 09:04

Re: Minimieren/Schließen einer Anwendung verhindern
 
Dass das Handle alleine nicht reicht ist mir klar. Ich stellte mir eher sowas vor wie:
function HandleToForm(Handle: HWND): TForm;

Olli 18. Sep 2005 10:29

Re: Minimieren/Schließen einer Anwendung verhindern
 
Zitat:

Zitat von tigerman33
Dass das Handle alleine nicht reicht ist mir klar. Ich stellte mir eher sowas vor wie:
function HandleToForm(Handle: HWND): TForm;

Dürfte nicht gehen, da es keine sinnvolle Methode gibt diese beiden miteinander zu verbinden. Das einzige wäre wohl das Rumstochern im Speicher *g*

Es könnte aber gut sein, daß man dank der RTTI des Zielprogramms dennoch dran kommt. Allerdings stelle ich mir das nicht allzu einfach vor.

DarkLord0 18. Sep 2005 14:51

Re: Minimieren/Schließen einer Anwendung verhindern
 
Okay, ich habe es jetzt mal mit einem globalen Fensterhook über eine DLL versucht :

DLL :
Delphi-Quellcode:
library wmsgcatch;

uses
  Windows,
  Messages;

const
mymsg='HNOTICERS';

var
HookHandle:Cardinal;
TargetWindowHandle:Cardinal;
OwnWindowHandle:Cardinal;
WM_HNOTICE1 : Cardinal = 0;

function GetMsgProc(code: integer; wParam: WPARAM; lParam: LPARAM): LResult; stdcall;
begin
WM_HNOTICE1:=RegisterWindowMessage(mymsg); //Damit zu Testzwecken dem Hauptprogramm eine Nachricht geschickt werden kann
setprop(OwnWindowHandle,mymsg,WM_HNOTICE1); //WM_HNOTICE1 übergeben
    with Windows.PMsg(lParam)^ do begin
    if ((message = WM_CLOSE)or(message=WM_QUERYENDSESSION)or(message=WM_MOUSEMOVE)) then begin //WM_MOUSEMOVE habe ich nur drin, um zu testen, ob das Hauptprogramm überhaupt benachrichtigt wird
     SendMessage(HWND_Broadcast, WM_HNOTICE1, wParam, lParam); //Das Hauptprogramm benachrichtigen
     PostMessage(HWND_Broadcast, WM_HNOTICE1, wParam, lParam); // Ich verwende sowohl SendMessage als auch PostMessage, um auszuschließen, dass es mit einer der beiden Funktionen Probleme gibt
      if (hwnd=TargetWindowHandle) then begin //Wenn es sich um Das Handle des zu 'schützenden' Fensters handelt
      SendMessage(HWND_Broadcast, WM_HNOTICE1, wParam, lParam);
      PostMessage(HWND_Broadcast, WM_HNOTICE1, wParam, lParam);
      pmsg(lparam).message:=WM_NULL; //Nachricht abbrechen
      end;end;   end;      
Result := CallNextHookEx(HookHandle, Code, wparam, lparam);

end;

function InstallHooks(Hwnd: Cardinal;OwnHwnd:Cardinal): Boolean; stdcall;
begin
TargetWindowHandle:=Hwnd; //Handle des zu schützenden Fensters
OwnWindowHandle:=OwnHwnd; //Handle des Hauptprogramm-Fensters

HookHandle := SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, hinstance, {GetWindowThreadProcessId(TargetWindowHandle)}0); //Verwende erst einmal 0 
Result:=Hookhandle<>0;
end;

function UninstallHooks: Boolean; stdcall;
begin
result:=UnHookWindowsHookEx(HookHandle);
end;

exports
  InstallHooks,
  UninstallHooks;

begin

end.
Hauptprogramm (das wichtige) :
Delphi-Quellcode:
[...]
type
procedure WndProc(var Mess:TMessage);override;
[...]
var
  Form1: TForm1;
  WM_HNOTICE1 : Cardinal = 0;

const
mymsg='HNOTICERS';

implementation
 function InstallHooks(Hwnd: THandle;OwnHwnd:Cardinal): Boolean; stdcall;
 external 'wmsgcatch.dll';
  function UninstallHooks: Boolean; stdcall;
  external 'wmsgcatch.dll';

{$R *.dfm}

procedure TForm1.WndProc(var Mess:TMessage);
begin
WM_HNOTICE1:=getprop(application.handle,mymsg); //WM_HNOTICE holen (falls vorhanden)
if mess.msg=WM_HNOTICE1 then
memo1.Lines.add('Nachricht erhalten.');
inherited WndProc(Mess) ;
end;

function FindAWindow(WinCaption: string; WinClassName: string): THandle; //Funktion, um das WindowHandle des Zielprogramms herauszufinden (nicht selbstgeschrieben)
var WindowInfo: TFindWindowStruct;
begin
  with WindowInfo do begin
    caption := WinCaption;
    className := WinClassName;
    WindowHandle := 0;
    EnumWindows(@EnumWindowsProc, LongInt(@WindowInfo));
    result := WindowHandle;
  end;
end;

function MyEnumWindowProc(AHandle: THandle; LParam: LongWord): boolean;
stdcall;
var
  ProcessID: THandle;
begin
  ProcessID := 0;
  GetWindowThreadProcessID(AHandle, ProcessID);
  Result := not (ProcessID = LParam);
  if not Result then
    WindowHandle := AHandle;
end;

procedure TForm1.FormCreate(Sender: TObject);
var targethandle:thandle;
begin
[... (Programm mit ShellExecute starten und targethandle mit FindAWindow beschaffen)]
postmessage(targethandle,WM_SYSCOMMAND,SC_MAXIMIZE,0);
SetForegroundWindow(targethandle); //Maximieren und in den Vordergrund (funktioniert bereits)
if InstallHooks(targethandle,application.handle) then //Hooks installieren.
label1.Caption:='Installed Successfully.';
end;
Leider funktioniert das nicht so wie es soll. Das Hauptprogramm bekommt zwar Nachrichten, wenn ich WH_MOUSEMOVE benutze, aber nicht bei WM_QUERYENDSESSION und WH_CLOSE. Wenn ich die DLL nur Nachrichten senden lasse, wenn hwnd=TargetWindowHandle ist, bekommt das Hauptprogramm noch nicht einmal bei WH_MOUSEMOVE Nachrichten.

DarkLord0 22. Sep 2005 11:33

Re: Minimieren/Schließen einer Anwendung verhindern
 
Keiner eine Idee, wo der Fehler liegen könnte? :/


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:03 Uhr.

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