Fenster erkennen und verstecken
Fenster erkennen und verstecken
Hallo zusammen,
Ich möchte gerne ein kleines Programm schreiben welches beim Starten einen Parameter übergeben bekommt (String, Titel eines Chrome Fensters).
Dieses Programm soll dann das passende Browserfenster anhand des Strings erkennen und dieses Fenster dann verstecken.
Wie gehe ich denn am besten vor, um mir die passenden APIs zusammen zu suchen?
Danke und viele Grüße,
Marcus
Hintergrund Info:
Wir setzen auf der Arbeit Siemens Teamcenter ein. Der SSO Login erfolgt über einen Tab im Browser. Dieser hält die Session zwischen Client und Server. Wir haben nun das Problem, das User gerne mal den Browser (mit mehreren Tabs) schließen und anschließend die Verbindung zum Server verloren geht und im schlimmsten Fall Daten verloren gehen.
Möchte nun im Browser selbst eine Extension installieren welche den Tab erkennt und in einem separaten Chrome Fenster isoliert, so das nun gezielt dieses Fenster versteckt werden kann.
Ich möchte gerne ein kleines Programm schreiben welches beim Starten einen Parameter übergeben bekommt (String, Titel eines Chrome Fensters).
Dieses Programm soll dann das passende Browserfenster anhand des Strings erkennen und dieses Fenster dann verstecken.
Wie gehe ich denn am besten vor, um mir die passenden APIs zusammen zu suchen?
Danke und viele Grüße,
Marcus
Hintergrund Info:
Wir setzen auf der Arbeit Siemens Teamcenter ein. Der SSO Login erfolgt über einen Tab im Browser. Dieser hält die Session zwischen Client und Server. Wir haben nun das Problem, das User gerne mal den Browser (mit mehreren Tabs) schließen und anschließend die Verbindung zum Server verloren geht und im schlimmsten Fall Daten verloren gehen.
Möchte nun im Browser selbst eine Extension installieren welche den Tab erkennt und in einem separaten Chrome Fenster isoliert, so das nun gezielt dieses Fenster versteckt werden kann.
Re: Fenster erkennen und verstecken
Verstehe nicht wirklich, was du machen willst.
Hilft das? https://linux.die.net/man/1/wmctrl
Hilft das? https://linux.die.net/man/1/wmctrl
Re: Fenster erkennen und verstecken
Hallo Theo,
ich versuche nochmal, es zu erklären. Meine Aufgabe ist zweigeteilt:
1. isoliere ich einen bestimmten Tab eines Chrome-Browsers unter Win10 in einem separaten Fenster. Die erfolgt mit Hilfe einer Extension direkt im Browser.
2. möchte ich danach dieses Fenster unsichtbar machen, so dass es nicht versehentlich von einem Anwender geschlossen werden kann. Dazu benötige ich ein kleines Tool, welches das Browserfenster erkennt und versteckt.
Mir geht es hauptsächlich um die Frage, wo ich für Win10 die entsprechenden APIs finde für das Arbeiten mit Fenstern.
Wenn ich nach "hide window" suche, dann gibt es fast ausschließlich Treffer, wie ich das eigene Programm verstecke; nicht aber wie man ein anderes Fenster versteckt.
Evtl. suche ich auch mangels Erfahrung nach den falschen Begriffen.
Grüße,
Marcus
ich versuche nochmal, es zu erklären. Meine Aufgabe ist zweigeteilt:
1. isoliere ich einen bestimmten Tab eines Chrome-Browsers unter Win10 in einem separaten Fenster. Die erfolgt mit Hilfe einer Extension direkt im Browser.
2. möchte ich danach dieses Fenster unsichtbar machen, so dass es nicht versehentlich von einem Anwender geschlossen werden kann. Dazu benötige ich ein kleines Tool, welches das Browserfenster erkennt und versteckt.
Mir geht es hauptsächlich um die Frage, wo ich für Win10 die entsprechenden APIs finde für das Arbeiten mit Fenstern.
Wenn ich nach "hide window" suche, dann gibt es fast ausschließlich Treffer, wie ich das eigene Programm verstecke; nicht aber wie man ein anderes Fenster versteckt.
Evtl. suche ich auch mangels Erfahrung nach den falschen Begriffen.
Grüße,
Marcus
-
- Beiträge: 2118
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: Fenster erkennen und verstecken
Ich geh bei sowas so vor, du suchst nach funktionen der Windows API, also um möglichst viele ergebnisse zu finden suche ich nach winapi + suchbegriff. Nicht nach lazarus + suchbegriff oder Delphi + suchbegriff, oder sonst irgendwas (das kommt später). Ich suche also als erstes nach "winapi hide window" (auf englisch hat man auch grundsätzlich bessere chancen).
Eines der ersten ergebnisse ist ein Stack Overflow thread indem von der funktion ShowWindow gesprochen wird, also suchen wir danach: "MSDN ShowWindow" und kommen auf die Dokumentation: Link. Beschreibung: Sets the specified window's show state. Schaut so aus wie das was wir wollen.
Die argumente sind hWnd und nCmdShow, wobei nCmdShow der neue status ist, mit einer Liste von möglichen werten, für uns relevant SW_HIDE (0) "Hides the window and activates another window." Klingt doch super.
hWnd ist A handle to the window. Also ist das nächste was man sucht: "WinAPI get window handle by name", und man findet diesen Stackoverflow thread
Dort steht dann das FindWindow 2 parameter annimmt: lpClassName und lpWindowName, mit der beschreibung:
Manchmal sind WinAPI funktionen nicht so straight forward wie FindWindowA und ShowWindow, da würde ich dann empfehlen nach beispielen zu suchen, aus erfahrung kann ich sagen das man bessere chancen (bei winapi zeugs) hat nach delphi als nach lazarus zu googlen, ich würde also sowas wie "delphi findwindow" oder so googlen. Wenn ich da nix finde würde ich nach C++ suchen und versuchen das zu übersetzen (geht meist sehr einfach).
Ansonsten, bei solchen suchen ist weniger immer mehr. Such nicht nach sowas wie "lazarus hide window of chrome by title", das ist viel zu spezifisch. Du suchst nach einer Windows lösung, ob das jetzt Lazarus, Delphi oder C++ ist relativ egal, die unterliegende API kann überall benutzt werden (Du willst nur kein .Net kram, also C# oder VB haben). Das das fenster von chrome ist ist auch relativ egal, was für ein fenster geht sollte auch für das nächst beste andere fenster gehen. Und das du nach dem titel suchst, ist auch im ersten schritt irrelevant, du willst erst mal wissen wie du ein fenster versteckst, wie du an das fenster das du verstecken willst rankommst ist erst der zweite schritt. Damit wird daraus: "winapi hide window".
Ich muss aber zugeben, ich wusste an dieser stelle schon das das so generisch geht (man kann mit der WinAPI beliebige fenster aus beliebigen prozessen heraus steuern), das muss aber natürlich nicht der fall sein. Es kann also auch hilfreich sein sowas zu suchen wie "winapi hide window different process" oder sowas. Dabei hätte man dann das selbe gefunden.
PS: Browser sind etwas sehr komplex (chrome ist praktisch ein betriebsystem) es kann also gut sein das es nicht so trivial ist wie für andere anwendungen. Ich wär mir nicht so sicher ob es einfach möglich ist das fenster zu finden (kann sein das das tatsächliche website fenster mit dem titel ein subfenster von einem namenlosen überfenster ist) um die suche einzuschränken kannst du entweder EnumWindows benutzen (stand auch in einem der stack overflow threads) oder das lpClassName argument von FindWindowA benutzen.
Gibt auch einige tools mit denen du dir die Window structure anschauen kannst (z.b. Inspect von Microsoft), es kann sehr oft hilfreich sein sich für sowas zu erst anzuschauen wie der kram intern tatsächlich aufgebaut ist, und sich dann eine suchstrategie für diesen speziellen fall zu suchen. Aber dann kann es natürlich sein das eine solche Lösung mit der nächsten Chrome version wiederum kaputt gehen kann.
Die wahrscheinlich sauberere lösung wäre es wahrscheinlich für die website nen eigenen chrome prozess zu starten und den dann komplett zu verstecken (statt nach einem einzelnen fenster zu suchen), da du das ProzessHandle direkt aus der TProcess klasse bekommen kannst, wenn du chrome aus lazarus heraus öffnest, oder du einfach webkit oder gecko oder so in deinem lazarus projekt laufen lässt, und dann über ein chrome plugin die cookies der seite an das lazarusprogramm schickst, damit dieser dann die website in seinem eigenen browser öffnen kann.
Aber ich würds erst mal naiv versuchen, vielleicht mach ich mir hier schon wieder viel zu viele gedanken, und der zweizeiler oben reicht schon
Eines der ersten ergebnisse ist ein Stack Overflow thread indem von der funktion ShowWindow gesprochen wird, also suchen wir danach: "MSDN ShowWindow" und kommen auf die Dokumentation: Link. Beschreibung: Sets the specified window's show state. Schaut so aus wie das was wir wollen.
Die argumente sind hWnd und nCmdShow, wobei nCmdShow der neue status ist, mit einer Liste von möglichen werten, für uns relevant SW_HIDE (0) "Hides the window and activates another window." Klingt doch super.
hWnd ist A handle to the window. Also ist das nächste was man sucht: "WinAPI get window handle by name", und man findet diesen Stackoverflow thread
Direkt mit ner verlinkung zur MSDN seite von FindWindowA.Using FindWindow requires that you either know the window class or the window title. Both of these are not necessarily unique.
Dort steht dann das FindWindow 2 parameter annimmt: lpClassName und lpWindowName, mit der beschreibung:
Also ergibt sich als programm ungefähr sowas:If lpClassName is NULL, it finds any window whose title matches the lpWindowName parameter.
Code: Alles auswählen
uses windows; // winapi funktionen sind in der windows unit
...
var handle: HWND;
...
handle := FindWindowA(nil, 'Fenstertitel');
ShowWindow(handle, SW_HIDE); //falls SW_HIDE nicht gefunden wird, schreib einfach den wert (0) direkt rein
Ansonsten, bei solchen suchen ist weniger immer mehr. Such nicht nach sowas wie "lazarus hide window of chrome by title", das ist viel zu spezifisch. Du suchst nach einer Windows lösung, ob das jetzt Lazarus, Delphi oder C++ ist relativ egal, die unterliegende API kann überall benutzt werden (Du willst nur kein .Net kram, also C# oder VB haben). Das das fenster von chrome ist ist auch relativ egal, was für ein fenster geht sollte auch für das nächst beste andere fenster gehen. Und das du nach dem titel suchst, ist auch im ersten schritt irrelevant, du willst erst mal wissen wie du ein fenster versteckst, wie du an das fenster das du verstecken willst rankommst ist erst der zweite schritt. Damit wird daraus: "winapi hide window".
Ich muss aber zugeben, ich wusste an dieser stelle schon das das so generisch geht (man kann mit der WinAPI beliebige fenster aus beliebigen prozessen heraus steuern), das muss aber natürlich nicht der fall sein. Es kann also auch hilfreich sein sowas zu suchen wie "winapi hide window different process" oder sowas. Dabei hätte man dann das selbe gefunden.
PS: Browser sind etwas sehr komplex (chrome ist praktisch ein betriebsystem) es kann also gut sein das es nicht so trivial ist wie für andere anwendungen. Ich wär mir nicht so sicher ob es einfach möglich ist das fenster zu finden (kann sein das das tatsächliche website fenster mit dem titel ein subfenster von einem namenlosen überfenster ist) um die suche einzuschränken kannst du entweder EnumWindows benutzen (stand auch in einem der stack overflow threads) oder das lpClassName argument von FindWindowA benutzen.
Gibt auch einige tools mit denen du dir die Window structure anschauen kannst (z.b. Inspect von Microsoft), es kann sehr oft hilfreich sein sich für sowas zu erst anzuschauen wie der kram intern tatsächlich aufgebaut ist, und sich dann eine suchstrategie für diesen speziellen fall zu suchen. Aber dann kann es natürlich sein das eine solche Lösung mit der nächsten Chrome version wiederum kaputt gehen kann.
Die wahrscheinlich sauberere lösung wäre es wahrscheinlich für die website nen eigenen chrome prozess zu starten und den dann komplett zu verstecken (statt nach einem einzelnen fenster zu suchen), da du das ProzessHandle direkt aus der TProcess klasse bekommen kannst, wenn du chrome aus lazarus heraus öffnest, oder du einfach webkit oder gecko oder so in deinem lazarus projekt laufen lässt, und dann über ein chrome plugin die cookies der seite an das lazarusprogramm schickst, damit dieser dann die website in seinem eigenen browser öffnen kann.
Aber ich würds erst mal naiv versuchen, vielleicht mach ich mir hier schon wieder viel zu viele gedanken, und der zweizeiler oben reicht schon
Re: Fenster erkennen und verstecken
Wow, guten Morgen.
Das war genau was ich suchte.
Tatsächlich hatte ich es um 2 Uhr bereits hin gekriegt, aber nicht mehr geantwortet. Habe aber nicht mit so einem Frühaufsteher gerechnet
Damit funktioniert es wie gewünscht.
Ich muss mal schauen, wie viel Arbeit genau ich da rein stecke. Das waren nun nur wenige Stunden, mit tollem Erfolg.
Bin aber kein ITler, sondern Anwender unserer Unternehmenssoftware. Wollte nur nicht glauben, dass es "nicht geht" und mir selbst einen Proof-of-Concept bauen.
Am Ende kann das gerne noch viel besser von einem Profi umgesetzt werden.
Vielen Dank für den Tipp mit "winapi", das macht Sinn wie du es erklärst.
Grüße,
Marcus
Das war genau was ich suchte.
Tatsächlich hatte ich es um 2 Uhr bereits hin gekriegt, aber nicht mehr geantwortet. Habe aber nicht mit so einem Frühaufsteher gerechnet

Damit funktioniert es wie gewünscht.
Ich muss mal schauen, wie viel Arbeit genau ich da rein stecke. Das waren nun nur wenige Stunden, mit tollem Erfolg.
Bin aber kein ITler, sondern Anwender unserer Unternehmenssoftware. Wollte nur nicht glauben, dass es "nicht geht" und mir selbst einen Proof-of-Concept bauen.
Am Ende kann das gerne noch viel besser von einem Profi umgesetzt werden.
Vielen Dank für den Tipp mit "winapi", das macht Sinn wie du es erklärst.
Grüße,
Marcus
Code: Alles auswählen
// https://msdn.microsoft.com/en-us/data/72szh9c7(v=vs.85)
// https://www.swissdelphicenter.ch/de/showcode.php?id=327
function FindWindowByTitle(WindowTitle: string): Hwnd;
var
NextHandle: Hwnd;
NextTitle: array[0..260] of char;
begin
// Get the first window
NextHandle := GetWindow(Application.Handle, GW_HWNDFIRST);
while NextHandle > 0 do
begin
// retrieve its text
GetWindowText(NextHandle, NextTitle, 255);
if Pos(WindowTitle, StrPas(NextTitle)) <> 0 then
begin
Result := NextHandle;
Exit;
end
else
// Get the next window
NextHandle := GetWindow(NextHandle, GW_HWNDNEXT);
end;
Result := 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
h: hwnd;
begin
h := FindWindowByTitle('Browsertitel');
if h <> 0 then // if we found notepad
ShowWindow(h, SW_HIDE)
else
ShowMessage('not found.');
end;
Re: Fenster erkennen und verstecken
Genau das macht wmctrl, nur halt für Linux, von Windows hattest du nichts gesagt.mzurhorst hat geschrieben: 2. möchte ich danach dieses Fenster unsichtbar machen, so dass es nicht versehentlich von einem Anwender geschlossen werden kann. Dazu benötige ich ein kleines Tool, welches das Browserfenster erkennt und versteckt.

Re: Fenster erkennen und verstecken
Ja, stimmt.
Ich bin davon ausgegangen dass Lazarus-Code unabhängig vom OS ist und das hinter den Kulissen erledigt.
Ich bin davon ausgegangen dass Lazarus-Code unabhängig vom OS ist und das hinter den Kulissen erledigt.
Re: Fenster erkennen und verstecken
Ich weiss nicht, ob es ein Unit gibt, die solche Funktionen X-Platform kapselt. Denkbar ist das.mzurhorst hat geschrieben:Ja, stimmt.
Ich bin davon ausgegangen dass Lazarus-Code unabhängig vom OS ist und das hinter den Kulissen erledigt.
Aber beim manipulieren fremder Fenster bzw. des Windowmanagers verlässt man natürlich den Kern der Anwendungsprogrammierung.
Ausserdem sind die Unterschiede in der Funktionalität wahrscheinlich recht gross zwischen den Systemen.
Re: Fenster erkennen und verstecken
Im Prinzip, ja. Aber wenn du die Unit "Windows" verwendest, dann wird das Programm eben von Windows abhängig. Um unabhängig vom OS zu werden, gibt es die Units LCLIntf, LCLType, LCLProc und LMessages - dort werden viele betriebssystem-spezifische Aufrufe für andere widgetsets implementiert. ShowWindow ist auch mit dabei, FindWindow dagegen nicht - also bleibt das ganze trotzdem eine "windows-only" Lösung.mzurhorst hat geschrieben:Ja, stimmt.
Ich bin davon ausgegangen dass Lazarus-Code unabhängig vom OS ist und das hinter den Kulissen erledigt.
-
- Beiträge: 2118
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: Fenster erkennen und verstecken
Ich bin nicht früh aufgestanden, sondern sehr spät schlafen gegangenmzurhorst hat geschrieben:Tatsächlich hatte ich es um 2 Uhr bereits hin gekriegt, aber nicht mehr geantwortet. Habe aber nicht mit so einem Frühaufsteher gerechnet![]()

So als faustregel, wenn du auf was einfluss nehmen willst was nicht mehr Teil der eigenen anwendung ist (z.b. Fremde fenster bearbeiten, Prozessspeicher auslesen, Desktop hintergrundbild setzen, etc.) musst du wahrscheinlich auf die SystemAPI zugreifen.mzurhorst hat geschrieben:Ja, stimmt.
Ich bin davon ausgegangen dass Lazarus-Code unabhängig vom OS ist und das hinter den Kulissen erledigt.
Lazarus hat das ziel das LCL anwendungen überall gleich laufen, nicht eine komplette SystemAPI zu streamlinen. Das wäre ein komplettes projekt für sich (bzw. es ist ein komplettes projekt für sich, nämlich das ist genau was Wine macht)
Re: Fenster erkennen und verstecken
Hallo nochmal.
Ich wollte mal fix den Test aus dem GUI in ein schlichtes Executable umwandeln, welches bei Start die Prozedur startet.
Allerdings kriege ich nun einen Fehler beim Kompilieren in dieser Zeile:
NextHandle := GetWindow(Application.Handle, GW_HWNDFIRST);
Application sei nicht deklariert. Kommt das nicht auf den uses Windows?
Danke und Grüße,
Marcus
Ich wollte mal fix den Test aus dem GUI in ein schlichtes Executable umwandeln, welches bei Start die Prozedur startet.
Allerdings kriege ich nun einen Fehler beim Kompilieren in dieser Zeile:
NextHandle := GetWindow(Application.Handle, GW_HWNDFIRST);
Application sei nicht deklariert. Kommt das nicht auf den uses Windows?
Danke und Grüße,
Marcus
Re: Fenster erkennen und verstecken
TApplication ist in Forms und für's GUI gedacht:
https://lazarus-ccr.sourceforge.io/docs ... ation.html
https://lazarus-ccr.sourceforge.io/docs ... ation.html
Re: Fenster erkennen und verstecken
Huch, welcher Handle ist das denn? Ich dachte das sei derjenige on z. B. dem Chrome Fenster, was versteckt werden soll.
Den muss ich doch auch finden können wenn ich selbst kein GUI habe.
Den muss ich doch auch finden können wenn ich selbst kein GUI habe.
Re: Fenster erkennen und verstecken
Das ist das von deiner eigenen GUI Anwendung.mzurhorst hat geschrieben:Huch, welcher Handle ist das denn?
Wie und ob das, was du willst von Console bzw. Service geht, muss dir ein Windows Spezialist oder Google beantworten. Das weiss ich nicht.
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Re: Fenster erkennen und verstecken
Ich hatte mal angefangen teile von "wmctrl" nach Pascal zu Konvertieren.
es ist aber noch sehr früh am Anfang, dass geht aber nur soweit ich weiß unter X11 basierten Desktops.
Ich kann die Arbeitsfläche Wechseln und ich kann eine Liste der Fenster holen, dabei gibt es jedoch noch hin und wieder ein Pointer Fehler.
Im Anhang findet ihr mein Projekt.
In der Hauptunit findet ihr auch den Link zum Github von wmctrl, danach habe ich mich gerichtet.
Edit1: Es ist mehr zum Zeigen.... es ist halt noch sehr früh am Anfang.
es ist aber noch sehr früh am Anfang, dass geht aber nur soweit ich weiß unter X11 basierten Desktops.
Ich kann die Arbeitsfläche Wechseln und ich kann eine Liste der Fenster holen, dabei gibt es jedoch noch hin und wieder ein Pointer Fehler.
Im Anhang findet ihr mein Projekt.
In der Hauptunit findet ihr auch den Link zum Github von wmctrl, danach habe ich mich gerichtet.
Edit1: Es ist mehr zum Zeigen.... es ist halt noch sehr früh am Anfang.
- Dateianhänge
-
plwmCtrl.zip
- (120.84 KiB) 109-mal heruntergeladen
MFG
Michael Springwald
Michael Springwald