0

An application can carry out any system command at any time by passing a WM_SYSCOMMAND message to DefWindowProc.

If I don't have any windows, which window can I post/send WM_SYSCOMMAND to carry out system commands?

First, GetDesktopWindow() doesn't work.
Second, while GetForegroundWindow() works most of the time, it won't work if the foreground window decides to intercept WM_SYSCOMMAND or has a higher integrity level.
And HWND_BROADCAST is the worst option.

So what about GetShellWindow()?

Or, can I direct call DefWindowProcW(RANDOM_WINDOW, WM_SYSCOMMAND, ...)? It seems that this will work as long as RANDOM_WINDOW is any valid HWND, and the integrity level is no higher than caller.

( I'm raising this question because there are some terrible answers about turning off the monitor, such as SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, 2). While some have warned against this in the comments, and Raymond Chen has even written an article about it, even Raymond Chen's solution involves creating a custom window. To fix(edit) these terrible answers, I want to provide an equally simple alternative solution. Because I can't just say "use any your own HWND, if you don't have any window, then create one". For those who unfamiliar with Win32, they won't want to create a custom window specifically for this, and they're unaware of the flaws in these solutions. )

Edit: It seems everyone thinks I don't know how to create a window or correctly turn off the monitor.

void TurnOffMonitor() {
    auto TurnOffMonitorWndproc = [](HWND hWnd, UINT  uMsg, WPARAM wParam, LPARAM lParam) ->LRESULT {
        if (uMsg == WM_NCCREATE) {
            DefWindowProcW(hWnd, WM_SYSCOMMAND, SC_MONITORPOWER, 2);
            return FALSE;
        }
        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
        };
    WNDCLASSW wc{};
    wc.lpfnWndProc = TurnOffMonitorWndproc;
    wc.lpszClassName = L"TOMWC";
    ATOM classATOM = RegisterClassW(&wc);
    CreateWindowExW(0, MAKEINTATOM(classATOM), L"", 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, 0);
    UnregisterClassW(MAKEINTATOM(classATOM), 0);
}

Although I must admit, I don't know how to do this in a language other than C/C++.

8
  • Sure you can call DefWindowProc() directly. I would break down the preconceptions and create a window for this. It doesn't have to be visible. Commented Nov 18 at 4:06
  • 1
    There is no guarantee that sending a message to another window will get the message processed the way you want. Each Window procedure that handles messages will dispatch and process them according to the application's requirements. Sending them a message that they do not process will just result in it being ignored. Commented Nov 18 at 13:01
  • 5
    If you don't know how to create a window, then maybe you aren't ready for Win32 programming. Deciding to reject the correct solution to a problem because you don't want to create a window is bizarre to say the least. If you want to ask about turning off monitors, you should ask about that. Or just accept the many many duplicates. Commented Nov 18 at 14:45
  • 6
    I'm not sure how Raymond Chen could make it any clearer: "The correct solution is not to post messages to random windows. If you want the message to go through window message default processing, create a window and process it yourself. Don’t try to trick some other window into doing it for you." If you refuse to accept that then I don't know what to tell you. You can probably get away with calling DefWindowProc() on some random window 99% of the time, but why leave it to chance? Commented Nov 18 at 19:45
  • Today I learned that a C++ lambda with no captures decays to a simple function pointer. Commented Nov 18 at 21:38

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.