I came across weird problem. I have C++ (WinAPI) application and if I close it via [X] window button, everything works correctly - window is closed, application is ended.
But when I close the application from the taskbar button context menu, the window closes but application/process is still running. Stuck on GetMessage.
The application contains only one window.
My WndProc simply contains WM_DESTROY handler which is processed correctly in any case:
switch (message) {
...
case WM_DESTROY:
    PostQuitMessage(0);
    break;
default:
    return DefWindowProc(hWnd, message, wParam, lParam);
}
The application's main loop is:
while (GetMessage(&msg, NULL, 0, 0) > 0) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
When I close the application from taskbar menu, the window closes but the process remains stuck on GetMessage. Just like it does not receive WM_QUIT correctly. But if I replace GetMessage with PeekMessage, it reads WM_QUIT from queue correctly.
Also just adding the additional PeekMessage before GetMessage makes it work:
while (true) {
    if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
        int res = GetMessage(&msg, NULL, 0, 0);
        if (res) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        } else {
            break;
        }
    }
}
Is there any reason why simple GetMessage would not receive WM_QUIT correctly when application is closed from the taskbar menu?
Minimal application code to reproduce the problem:
#include "windows.h"
#pragma comment (lib,"user32.lib")
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;   
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    // register Win32 class for this app
    WNDCLASSEX wndClass = { 0 };
    wndClass.cbSize = sizeof(wndClass);
    wndClass.lpszClassName = L"Minimal Window";
    wndClass.hInstance = hInstance;
    wndClass.style = CS_HREDRAW | CS_VREDRAW;
    wndClass.lpfnWndProc = WndProc;
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW);
    if (RegisterClassEx(&wndClass)) {
        HWND hWnd = CreateWindowEx(0, wndClass.lpszClassName, L"Minimal", WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 0, 0, 1024, 480, NULL, NULL, hInstance, NULL);
        ShowWindow(hWnd, SW_SHOW);
        UpdateWindow(hWnd);
        // process window messages
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }               
    }
    return 0;
}