Ich habe ein weiteres neues Tool zu meiner Tiny Tools Collection hinzugefügt: ToggleDisplay

Code: https://github.com/sgrottel/tiny-tools-collection/tree/main/ToggleDisplay
Ausführbare Datei: https://github.com/sgrottel/tiny-tools-collection/releases/tag/ToggleDisplay-v1.0

Damit könnt Ihr Displays aktivieren, deaktivieren und umschalten.

Warum das? Mein Computer ist an 2-3 Bildschirme angeschlossen. Zwei Computermonitore auf meinem Schreibtisch für die Arbeit. Und ein Fernseher auf der anderen Seite des Raumes, z.B. um Spiele von meinem Computer aus zu spielen oder um Videodateien in Ruhe anzusehen.

Oft genug fahre ich den Computer hoch, und dann verschwindet meine Maus vom Desktop, weil ich vergessen habe, dass der Fernseher vorher „an“ war, und die Maus hat sich über die Desktop-Monitore hinaus bewegt. Das ist ärgerlich. Die eingebaute Funktion „Windows-Taste + P“ ist verständlicherweise auf zwei Monitore beschränkt. Also musste ich immer „Windows + P“ drücken, dann „Weitere Einstellungen“, warten, bis der Dialog erscheint, herumfummeln, auf „Übernehmen“ drücken, … Ihr versteht, was ich meine.

Also habe ich im Internet recherchiert, wie man eine Anzeige programmgesteuert aktivieren oder deaktivieren kann. Und es gibt mehrere kostenlose Tools, mit denen das möglich ist. Ich habe zwei ausprobiert, und beide haben nicht funktioniert. Dann gibt es einen Hack, bei dem eine ausführbare Datei von Windows 10 unter Windows 11 verwendet wird. Ja, nein. Also gut. Suchen Sie weiter!

Es stellt sich heraus, dass es eine einfache API dafür gibt: ChangeDisplaySettingsEx. Nach einigen Experimenten konnte ich die Anzeige deaktivieren, aber nicht (wieder) aktivieren. Nicht gut genug. Weiter suchen!

Kurz später stellt sich heraus, dass es eine zweite API gibt, die nicht so einfach ist und für die es so gut wie keine brauchbare Dokumentation gibt: SetDisplayConfig. Dies scheint die API zu sein, die der in Windows eingebaute Dialog zur Anzeigekonfiguration verwendet. Aber … wie. Ich fand Code von „PuFF1k“ auf StackOverflow (https://stackoverflow.com/a/62038912/552373), der die API-Aufrufe des Windows-Dialogs zurückentwickelt hat. Ich habe seinen Code ausprobiert, und es funktioniert. Toll! Vielen Dank, PuFF1k!

Im Kern ist der Tricks, keine modeInfo-Daten an SetDisplayConfig zu übergeben, und alle sourceInfo.modeInfoIdx und targetInfo.modeInfoIdx aller Paths auf DISPLAYCONFIG_PATH_MODE_IDX_INVALID zu setzen.

Ein paar Überarbeitungen und Aufräumarbeiten später habe ich ToggleDisplay, bereit, mit der Welt geteilt zu werden.

Übrigens habe ich jetzt auch den Quellcode einiger meiner älteren Tools in dieses Tiny Tools Collection Repository aufgenommen:

Bei dieser Gelegenheit habe ich auch diese Projekte auf die neuesten DotNet-Laufzeiten aktualisiert. Eine automatisierte Build-Pipeline oder Releases habe ich nicht aufgesetzt. Vielleicht ein anderes Mal.

Dies ist mein dritter und letzter Artikel in meiner Serie über Anwendungs-Icons und -Logos. Diesmal schreibe ich über die Größe der Icons und warum wir darauf achten sollten. Zugegeben, hier geht es ziemlich um Perfektion, aber ich zeige eine leicht erreichbare und gute Optimierung die es wert ist. Seht Euch diese beiden Bilder an:

Sie zeigen das gleiche Icon. Genau das gleich Icon. Wirklich. Und beide zeigen das Bild mit 32×32 Pixeln.

Icon-Größen

Nochmal zur Wiederholung, wozu dienen Icons: Es handelt sich um eine ikonische, grafische Darstellung eines Logos, die besonders für kleine Größen optimiert ist, wie Favicons, kleine Logos oder Softwareanwendungs-Icons. Sie sind für sehr kleine Größen gedacht, traditionell bis runter zu 16×16 Pixel. Bei höher aufgelösten Bildschirmen ist diese superkleine Größe nicht mehr ganz so relevant. Deshalb habe ich für mein obiges Beispiel 32×32 gewählt. Diese Icons sollen also für solch kleinen Größen funktionieren. Ja, wir erstellen ausdrücklich Icons für diese kleinen Größen. Und genau das ist mein Argument, dass wir uns die Mühe machen sollten, die Grafiken auch für genau diese Größen zu optimieren, die wir anstreben, wenn wie das schon machen: 16×16, 24×24, 32×32, 48×48 und 64×64, traditionell.

Worin besteht nun der Unterschied zwischen den beiden obigen Bildern? Lassen Sie mich ohne zusätzliche Interpolation hineinzoomen, um den Unterschied deutlicher zu machen:

Das linke Bild ist das Referenzbild, das ich aus dem Clipart übernommen habe. Es zeigt genau das, was ich zeigen möchte, und stammt beispielsweise aus einer externen Designquelle. Aber die Linien stimmen nicht mit dem Pixelraster überein. Daher führt die Anti-Aliasing-Interpolation zu dem unscharfen Bild. Das rechte Bild ist die gleiche Grafik, aber alle Linienscheitelpunkte wurden leicht verschoben, um sie genau am Pixelraster auszurichten. Das Ergebnis ist ein viel schärferes Aussehen. Und der Aufwand ist minimal. Es genügt, das Symbol zu duplizieren und ein paar Eckpunkte in Ihrem Lieblingsgrafikprogramm zu verschieben und auf dem Pixelraster einschnappen zu lassen. Das ist es auf jeden Fall wert.

Ok, können wir nicht einfach für 16×16 optimieren und gut ist?

Nein. Zum einen ist 16×16 sehr, sehr klein, und wie oben geschrieben, verliert es im Zeitalter der hochauflösenden Displays an Bedeutung. Ähnlich wie bei der Abstraktion von einem Logo zu einem Icon, wie in meinem ersten Artikel dieser Serie beschrieben, vereinfachen viele Icons und entfernen Details, wenn sie von 32×32 Pixel großen Versionen auf die 16×16 Pixel großen Versionen heruntergehen:

Und der zweite Grund sind die Zwischengrößen, die berüchtigten 24×24 Pixel. Das ist ein Skalierungsfaktor von 1,5 gegenüber der 16×16-Version. Jede Linie könnte wieder in den Zwischenpixeln landen und verschwimmen, wenn man einfach hochskaliert.

Es ist also sinnvoll, mehrere Größen des Symbols zu erstellen, wobei jede Größe eine optimierte Platzierung der Eckpunkte der Grafik aufweist. Je nach Komplexität der Symbolgrafik ist eine weitere Hochskalierung irgendwann irrelevant und kann automatisch erfolgen. Die Größe von 64×64 Pixeln ist ein traditioneller Punkt dafür.

Ich persönlich versuche normalerweise, Icons mit 32×32 Pixeln zu entwerfen. Die 64×64-Pixel- und 256×256-Pixel-Versionen sind dann automatische Upscales, werden aber immer ausdrücklich in die Icon-Dateien aufgenommen. Die drei traditionellen Größen, die noch fehlen, 16×16, 24×24 und 48×48 Pixel, werden manuell optimiert, damit sie schärfer aussehen. Natürlich ist dieser Ansatz nur ein Ausgangspunkt, und manchmal hat die Referenz eine andere Größe.

Die geraden Linien

Es geht also nur um gerade horizontale und vertikale Linien, denn nur diese können perfekt mit dem Pixelraster übereinstimmen? Nein. Jede Form verliert an Details und wird bei kleineren Größen zunehmend unschärfer. Ich habe oben geschrieben, dass die Verringerung der grafischen Details bei einer Verkleinerung notwendig sein könnte. Das gilt für alle Formen. Und es kann nicht nur eine _Reduzierung_ sein. Manchmal kann eine Änderung oder sogar ein vollständiger Ersatz einer Form sinnvoll sein, wie im obigen Beispiel. Insbesondere bei der Verkleinerung auf 16×16 Pixel sind die Konzepte der Pixelkunst mit ihrer Reduzierung der meisten Details und der besonderen Betonung anderer Details eine Überlegung wert:

Das rechte Bild zeigt das Clipart-Original. Das mittlere Bild zeigt die Vektorgrafik des 16×16 Pixel großen Bildes auf der linken Seite. Schauen Sie sich den Riemen des Helms an. Dieser ist überhaupt nicht mehr gebogen. Stattdessen werden ein paar volle Pixel für die Gesamtform und ein paar teilweise gefüllte Pixel für ein kontrolliertes Anti-Aliasing verwendet.

Zusammenfassung

Icons sind als sehr kleine Darstellungen eines Logos und für Ihre Anwendung, Webseite oder ähnliches gedacht. Da dies ihr Zweck ist, sollten wir darauf achten, sie auch für diese Größen zu optimieren!

  • Formen, insbesondere, aber nicht ausschließlich, horizontale und vertikale Linien, sollten genau an den Grenzen des Pixelrasters platziert werden, um Unschärfen aufgrund von Interpolation zu vermeiden.
  • Die 16×16-, 24×24-, 32×32- und 48×48-Pixel-Versionen eines Symbols profitieren am meisten von einer manuellen Optimierung, vielleicht sogar von einer Reduzierung der Grafikdetails oder einer Änderung der Form.
  • Was auch immer wir tun, wir sollten immer die Qualität im Auge behalten.

So könnte ein SVG, das nur ein Bild in einer bestimmten Größe darstellt, als Datenquelle für Ikonenbilder verwendet werden. Aber wenn es für alle Größen verwendet wird, wird die visuelle Qualität bei einigen Größen immer schlechter sein als bei expliziten pixelbasierten Grafiken, die für diese spezifische Größe optimiert sind.

Artikelserie

Vor einiger Zeit habe ich hier auf meiner Website einen Abschnitt über Tools eingerichtet, die ich benutze und mag. Ich hab diese Serie begonnen, indem ich über das Suchtool Everything von Voidtools geschrieben hatte, das superschnell und großartig ist.

Seitdem habe ich Everything in verschiedene interne Tools von mir eingesetzt, meist über das Everything-CLI und parsen dessen Ausgabe. Allerdings hatte ich einige Probleme mit Unicode-Dateinamen. Dann habe ich mir Dotnet-Libraries angesehen, vor allem Everything .Net Client und EverythingNet. Beide sind im Grunde P/Invoke-Wrapper um das Everything SDK, das selbst ein Wrapper um Interprocess Calls (IPC) zum Everything-Dienst ist. Und da ich mich mit Low-Level-Techniken wie Windows-Message-basierender IPC auskenne und ich keine Wrapper von Wrapper von Funktionen mag, habe ich beschlossen, eine eigene Library zu schreiben: Everything Search Client

Es ist eine .Net 6.0 Bibliothek, komplett in CSharp geschrieben, mit einigen P/Invoke-Aufrufen zu nativen Windows-Funktionen des Betriebssystems und direkter Kommunikation mit dem Everything-Dienst.

Der Code ist auf Github verfügbar und das fertige Nuget-Paket ist auf Nuget.org.

Wenn Sie es nützlich finden und es in einem eigenen Tool verwenden, würde ich mich freuen, davon zu hören: Used By, How to Contribute

[This article is only available in English. Sorry.]

Git has this cursed function to fuck up your files by doing unspeakable things to your line endings.

For example, from Githubs Documentation on Line Endings:

On Windows, you simply pass true to the configuration. For example:

$ git config –global core.autocrlf true

Please, never never never never never never never never never never never never do this!

THERE IS NO REASON TO DO IT!

Git is here to keep track of our files, NOT TO CHANGE OUR FILES IN ANY WAY.

So, please, just, never never never never never never never never never never never never do this! Leave my file endings alone!

Erst kürzlich habe ich diesen Artikel auf Golem über Mouse Without Borders gelesen.

Mouse Without Borders (http://www.aka.ms/mm)

Mein aktuelles Projekt auf der Arbeit dreht sich um Netzwerkkommunikation. Aus verschiedenen Gründen kann ich nicht mit einem einzigen Computer und simulierten Netzwerken arbeiten, sondern ich brauche zwei physische Maschinen, um meine Arbeit zu erledigen. Und ich hasse es, ständig die Tastaturen und Mäuse zu wechseln. Aber ich dachte: „Wie viele Menschen haben ein solches Problem? Sicherlich nicht viele.“ Also habe ich es akzeptiert. Und jetzt kommt mir Mouse Without Borders völlig unerwartet zu Hilfe. Großartig! Und es funktioniert!

Vielleicht habt Ihr bemerkt, dass die Shields.io-Badges für die Nuget-Pakete, die ich betreue, seit einigen Tagen verschwunden sind und jetzt durch eine einfache Tabelle ersetzt wurden. Was ist passiert?

Nun eine Entscheidung eines deutschen Gerichts is passiert, dass die Verwendung von Google Fonts von deren CDN-Server, der in den USA gehostet wird, eine Verletzung der Privatsphäre darstellen kann, wenn sie ohne die Zustimmung der Nutzer verwendet wird. Scheinbar sind auch schon einige räuberische Anwälte bereits auf der Jagd. Daher habe ich alle meine Websites so umgestellt, dass die von mir verwendeten Schriftarten auf denselben Servern gehostet werden. Auch wenn ich mich über den zusätzlichen Aufwand geärgert habe, verstehe ich die Wichtigkeit des Datenschutzes und kann die Entscheidung in diesem Sinne nachvollziehen. Soviel zu den Google Fonts. Was ist mit dem Rest?

Ich wollte meine Website so zu ändern, dass entweder alles selbst gehostet wird oder dass ich für alle eingebetteten Inhalte explizit Inhalte anfordere. Aus diesem Grund wird Shields.io nicht mehr direkt auf meiner Website verwendet. Das mag übertrieben wirken, aber ich denke es hilft auch für die „Stabilität“ des Inhalts. Jetzt holt sich mein Backend alle Daten, die ich brauche, speichert sie auf meinem eigenen Server und liefert sie als lokalen Teil meiner Website aus. In diesem Fall habe ich das Abrufen der Daten sogar auf einen Cron-Job umgestellt, der einmal pro Tag läuft. Ich bin sowieso nicht so schnell mit Nuget-Paketen.

Damit werden nun alle Inhalte, die auf sgrottel.de angezeigt werden, von den Servern ausgeliefert, auf denen sgrottel.de gehostet wird.

Der Nachteil ist natürlich, dass dies einen zusätzlichen Wartungsaufwand für mich bedeutet. Das Backend ruft halbdokumentierte APIs auf, die sich jederzeit ändern können, und es führt einige fragile Parsing-Vorgänge durch, z.B. im Falle der nicht so gut strukturierten Lua-Projekt-Website. Die derzeitige Lösung kann keine endgültige Lösung sein, und wird in Zukunft verbessert werden müssen. Wir werden sehen.