Skip to content

Commit 529246b

Browse files
[WIN32SS:USER] Fix ScrollBar class creation when using comctl32 v6, mute useless errors
For some reason, both Windows and Wine define ScrollBar class to be forwarded. Wine does not re-register the ScrollBar class, and Windows does not appear to do so either. Previously, ReactOS relied on a hack to register the ScrollBar class: https://github.com/reactos/reactos/blob/eecfbaeaa0bdef86f0cecff9828871be276ccd6e/dll/win32/comctl32/theming.c#L164. Wine uses a is_builtin_class function to determine if the class is implemented server side rather than user32/comctl32, so use the same function. Wine switched to registering all of its comctl32 classes in RegisterClassNameW rather than its dllmain. See wine-mirror/wine@05421ef. Remove errors when the class could not be located in the first pass, which is now the default behavior, which results in user32!VersionRegisterClass being called, which allows CreateWindow to succeed. I also confirmed that Windows's comctl32 registers its classes when RegisterClassNameW is called by user32, not at startup using a debugger.
1 parent c4331b4 commit 529246b

3 files changed

Lines changed: 51 additions & 24 deletions

File tree

win32ss/user/ntuser/class.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,11 +1477,11 @@ IntGetAndReferenceClass(PUNICODE_STRING ClassName, HINSTANCE hInstance, BOOL bDe
14771477
{
14781478
if (IS_ATOM(ClassName->Buffer))
14791479
{
1480-
ERR("Class 0x%p not found\n", ClassName->Buffer);
1480+
TRACE("Class 0x%p not found\n", ClassName->Buffer);
14811481
}
14821482
else
14831483
{
1484-
ERR("Class \"%wZ\" not found\n", ClassName);
1484+
TRACE("Class \"%wZ\" not found\n", ClassName);
14851485
}
14861486

14871487
return NULL;

win32ss/user/ntuser/window.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2214,7 +2214,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
22142214
if(!Class)
22152215
{
22162216
EngSetLastError(ERROR_CANNOT_FIND_WND_CLASS);
2217-
ERR("Failed to find class %wZ\n", ClassName);
2217+
TRACE("Failed to find class %wZ\n", ClassName);
22182218
goto cleanup;
22192219
}
22202220

win32ss/user/user32/windows/class.c

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,25 +47,26 @@ LPCWSTR is_comctl32_class( const WCHAR *name )
4747
{
4848
static const WCHAR classesW[][20] =
4949
{
50-
{'C','o','m','b','o','B','o','x','E','x','3','2',0},
51-
{'m','s','c','t','l','s','_','h','o','t','k','e','y','3','2',0},
52-
{'m','s','c','t','l','s','_','p','r','o','g','r','e','s','s','3','2',0},
53-
{'m','s','c','t','l','s','_','s','t','a','t','u','s','b','a','r','3','2',0},
54-
{'m','s','c','t','l','s','_','t','r','a','c','k','b','a','r','3','2',0},
55-
{'m','s','c','t','l','s','_','u','p','d','o','w','n','3','2',0},
56-
{'N','a','t','i','v','e','F','o','n','t','C','t','l',0},
57-
{'R','e','B','a','r','W','i','n','d','o','w','3','2',0},
58-
{'S','y','s','A','n','i','m','a','t','e','3','2',0},
59-
{'S','y','s','D','a','t','e','T','i','m','e','P','i','c','k','3','2',0},
60-
{'S','y','s','H','e','a','d','e','r','3','2',0},
61-
{'S','y','s','I','P','A','d','d','r','e','s','s','3','2',0},
62-
{'S','y','s','L','i','s','t','V','i','e','w','3','2',0},
63-
{'S','y','s','M','o','n','t','h','C','a','l','3','2',0},
64-
{'S','y','s','P','a','g','e','r',0},
65-
{'S','y','s','T','a','b','C','o','n','t','r','o','l','3','2',0},
66-
{'S','y','s','T','r','e','e','V','i','e','w','3','2',0},
67-
{'T','o','o','l','b','a','r','W','i','n','d','o','w','3','2',0},
68-
{'t','o','o','l','t','i','p','s','_','c','l','a','s','s','3','2',0},
50+
L"ComboBoxEx32",
51+
L"msctls_hotkey32",
52+
L"msctls_progress32",
53+
L"msctls_statusbar32",
54+
L"msctls_trackbar32",
55+
L"msctls_updown32",
56+
L"NativeFontCtl",
57+
L"ReBarWindow32",
58+
L"SysAnimate32",
59+
L"SysDateTimePick32",
60+
L"SysHeader32",
61+
L"SysIPAddress32",
62+
L"SysLink",
63+
L"SysListView32",
64+
L"SysMonthCal32",
65+
L"SysPager",
66+
L"SysTabControl32",
67+
L"SysTreeView32",
68+
L"ToolbarWindow32",
69+
L"tooltips_class32",
6970
};
7071

7172
int min = 0, max = (sizeof(classesW) / sizeof(classesW[0])) - 1;
@@ -80,6 +81,27 @@ LPCWSTR is_comctl32_class( const WCHAR *name )
8081
return NULL;
8182
}
8283

84+
static BOOL is_builtin_class( const WCHAR *name )
85+
{
86+
static const WCHAR *classesW[] =
87+
{
88+
L"IME",
89+
L"MDIClient",
90+
L"Scrollbar",
91+
};
92+
93+
int min = 0, max = _countof(classesW) - 1;
94+
95+
while (min <= max)
96+
{
97+
int res, pos = (min + max) / 2;
98+
if (!(res = strcmpiW( name, classesW[pos] ))) return TRUE;
99+
if (res < 0) max = pos - 1;
100+
else min = pos + 1;
101+
}
102+
return FALSE;
103+
}
104+
83105
LPCWSTR
84106
FASTCALL
85107
ClassNameToVersion(
@@ -128,6 +150,13 @@ ClassNameToVersion(
128150
RtlInitUnicodeString(&SectionName, lpszClass);
129151
}
130152
}
153+
154+
// check if the classes are built into win32k, if so use the non-versioned variant as comctl32 does not register the versioned class names
155+
if (is_builtin_class(SectionName.Buffer))
156+
{
157+
return NULL;
158+
}
159+
131160
#ifdef USE_VERSIONED_CLASSES
132161
Status = RtlFindActivationContextSectionString( FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX,
133162
NULL,
@@ -205,8 +234,6 @@ VersionRegisterClass(
205234
WCHAR ClassNameBuf[MAX_PATH] = {0};
206235
RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame = { sizeof(Frame), 1 };
207236

208-
ERR("VersionRegisterClass: Attempting to call RegisterClassNameW in %S.\n", lpLibFileName);
209-
210237
RtlActivateActivationContextUnsafeFast(&Frame, Contex);
211238

212239
_SEH2_TRY

0 commit comments

Comments
 (0)