Win32: Alt+key beeps, a borrowed window class name, and one surrogate stash for every window #185
Labels
No labels
claude:blocked
claude:done
claude:failed
claude:in-progress
claude:ready
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Catcrafts/Crafter.Graphics#185
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Three small problems in the Win32 window code, found while reviewing
claude/win32-title. Line numbers refer toimplementations/Crafter.Graphics-Window.cppat852ae8a.Alt+key beeps
TranslateMessageturns Alt with a character key intoWM_SYSCHAR, which reachesDefWindowProcthrough the default case (:339) and becomesSC_KEYMENU. The window has no menu, soWM_MENUCHARgets its default answer,MNC_IGNORE, and Windows plays the error sound. An application that binds Alt+Enter or Alt+1 to 9 throughonRawKeyDowngets its action and a beep on every press.Fix: answer
WM_MENUCHARwithMAKELRESULT(0, MNC_CLOSE). Alt+Space still opens the system menu.The window class name can belong to someone else
The class is called
"myWindowClass"(:128), registered under the executable'shInstance, andERROR_CLASS_ALREADY_EXISTS(:410) is taken to mean an earlier window registered it. If the consumer's own window code uses the same name (it comes from a well-known Win32 tutorial), or a second copy of the library in a DLL registers it first,CreateWindowExbuilds the HWND with that class's window procedure: no input, no resize,opennever cleared.Fix: a name only this library uses, such as
L"Crafter.Graphics.Window", and onERROR_CLASS_ALREADY_EXISTSaGetClassInfoExWcheck that itslpfnWndProcisWndProc.One surrogate stash for every window
WM_CHARkeeps a pending high surrogate in a function-localstatic(:211) that every window shares, and only a low surrogate clears it. A high surrogate, then other characters, then a lone low surrogate are joined into a character neither unit belonged to:0xD83D,'a',0xDE00comes out as"a"and then U+1F600. Well-formed input never does this; malformed input fromSendInputorPostMessageWcan.Fix: keep the stash in the
Window, and drop a pending high surrogate when anything other than a low surrogate follows it.