Graphik über den Bildschirm legen (Windows)

White_Fox

Top Contributor
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?
 
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.
 
Herzlichen Dank für die vielen Anregungen.

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:
Das Programm wirft zwar keinen Fehler, aber zeigt eben auch nix. Die zwei Textboxen, die es anzeigen soll, sehe ich nirgendwo.
 
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.
 
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:
Code:
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);
    }
}
 

Zurück
Oben