I have developed a C++ application that creates a watermark on the screen. The watermark is displayed correctly on the current desktop, but when I create a new virtual desktop using Windows 10’s built-in virtual desktop feature, the watermark only appears on the first virtual desktop and does not carry over to the new ones.
I am using the Windows API to manage the watermark display and handle virtual desktop changes. Despite my efforts, the watermark doesn’t appear on newly created virtual desktops.
Here’s a simplified version of my code for displaying the watermark:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// Create a memory DC and bitmap for drawing
HDC memDC = CreateCompatibleDC(hdc);
if (!memDC) {
DebugOutput(L"Failed to create memory DCn");
EndPaint(hWnd, &ps);
return 0;
}
HBITMAP memBitmap = CreateCompatibleBitmap(hdc, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top);
if (!memBitmap) {
DebugOutput(L"Failed to create compatible bitmapn");
DeleteDC(memDC);
EndPaint(hWnd, &ps);
return 0;
}
HBITMAP oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);
// Create Graphics object
Graphics graphics(memDC);
// Fill the background with black color
graphics.Clear(BackgroundColor); // Black background
// Draw the watermark
std::wstring watermarkText = EnsureTextLength(GetWatermarkText());
DrawWatermarks(graphics, watermarkText, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top);
// Copy the memory DC to the screen DC
BitBlt(hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, memDC, 0, 0, SRCCOPY);
// Cleanup
SelectObject(memDC, oldBitmap);
DeleteObject(memBitmap);
DeleteDC(memDC);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
UnregisterVirtualDesktopNotification();
PostQuitMessage(0);
break;
case WM_DISPLAYCHANGE:
RefreshWatermarkWindows(hInst); // Refresh watermark windows on display change
break;
case WM_ACTIVATEAPP:
case WM_NEXTDLGCTL:
case WM_SHOWWINDOW:
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
break;
case WM_VIRTUAL_DESKTOP_CHANGED:
RefreshWatermarkWindows(hInst); // Handle virtual desktop change
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
void RefreshWatermarkWindows(HINSTANCE hInstance) {
// Destroy all existing windows
for (HWND hWnd : windows) {
DestroyWindow(hWnd);
}
// Ensure all messages related to destruction are processed
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
windows.clear(); // Clear the windows vector
// Create watermark windows for all monitors`your text`
EnumDisplayMonitors(NULL, NULL, [](HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) -> BOOL {
HINSTANCE hInstance = reinterpret_cast<HINSTANCE>(dwData);
CreateWatermarkWindow(hInstance, *lprcMonitor);
return TRUE;
}, reinterpret_cast<LPARAM>(hInstance));
}
I have tried listening to the WM_VIRTUAL_DESKTOP_CHANGED
message to detect when the user switches or creates a virtual desktop, but the watermark still doesn’t appear on the new desktops.
Ghaith Saaa is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.