0

Here is my code example:

LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam, int iCmdShow)
{
    static char szAppName[] = "hidden window";

    HWND        hWnd = GetActiveWindow();

    WNDCLASSEX  wndclass;
    wndclass.cbSize = sizeof(wndclass);
    wndclass.style = CS_OWNDC;
    wndclass.lpfnWndProc = WindowProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = NULL;
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    RegisterClassEx(&wndclass);

    hWnd = CreateWindow(
        szAppName,
        "hidden window", // window caption
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);

    ShowWindow(hWnd, SW_HIDE);
    UpdateWindow(hWnd);

    // Some code
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    ofstream myfile;
    myfile.open("log.txt", ios::app);
    myfile << "I was called \n";
    switch (uMsg)
    {
    case  WM_QUERYENDSESSION:
    {
        myfile << "WM_QUERYENDSESSION CALLED\n";
        return TRUE;

        break;
    }
    }
    myfile.close();

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

I register handler by wndclass.lpfnWndProc = WindowProc; and WindowProc is triggered few times and writes "I was called \n" only when I start app, but when I shutdown system absolutely nothing writes to log.txt, therefore handler is not triggered. I tried different examples, but nothing works to me. Any ideas what's wrong here?

Vlad Ross
  • 63
  • 7
  • I am sure, because at program start I see newly generated file with 4 records "I was called \n" – Vlad Ross May 29 '19 at 12:29
  • Try closing `myfile` after logging WM_QUERYENDSESSION CALLED. As things stand, it's probably not being flushed to disk. – Paul Sanders May 29 '19 at 12:44
  • I did as you said, also tried to show messageBox, but it didn't help – Vlad Ross May 29 '19 at 12:51
  • 2
    What is `//some code` maybe it is your message dispatch loop which does not handle messages properly could you at least provide that? – Yastanub May 29 '19 at 12:55
  • @PaulSanders according to [this question's answers](https://stackoverflow.com/questions/4802494/do-i-need-to-close-a-stdfstream) `std::fstream` objects are RAII objects which means they should close and flush semselfs on destruction. – Yastanub May 29 '19 at 12:57
  • @Yastanub Good point, I stand corrected. – Paul Sanders May 29 '19 at 12:59
  • 1
    @VladRoss have you tried outputing to your file when receiving the `WM_ENDSESSION` message? As stated in the [WM_QUERYENDSESSION's Documentation](https://learn.microsoft.com/en-us/windows/desktop/shutdown/shutting-down) "Each application should return TRUE or FALSE immediately upon receiving this message, and defer any cleanup operations until it receives the WM_ENDSESSION message." Maybe it is some Windows shutdown magic that some system calls like writing or opening a file wont work while `WM_QUERYENDSESSION` Message is received. – Yastanub May 29 '19 at 13:07
  • 1
    Okay so i compiled your example myself all i added was a simply message processing loop to the main function and i can not reproduce your error. I get a `log.txt` fiel with the expected content. So either it is because of the not shown code or how you shut down your system or application repectively. – Yastanub May 29 '19 at 14:10
  • 2
    My educated guess would be, "some code" doesn't involve calling `GetMessage` and `DispatchMessage` (also known as a message loop or message pump). That's how window messages get routed to the window procedure. No message pump == no messages. – Igor Tandetnik May 29 '19 at 14:19
  • Yeah, https://learn.microsoft.com/en-us/windows/desktop/winmsg/using-messages-and-message-queues that's it. Thanks for help! But what if I already have my main loop where I do my stuff with some delay, should I run Message Loop in separated thread? – Vlad Ross May 29 '19 at 15:13
  • As I see, if I run it in separate loop it doesn't get messages, so I should run my main loop in separated thread? – Vlad Ross May 29 '19 at 15:32
  • @VladRoss im not sure if i get you here but cant you just transform your main loop to your message loop? You also have a `PeekMessage` function which does not block which you might prefer. If ou struggle with the loop open a new question. – Yastanub May 29 '19 at 16:32
  • Message queues are per-thread. You must run the pump on the same thread that called `CreateWindow`, in order to deliver messages to that window. – Igor Tandetnik May 30 '19 at 14:54
  • Thx, I already understood this, so I call `CreateWindow` and Message loop in separated thread, it works fine – Vlad Ross May 31 '19 at 17:01

0 Answers0