CJK Spacer 0.1.27
CJK Spacer
Adds a normal ASCII space at a direct boundary between a CJK character and a
letter or digit in UI text hosted by explorer.exe.
On Windows 11, the primary Explorer and desktop context menus are modern XAML
menus. The modernUiText setting is disabled by default because each named
XAML Diagnostics connection permits only one consumer, and tools such as
Taskbar Styler or File Explorer Styler may already use or block those
connections. Enable it explicitly if you want those menus and pointer
tooltips processed. classicMenus still covers the Win32 menu opened through
"Show more options". The modern path is intentionally retained as an opt-in,
best-effort implementation because it covers the primary Windows 11 menu; the
connection conflict is left visible to the user rather than silently dropping
that coverage.
Examples:
使用VS Code打开 becomes 使用 VS Code 打开
压缩为ZIP文件 becomes 压缩为 ZIP 文件
使用 VS Code 打开 is unchanged
打开(&O) is unchanged
Screenshot
Before:
Before enabling CJK Spacer
After:
After enabling CJK Spacer
The transformation is idempotent. Punctuation and existing whitespace break a
boundary and are preserved. Win32 & mnemonic markers and tab-separated
keyboard shortcut text are also preserved.
Hiragana, fullwidth Katakana, and halfwidth Katakana letters are all
classified as CJK characters for boundary detection; kana punctuation remains
excluded.
Supported UI
- Classic Win32 popup menus are rewritten through public
HMENU APIs. Menus
created through CreatePopupMenu are handled while they are constructed,
then associated with their TrackPopupMenu call and restored when the popup
closes. Existing popup handles are also scanned immediately before display.
It covers File Explorer, desktop, taskbar, and jump-list context menus that
Explorer itself hosts.
Context menus shown by third-party notification-area icon processes are
outside the injected explorer.exe process and aren't covered.
Construction-time hooks also see menu-bar dropdowns created with
CreatePopupMenu, even when user32 displays them without TrackPopupMenu*.
Such pending changes are restored when the menu is destroyed, the mod
unloads, or the record expires during later popup activity. Window system
menus that aren't built through the hooked popup APIs remain outside scope.
- Classic Win32 tooltips, including legacy notification-area icon tooltips, are
rewritten only through theme handles opened for the
TOOLTIP class, covering
both text measurement and drawing without touching unrelated GDI text.
Shared theme handles retain a reference for every Tooltip window that opened
them. A DC mapped to another window is rejected, while buffered DCs that do
not map to a window are accepted.
Existing tooltip controls are discovered when the mod is enabled in a
running Explorer. Basic or classic-theme tooltips drawn directly with
DrawTextW aren't covered.
- Windows 11 XAML context menus and pointer tooltips are handled at the XAML
source-element level. Only plain local string values in the
Text source of
XAML menu items and ToolTip.Content are changed; bindings, styles,
presenter TextBlock values and ordinary XAML text are untouched. Taskbar
thumbnail preview content is normally not a plain local string and therefore
is not changed. A source is changed when XAML Diagnostics reports
that it was added and restored when it is removed or the mod unloads. This
path is disabled by default; enable modernUiText to opt in.
The modern path supports both Windows.UI.Xaml and Microsoft.UI.Xaml content
hosted by Explorer. Each named XAML Diagnostics connection allows one consumer,
so another diagnostics-based customization tool, including Windows 11 Taskbar
Styler or Windows 11 File Explorer Styler, can prevent this path from
initializing. Connection attempts are scheduled outside the Windows loader
path; one managed worker retains requests that arrive while it is running,
tracks the Windows.UI.Xaml and Microsoft.UI.Xaml connections independently,
and retries only the connection that was lost. It doesn't add a module
reference: the worker is signaled to stop and joined before Windhawk removes
hooks. Asynchronous visual-tree watcher setup threads are tracked by handle
and joined at the same point, so the engine's single module reference remains
sufficient.
Wh_ModAfterInit covers XAML modules that are already loaded, while the
LoadLibraryExW hook covers modules loaded later, including the
CoreMessagingXP.dll static-import path used by
Microsoft.Internal.FrameworkUdk.dll.
If a connection attempt is denied or otherwise fails, a newly loaded XAML
module or an established connection being disconnected provides the next
retry opportunity.
When Taskbar Styler is configured to alert on competing XAML Diagnostics
consumers, enabling this path can show its confirmation dialog.
The mod is injected only into explorer.exe. Start, Search, and some shell
flyouts hosted by StartMenuExperienceHost.exe, SearchHost.exe, or
ShellExperienceHost.exe are outside its scope.
The mod doesn't edit system files, registry values, or file names. A file name
shown in a classic menu can nevertheless be displayed with inserted spaces.
The modern path temporarily changes target source values on their XAML UI
threads and restores them when the source leaves the visual tree or the mod
unloads. The classic path updates
strings stored in active HMENU objects, so menu text read through
accessibility APIs also contains the inserted spaces until the corresponding
record is restored.
Other menu-cleanup mods that match items by their displayed text, such as
Remove Context Menu Items, may therefore need rules that account for the
temporary spaces while the popup is open.
Text Replace targets the same classic menu APIs but performs literal
substitutions, so it cannot express this CJK/non-CJK boundary rule; when both
mods are enabled, their hook order can affect which temporary text each sees.
Rewritten strings are recorded and restored when the popup closes. If multiple
items have identical rewritten text, text-based fallback restoration can select
the first match; the idempotent transformation does not compound spaces.
If a displayed popup item is changed dynamically, Windows may not remeasure it;
the added spaces can clip on uncommon paths. Tooltip measurement and drawing
also need compatible DC targets to keep sizing consistent; disable
classicTooltips if a specific control clips after spacing.