// Den Windows-11-Fensterrand loswerden. // // Commander-Fund (01.09.2026): „Ich hab noch den rand ich glaube der kommt // aber von windows selbst oder?" — Genau so ist es. Ein rahmenloses Fenster // (`frame: false`) behält unter Windows 11 trotzdem den DWM-Rand: eine // hauchfeine Linie in der Systemfarbe, gezeichnet vom Fenstermanager, nicht // von der Seite. Mit CSS ist da nichts zu holen, das liegt außerhalb des // Fensterinhalts. // // DwmSetWindowAttribute kennt dafür zwei Schalter (dwmapi.h, beide erst ab // Windows 11 Build 22000): // DWMWA_BORDER_COLOR (34) = DWMWA_COLOR_NONE (0xFFFFFFFE) // DWMWA_WINDOW_CORNER_PREFERENCE (33) = DWMWCP_DONOTROUND (1) // // Ältere Windows antworten mit einem Fehler-HRESULT. Das ist KEIN Problem // und wird als Wert zurückgegeben, nicht verschluckt (R4): Unter Windows 10 // gibt es diesen Rand schlicht nicht. // // Dies ist neben `leine.ts` und `kern/laufwerk/win32.ts` der DRITTE erlaubte // koffi-Ort; der Wächter-Test R1 kennt genau diese drei. Begründung wie // dort: ein Win32-Aufruf, der nirgendwo sonst hingehört — und er MUSS im // Haupt liegen, weil nur dort das Fensterhandle existiert. import koffi from 'koffi' const DWMWA_WINDOW_CORNER_PREFERENCE = 33 const DWMWA_BORDER_COLOR = 34 /** „Zeichne gar keinen Rand" — nicht zu verwechseln mit Schwarz. */ const DWMWA_COLOR_NONE = 0xfffffffe const DWMWCP_DONOTROUND = 1 export interface RandErgebnis { ok: boolean /** '' wenn alles saß; sonst der HRESULT-Grund im Klartext. */ fehler: string } /** * Rand entfernen. `eckenKantig` schaltet zusätzlich die runden Ecken ab — * standardmäßig AUS, weil runde Ecken unter Windows 11 das Übliche sind * und Rippy sich nicht fremder anfühlen soll, als es muss. * * @param handle Das native Fensterhandle (`BrowserWindow.getNativeWindowHandle()`). */ export function fensterrandEntfernen(handle: Buffer, eckenKantig = false): RandErgebnis { if (handle.length < 8) return { ok: false, fehler: 'Fensterhandle unbrauchbar' } try { const dwmapi = koffi.load('dwmapi.dll') // Das Handle steckt als Zeiger IM Puffer. Auf x64 wandert ein Zeiger im // selben Register wie ein uint64 — deshalb ist das hier gefahrlos. const DwmSetWindowAttribute = dwmapi.func( 'int32_t __stdcall DwmSetWindowAttribute(uint64_t hwnd, uint32_t dwAttribute, void *pvAttribute, uint32_t cbAttribute)', ) const hwnd = handle.readBigUInt64LE(0) const farbe = Buffer.alloc(4) farbe.writeUInt32LE(DWMWA_COLOR_NONE, 0) const randErgebnis = DwmSetWindowAttribute(hwnd, DWMWA_BORDER_COLOR, farbe, 4) let eckenErgebnis = 0 if (eckenKantig) { const ecken = Buffer.alloc(4) ecken.writeUInt32LE(DWMWCP_DONOTROUND, 0) eckenErgebnis = DwmSetWindowAttribute(hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, ecken, 4) } if (randErgebnis !== 0 || eckenErgebnis !== 0) { // Ein negatives HRESULT heißt hier fast immer: älteres Windows, das // diese Schalter nicht kennt. Rippy läuft weiter, nur mit Rand. return { ok: false, fehler: `DwmSetWindowAttribute: HRESULT 0x${(randErgebnis >>> 0).toString(16)} (Rand) / 0x${(eckenErgebnis >>> 0).toString(16)} (Ecken) — vermutlich Windows 10`, } } return { ok: true, fehler: '' } } catch (fehler) { return { ok: false, fehler: `koffi/dwmapi nicht verfügbar: ${String(fehler)}` } } }