Add double-buffering - No more flicker!
This commit is contained in:
parent
1763bf72da
commit
f11b6abeec
@ -39,6 +39,8 @@ namespace watchfuleye {
|
||||
, m_greenBrush(nullptr)
|
||||
, m_yellowBrush(nullptr)
|
||||
, m_redBrush(nullptr)
|
||||
, m_offscreenDC(nullptr)
|
||||
, m_offscreenBitmap(nullptr)
|
||||
{
|
||||
std::cout << std::format("{} {}\n", m_appName, m_appVersion);
|
||||
}
|
||||
@ -114,9 +116,9 @@ namespace watchfuleye {
|
||||
app->m_yellowBrush = CreateSolidBrush(RGB(255, 255, 150));
|
||||
app->m_redBrush = CreateSolidBrush(RGB(255, 150, 150));
|
||||
|
||||
// App will update (repaint) every second
|
||||
// App will update (repaint) at 5 FPS
|
||||
SendMessage(hWnd, WM_UPDATE, NULL, NULL);
|
||||
SetTimer(hWnd, IDT_UPDATE, 1000, nullptr);
|
||||
SetTimer(hWnd, IDT_UPDATE, 200, nullptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -167,7 +169,7 @@ namespace watchfuleye {
|
||||
if (HIWORD(wParam) == 0 && LOWORD(wParam) == IDM_ABOUT) {
|
||||
MessageBox(hWnd, std::format("{} {}\nCopyright Grayson Riffe 2026\ngraysonriffe.com\n\n"
|
||||
"\t{} is a simple countdown application\n"
|
||||
"specifically designed for this electronics testing labratory.\n\n"
|
||||
"specifically designed for this electronics testing labratory.\n"
|
||||
"Hopefully, it's working!", app->m_appName, app->m_appVersion,
|
||||
app->m_appName).c_str(), std::format("About {}", app->m_appName).c_str(), MB_OK);
|
||||
|
||||
@ -198,12 +200,32 @@ namespace watchfuleye {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_ERASEBKGND: {
|
||||
HDC hDC = reinterpret_cast<HDC>(wParam);
|
||||
case WM_ERASEBKGND: { // Don't erase the background, it is already done in WM_PAINT
|
||||
return 1;
|
||||
}
|
||||
|
||||
case WM_PAINT: {
|
||||
PAINTSTRUCT ps = {};
|
||||
HDC hDC = BeginPaint(hWnd, &ps);
|
||||
|
||||
RECT clientRect = {};
|
||||
GetClientRect(hWnd, &clientRect);
|
||||
|
||||
// Create offscreen buffer if not already created
|
||||
if (!app->m_offscreenDC) {
|
||||
app->m_offscreenDC = CreateCompatibleDC(hDC);
|
||||
app->m_offscreenBitmap = CreateCompatibleBitmap(hDC, clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
|
||||
}
|
||||
|
||||
// Setup RECTs
|
||||
RECT timeRect = clientRect;
|
||||
timeRect.top -= 25, timeRect.bottom -= 25;
|
||||
|
||||
RECT lowerRect = { .top = WINDOW_HEIGHT - 65, .right = WINDOW_WIDTH, .bottom = WINDOW_HEIGHT };
|
||||
|
||||
HANDLE prevBitmap = SelectObject(app->m_offscreenDC, app->m_offscreenBitmap);
|
||||
|
||||
// Fill background
|
||||
HBRUSH backgroundBrush = nullptr;
|
||||
|
||||
if (!app->m_active)
|
||||
@ -215,25 +237,11 @@ namespace watchfuleye {
|
||||
else
|
||||
backgroundBrush = app->m_yellowBrush;
|
||||
|
||||
FillRect(hDC, &clientRect, backgroundBrush);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
case WM_PAINT: {
|
||||
PAINTSTRUCT ps = {};
|
||||
HDC hDC = BeginPaint(hWnd, &ps);
|
||||
|
||||
// Setup RECTs
|
||||
RECT timeRect = {};
|
||||
GetClientRect(hWnd, &timeRect);
|
||||
timeRect.top -= 25, timeRect.bottom -= 25;
|
||||
|
||||
RECT lowerRect = { .top = WINDOW_HEIGHT - 65, .right = WINDOW_WIDTH, .bottom = WINDOW_HEIGHT };
|
||||
FillRect(app->m_offscreenDC, &clientRect, backgroundBrush);
|
||||
|
||||
// Setup text options
|
||||
SetTextColor(hDC, RGB(0, 0, 0));
|
||||
SetBkMode(hDC, TRANSPARENT);
|
||||
SetTextColor(app->m_offscreenDC, RGB(0, 0, 0));
|
||||
SetBkMode(app->m_offscreenDC, TRANSPARENT);
|
||||
|
||||
// Calculate time
|
||||
Seconds elapsed = Duration(Clock::now() - app->m_startTime).count();
|
||||
@ -242,29 +250,33 @@ namespace watchfuleye {
|
||||
remaining -= elapsed;
|
||||
|
||||
if (!app->m_active || (app->m_active && !app->m_overTime)) { // Draw time
|
||||
SelectObject(hDC, app->m_timeFont);
|
||||
SelectObject(app->m_offscreenDC, app->m_timeFont);
|
||||
unsigned int minutes = remaining % (3600) / 60, seconds = remaining % 60;
|
||||
DrawText(hDC, std::format("{:02}:{:02}", minutes, seconds).c_str(), -1, &timeRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
|
||||
DrawText(app->m_offscreenDC, std::format("{:02}:{:02}", minutes, seconds).c_str(), -1, &timeRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
|
||||
}
|
||||
|
||||
if (!app->m_active) { // Ready (green)
|
||||
SelectObject(hDC, app->m_lowerFont);
|
||||
DrawText(hDC, "Ready", -1, &lowerRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
|
||||
SelectObject(app->m_offscreenDC, app->m_lowerFont);
|
||||
DrawText(app->m_offscreenDC, "Ready", -1, &lowerRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
|
||||
}
|
||||
else if (!app->m_overTime) { // Counting (yellow)
|
||||
SelectObject(hDC, app->m_lowerFont);
|
||||
DrawText(hDC, "Time Remaining on Tester", -1, &lowerRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
|
||||
SelectObject(app->m_offscreenDC, app->m_lowerFont);
|
||||
DrawText(app->m_offscreenDC, "Time Remaining on Tester", -1, &lowerRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
|
||||
}
|
||||
else { // Over time (red)
|
||||
SelectObject(hDC, app->m_lowerFont);
|
||||
DrawText(hDC, "Please Eject Your USB", -1, &lowerRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
|
||||
SelectObject(hDC, app->m_timeFont);
|
||||
DrawText(hDC, "STOP", -1, &timeRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
|
||||
SelectObject(app->m_offscreenDC, app->m_lowerFont);
|
||||
DrawText(app->m_offscreenDC, "Please Eject Your USB", -1, &lowerRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
|
||||
SelectObject(app->m_offscreenDC, app->m_timeFont);
|
||||
DrawText(app->m_offscreenDC, "STOP", -1, &timeRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
|
||||
}
|
||||
|
||||
if (remaining <= 0)
|
||||
app->m_overTime = true;
|
||||
|
||||
BitBlt(hDC, 0, 0, clientRect.right - clientRect.left, clientRect.bottom - clientRect.top, app->m_offscreenDC, 0, 0, SRCCOPY);
|
||||
|
||||
SelectObject(app->m_offscreenDC, prevBitmap);
|
||||
|
||||
EndPaint(hWnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
@ -335,5 +347,8 @@ namespace watchfuleye {
|
||||
DeleteObject(m_greenBrush);
|
||||
DeleteObject(m_yellowBrush);
|
||||
DeleteObject(m_redBrush);
|
||||
|
||||
DeleteObject(m_offscreenBitmap);
|
||||
DeleteDC(m_offscreenDC);
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,5 +38,7 @@ namespace watchfuleye {
|
||||
HRGN m_region;
|
||||
HFONT m_timeFont, m_lowerFont;
|
||||
HBRUSH m_greenBrush, m_yellowBrush, m_redBrush;
|
||||
HDC m_offscreenDC;
|
||||
HBITMAP m_offscreenBitmap;
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user