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:
+21
-5
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user