Speaking as a long-time Win32 programmer, the requirements for your app are doable in a few KB (yes, kilobytes --- my vague estimate is less than 8KB) standalone executable. This is how I arrived at that:
Enumerating the machine’s displays and their bounds
A few API calls. Probably a few hundred bytes.
Placing borderless, titlebar-less, non-activating black windows
Creating non-functional windows is trivial. Another few hundred bytes at most.
Intercepting a global keyboard shortcut
A few dozen bytes to call SetWindowsHookEx.
Optionally running at startup
Write to the appropriate registry key. A few hundred bytes.
Storing some persistent settings
Ditto. Another few hundred bytes. You can use a .ini file too, for around the same size.
Displaying a tray icon with a few menu items
Most of this size of this will be the icon itself - a few kilobytes; the next biggest contributor will be text strings; and the rest is accomplished with a few hundred bytes of API calls.
Add another few hundred bytes of (not much) logic, round up to a kilobyte and add maybe another for general overhead.
But, in 2026, writing a greenfield application in a memory-unsafe language like C++ is a crime.
Don't be swayed by the propaganda. Especially if your application has essentially no untrusted input.