I've been working on a Windows privacy utility in C++ and wanted to share a cleaned-up release I just finished. It's called "Privacy Shield" and temporarily obscures any visible window with a topmost overlay to protect your screen from prying eyes in shared environments. The interface shows open windows by title, size, and handle; select one and click Protect (or press Enter) to place a full black overlay that follows resizes and moves using a safe 250 ms timer, and it will prompt you to confirm if you want to keep it protected. It supports a tray icon (double-click restores the main window), a global Ctrl+Shift+Q hotkey to quit cleanly, F5 to refresh, Unprotect All, and Esc to minimize to the tray. I fixed memory leaks, ensured timer safety using HWND as a unique identifier, corrected DWM frame bounds for accurate rectangles, implemented proper cleanup on exit, and optimized the window enumeration to eliminate crashes and ghost overlays. It compiles cleanly with standard Win32 libraries—I'd appreciate any feedback or suggestions for improving performance on multi-monitor setups.
I'm not sure about the shortcuts and the double-click, but everything else is there.
C++:
/*
MIT License
Copyright (c) 2025 CoTon_TiGe_MoUaRf
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
This project is divided into two parts for sharing purposes due to its length. Each part can be used independently while maintaining the same terms outlined in this license.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <windows.h>
#include <commctrl.h>
#include <dwmapi.h>
#include <shellapi.h>
#include <unordered_map>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "dwmapi.lib")
#pragma comment(lib, "shell32.lib")
#define WM_TRAY_MSG (WM_USER + 1)
#define HOTKEY_QUIT_ID 1
#define ID_LIST 100
#define ID_PROTECT 101
#define ID_UNPROTECT 102
#define ID_REFRESH 103
#define ID_TRAY 104
#define ID_EXIT 105
struct WindowInfo {
HWND hwnd;
std::string title;
RECT rect;
};
struct ProtectedWindow {
HWND original;
HWND overlay;
UINT_PTR timerId;
RECT lastRect;
bool valid;
};
std::unordered_map<HWND, ProtectedWindow> protectedWindows;
std::vector<WindowInfo> windowList;
HWND hMainWnd = NULL;
HWND hTrayWnd = NULL;
NOTIFYICONDATAA nid = {0};
bool isTrayOnly = false;
// Forward declarations
LRESULT CALLBACK OverlayWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK TrayWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
// Utility: get visual bounds (DWM extended frame) with fallback
bool GetVisualWindowRect(HWND hwnd, RECT& outRect) {
RECT r = {0};
HRESULT hr = DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &r, sizeof(r));
if (SUCCEEDED(hr)) {
outRect = r;
return true;
}
return GetWindowRect(hwnd, &outRect) != 0;
}
// Overlay window proc
LRESULT CALLBACK OverlayWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_NCHITTEST:
return HTTRANSPARENT; // let clicks fall through
case WM_DESTROY:
return 0;
default:
return DefWindowProcA(hwnd, msg, wParam, lParam);
}
}
// Create overlay covering rect (in screen coords)
HWND CreateMaskOverlay(const RECT& rect) {
HINSTANCE hInst = GetModuleHandle(NULL);
static bool registered = false;
if (!registered) {
WNDCLASSEXA wc = {0};
wc.cbSize = sizeof(wc);
wc.lpfnWndProc = OverlayWndProc;
wc.hInstance = hInst;
wc.lpszClassName = "PrivacyMaskFixedOverlay_v2";
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClassExA(&wc);
registered = true;
}
int w = rect.right - rect.left;
int h = rect.bottom - rect.top;
HWND overlay = CreateWindowExA(
WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_LAYERED | WS_EX_NOACTIVATE | WS_EX_TRANSPARENT,
"PrivacyMaskFixedOverlay_v2", "Protected", WS_POPUP,
rect.left, rect.top, w, h,
NULL, NULL, hInst, NULL
);
if (!overlay) return NULL;
// Opaque black
SetLayeredWindowAttributes(overlay, RGB(0,0,0), 255, LWA_ALPHA);
SetWindowPos(overlay, HWND_TOPMOST, rect.left, rect.top, w, h, SWP_NOACTIVATE | SWP_SHOWWINDOW);
return overlay;
}
// ✅ UNPROTECT SÉCURISÉ
void UnprotectWindow(HWND originalHwnd) {
auto it = protectedWindows.find(originalHwnd);
if (it == protectedWindows.end()) return;
ProtectedWindow& pw = it->second;
// Kill timer
if (pw.timerId) {
KillTimer(NULL, pw.timerId);
pw.timerId = 0;
}
// Destroy overlay
if (IsWindow(pw.overlay)) {
DestroyWindow(pw.overlay);
}
// Restore original window
if (IsWindow(pw.original)) {
ShowWindow(pw.original, SW_RESTORE);
}
// Remove from map
protectedWindows.erase(it);
}
// ✅ TIMER SÉCURISÉ : utilise HWND comme clé unique
void CALLBACK SafeOverlayTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) {
HWND originalHwnd = (HWND)idEvent;
auto it = protectedWindows.find(originalHwnd);
if (it == protectedWindows.end()) return;
ProtectedWindow& pw = it->second;
// Vérification de validité
if (!pw.valid || !IsWindow(pw.original) || !IsWindow(pw.overlay)) {
UnprotectWindow(originalHwnd);
return;
}
RECT rect;
if (!GetVisualWindowRect(pw.original, rect)) {
return;
}
// Si rect changé, update overlay
if (memcmp(&rect, &pw.lastRect, sizeof(RECT)) != 0) {
pw.lastRect = rect;
int w = rect.right - rect.left;
int h = rect.bottom - rect.top;
SetWindowPos(pw.overlay, HWND_TOPMOST, rect.left, rect.top, w, h,
SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOZORDER);
}
}
// ✅ PROTECT SÉCURISÉ
void ProtectWindow(HWND hwnd) {
RECT rect;
if (!GetVisualWindowRect(hwnd, rect)) return;
if ((rect.right - rect.left) <= 0 || (rect.bottom - rect.top) <= 0) return;
// Déjà protégé ?
if (protectedWindows.count(hwnd)) return;
HWND overlay = CreateMaskOverlay(rect);
if (!overlay) return;
ProtectedWindow pw;
pw.original = hwnd;
pw.overlay = overlay;
pw.timerId = SetTimer(NULL, (UINT_PTR)hwnd, 250, SafeOverlayTimerProc);
pw.lastRect = rect;
pw.valid = true;
protectedWindows[hwnd] = pw;
if (MessageBoxA(hMainWnd, "Window protected. Unprotect now?", "Privacy Shield",
MB_OKCANCEL | MB_ICONQUESTION) == IDCANCEL) {
UnprotectWindow(hwnd);
}
}
// ✅ ENUMWINDOWS EFFICACE
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
HWND hList = (HWND)lParam;
if (IsWindowVisible(hwnd) && !IsIconic(hwnd)) {
char title[512] = {0};
GetWindowTextA(hwnd, title, sizeof(title));
if (strlen(title) > 0) {
RECT rect;
if (!GetVisualWindowRect(hwnd, rect)) return TRUE;
bool isProtected = protectedWindows.count(hwnd) > 0;
std::string prefix = isProtected ? "Protected: " : "Window: ";
WindowInfo info = {hwnd, std::string(title), rect};
windowList.push_back(info);
int w = rect.right - rect.left;
int h = rect.bottom - rect.top;
char buf[1024];
sprintf_s(buf, sizeof(buf), "%s%s (%dx%d) [0x%p]",
prefix.c_str(), title, w, h, (void*)hwnd);
SendMessageA(hList, LB_ADDSTRING, 0, (LPARAM)buf);
}
}
return TRUE;
}
// Refresh the listbox content
void RefreshWindowList(HWND hList) {
SendMessageA(hList, LB_RESETCONTENT, 0, 0);
windowList.clear();
// ✅ Utilise EnumWindows (plus efficace)
EnumWindows(EnumWindowsProc, (LPARAM)hList);
}
// Unprotect all
void UnprotectAll() {
std::vector<HWND> toUnprotect;
for (const auto& pair : protectedWindows) {
toUnprotect.push_back(pair.first);
}
for (HWND hwnd : toUnprotect) {
UnprotectWindow(hwnd);
}
}
// Main window procedure
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE: {
CreateWindowA("STATIC", "Available Windows:", WS_VISIBLE | WS_CHILD | SS_LEFT,
10, 10, 460, 20, hwnd, NULL, NULL, NULL);
HWND hList = CreateWindowA("LISTBOX", NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL | LBS_NOTIFY,
10, 35, 460, 220, hwnd, (HMENU)ID_LIST, NULL, NULL);
CreateWindowA("BUTTON", "Protect (Enter)", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
10, 265, 120, 30, hwnd, (HMENU)ID_PROTECT, NULL, NULL);
CreateWindowA("BUTTON", "Unprotect All", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
140, 265, 120, 30, hwnd, (HMENU)ID_UNPROTECT, NULL, NULL);
CreateWindowA("BUTTON", "Refresh (F5)", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
270, 265, 100, 30, hwnd, (HMENU)ID_REFRESH, NULL, NULL);
CreateWindowA("BUTTON", "Show in Tray (Esc)", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
380, 265, 120, 30, hwnd, (HMENU)ID_TRAY, NULL, NULL);
CreateWindowA("BUTTON", "Quitter", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
10, 305, 120, 30, hwnd, (HMENU)ID_EXIT, NULL, NULL);
RefreshWindowList(hList);
break;
}
case WM_COMMAND: {
HWND hList = GetDlgItem(hwnd, ID_LIST);
int index = (int)SendMessageA(hList, LB_GETCURSEL, 0, 0);
switch (LOWORD(wParam)) {
case ID_PROTECT:
if (index >= 0 && index < (int)windowList.size()) {
ProtectWindow(windowList[index].hwnd);
RefreshWindowList(hList);
}
break;
case ID_UNPROTECT:
UnprotectAll();
RefreshWindowList(hList);
MessageBoxA(hwnd, "All windows unprotected!", "Privacy Shield", MB_OK | MB_ICONINFORMATION);
break;
case ID_REFRESH:
RefreshWindowList(hList);
break;
case ID_TRAY:
ShowWindow(hwnd, SW_HIDE);
isTrayOnly = true;
break;
case ID_EXIT: {
UnprotectAll();
Shell_NotifyIconA(NIM_DELETE, &nid);
UnregisterHotKey(NULL, HOTKEY_QUIT_ID);
PostQuitMessage(0);
break;
}
}
break;
}
case WM_KEYDOWN: {
switch (wParam) {
case VK_RETURN:
SendMessage(hwnd, WM_COMMAND, ID_PROTECT, 0);
break;
case VK_F5:
SendMessage(hwnd, WM_COMMAND, ID_REFRESH, 0);
break;
case VK_ESCAPE:
SendMessage(hwnd, WM_COMMAND, ID_TRAY, 0);
break;
}
return 0;
}
case WM_SYSCOMMAND:
if (wParam == SC_CLOSE) {
ShowWindow(hwnd, SW_HIDE);
return 0;
}
break;
case WM_DESTROY:
UnprotectAll();
Shell_NotifyIconA(NIM_DELETE, &nid);
UnregisterHotKey(NULL, HOTKEY_QUIT_ID);
PostQuitMessage(0);
return 0;
case WM_HOTKEY:
if (wParam == HOTKEY_QUIT_ID) {
UnprotectAll();
Shell_NotifyIconA(NIM_DELETE, &nid);
UnregisterHotKey(NULL, HOTKEY_QUIT_ID);
PostQuitMessage(0);
}
break;
}
return DefWindowProcA(hwnd, msg, wParam, lParam);
}
LRESULT CALLBACK TrayWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if (msg == WM_TRAY_MSG) {
if (lParam == WM_LBUTTONDBLCLK) {
ShowWindow(hMainWnd, SW_RESTORE);
isTrayOnly = false;
SetForegroundWindow(hMainWnd);
}
}
return DefWindowProcA(hwnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) {
INITCOMMONCONTROLSEX icex = { sizeof(icex), ICC_STANDARD_CLASSES };
InitCommonControlsEx(&icex);
// Main window
WNDCLASSEXA wcMain = {0};
wcMain.cbSize = sizeof(wcMain);
wcMain.lpfnWndProc = MainWndProc;
wcMain.hInstance = hInstance;
wcMain.lpszClassName = "PrivacyShieldFixedMain_v2";
wcMain.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
RegisterClassExA(&wcMain);
hMainWnd = CreateWindowExA(0, wcMain.lpszClassName, "Privacy Shield v2 - Fixed",
WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT,
500, 350, NULL, NULL, hInstance, NULL);
// ✅ TRAY WINDOW CORRIGÉ
WNDCLASSEXA wcTray = {0};
wcTray.cbSize = sizeof(wcTray);
wcTray.lpfnWndProc = TrayWndProc;
wcTray.hInstance = hInstance;
wcTray.lpszClassName = "PrivacyShieldTray_v2";
RegisterClassExA(&wcTray);
hTrayWnd = CreateWindowExA(0, wcTray.lpszClassName, NULL, WS_OVERLAPPED,
0,0,0,0, NULL, NULL, hInstance, NULL);
ShowWindow(hTrayWnd, SW_HIDE); // ✅ CORRIGÉ : montrer le tray window
ShowWindow(hMainWnd, nCmdShow);
UpdateWindow(hMainWnd);
// Tray icon
nid.cbSize = sizeof(nid);
nid.hWnd = hTrayWnd;
nid.uID = 1;
nid.uFlags = NIF_MESSAGE | NIF_TIP;
nid.uCallbackMessage = WM_TRAY_MSG;
strcpy_s(nid.szTip, "Privacy Shield v2 - Double-click");
Shell_NotifyIconA(NIM_ADD, &nid);
// Register global hotkey
if (!RegisterHotKey(NULL, HOTKEY_QUIT_ID, MOD_CONTROL | MOD_SHIFT, 'Q')) {
MessageBoxA(NULL, "Failed to register hotkey!", "Error", MB_OK | MB_ICONERROR);
}
// Message loop
MSG msg;
while (GetMessageA(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
// ✅ CLEANUP FINAL COMPLÈT
UnprotectAll();
Shell_NotifyIconA(NIM_DELETE, &nid);
UnregisterHotKey(NULL, HOTKEY_QUIT_ID);
return 0;
}
I'm not sure about the shortcuts and the double-click, but everything else is there.