Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Applikation IMMER im Vordergrund (https://www.delphipraxis.net/174168-applikation-immer-im-vordergrund.html)

sundance 8. Apr 2013 11:17

Applikation IMMER im Vordergrund
 
Hallo DelphiGemeinde,

ich habe folgende Herausforderung:
Eine Applikation soll ein Fenster anzeigen, welches in der Bildschirmmitte im Vordergrund aller Fenster angezeigt wird. Das habe ich mit
Delphi-Quellcode:
fsStayOnTop
und einer schwarzen, davorliegenden teiltransparenten Form (Größe = kompletter Bildschirm) gelöst (damit kann man die bereits vorhandenen Fenster nicht mehr per Mausklick aktivieren). Das Fenster soll den Benutzer dazu zwingen, eine Auswahl zu treffen und dann auf OK zu klicken.
Leider kann man aber per Taskmanager bzw. Taskwechsel auf eine offene Applikation umschalten und somit mein Programm "in den Hintergrund" verfrachten, ohne die notwendige Auswahl zu treffen.
Gibt es eine (einfache) Möglichkeit, das zu verhindern?

(edit: Programm soll unter XP laufen)

CCRDude 8. Apr 2013 11:38

AW: Applikation IMMER im Vordergrund
 
Welches Betriebssystem?

Ab Vista macht UAC vor, wie es gehen könnte (wobei die API-Funktionen seit Win2000 vorhanden sein sollten) - alternativen Desktop anlegen und bei Prozessstart vor UI-Initialisierung den UI-Thread dahin auswandern lassen.

UAC schaltet dazu consent.exe dazu und wertet wohl dessen Rückgabewert aus. Da afaik eine bereits angezeigte Anwendung nicht den Desktop wechseln kann, bräuchtest Du auch einen Helfer-Prozess dafür.

Stichworte: MSDN-Library durchsuchenCreateDesktop, MSDN-Library durchsuchenSetThreadDesktop, MSDN-Library durchsuchenSwitchDektop. Für's Debuggen sicherstellen, dass der Wechsel auf den Originaldesktop immer irgendwie noch erfolgen kann, sonst wird's ungemütlich ;)

sundance 8. Apr 2013 11:44

AW: Applikation IMMER im Vordergrund
 
@CCRDude,
ich fürchte, das übersteigt meine Programmierkenntnisse ein wenig... :roll:

Der schöne Günther 8. Apr 2013 11:46

AW: Applikation IMMER im Vordergrund
 
Nicht wirklich einfach, denn danach geht es munter weiter. Wie stark willst du das System abschotten?
  • Systemtasten (ALT+TAB, Windows-Taste, STRG+ESC, ...)
  • Task-Manager
  • User-Logoff
  • Rechner herunterfahren
  • Popups, z.B. Autorun bei eingestecktem USB-Stick

Ich würde als erstes überlegen, ob es wirklich wert ist, die zusätzliche Zeit hier zu investieren, oder ob man hier nicht schon den Schlussstrich zieht.

Falls du dich für die erste Variante entscheidest (ich habe es getan :stupid:), hier in Kurzform:

Die Systemtasten musst du mit einem globalen Lowlevel-Keyboard-Hook abblocken. Hier im Forum findet man bestimmt was zu "Systemtasten deaktivieren" oder den Stichworten
Delphi-Quellcode:
WH_KEYBOARD_LL
und
Delphi-Quellcode:
LowLevelKeyboardProc
.

Selbst wenn die Tasten raus sind, gibt es noch eine Menge anderer Möglichkeiten, beispielsweise kann man immer noch mit rechts auf die Taskleiste klicken und von dort den Taskmamanger aufrufen. Um den Taskmanager (oder Abmelden des Benutzers) zu deaktivieren braucht dein Programm übrigens Adminrechte, geht aber insgesamt recht einfach mit einem Registry-Eintrag...


Einen komplett neuen Desktop zu erstellen wäre eine zweite Methode (die ich aus Interesse auch mal gefahren bin), macht meiner Meinung nach aber weder viel Sinn noch Spaß, es sei denn, man will Atomkraftwerke nach militärischen Standards absichern - Wenn ich nicht danebenliege, greift selbst ein auf Desktop 1 gestarteter Keylogger keine Passwörter ab, die auf Desktop 2 eingegeben werden. Nur wie gesagt - Wenn dein Programm nicht wieder korrekt zu Desktop 1 zurückwechselt - Dann bleibst du da :-D

CCRDude 9. Apr 2013 07:20

AW: Applikation IMMER im Vordergrund
 
@Günther: die ersten drei Punkte davon erledigt der dritte Desktop ja schon.

Und das sind wirklich nur 3-4 API-Aufrufe, die natürlich richtig geplant sein müssen. Ich hab mir ne Unit ( < 400 Zeilen, schon inklusive Code, vom vorigen Desktop einen Screenshot zu erstellen und als neuen ausgegrauten Hintergrund zu verwenden) geschrieben, die im initialization auf einen anderen Desktop wechselt und im finalization zurück. Solange das verwendende Programm nicht in anderen Units im initialization-Teil bereits UI-relevante API-Aufrufe verwendet, füge ich diese nur dem uses-Part zu und fertig (hier meine Anwendung) :)

Ganz ehrlich - Keyboard-Hooks sind komplizierter :-D

Ob es hier wirklich Sinn macht, kann ich natürlich nicht entscheiden, diese Technik ist ja schon ein sehr harter Eingriff in die Rechnernutzung und sollte wohl überlegt sein.

Der schöne Günther 9. Apr 2013 07:51

AW: Applikation IMMER im Vordergrund
 
Ja, das ist wirklich ein ziemlich deftiger Eingriff in den normalen Ablauf. Ich würde mir das auch drei mal überlegen ob man das wirklich braucht.

Als ich mich damit befasst hatte, kannte ich mich noch weniger mit Delphi aus und wusste nichts von einem
Delphi-Quellcode:
initialization
und
Delphi-Quellcode:
finalization
- Dementsprechend fummelig wurde es dann auch, da man einen Prozess nicht mehr von einem Desktop zum anderen schieben kann - Wurde er dort erstellt, bleibt er dort. Einzelne Threads schon, aber keine ganzen Prozesse (oder? :oops:)

Funktionierte STRG+ALT+ENTF nicht mehr auf dem zweiten Desktop? Ich dachte schon, könnte mich aber auch irren...


Trotzdem finde ich auch, der zweite Desktop bleibt die "noch sicherere" Alternative. Stellt sich nur die Frage, ob man das wirklich braucht...

sundance 9. Apr 2013 10:00

AW: Applikation IMMER im Vordergrund
 
@CCRDude:
Zitat:

Ich hab mir ne Unit ( < 400 Zeilen, schon inklusive Code, vom vorigen Desktop einen Screenshot zu erstellen und als neuen ausgegrauten Hintergrund zu verwenden) geschrieben (...)
Vielleicht kannst du dich ja durchringen, uns diese Unit zur Verfügung zu stellen...

@Günther:
Deiner Anregung folgend habe ich jetzt folgendes eingebaut:
Code:
// --- Routinen zur Installation eines Keyboard-Hooks --------------------------

var
  HookHandle: Cardinal = 0;


function LowLevelKeyboardProc(nCode: Integer; wParam: wParam; lParam: lParam): LRESULT; stdcall;
begin
  if (nCode < 0) then
    Result := CallNextHookEx(HookHandle, nCode, wParam, lParam)
  else
    Result := 1;
end;


function InstallHook(Hwnd: Cardinal): Boolean; stdcall;
begin
  Result := False;
  if (HookHandle = 0) then begin
    HookHandle := SetWindowsHookEx(13, LowLevelKeyboardProc, 0, 0);
    Result := (HookHandle <> 0);
  end;
end;


function UninstallHook: Boolean; stdcall;
begin
  Result := UnhookWindowsHookEx(HookHandle);
  HookHandle := 0;
end;
wobei InstallHook im
Delphi-Quellcode:
FormCreate
und UninstallHook im
Delphi-Quellcode:
FormDestroy
Event ausgeführt wird.
Damit habe ich (fast) alles gesperrt, was mir wichtig war (Die Taskleiste kann der Anwender wegen der vollformatigen, schwarzen Form nicht erreichen).
Aber der gemeine Anwender ist meist sehr erfinderisch; mal sehen, was er sich jetzt einfallen läßt...

Der schöne Günther 9. Apr 2013 10:05

AW: Applikation IMMER im Vordergrund
 
Zitat:

Zitat von sundance (Beitrag 1210754)
Aber der gemeine Anwender ist meist sehr erfinderisch; mal sehen, was er sich jetzt einfallen läßt...

Und wie. Deshalb würde ich mich auch nicht vertraglich auf irgendetwas festnageln lassen, dass irgendein Zugriff dadurch effektiv unterbunden wird. Denn STRG+ALT+ENTF hebelt man nicht einfach mit einem Keyboard-Hook aus, was ist, wenn die Stromzufuhr kurzzeitig unterbrochen wird, wandern Popups durch späteres Einstecken eines USB-Sticks wieder in den Hintergrund, was ist, wenn die Maussoftware bsp. ein Klicken des Mausrads auf ein Öffnen des Startmenüs mappt, ...

Und und und :-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:23 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