Application hangs when switching to built-in Chinese IME

LEI WANG 1 Reputation point
2022-06-13T13:31:25.647+00:00

Hi, I am trying to detect key combinations with SYSKEY(ALT) and the left mouse button down event so I can do something with holding ALT key down and dragging the mouse. When release the mouse, the dragging should not be tracked anymore.
Code-wise, I am having a while loop once WM_LBUTTONDOWN event is received, and keep querying the WM_LBUTTONUP event. If the WM_LBUTTONUP event is not in the message queue, I'll continue checking whether SYSKEY is being held, otherwise, I'll break out the while loop and tell the caller that the mouse is not down anymore.
Everything works fine until we run our app in Windows 11 and switch to Chinese IME (either traditional or simplified). In this case, the WM_LBUTTONUP event will never come and the
app just freezes.
This can be reproduced with a boilerplate code of Windows Desktop Application in Visual Studio 2022. The only change made is inside the "Main message loop" part, as below:

// Main message loop  
while (GetMessage(&msg, nullptr, 0, 0)  
{  
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))  
        {  
            TranslateMessage(&msg);  
            switch (msg.message)  
            {  
            case WM_LBUTTONDOWN:  
                OutputDebugString(_T("Mouse left button DOWN!\n"));  
                while (true)  
                {  
                    if (PeekMessage(&msg, NULL, WM_LBUTTONUP, WM_LBUTTONUP, PM_NOREMOVE))  // PM_NOREMOVE is used, as this message will be used somewhere else  
                    {  
                        OutputDebugString(_T("Mouse left button UP in loop!\n"));  
                        break;  
                    }  
  
                    // PM_REMOVE option  
                    if (PeekMessage(&msg, NULL, WM_SYSKEYDOWN, WM_SYSKEYUP, PM_REMOVE));  
                    {  
                        OutputDebugString(_T("SYSKEY pressed in loop\n"));  
                    }  
  
                   // PM_NOREMOVE option  
                   /*if (PeekMessage(&msg, NULL, WM_SYSKEYDOWN, WM_SYSKEYUP, PM_NOREMOVE))  
                    {  
                        OutputDebugString(_T("SYSKEY pressed in loop\n"));  
                        GetMessage(&msg, NULL, WM_SYSKEYDOWN, WM_SYSKEYUP); // The app will hang right in here if PM_NOREMOVE  
                    }*/  
  
                    if (GetLastError())  
                    {  
                        OutputDebugString(_T("Error occured\n"));  
                    }  
                }  
                OutputDebugString(_T("Exited loop\n"));  
                break;  
            case WM_LBUTTONUP:  
                OutputDebugString(_T("Mouse left button UP!\n"));  
                break;  
            case WM_SYSKEYDOWN:  
                OutputDebugString(_T("SYSKEY DOWN!\n"));  
                break;  
            case WM_SYSKEYUP:  
                OutputDebugString(_T("SYSKEY UP!\n"));  
                break;  
            default:  
                break;  
            }  
  
            DispatchMessage(&msg);  
 }  
}  

The logs when pressing SYSKEY first, and then the mouse, is as below. We can see that SYSKEY is being held, and once the the mouse is clicked, it stopped logging. (The ALT was being held all the time until mouse was clicked, but there was still a SYSKEY UP message).
Another scenario is clicking and holding the left mouse button first, then press ALT. Then the app also stopped logging and froze.

Please note that this only happens when the app is running with Chinese IME activated.

Mouse left button DOWN
Mouse left button UP in loop
Exit loop
Mouse left button UP
Mouse left button DOWN
Mouse left button UP in loop
Exit loop
Mouse left button UP
SYSKEY DOWN
SYSKEY DOWN
SYSKEY DOWN
SYSKEY DOWN
SYSKEY DOWN
SYSKEY DOWN
SYSKEY DOWN
SYSKEY DOWN
SYSKEY UP
Mouse left button DOWN

Windows 11
Windows 11
A Microsoft operating system designed for productivity, creativity, and ease of use.
3,513 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
2,627 questions
{count} votes