Verhindern, dass Anwendungen den Fokus stehlen

191

Gibt es Lösungen, um zu verhindern, dass Anwendungen den Fokus aus dem aktiven Fenster stehlen?

Dies ist besonders ärgerlich, wenn ich eine Anwendung starte, zu etwas anderem wechsle und die neue Anwendung einen halben Textsatz empfängt.

svandragt
quelle
9
@Ivo Windows 7 in meinem Fall aber ich denke für SuperUser wären alle Windows Versionen relevant
svandragt
3
Der Moderator hat diese Frage ( superuser.com/questions/199821/…) mit der aktuellen Frage zusammengeführt . Dies ist falsch. Die Antwort auf die aktuelle Frage gilt nicht für Windows 7 und sollte daher nicht zusammengeführt werden. Bisher konnte ich keine Lösung für dieses Problem in Windows 7 finden
Alex Angelico
17
Dies ist eines meiner Lieblings-Peelings mit jeder GUI, die ich jemals benutzt habe. Sie tippen und tadeln, einige piepende Dialogfelder stehlen den Fokus und die Hälfte Ihrer Tastatureingaben gehen an einen anderen Ort. Man könnte meinen, die Entwickler von Fenstersystemen hätten dies vor Jahrzehnten herausgefunden. Wenn ein Fenster aktiv ist, verzögern Sie die Belichtung des neuen Fensters. ZB erst drei oder vier Sekunden nach dem letzten Klicken oder Drücken der Taste im aktuell ausgewählten Fenster etwas auf der Benutzeroberfläche anzeigen. Doh!
Kaz
24
This is especially annoying when I'm starting an application, switch to do something else and the new application starts receiving half a sentence of text.Noch ärgerlicher ist es, wenn ein Dialogfeld angezeigt wird und Sie es unbeabsichtigt schließen, ohne die Nachricht zu sehen, weil Sie gerade gedrückt Spaceoder Entereinen Satz eingegeben haben.
Synetech
3
Das ist eigentlich mehr als ärgerlich, ich würde sagen, dass es ein Sicherheitsrisiko ist. Es gibt nichts, was das Auftauchen einer Anwendung verhindern könnte, wenn Sie gerade ein Kennwort eingeben und Ihre Eingaben abrufen.
Chris Peacock

Antworten:

51

Dies ist ohne umfangreiche Manipulation von Windows-Interna nicht möglich und Sie müssen darüber hinwegkommen.

Es gibt Momente im täglichen Computereinsatz, in denen es wirklich wichtig ist, dass Sie eine Aktion ausführen, bevor das Betriebssystem die Ausführung einer anderen zulässt. Dazu muss Ihr Fokus auf bestimmte Fenster fixiert werden. In Windows liegt die Kontrolle über dieses Verhalten weitgehend bei den Entwicklern der einzelnen Programme, die Sie verwenden.

Nicht jeder Entwickler trifft die richtigen Entscheidungen, wenn es um dieses Thema geht.

Ich weiß, dass das sehr frustrierend und nervig ist, aber Sie können Ihren Kuchen nicht haben und ihn auch essen. Es gibt wahrscheinlich viele Fälle in Ihrem täglichen Leben, in denen Sie vollkommen in Ordnung sind, wenn der Fokus auf ein bestimmtes Benutzeroberflächenelement oder eine Anwendung verschoben wird, in der der Fokus darauf verriegelt bleiben soll. Die meisten Anwendungen sind jedoch bei der Entscheidung, wer gerade die Nase vorn hat, ziemlich gleich und das System kann niemals perfekt sein.

Vor einiger Zeit habe ich ausführliche Nachforschungen angestellt, um dieses Problem ein für alle Mal zu lösen (und bin gescheitert). Das Ergebnis meiner Recherche finden Sie auf der Projektseite Ärger .

Das Projekt enthält auch eine Anwendung, die wiederholt versucht, den Fokus zu erreichen, indem sie Folgendes aufruft:

switch( message ) {
  case WM_TIMER:
    if( hWnd != NULL ) {
      // Start off easy
      // SetForegroundWindow will not move the window to the foreground,
      // but it will invoke FlashWindow internally and, thus, show the
      // taskbar.
      SetForegroundWindow( hWnd );

      // Our application is awesome! It must have your focus!
      SetActiveWindow( hWnd );

      // Flash that button!
      FlashWindow( hWnd, TRUE );
    }
    break;

Wie wir aus diesem Snippet ersehen können, konzentrierte sich meine Forschung auch auf andere Aspekte des Verhaltens der Benutzeroberfläche, die mir nicht gefallen.

Ich habe versucht, dieses Problem zu lösen, indem ich in jeden neuen Prozess eine DLL geladen und die API-Aufrufe angehängt habe, die dazu führen, dass ein anderes Fenster aktiviert wird.
Der letzte Teil ist einfach, dank der hervorragenden API-Hooking-Bibliotheken. Ich habe die sehr gute mhook Bibliothek benutzt :

#include "stdafx.h"
#include "mhook-2.2/mhook-lib/mhook.h"

typedef NTSTATUS( WINAPI* PNT_QUERY_SYSTEM_INFORMATION ) ( 
  __in       SYSTEM_INFORMATION_CLASS SystemInformationClass,     
  __inout    PVOID SystemInformation, 
  __in       ULONG SystemInformationLength, 
  __out_opt  PULONG ReturnLength    
);

// Originals
PNT_QUERY_SYSTEM_INFORMATION OriginalFlashWindow   = 
  (PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress( 
  ::GetModuleHandle( L"user32" ), "FlashWindow" );

PNT_QUERY_SYSTEM_INFORMATION OriginalFlashWindowEx = 
  (PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress( 
  ::GetModuleHandle( L"user32" ), "FlashWindowEx" );

PNT_QUERY_SYSTEM_INFORMATION OriginalSetForegroundWindow = 
  (PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress( 
  ::GetModuleHandle( L"user32" ), "SetForegroundWindow" );

// Hooks
BOOL WINAPI
HookedFlashWindow(
  __in  HWND hWnd,
  __in  BOOL bInvert
  ) {
  return 0;
}

BOOL WINAPI 
HookedFlashWindowEx(
  __in  PFLASHWINFO pfwi
  ) {
  return 0;
}

BOOL WINAPI 
HookedSetForegroundWindow(
  __in  HWND hWnd
  ) {
  // Pretend window was brought to foreground
  return 1;
}


BOOL APIENTRY 
DllMain( 
  HMODULE hModule,
  DWORD   ul_reason_for_call,
  LPVOID  lpReserved
  ) {
  switch( ul_reason_for_call ) {
    case DLL_PROCESS_ATTACH:
      Mhook_SetHook( (PVOID*)&OriginalFlashWindow,         HookedFlashWindow );
      Mhook_SetHook( (PVOID*)&OriginalFlashWindowEx,       HookedFlashWindowEx );
      Mhook_SetHook( (PVOID*)&OriginalSetForegroundWindow, HookedSetForegroundWindow );
      break;

    case DLL_PROCESS_DETACH:
      Mhook_Unhook( (PVOID*)&OriginalFlashWindow );
      Mhook_Unhook( (PVOID*)&OriginalFlashWindowEx );
      Mhook_Unhook( (PVOID*)&OriginalSetForegroundWindow );
      break;
  }
  return TRUE;
}

Bei meinen damaligen Tests hat das super geklappt. Mit Ausnahme des Teils des Ladens der DLL in jeden neuen Prozess. Wie man sich vorstellen kann, ist das nichts, was man zu leicht nehmen sollte. Ich habe damals den AppInit_DLLs- Ansatz verwendet (was einfach nicht ausreicht).

Grundsätzlich funktioniert das super. Aber ich habe nie die Zeit gefunden, etwas zu schreiben, das meine DLL richtig in neue Prozesse einfügt. Und die dafür aufgewendete Zeit überschattet größtenteils den Ärger, den der Fokusraub mir bereitet.

Neben dem DLL-Injection-Problem gibt es auch eine Focus-Stealing-Methode, die ich in der Implementierung von Google Code nicht behandelt habe. Ein Mitarbeiter hat tatsächlich zusätzliche Nachforschungen angestellt und sich mit dieser Methode befasst. Das Problem wurde auf SO diskutiert: https://stackoverflow.com/questions/7430864/windows-7-prevent-application-from-losing-focus

Der Hochstapler
quelle
Glauben Sie, dass Ihre Lösung nach Java portiert werden könnte? Ich habe gesucht und Fragen gestellt, aber nichts gefunden. Vielleicht könnte ich die Hook-Bibliothek selbst in Java importieren jne?
Tomáš Zato,
@ TomášZato: Keine Ahnung. Ich benutze diesen Code selbst nicht aktiv.
Der Hochstapler
Ich versuche es zumindest als C ++ zu kompilieren (und dann die kompilierte DLL aus Java zu injizieren / zu entfernen). Aber das geht auch nicht so gut. Ich möchte es hier nicht in Kommentaren diskutieren, aber wenn Sie mir tatsächlich helfen könnten, es zum Laufen zu bringen, wäre ich sehr anmutig! Ich habe einen Chatraum erstellt. Wenn das funktioniert, schreibe
Tomáš Zato
23

In Windows 7 wird der ForegroundLockTimeoutRegistrierungseintrag nicht mehr überprüft. Sie können dies mit Process Monitor überprüfen. In Windows 7 können Sie das Vordergrundfenster nicht ändern. Lesen Sie die Details , es gibt es sogar seit Windows 2000.

Die Dokumentation ist jedoch beschissen und sie jagen sich gegenseitig und finden Wege , das zu umgehen .

Es ist also etwas mit Buggy los SetForegroundWindow, oder ähnliche API-Funktionen ...

Die einzige Möglichkeit, dies wirklich richtig zu machen, besteht darin, eine kleine Anwendung zu erstellen, die in regelmäßigen Abständen aufruft LockSetForegroundWindowund alle Aufrufe unserer fehlerhaften API-Funktion praktisch deaktiviert.

Wenn das nicht ausreicht (ein weiterer fehlerhafter API-Aufruf?), Können Sie noch weiter gehen und einige API-Überwachungen durchführen, um zu sehen, was vor sich geht. Anschließend schließen Sie die API-Aufrufe einfach an jeden Prozess an, nach dem Sie alle durcheinandergebrachten Aufrufe entfernen können der Vordergrund. Ironischerweise wird dies jedoch von Microsoft abgeraten ...

Tamara Wijsman
quelle
3
Hat jemand einen reproduzierbaren Anwendungsfall dafür in Windows 7? Angesichts der Tatsache, dass die Leute eher das Gegenteil erleben (zum Beispiel, dass ich oft fordere, dass Windows hinter meinem aktuellen Fenster versteckt wird) und dass ich dies in Windows 7 noch nicht sehe, wäre es ziemlich ärgerlich, eine Anwendung zu schreiben, aber nicht in der Lage zu sein Probier es aus. Darüber hinaus sollte dies nach Angaben von Microsoft unter Windows 7 nicht mehr passieren. Bestenfalls wurde festgestellt, dass der Fokus der Tastatur nur versehentlich geändert werden kann. Dieser API-Aufruf behebt das, aber ich weiß nicht, wie ich testen soll, ob es tatsächlich funktioniert. .
Tamara Wijsman
1
Das Installationsprogramm (basierend auf InnoSetup) startet andere Prozesse und mögliche andere (versteckte) Setups, aber ich weiß nicht, auf welchem ​​Setup-Ersteller sie basieren.
Daniel Beck
6
@TomWijsman: Öffnen Sie regedit und suchen Sie nach zufälligem Text, der nicht gefunden wird. Gehe in eine andere App und beginne zu tippen. Wenn die Suche beendet ist, stiehlt regedit den Fokus.
Endolith
1
@endolith: Nicht reproduzierbar, allerdings mit Windows 8 Replase Preview. Welches Betriebssystem verwenden Sie? In meinem Fall wird nur die Anwendung am unteren Rand hervorgehoben, aber das Surfen wird überhaupt nicht unterbrochen ...
Tamara Wijsman
21
Ja, Win7 Pro 64-Bit. Bei erhöhten Prozessen ist das Stehlen von Fokussierungen sogar noch schlimmer, da sie das Drücken der <Eingabetaste> erfassen, wenn dies nicht der Fall ist. Nichts sollte jemals in der Lage sein, den Fokus zu stehlen.
Endolith
18

Es gibt eine Option in TweakUI, die dies tut. Es verhindert, dass die meisten der üblichen Tricks, die zweifelhafte Softwareentwickler anwenden, die Konzentration auf ihre App forcieren.

Es ist jedoch ein anhaltender Rüstungskrieg, daher weiß ich nicht, ob er für alles funktioniert.

Update : Laut EndangeredMassa funktioniert TweakUI unter Windows 7 nicht.

Simon P Stevens
quelle
2
Ist Tweakui mit Windows 7 kompatibel?
Frankster
@frankster. Keine Ahnung, sorry, ich vermute es ist wahrscheinlich nicht. Laden Sie es herunter und probieren Sie es aus. Melde dich, wenn du das tust, jeder weiß.
Simon P Stevens
5
Selbst wenn Sie die von TweakUI festgelegte Registrierungseinstellung verwenden, funktioniert dies unter Win7 nicht.
EndangeredMassa
@EndangeredMassa Welcher Registrierungsschlüssel ist das?
n611x007,
2
Der Registrierungsschlüssel lautet HKEY_CURRENT_USER \ Control Panel \ Desktop \ ForegroundLockTimeout (in Millisekunden). Und ja, es funktioniert nicht mehr unter Windows 7.
foo
14

Ich glaube, dass es einige Verwirrung geben kann, da es zwei Möglichkeiten gibt, den Fokus zu stehlen: (1) ein Fenster, das in den Vordergrund tritt, und (2) das Fenster, das Tastenanschläge empfängt.

Das hier angesprochene Problem ist wahrscheinlich das zweite, bei dem ein Fenster den Fokus beansprucht, indem es sich in den Vordergrund rückt - ohne die Aufforderung oder Erlaubnis des Benutzers.

Die Diskussion muss hier zwischen XP und 7 aufgeteilt werden.

Windows XP

In XP gibt es einen Registry-Hack, durch den XP auf die gleiche Weise wie Windows 7 funktioniert und verhindert, dass Anwendungen den Fokus stehlen:

  1. Verwenden Sie regedit gehen Sie zu: HKEY_CURRENT_USER\Control Panel\Desktop.
  2. Doppelklicken Sie auf ForegroundLockTimeoutund setzen Sie den Wert hexadezimal auf 30d40.
  3. Drücken Sie OK und beenden Sie regedit.
  4. Starten Sie Ihren PC neu, damit die Änderungen wirksam werden.

Windows 7

(Die folgende Diskussion bezieht sich hauptsächlich auch auf XP.)

Bitte haben Sie Verständnis dafür, dass Windows auf keine Weise verhindern kann, dass Anwendungen den Fokus stehlen und funktionsfähig bleiben. Wenn Ihr Antivirus beispielsweise während einer Dateikopie eine mögliche Bedrohung entdeckt und Sie in einem Fenster dazu auffordern möchte, eine Aktion auszuführen, werden Sie niemals verstehen, warum die Kopie niemals beendet wird, wenn dieses Fenster blockiert ist.

In Windows 7 ist nur eine Änderung des Verhaltens von Windows selbst möglich, nämlich die Verwendung der MS-Windows-Registrierungs-Hacks "Fokus folgt Maus" , wobei der Fokus und / oder die Aktivierung immer auf die Fenster unter dem Cursor gerichtet sind. Es kann eine Verzögerung hinzugefügt werden, um zu verhindern, dass Anwendungen auf dem gesamten Desktop angezeigt werden.
Siehe diesen Artikel: Windows 7 - Maus-Hover aktiviert das Fenster .

Andernfalls muss das schuldige Programm erkannt und neutralisiert werden: Wenn dies immer dieselbe Anwendung ist, die den Fokus erhält, ist diese Anwendung so programmiert, dass sie den Fokus erhält, und dies kann verhindert werden, indem entweder der Start des Computers deaktiviert wird oder Verwenden Sie eine von dieser Anwendung bereitgestellte Einstellung, um dieses Verhalten zu vermeiden.

Sie können das im VB-Code enthaltene VBS-Skript verwenden, das angibt, wer den Fokus stiehlt. Der Autor hat den Täter als "Call-Home" -Updater für eine Druckersoftware identifiziert.

Eine verzweifelte Maßnahme, wenn alles andere fehlschlägt und Sie diese schlecht programmierte Anwendung identifiziert haben, besteht darin, sie zu minimieren und zu hoffen, dass sie sich dann nicht in den Vordergrund rückt. Eine stärkere Form der Minimierung ist die Verwendung eines der in Best Free Application Minimizer aufgelisteten kostenlosen Produkte in der Taskleiste .

Die letzte Idee in der Reihenfolge der Verzweiflung besteht darin, Ihren Desktop virtuell zu beschädigen , indem Sie ein Produkt wie Desktops oder Dexpot verwenden und Ihre Arbeit auf einem anderen Desktop als dem Standarddesktop ausführen .

[BEARBEITEN]

Da Microsoft die Archive Gallery eingestellt hat, wird hier der oben genannte VB-Code wiedergegeben:

Declare Auto Function GetForegroundWindow Lib "user32.dll" () As Integer
Declare Auto Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As Integer, ByRef procid As Integer) As UInteger

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.RichTextBox1.AppendText("Starting up at " & Now & vbCrLf)
    End Sub

    Private Sub GoingAway(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Deactivate, Me.LostFocus

        Dim hwnd As Integer = GetForegroundWindow()
        ' Note that process_id will be used as a ByRef argument
        ' and will be changed by GetWindowThreadProcessId
        Dim process_id As Integer = 1
        GetWindowThreadProcessId(hwnd, process_id)

        If (process_id <> 1) Then
            Dim appExePath As String = Process.GetProcessById(process_id).MainModule.FileName() 
            Me.RichTextBox1.AppendText("Lost focus at " & Now & " due to " & appExePath & vbCrLf)
        Else
            Me.RichTextBox1.AppendText("Lost focus due to unknown cause.")
        End If

    End Sub
Harrymc
quelle
48
"Wenn dieses Fenster blockiert ist, werden Sie nie verstehen, warum die Kopie niemals beendet wird." Das ist nicht wahr. Das richtige Verhalten besteht darin, den Benutzer mit einem blinkenden Taskleistensymbol zu benachrichtigen (oder möglicherweise mit einer Popup- oder Toaster-Benachrichtigung oder Ähnlichem). Wenn Sie den Benutzer mit einem Fenster unterbrechen, in dem die Tastatureingaben abgefangen werden, wird die Antivirensoftware angewiesen, die eine oder andere Aktion nach dem Zufallsprinzip auszuführen. Auf keinen Fall ein guter Weg, um Dinge zu tun.
Endolith
1
"Wenn dieses Fenster blockiert ist, würden Sie nie verstehen, warum die Kopie niemals beendet wird" Das ist nicht wahr. Das richtige Verhalten besteht darin, den Benutzer mit einem blinkenden Taskleistensymbol zu benachrichtigen. Manchmal habe ich in einem laufenden Programm auf eine Schaltfläche oder etwas anderes geklickt, wodurch ein neuer modaler Dialog erstellt wurde (z. B. Öffnen einer Datei ) Ich wechsle zu einem anderen Programm, bevor der Dialog erstellt wird. Infolgedessen wird der Dialog ausgeblendet und das andere Programm kann nicht aufgerufen und der Dialog nicht geschlossen werden. Weder die Schaltfläche in der Taskleiste noch sie Alt-Tabfunktionieren. nur den Dialog nach vorne zwingen.
Synetech
1
@Synetech: Manchmal besteht die einzige Lösung für das nicht vordere Dialogfeld darin, die Aufgabe abzubrechen. Die Fokusalgorithmen in Windows sind wirklich mies.
Harrymc
2
@harrymc, ich muss nie darauf zurückgreifen, eine der Apps zu töten. Ich führe einfach mein Fensterbearbeitungsprogramm aus ( WinSpy ++ macht den Trick einfach großartig) und verstecke das Fenster vor mir. Dann kann ich das nicht mehr aktive Dialogfeld schließen und das ausgeblendete Fenster wieder anzeigen. Es ist nicht bequem, aber es ist besser, als einen der Prozesse zu beenden.
Synetech
1
@harrymc, nicht wirklich; Das Beenden einer App und das Verlieren von Dingen macht einfach mehr Dampf. Wenn es sich um ein modales Dialogfeld handelt (das das übergeordnete Fenster sperrt und keine Taskleistenschaltfläche aufweist), wird es nicht in der Alt+TabListe und meiner Erfahrung nach in einem solchen Fenster angezeigt Alt+TabWenn ein modaler Dialog geöffnet ist, wird der modale Dialog nicht immer (nie?) angezeigt , insbesondere, wenn der Dialog nie geändert wurde, um den Fokus zu erhalten. :-|
Synetech
2

Ghacks hat eine mögliche Lösung:

Es kommt mehrmals täglich vor, dass einige Anwendungen den Fokus des aktiven Fensters stehlen, indem sie aufspringen. Dies kann verschiedene Gründe haben, zum Beispiel wenn ich Dateien extrahiere oder eine Übertragung beendet wird. In den meisten Fällen spielt es keine Rolle, aber manchmal schreibe ich einen Artikel. Dies bedeutet nicht nur, dass ich einige Wörter erneut eingeben muss, sondern auch, dass ich die Konzentration verloren habe und klicken muss, um den Fokus wiederzuerlangen.

Auf der Pro Reviewer- Website finden Sie einen Tipp, wie Sie dies verhindern können. Die einfachste Möglichkeit, Fokusdiebstahl zu verhindern, ist die Verwendung der Tweak-Benutzeroberfläche mit der Einstellung „Verhindern, dass Anwendungen den Fokus stehlen“. Wenn Sie diese Option aktivieren, wird verhindert, dass andere Anwendungen plötzlich auftauchen und den Fokus des Fensters stehlen, in dem Sie gerade arbeiten.

Dies funktioniert nur, wenn die Anwendung zuvor minimiert wurde. Anstatt den Fokus zu stehlen, blinkt er mehrmals, was im selben Menü in der Benutzeroberfläche von Tweak festgelegt werden kann . Wenn Sie Tweak UI nicht verwenden möchten, können Sie die Einstellung in der Windows-Registrierung ändern.

Navigieren Sie zum Registrierungsschlüssel HKEY_CURRENT_USER> Systemsteuerung> Desktop und ändern Sie den ForegroundLockTimeout-Wert in 30d40 (hexadezimal) oder 200000 (dezimal). Der Schlüssel ForeGroundFlashCount definiert die Anzahl der Blitze eines Fensters, um den Benutzer zu warnen, wobei 0 unbegrenzt bedeutet.

Ivo Flipse
quelle
20
Dies funktioniert unter keinem Betriebssystem nach XP. Dieser Registrierungswert ist bereits auf diesen Wert gesetzt (standardmäßig, glaube ich) und funktioniert sowieso nicht.
EndangeredMassa
1
Nur zum zweiten, dass ich unter Windows 7 (64-Bit) Focus-Stealing erlebe (VS 2012, wenn es endlich aktiv ist, zum Beispiel), und der obige Registrierungsvorschlag ist bereits vorhanden. Technische Bestätigung in dieser Antwort: superuser.com/a/403554/972
Michael Paulukonis
2

Inspiriert von der Antwort von Der Hochstapler habe ich beschlossen, einen DLL-Injektor zu schreiben, der sowohl mit 64- als auch mit 32-Bit-Prozessen funktioniert und das Stehlen von Fokus auf Windows 7 oder neuer verhindert: https://blade.sk/stay-focused/

Die Art und Weise, wie es funktioniert, besteht darin, dass es nach neu erstellten Fenstern (unter Verwendung von SetWinEventHook) sucht und eine DLL, die der von Der Hochstapler sehr ähnlich ist, in den Prozess des Fensters einfügt, falls diese noch nicht vorhanden ist. Es entlädt die DLLs und stellt die ursprüngliche Funktionalität beim Beenden wieder her.

Nach meinen Tests funktioniert es bisher sehr gut. Das Problem scheint jedoch tiefer zu gehen als nur das Anrufen von Apps SetForegroundWindow. Wenn zum Beispiel ein neues Fenster erstellt wird, wird es automatisch in den Vordergrund gerückt, was auch die Eingabe eines Benutzers in ein anderes Fenster stört.

Um mit anderen Methoden des Fokusdiebstahls fertig zu werden, sind weitere Tests erforderlich. Ich würde mich über Feedback zu Szenarien freuen, in denen dies geschieht.

Klinge
quelle
0

Ich habe herausgefunden, wie die Taskleiste daran gehindert werden kann, ein neu aktiviertes Zielfenster zu flashen, nachdem Sie das Hauptfenster dieses Prozesses programmgesteuert von einem anderen Prozess aus aktiviert, maximiert und fokussiert haben. Erstens gibt es viele Einschränkungen, ob diese Operation zulässig ist.

"Das System schränkt ein, welche Prozesse das Vordergrundfenster festlegen können. Ein Prozess kann das Vordergrundfenster nur festlegen, wenn eine der folgenden Bedingungen erfüllt ist:

  • Der Prozess ist der Vordergrundprozess.
  • Der Prozess wurde durch den Vordergrundprozess gestartet.
  • Der Prozess hat das letzte Eingabeereignis empfangen.
  • Es gibt keinen Vordergrundprozess.
  • Der Vordergrundprozess wird debuggt.
  • Der Vordergrund ist nicht gesperrt (siehe LockSetForegroundWindow).
  • Das Zeitlimit für die Vordergrundsperre ist abgelaufen (siehe SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
  • Es sind keine Menüs aktiv.

https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-allowsetforegroundwindow

Also , wenn der Controlling - Prozess im Vordergrund steht, kann es vorübergehend ermöglicht eine anderen Prozess vollständig in den Vordergrund zu stehlen , indem Aufruf AllowSetForegroundWindow mit der Prozess - ID des Zielprozesses. Danach kann der Zielprozess SetForegroundWindow selbst mit seinem eigenen Fenster-Handle aufrufen und es wird funktionieren.

Dies erfordert natürlich eine gewisse Koordination zwischen den beiden Prozessen, funktioniert jedoch, und wenn Sie dies tun, um eine Einzelinstanz-App zu implementieren, die alle Explorer-Klickstarts in die vorhandene App-Instanz umleitet, sind Sie bereits dabei Habe sowieso eine (zB) Named Pipe um Dinge zu koordinieren.

Glenn Slayden
quelle