Black cockpit canvas + flicker-free pane painting

SS_BLACKRECT paints the system window-frame color - gray on modern
Windows - so the viewscreen child is now a plain STATIC subclassed to
erase true black. The MFD/map panes flickered because Paint() cleared
the on-screen surface before redrawing at the fill cadence; the pane
now composes off screen and lands in a single BitBlt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-12 15:41:49 -05:00
co-authored by Claude Fable 5
parent 293e369656
commit 2a6398702c
2 changed files with 48 additions and 6 deletions
+21 -5
View File
@@ -323,11 +323,21 @@ void
RECT client; RECT client;
GetClientRect((HWND) window, &client); GetClientRect((HWND) window, &client);
FillRect(hdc, &client, (HBRUSH) GetStockObject(BLACK_BRUSH));
SetStretchBltMode(hdc, COLORONCOLOR); //---------------------------------------------------------------
// Double-buffered: compose the whole pane off screen and blit it
// in one operation, otherwise the clear-then-draw sequence
// flickers at the repaint cadence.
//---------------------------------------------------------------
HDC mem = CreateCompatibleDC(hdc);
HBITMAP surface = CreateCompatibleBitmap(hdc, client.right, client.bottom);
HBITMAP old_surface = (HBITMAP) SelectObject(mem, surface);
FillRect(mem, &client, (HBRUSH) GetStockObject(BLACK_BRUSH));
SetStretchBltMode(mem, COLORONCOLOR);
StretchDIBits( StretchDIBits(
hdc, mem,
displayX, displayY, displayW, displayH, displayX, displayY, displayW, displayH,
0, 0, sourceWidth, sourceHeight, 0, 0, sourceWidth, sourceHeight,
pixels, (const BITMAPINFO *) blitHeader, pixels, (const BITMAPINFO *) blitHeader,
@@ -349,15 +359,21 @@ void
rect.bottom = button->y + button->h; rect.bottom = button->y + button->h;
HBRUSH fill = CreateSolidBrush(ButtonFill(button->amber, level)); HBRUSH fill = CreateSolidBrush(ButtonFill(button->amber, level));
FillRect(hdc, &rect, fill); FillRect(mem, &rect, fill);
DeleteObject(fill); DeleteObject(fill);
HBRUSH frame = CreateSolidBrush( HBRUSH frame = CreateSolidBrush(
(i == pressedIndex) ? RGB(255, 255, 255) : RGB(48, 48, 48)); (i == pressedIndex) ? RGB(255, 255, 255) : RGB(48, 48, 48));
FrameRect(hdc, &rect, frame); FrameRect(mem, &rect, frame);
DeleteObject(frame); DeleteObject(frame);
} }
BitBlt(hdc, 0, 0, client.right, client.bottom, mem, 0, 0, SRCCOPY);
SelectObject(mem, old_surface);
DeleteObject(surface);
DeleteDC(mem);
EndPaint((HWND) window, &ps); EndPaint((HWND) window, &ps);
} }
+27 -1
View File
@@ -3801,6 +3801,26 @@ void
//######################################################################## //########################################################################
//############################ SVGA640x480x16 ############################ //############################ SVGA640x480x16 ############################
//######################################################################## //########################################################################
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Single-window cockpit: the viewscreen child erases true black
// (SS_BLACKRECT paints the system window-frame gray on modern Windows).
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static WNDPROC gViewscreenBaseProc = NULL;
static LRESULT CALLBACK
ViewscreenBlackProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_ERASEBKGND)
{
RECT client;
GetClientRect(hwnd, &client);
FillRect((HDC) wParam, &client, (HBRUSH) GetStockObject(BLACK_BRUSH));
return 1;
}
return CallWindowProcA(gViewscreenBaseProc, hwnd, message, wParam, lParam);
}
SVGA16::SVGA16( SVGA16::SVGA16(
int mode, int mode,
int init_width, int init_width,
@@ -3916,14 +3936,20 @@ SVGA16::SVGA16(
if (cockpit != NULL) if (cockpit != NULL)
{ {
// plain STATIC (SS_BLACKRECT actually paints the system
// window-frame GRAY on modern Windows), subclassed below to
// erase true black
cockpitViewscreen = CreateWindowExA( cockpitViewscreen = CreateWindowExA(
0, "STATIC", "", 0, "STATIC", "",
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SS_BLACKRECT, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
0, 0, 0, 0,
view_w, view_h, view_w, view_h,
cockpit, NULL, GetModuleHandleA(NULL), NULL); cockpit, NULL, GetModuleHandleA(NULL), NULL);
if (cockpitViewscreen != NULL) if (cockpitViewscreen != NULL)
{ {
gViewscreenBaseProc = (WNDPROC) SetWindowLongPtrA(
cockpitViewscreen, GWLP_WNDPROC,
(LONG_PTR) ViewscreenBlackProc);
gMainPresentWindow = cockpitViewscreen; gMainPresentWindow = cockpitViewscreen;
} }
} }