Fixed a race condition on RPC worker thread creation, and a typo.
[wine] / dlls / user / tests / class.c
1 /* Unit test suite for window classes.
2  *
3  * Copyright 2002 Mike McCormack
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include <assert.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23
24 #include "wine/test.h"
25 #include "winbase.h"
26 #include "winreg.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29
30 #define NUMCLASSWORDS 4
31
32 LRESULT WINAPI ClassTest_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
33 {
34     return DefWindowProcW (hWnd, msg, wParam, lParam);
35 }
36
37 /***********************************************************************
38  *
39  *           WinMain
40  */
41 void ClassTest(HINSTANCE hInstance, BOOL global)
42 {
43     WNDCLASSW cls, wc;
44     WCHAR className[] = {'T','e','s','t','C','l','a','s','s',0};
45     WCHAR winName[]   = {'W','i','n','C','l','a','s','s','T','e','s','t',0};
46     HWND hTestWnd;
47     DWORD i;
48     WCHAR str[20];
49     ATOM classatom;
50
51     cls.style         = CS_HREDRAW | CS_VREDRAW | (global?CS_GLOBALCLASS:0);
52     cls.lpfnWndProc   = ClassTest_WndProc;
53     cls.cbClsExtra    = NUMCLASSWORDS*sizeof(DWORD);
54     cls.cbWndExtra    = 12;
55     cls.hInstance     = hInstance;
56     cls.hIcon         = LoadIconW (0, (LPWSTR)IDI_APPLICATION);
57     cls.hCursor       = LoadCursorW (0, (LPWSTR)IDC_ARROW);
58     cls.hbrBackground = GetStockObject (WHITE_BRUSH);
59     cls.lpszMenuName  = 0;
60     cls.lpszClassName = className;
61
62     classatom=RegisterClassW(&cls);
63     if (!classatom && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
64         return;
65     ok(classatom, "failed to register class");
66
67     ok(!RegisterClassW (&cls),
68         "RegisterClass of the same class should fail for the second time");
69
70 #if 0
71     /* these succeeds on Wine, but shouldn't cause any trouble ... */
72     ok(!GlobalFindAtomW(className),
73         "Found class as global atom");
74
75     ok(!FindAtomW(className),
76         "Found class as global atom");
77 #endif
78
79     /* Setup windows */
80     hTestWnd = CreateWindowW (className, winName,
81        WS_OVERLAPPEDWINDOW + WS_HSCROLL + WS_VSCROLL,
82        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0,
83        0, hInstance, 0);
84
85     ok(hTestWnd!=0, "Failed to create window");
86
87     /* test initial values of valid classwords */
88     for(i=0; i<NUMCLASSWORDS; i++)
89     {
90         SetLastError(0);
91         ok(!GetClassLongW(hTestWnd,i*sizeof (DWORD)),
92             "GetClassLongW initial value nonzero!");
93         ok(!GetLastError(),
94             "GetClassLongW failed!");
95     }
96
97 #if 0
98     /*
99      *  GetClassLongW(hTestWnd, NUMCLASSWORDS*sizeof(DWORD))
100      *  does not fail on Win 98, though MSDN says it should
101      */
102     SetLastError(0);
103     GetClassLongW(hTestWnd, NUMCLASSWORDS*sizeof(DWORD));
104     ok(GetLastError(),
105         "GetClassLongW() with invalid offset did not fail");
106 #endif
107
108     /* set values of valid class words */
109     for(i=0; i<NUMCLASSWORDS; i++)
110     {
111         SetLastError(0);
112         ok(!SetClassLongW(hTestWnd,i*sizeof(DWORD),i+1),
113             "GetClassLongW(%ld) initial value nonzero!",i*sizeof(DWORD));
114         ok(!GetLastError(),
115             "SetClassLongW(%ld) failed!",i*sizeof(DWORD));
116     }
117
118     /* test values of valid classwords that we set */
119     for(i=0; i<NUMCLASSWORDS; i++)
120     {
121         SetLastError(0);
122         ok( (i+1) == GetClassLongW(hTestWnd,i*sizeof (DWORD)),
123             "GetClassLongW value doesn't match what was set!");
124         ok(!GetLastError(),
125             "GetClassLongW failed!");
126     }
127
128     /* check GetClassName */
129     i = GetClassNameW(hTestWnd, str, sizeof str);
130     ok(i == lstrlenW(className),
131         "GetClassName returned incorrect length");
132     ok(!lstrcmpW(className,str),
133         "GetClassName returned incorrect name for this window's class");
134
135     /* check GetClassInfo with our hInstance */
136     if(GetClassInfoW(hInstance, str, &wc))
137     {
138         ok(wc.cbClsExtra == cls.cbClsExtra,
139             "cbClsExtra did not match");
140         ok(wc.cbWndExtra == cls.cbWndExtra,
141             "cbWndExtra did not match");
142         ok(wc.hbrBackground == cls.hbrBackground,
143             "hbrBackground did not match");
144         ok(wc.hCursor== cls.hCursor,
145             "hCursor did not match");
146         ok(wc.hInstance== cls.hInstance,
147             "hInstance did not match");
148     }
149     else
150         ok(FALSE,"GetClassInfo (hinstance) failed!");
151
152     /* check GetClassInfo with zero hInstance */
153     if(global)
154     {
155         if(GetClassInfoW(0, str, &wc))
156         {
157             ok(wc.cbClsExtra == cls.cbClsExtra,
158                 "cbClsExtra did not match %x!=%x",wc.cbClsExtra,cls.cbClsExtra);
159             ok(wc.cbWndExtra == cls.cbWndExtra,
160                 "cbWndExtra did not match %x!=%x",wc.cbWndExtra,cls.cbWndExtra);
161             ok(wc.hbrBackground == cls.hbrBackground,
162                 "hbrBackground did not match %p!=%p",wc.hbrBackground,cls.hbrBackground);
163             ok(wc.hCursor== cls.hCursor,
164                 "hCursor did not match %p!=%p",wc.hCursor,cls.hCursor);
165             ok(!wc.hInstance,
166                 "hInstance not zero for global class %p",wc.hInstance);
167         }
168         else
169             ok(FALSE,"GetClassInfo (0) failed for global class!");
170     }
171     else
172     {
173         ok(!GetClassInfoW(0, str, &wc),
174             "GetClassInfo (0) succeeded for local class!");
175     }
176
177     ok(!UnregisterClassW(className, hInstance),
178         "Unregister class succeeded with window existing");
179
180     ok(DestroyWindow(hTestWnd),
181         "DestroyWindow() failed!");
182
183     ok(UnregisterClassW(className, hInstance),
184         "UnregisterClass() failed");
185
186     return;
187 }
188
189 START_TEST(class)
190 {
191     HANDLE hInstance = GetModuleHandleA( NULL );
192
193     ClassTest(hInstance,FALSE);
194     ClassTest(hInstance,TRUE);
195 }