Probleme mit Fenster auf einem WorkerW-Fenster

  • C#
  • .NET 5–6

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von DTF.

    Probleme mit Fenster auf einem WorkerW-Fenster

    Hi,

    ich sitz gerade dran eine Anwendung auf einem WorkerW-Fenster zu platzieren, auf dem Desktop hinter den Icons. Das funktioniert nicht ganz wie gewünscht. Wird das Fenster geschlossen, bleibt es sichtbar. Spy++ zeigt aber keine Childs mehr an.

    Hier wird das gezeigt:(Malen wie auch Fenster adden)
    codeproject.com/Articles/85602…top-Icons-in-Windows-plus

    Hab versucht mit RedrawWindow, InvalidateRect und UpdateWindow ein neu zeichnen zu erzwingen, aus Verzweiflung sogar SendMessage WM_PAINT probiert. Wie ich es dreh und wende das Fenster bleibt sichtbar.

    Durch Zufall hatte ich dann dem WinForm Opacity = 0 und WindowState auf maximized gestellt.(Im Form Load) Dann ist das Fenster entgegen jeder Erwartung sichtbar, allersdings mit WindowState.Normal, wird die App normal geschlossen oder auch abgeschossen, ist das Fenster weg und auch nicht mehr sichtbar. Scheint aber eher ein Bug zu sein, weil in WPF funktioniert das so nicht, wo dann das Fenster ist, ist nur ein schwarzes Rectangle das auch dableibt. Von daher werde ich das so nicht machen.

    Ich kann mir zwar auch den DC vom WorkerW holen und alles in ein Bitmap zwischenspeichern, das Wallpaper ist dann im Bitmap(schon probiert), dieses bitmap dann auf den WorkerW Fenster beim beenden malen. Aber keine echte Lösung, wenn im Taskmanager abgeschossen wird, oder gar ein AppCrash eintreten sollte, muss man den Explorer neu starten, sonst hat man dieses Artefakt erstmal auf'm Bildschirm. F5 auf'm Desktop drücken hilft auch nicht, auch kein ShChangeNotify. Werden nur die Icons vom SysListView32 aktualisiert.

    Ich glaube ich bin auf dem Holzweg. Wer hat irgendwelche Informationen für mich, wie man das funktionierend umsetzt? Also eine App auf dem Desktop hinter den Icons. Malen ist zu flickerig und bleibt auch da, das hab ich auch durchgekaut.

    Ich hab mal eine WinForms-NET Mappe angelegt die das reproduziert. So wie der Code jetzt ist funktioniert es bei mir(Win11 Pro 22H2). Kommentiert man die beiden Zeilen raus, bleibt das sichtbar.

    C#-Quellcode

    1. Opacity = 0;
    2. WindowState = FormWindowState.Maximized;


    Wer's probiert hat und das auf Bildschirm hat, einfach diese Commands in eine Bat und ausführen oder in einem Terminal eingeben um den explorer neu zu starten, dann ist alles wieder gut.

    Quellcode

    1. taskkill /im explorer.exe /f
    2. start explorer.exe


    PS. verschiebt man das Fenster via Code, wird es verschoben, aber der Bereich ausserhalb des Fensters wird nicht aktualisiert, so bleiben dann auch Artefakte.
    PPS. Ist klar, das so keine Mouse-/Keyboard-events durchkommen im Messageloop, das ist auch kein Problem, werde wenn das klappt wie ich hoffe einen Maushook nutzen. Evtl. kann man am WS_EX-Style hantieren, der WorkerW ist ja unter anderem WS_EX_TRANSPARENT(hat nichts mit Opacity zu tun!).

    Dateien
    • Sample.zip

      (5,71 kB, 65 mal heruntergeladen, zuletzt: )
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „DTF“ ()

    DTF schrieb:

    dann ist alles wieder gut.

    Oder einfach ein neues (das aktuelle) Wallpaper neu setzten, dann ist es auch wieder weg. Lustig. Habe gerade mal meine alte SetWindowAsWallpaper-Funtkion ausprobiert und habe das selbe verhalten. Es geht nicht mehr weg.
    @Fakiz Geil, klappt wie es soll. Musste nicht mal das WorkerW Fenster vertsecken(Siehe Anhang ist WS_VISIBLE), Fenster wird gezeigt und nach dem normalen schliessen, wie auch Process abschiessen ist nix mehr zu sehen. Auch mit der WPF Version, alles einwandfrei.

    @Bluespide
    Das mit dem Wallpaper neu setzen, ja, das könnte auch gehen. Der DC vom WorkerW lieferte mir ja das Wallpaper, hab das ja in ein Bitmap gemalt. Durch änderung hätte der WorkerW vom OS aus ja aktualisiert werden müssen.

    Konnte das auf diese paar Zeilen reduzieren auf Win11, ich hatte im Vergleich dazu fast einen Roman. Morgen mal auf Win10 probieren, wie das da mit dem einem WorkerW-Fenster ist.

    C#-Quellcode

    1. IntPtr hwnd = NativeMethods.FindWindow("Progman", "Program Manager");
    2. if (hwnd == IntPtr.Zero) throw new Exception("Progman not found");
    3. NativeMethods.SetParent(Handle, hwnd);

    Bilder
    • 1.jpg

      126,16 kB, 978×553, 50 mal angesehen
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „DTF“ ()

    Ich hab das eben auf Win10 probiert. Da war es erst nicht sichtbar, hab dann das WorkerW Fenster versteckt, dann ging es. Als ich das eben auf einem frisch gestarteten Win11 probiert hab, musste der WorkerW nun doch versteck werden, da war auf meinem Hauptrechner gestern der Wurm drin.


    So klappt das auf Win10 und 11, das hab ich jetzt ausgiebig auf 4 Rechnern getestet, unter verschiedenen Bedingungen. Allerdings war das WorkerW-Fenster immer schon da, hab die Zeile mit der Custom message drin gelassen, könnte besser sein.

    C#-Quellcode

    1. private IntPtr workerW = IntPtr.Zero;
    2. private void Form1_Load(object sender, EventArgs e)
    3. {
    4. IntPtr hwnd = NativeMethods.FindWindow("Progman", "Program Manager");
    5. if (hwnd == IntPtr.Zero) throw new Exception("Progman not found");
    6. NativeMethods.SendMessageTimeout(hwnd, 0x052C, IntPtr.Zero, IntPtr.Zero, NativeMethods.SMTO_NORMAL, 1000, IntPtr.Zero);
    7. NativeMethods.EnumWindows(new NativeMethods.EnumWindowsProc(SearchWorkerW), IntPtr.Zero);
    8. if (workerW == IntPtr.Zero) throw new Exception("WorkerW not found");
    9. NativeMethods.ShowWindow(workerW, NativeMethods.SW_HIDE);
    10. NativeMethods.SetParent(Handle, hwnd);
    11. }
    12. private bool SearchWorkerW(IntPtr hwnd, IntPtr lParam)
    13. {
    14. IntPtr sv = NativeMethods.FindWindowEx(hwnd, IntPtr.Zero, "SHELLDLL_DefView", null);
    15. if (sv != IntPtr.Zero) workerW = NativeMethods.FindWindowEx(IntPtr.Zero, hwnd, "WorkerW", null);
    16. return workerW == IntPtr.Zero;
    17. }

    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D