# Graphik über den Bildschirm legen (Windows)



## White_Fox (10. Aug 2022)

Moin Leute

Folgendes Vorhaben: Ich will eine kleine Graphik über meinen Bildschirm legen. Sagen wir, es soll ein kleines Dreieck in der Bildschirmmitte erscheinen. Zum größten Teil durchsichtig, sodaß der dahinterliegende Bildschirminhalt noch immer gut zu sehen ist.

Ein Programm, mit dem der Benutzer im Vordergrund arbeitet, soll weiter im Vordergrund bleiben, man soll damit ganz normal weiterarbeiten können. Am besten bleibt es vollkommen unberührt vom Erscheinen und Dasein des besagten Dreiecks.

Für die Maus soll das Dreieck praktisch inexistent sein. Klickt der Benutzer auf das Dreieck, so soll das Verhalten genau so sein, als gäbe es das Dreieck nicht. Ist hinter dem Dreieck z.B. ein Button von irgendeinem Programm, so soll es sein als hätte der Benutzer auf den Button geklickt.

Hat jemand eine Idee, wie ich das realisieren kann?


----------



## KonradN (10. Aug 2022)

Für welche Betriebssysteme?

Unter Windows könnte man dies erreichen - das Fenster holen und Attribute setzen. Eine schnelle Suche hat jetzt nur VB Code ergeben, aber die Methoden sind ja auch per JNI oder so aufrufbar und es ist nicht wirklich komplex: https://www.codeproject.com/Articles/12877/Transparent-Click-Through-Forms


----------



## White_Fox (10. Aug 2022)

Ja, für Windows.


----------



## Robert Zenz (10. Aug 2022)

Counter Strike Fadenkreuz?

Wie @KonradN bereits gesagt hat, es kommt immer auf das Betriebssystem an. Grundsaetzlich kann man aber eigentlich immer ein einfaches Fenster erzeugen und dieses dann mit den notwendigen (systemspezifischen) Attributen ausstatten um es durchsichtig zu machen. Die Ereignisse ist wieder ein anderes Thema, aber wenn ein Spiel den Fokus hat, hat es ohnehin den Fokus die meiste Zeit ueber. Eventuell kommt man sogar damit weg ein Swing Fenster zu machen, und dort den Hintergrund dann teilweise Transparent zu machen. Ich bilde mir ein dafuer haette es irgendwo irgendwie mal Unterstuetzung gegeben.

Ich glaube unter X11 gab es noch eigene Eigenschaften welche es erlaubten dass ein Fenster "durchklickbar" ist.


----------



## thecain (10. Aug 2022)

Oder ganz "Old School" eine halbtransparente folie auf den Bildschirm kleben.


----------



## White_Fox (11. Aug 2022)

Herzlichen Dank für die vielen Anregungen.



Robert Zenz hat gesagt.:


> Counter Strike Fadenkreuz?


Hehe...nein, nicht ganz so kompliziert. Aber im Prinzip ähnlich. Habt ihr schonmal etwas von Neurofeedback gehört?




Leute, die sowas machen, haben noch eine Art "Alltagstraining". Z.B. kleine Kärtchen, wo dieser blaue Pfeil drauf ist. Da gibt es zwar kein Feedback, aber der erlernte Trainingseffekt kommt trotzdem.  Und das will ich adaptieren...für Arbeit am Rechner. Ein kleiner Dämon im Hintergrund, der hin und wieder diesen Pfeil auf dem Bildschirm anzeigt, aber sonst beim Arbeiten nicht stört.

Der Witz von @thecain trifft es sogar tatsächlich ganz gut...ich will die Folie halt nur nicht händisch dauernd auf den Bildschirm ziehen und wieder draufpappen müssen.

Ich habe gestern mal noch auf die Schnelle das hier in meine IDE geworfen:








						How to create an overlay window in Java?
					

I'm trying to create a HUD style display for a foreign application.  To do this, I'd need to make a transparent overlay window, that would be placed on top of the window of the foreign application....




					stackoverflow.com
				



Das Programm wirft zwar keinen Fehler, aber zeigt eben auch nix. Die zwei Textboxen, die es anzeigen soll, sehe ich nirgendwo.


----------



## Robert Zenz (11. Aug 2022)

White_Fox hat gesagt.:


> Das Programm wirft zwar keinen Fehler, aber zeigt eben auch nix. Die zwei Textboxen, die es anzeigen soll, sehe ich nirgendwo.



Ja, sowas hatte ich in Erinnerung dass man mit Swing machen kann. Bei mir funktioniert das Beispiel unter Linux/X11. Eventuell ist die Groesze vom Fenster bei dir falsch, du kannst mal probieren eine Groesze zu setzen, oder dir die Groesze nach dem anzeigen entweder im Debugger anzusehen oder ausgeben zu lassen.

Beachte bei dem Beispiel dass der Prozess sich nicht mit dem Fenster schlieszt, das muss man noch einbauen.


----------



## KonradN (11. Aug 2022)

Also das JNA wirst Du brauchen, wenn Du willst, dass da etwas nicht angeklickt werden kann. Aber wie das geht, ist ja prinzipiell gezeigt in dem Link. (Sind ja nur wenige Aufrufe die interessant sind!) Das lässt sich also einfach in JNA übernehmen.

Das habe ich jetzt einfach einmal auf die Schnelle in Java gemacht (Das scheint ja wohl ein Problem zu sein, wenn das von allen so ignoriert wird?)

Meine Versuche mit der Transparenz waren aber noch nicht ganz so erfolgreich. Daran kann man also noch gerne etwas weiter herum spielen. Ich habe es leider nicht hin bekommen, dass der Hintergrund des Fensters ganz transparent ist.

Damit hat man aber dann direkt eine Grundlage für weitere Spielchen:

```
package de.kneitzel;

import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;

import javax.swing.*;
import java.awt.*;
import java.util.UUID;

import static com.sun.jna.platform.win32.WinUser.*;

public class OnTopWindow {
    public static class MainPanel extends JPanel {
        int dx, dy;
        Color background = new Color(0,0,0,255);
        Color drawing = new Color(255,255,255,255);
        public MainPanel(int dx, int dy) {
            this.dx = dx;
            this.dy = dy;
            setOpaque(true);
            setBackground(background);
        }

        @Override
        public void paintComponent(Graphics g) {
            g.setColor(drawing);
            g.drawLine(0, dy/2, dx, dy/2);
        }
    }

    public static void main(String[] args) {
        String title = UUID.randomUUID().toString();
        JFrame frame = new JFrame(title);
        frame.setSize(200, 200);
        frame.setUndecorated(true);
        frame.setAlwaysOnTop(true);
        frame.setBackground(new Color(0,0,0,255));
        //frame.setOpacity(0.1f);
        frame.add(new MainPanel(200, 200));
        frame.getRootPane().putClientProperty("apple.awt.draggableWindowBackground", false);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        WinDef.HWND hwnd = User32.INSTANCE.FindWindow(null, title);
        int curVal = User32.INSTANCE.GetWindowLong(hwnd, GWL_EXSTYLE);
        User32.INSTANCE.SetWindowLong(hwnd, GWL_EXSTYLE, curVal | WS_EX_TRANSPARENT | WS_EX_LAYERED);
        User32.INSTANCE.SetLayeredWindowAttributes(hwnd, 0, (byte) 30, LWA_ALPHA);
    }
}
```


----------



## Oneixee5 (11. Aug 2022)

Wenn man ein Oracle-Java verwendet, dann könnte man den Splashscreen für solche Zwecke verwenden.


----------



## KonradN (11. Aug 2022)

Oneixee5 hat gesagt.:


> Wenn man ein Oracle-Java verwendet, dann könnte man den Splashscreen für solche Zwecke verwenden.


Der lässt aber doch keine Mausklicks durch. Das war doch eine Anforderung. Der Code von mir leistet das - Clicks und co gehen durch die App sozusagen durch


----------

