ReactOS  0.4.14-dev-77-gd9e7c48
class.c
Go to the documentation of this file.
1 /* Unit test suite for window classes.
2  *
3  * Copyright 2002 Mike McCormack
4  * Copyright 2003 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 /* To get CS_DROPSHADOW with the MSVC headers */
22 #ifndef __REACTOS__
23 #define _WIN32_WINNT 0x0501
24 #endif
25 
26 #include <stdlib.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29 
30 #include "wine/test.h"
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winnls.h"
34 #include "winreg.h"
35 #include "wingdi.h"
36 #include "winuser.h"
37 #include "commctrl.h"
38 
39 #define NUMCLASSWORDS 4
40 
41 #define IS_WNDPROC_HANDLE(x) (((ULONG_PTR)(x) >> 16) == (~0u >> 16))
42 
43 #ifdef __i386__
44 #define ARCH "x86"
45 #elif defined __x86_64__
46 #define ARCH "amd64"
47 #elif defined __arm__
48 #define ARCH "arm"
49 #elif defined __aarch64__
50 #define ARCH "arm64"
51 #else
52 #define ARCH "none"
53 #endif
54 
55 static const char comctl32_manifest[] =
56 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
57 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n"
58 " <assemblyIdentity\n"
59 " type=\"win32\"\n"
60 " name=\"Wine.User32.Tests\"\n"
61 " version=\"1.0.0.0\"\n"
62 " processorArchitecture=\"" ARCH "\"\n"
63 " />\n"
64 "<description>Wine comctl32 test suite</description>\n"
65 "<dependency>\n"
66 " <dependentAssembly>\n"
67 " <assemblyIdentity\n"
68 " type=\"win32\"\n"
69 " name=\"microsoft.windows.common-controls\"\n"
70 " version=\"6.0.0.0\"\n"
71 " processorArchitecture=\"" ARCH "\"\n"
72 " publicKeyToken=\"6595b64144ccf1df\"\n"
73 " language=\"*\"\n"
74 " />\n"
75 "</dependentAssembly>\n"
76 "</dependency>\n"
77 "</assembly>\n";
78 
80 {
81  if (msg == WM_NCCREATE) return 1;
82  return DefWindowProcW (hWnd, msg, wParam, lParam);
83 }
84 
86 {
87  if (msg == WM_NCCREATE) return 1;
88  return DefWindowProcA (hWnd, msg, wParam, lParam);
89 }
90 
91 /***********************************************************************
92  */
93 static void ClassTest(HINSTANCE hInstance, BOOL global)
94 {
95  WNDCLASSW cls, wc;
96  static const WCHAR className[] = {'T','e','s','t','C','l','a','s','s',0};
97  static const WCHAR winName[] = {'W','i','n','C','l','a','s','s','T','e','s','t',0};
98  ATOM test_atom;
99  HWND hTestWnd;
100  LONG i;
101  WCHAR str[20];
102  ATOM classatom;
103 
104  cls.style = CS_HREDRAW | CS_VREDRAW | (global?CS_GLOBALCLASS:0);
106  cls.cbClsExtra = NUMCLASSWORDS*sizeof(DWORD);
107  cls.cbWndExtra = 12;
108  cls.hInstance = hInstance;
110  cls.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW);
112  cls.lpszMenuName = 0;
113  cls.lpszClassName = className;
114 
115  classatom=RegisterClassW(&cls);
116  if (!classatom && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
117  return;
118  ok(classatom, "failed to register class\n");
119 
120  ok(!RegisterClassW (&cls),
121  "RegisterClass of the same class should fail for the second time\n");
122 
123  /* Setup windows */
124  hTestWnd = CreateWindowW (className, winName,
126  CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0,
127  0, hInstance, 0);
128 
129  ok(hTestWnd!=0, "Failed to create window\n");
130 
131  /* test initial values of valid classwords */
132  for(i=0; i<NUMCLASSWORDS; i++)
133  {
134  SetLastError(0);
135  ok(!GetClassLongW(hTestWnd,i*sizeof (DWORD)),
136  "GetClassLongW initial value nonzero!\n");
137  ok(!GetLastError(),
138  "GetClassLongW failed!\n");
139  }
140 
141  if (0)
142  {
143  /*
144  * GetClassLongW(hTestWnd, NUMCLASSWORDS*sizeof(DWORD))
145  * does not fail on Win 98, though MSDN says it should
146  */
147  SetLastError(0);
148  GetClassLongW(hTestWnd, NUMCLASSWORDS*sizeof(DWORD));
149  ok(GetLastError(),
150  "GetClassLongW() with invalid offset did not fail\n");
151  }
152 
153  /* set values of valid class words */
154  for(i=0; i<NUMCLASSWORDS; i++)
155  {
156  SetLastError(0);
157  ok(!SetClassLongW(hTestWnd,i*sizeof(DWORD),i+1),
158  "GetClassLongW(%d) initial value nonzero!\n",i);
159  ok(!GetLastError(),
160  "SetClassLongW(%d) failed!\n",i);
161  }
162 
163  /* test values of valid classwords that we set */
164  for(i=0; i<NUMCLASSWORDS; i++)
165  {
166  SetLastError(0);
167  ok( (i+1) == GetClassLongW(hTestWnd,i*sizeof (DWORD)),
168  "GetClassLongW value doesn't match what was set!\n");
169  ok(!GetLastError(),
170  "GetClassLongW failed!\n");
171  }
172 
173  /* check GetClassName */
174  i = GetClassNameW(hTestWnd, str, sizeof(str)/sizeof(str[0]));
175  ok(i == lstrlenW(className),
176  "GetClassName returned incorrect length\n");
177  ok(!lstrcmpW(className,str),
178  "GetClassName returned incorrect name for this window's class\n");
179 
180  /* check GetClassInfo with our hInstance */
181  if((test_atom = GetClassInfoW(hInstance, str, &wc)))
182  {
183  ok(test_atom == classatom,
184  "class atom did not match\n");
185  ok(wc.cbClsExtra == cls.cbClsExtra,
186  "cbClsExtra did not match\n");
187  ok(wc.cbWndExtra == cls.cbWndExtra,
188  "cbWndExtra did not match\n");
189  ok(wc.hbrBackground == cls.hbrBackground,
190  "hbrBackground did not match\n");
191  ok(wc.hCursor== cls.hCursor,
192  "hCursor did not match\n");
193  ok(wc.hInstance== cls.hInstance,
194  "hInstance did not match\n");
195  }
196  else
197  ok(FALSE,"GetClassInfo (hinstance) failed!\n");
198 
199  /* check GetClassInfo with zero hInstance */
200  if(global)
201  {
202  if((test_atom = GetClassInfoW(0, str, &wc)))
203  {
204  ok(test_atom == classatom,
205  "class atom did not match %x != %x\n", test_atom, classatom);
206  ok(wc.cbClsExtra == cls.cbClsExtra,
207  "cbClsExtra did not match %x!=%x\n",wc.cbClsExtra,cls.cbClsExtra);
208  ok(wc.cbWndExtra == cls.cbWndExtra,
209  "cbWndExtra did not match %x!=%x\n",wc.cbWndExtra,cls.cbWndExtra);
210  ok(wc.hbrBackground == cls.hbrBackground,
211  "hbrBackground did not match %p!=%p\n",wc.hbrBackground,cls.hbrBackground);
212  ok(wc.hCursor== cls.hCursor,
213  "hCursor did not match %p!=%p\n",wc.hCursor,cls.hCursor);
214  ok(!wc.hInstance,
215  "hInstance not zero for global class %p\n",wc.hInstance);
216  }
217  else
218  ok(FALSE,"GetClassInfo (0) failed for global class!\n");
219  }
220  else
221  {
222  ok(!GetClassInfoW(0, str, &wc),
223  "GetClassInfo (0) succeeded for local class!\n");
224  }
225 
226  ok(!UnregisterClassW(className, hInstance),
227  "Unregister class succeeded with window existing\n");
228 
229  ok(DestroyWindow(hTestWnd),
230  "DestroyWindow() failed!\n");
231 
232  ok(UnregisterClassW(className, hInstance),
233  "UnregisterClass() failed\n");
234 
235  return;
236 }
237 
238 static void check_style( const char *name, int must_exist, UINT style, UINT ignore )
239 {
240  WNDCLASSA wc;
241 
242  if (GetClassInfoA( 0, name, &wc ))
243  {
244  ok( !(~wc.style & style & ~ignore), "System class %s is missing bits %x (%08x/%08x)\n",
245  name, ~wc.style & style, wc.style, style );
246  ok( !(wc.style & ~style), "System class %s has extra bits %x (%08x/%08x)\n",
247  name, wc.style & ~style, wc.style, style );
248  }
249  else
250  ok( !must_exist, "System class %s does not exist\n", name );
251 }
252 
253 /* test styles of system classes */
254 static void test_styles(void)
255 {
256  /* check style bits */
257  check_style( "Button", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, 0 );
258  check_style( "ComboBox", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, 0 );
259  check_style( "Edit", 1, CS_PARENTDC | CS_DBLCLKS, 0 );
260  check_style( "ListBox", 1, CS_PARENTDC | CS_DBLCLKS, CS_PARENTDC /*FIXME*/ );
261  check_style( "MDIClient", 1, 0, 0 );
262  check_style( "ScrollBar", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, 0 );
263  check_style( "Static", 1, CS_PARENTDC | CS_DBLCLKS, 0 );
264  check_style( "ComboLBox", 1, CS_SAVEBITS | CS_DBLCLKS, 0 );
265  check_style( "DDEMLEvent", 0, 0, 0 );
266  check_style( "Message", 0, 0, 0 );
267  check_style( "#32768", 1, CS_DROPSHADOW | CS_SAVEBITS | CS_DBLCLKS, CS_DROPSHADOW ); /* menu */
268  check_style( "#32769", 1, CS_DBLCLKS, 0 ); /* desktop */
269  check_style( "#32770", 1, CS_SAVEBITS | CS_DBLCLKS, 0 ); /* dialog */
270  todo_wine { check_style( "#32771", 1, CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW, 0 ); } /* task switch */
271  check_style( "#32772", 1, 0, 0 ); /* icon title */
272 }
273 
274 static void check_class_(int line, HINSTANCE inst, const char *name, const char *menu_name)
275 {
276  WNDCLASSA wc;
277  UINT atom = GetClassInfoA(inst,name,&wc);
278  ok_(__FILE__,line)( atom, "Class %s %p not found\n", name, inst );
279  if (atom)
280  {
281  if (wc.lpszMenuName && menu_name)
282  ok_(__FILE__,line)( !strcmp( menu_name, wc.lpszMenuName ),
283  "Wrong name %s/%s for class %s %p\n",
284  wc.lpszMenuName, menu_name, name, inst );
285  else
286  ok_(__FILE__,line)( !menu_name == !wc.lpszMenuName, "Wrong name %p/%p for class %s %p\n",
287  wc.lpszMenuName, menu_name, name, inst );
288  }
289 }
290 #define check_class(inst,name,menu) check_class_(__LINE__,inst,name,menu)
291 
292 static void check_instance_( int line, const char *name, HINSTANCE inst,
293  HINSTANCE info_inst, HINSTANCE gcl_inst )
294 {
295  WNDCLASSA wc;
296  HWND hwnd;
297 
298  ok_(__FILE__,line)( GetClassInfoA( inst, name, &wc ), "Couldn't find class %s inst %p\n", name, inst );
299  ok_(__FILE__,line)( wc.hInstance == info_inst, "Wrong info instance %p/%p for class %s\n",
300  wc.hInstance, info_inst, name );
301  hwnd = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, inst, 0 );
302  ok_(__FILE__,line)( hwnd != NULL, "Couldn't create window for class %s inst %p\n", name, inst );
303  ok_(__FILE__,line)( (HINSTANCE)GetClassLongPtrA( hwnd, GCLP_HMODULE ) == gcl_inst,
304  "Wrong GCL instance %p/%p for class %s\n",
305  (HINSTANCE)GetClassLongPtrA( hwnd, GCLP_HMODULE ), gcl_inst, name );
306  ok_(__FILE__,line)( (HINSTANCE)GetWindowLongPtrA( hwnd, GWLP_HINSTANCE ) == inst,
307  "Wrong GWL instance %p/%p for window %s\n",
309  ok_(__FILE__,line)(!UnregisterClassA(name, inst),
310  "UnregisterClassA should fail while exists a class window\n");
312  "GetLastError() should be set to ERROR_CLASS_HAS_WINDOWS not %d\n", GetLastError());
314 }
315 #define check_instance(name,inst,info_inst,gcl_inst) check_instance_(__LINE__,name,inst,info_inst,gcl_inst)
316 
318 {
319  const char *name;
321 };
322 
324 {
325  struct class_info *class_info = param;
326 
328 
329  return 0;
330 }
331 
333 {
334  HANDLE hThread;
335  DWORD tid;
336  struct class_info class_info;
337 
338  class_info.name = name;
339  class_info.inst = inst;
342 
344  ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
345  ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
347 }
348 
349 /* test various instance parameters */
350 static void test_instances(void)
351 {
352  WNDCLASSA cls, wc;
353  WNDCLASSEXA wcexA;
354  HWND hwnd, hwnd2;
355  const char *name = "__test__";
356  HINSTANCE kernel32 = GetModuleHandleA("kernel32");
357  HINSTANCE user32 = GetModuleHandleA("user32");
358  HINSTANCE main_module = GetModuleHandleA(NULL);
359  HINSTANCE zero_instance = 0;
360  DWORD r;
361  char buffer[0x10];
362 
363  memset( &cls, 0, sizeof(cls) );
364  cls.style = CS_HREDRAW | CS_VREDRAW;
366  cls.cbClsExtra = 0;
367  cls.cbWndExtra = 0;
368  cls.lpszClassName = name;
369 
370  cls.lpszMenuName = "main_module";
371  cls.hInstance = main_module;
372 
373  ok( RegisterClassA( &cls ), "Failed to register local class for main module\n" );
374  check_class( main_module, name, "main_module" );
375  check_instance( name, main_module, main_module, main_module );
376  check_thread_instance( name, main_module, main_module, main_module );
377 
378  cls.lpszMenuName = "kernel32";
379  cls.hInstance = kernel32;
380  ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" );
381  check_class( kernel32, name, "kernel32" );
382  check_class( main_module, name, "main_module" );
383  check_instance( name, kernel32, kernel32, kernel32 );
384  check_thread_instance( name, kernel32, kernel32, kernel32 );
385  ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
386 
387  ZeroMemory(&wcexA, sizeof(wcexA));
388  wcexA.lpfnWndProc = DefWindowProcA;
389  wcexA.lpszClassName = "__classex_test__";
390  SetLastError(0xdeadbeef);
391  wcexA.cbSize = sizeof(wcexA) - 1;
392  ok( ((RegisterClassExA( &wcexA ) == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)),
393  "Succeeded with invalid number of cbSize bytes\n");
394  SetLastError(0xdeadbeef);
395  wcexA.cbSize = sizeof(wcexA) + 1;
396  ok( ((RegisterClassExA( &wcexA ) == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)),
397  "Succeeded with invalid number of cbSize bytes\n");
398  SetLastError(0xdeadbeef);
399  wcexA.cbSize = sizeof(wcexA);
400  ok( RegisterClassExA( &wcexA ), "Failed with valid number of cbSize bytes\n");
401  wcexA.cbSize = 0xdeadbeef;
402  ok( GetClassInfoExA(main_module, wcexA.lpszClassName, &wcexA), "GetClassInfoEx failed\n");
403  ok( wcexA.cbSize == 0xdeadbeef, "GetClassInfoEx returned wrong cbSize value %d\n", wcexA.cbSize);
404  UnregisterClassA(wcexA.lpszClassName, main_module);
405 
406  /* Bug 2631 - Supplying an invalid number of bytes fails */
407  cls.cbClsExtra = 0;
408  cls.cbWndExtra = -1;
409  SetLastError(0xdeadbeef);
410  ok( ((RegisterClassA( &cls ) == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)),
411  "Failed with invalid number of WndExtra bytes\n");
412 
413  cls.cbClsExtra = -1;
414  cls.cbWndExtra = 0;
415  SetLastError(0xdeadbeef);
416  ok( ((RegisterClassA( &cls ) == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)),
417  "Failed with invalid number of ClsExtra bytes\n");
418 
419  cls.cbClsExtra = -1;
420  cls.cbWndExtra = -1;
421  SetLastError(0xdeadbeef);
422  ok( ((RegisterClassA( &cls ) == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)),
423  "Failed with invalid number of ClsExtra and cbWndExtra bytes\n");
424 
425  cls.cbClsExtra = 0;
426  cls.cbWndExtra = 0;
427  SetLastError(0xdeadbeef);
428 
429  /* setting global flag doesn't change status of class */
430  hwnd = CreateWindowExA( 0, name, "test", 0, 0, 0, 0, 0, 0, 0, main_module, 0 );
431  ok( hwnd != 0, "CreateWindow failed error %u\n", GetLastError());
433  cls.lpszMenuName = "kernel32";
434  cls.hInstance = kernel32;
435  ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" );
436  check_class( kernel32, name, "kernel32" );
437  check_class( main_module, name, "main_module" );
438  check_instance( name, kernel32, kernel32, kernel32 );
439  check_instance( name, main_module, main_module, main_module );
440  check_thread_instance( name, kernel32, kernel32, kernel32 );
441  check_thread_instance( name, main_module, main_module, main_module );
442  ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
443 
444  /* changing the instance doesn't make it global */
446  ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" );
447  check_class( kernel32, name, "kernel32" );
448  check_instance( name, kernel32, kernel32, kernel32 );
449  check_thread_instance( name, kernel32, kernel32, kernel32 );
450  ok( !GetClassInfoA( 0, name, &wc ), "Class found with null instance\n" );
451  ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
452 
453  /* GetClassInfo with instance 0 finds user32 instance */
455  ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" );
456  if (!GetClassInfoA( 0, name, &wc )) zero_instance = user32; /* instance 0 not supported on wow64 */
457  else
458  {
459  check_instance( name, 0, 0, kernel32 );
460  check_thread_instance( name, 0, 0, kernel32 );
461  }
462  check_class( kernel32, name, "kernel32" );
463  check_class( user32, name, "main_module" );
464  check_class( zero_instance, name, "main_module" );
465  check_instance( name, kernel32, kernel32, kernel32 );
466  check_instance( name, user32, zero_instance, user32 );
467  check_thread_instance( name, kernel32, kernel32, kernel32 );
468  check_thread_instance( name, user32, zero_instance, user32 );
469  ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
470 
471  SetClassLongPtrA( hwnd, GCLP_HMODULE, 0x12345678 );
472  ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" );
473  check_class( kernel32, name, "kernel32" );
474  check_class( (HINSTANCE)0x12345678, name, "main_module" );
475  check_instance( name, kernel32, kernel32, kernel32 );
476  check_instance( name, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678 );
477  check_thread_instance( name, kernel32, kernel32, kernel32 );
478  check_thread_instance( name, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678 );
479  ok( !GetClassInfoA( 0, name, &wc ), "Class found with null instance\n" );
480 
481  /* creating a window with instance 0 uses the first class found */
482  cls.hInstance = (HINSTANCE)0xdeadbeef;
483  cls.lpszMenuName = "deadbeef";
484  cls.style = 3;
485  ok( RegisterClassA( &cls ), "Failed to register local class for deadbeef\n" );
486  hwnd2 = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, NULL, 0 );
487  ok( GetClassLongPtrA( hwnd2, GCLP_HMODULE ) == 0xdeadbeef,
488  "Didn't get deadbeef class for null instance\n" );
489  DestroyWindow( hwnd2 );
490  ok( UnregisterClassA( name, (HINSTANCE)0xdeadbeef ), "Unregister failed for deadbeef\n" );
491 
492  hwnd2 = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, NULL, 0 );
493  ok( (HINSTANCE)GetClassLongPtrA( hwnd2, GCLP_HMODULE ) == kernel32,
494  "Didn't get kernel32 class for null instance\n" );
495  DestroyWindow( hwnd2 );
496 
497  r = GetClassNameA( hwnd, buffer, 4 );
498  ok( r == 3, "expected 3, got %d\n", r );
499  ok( !strcmp( buffer, "__t"), "name wrong: %s\n", buffer );
500 
501  ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
502 
503  hwnd2 = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, NULL, 0 );
504  ok( GetClassLongPtrA( hwnd2, GCLP_HMODULE ) == 0x12345678,
505  "Didn't get 12345678 class for null instance\n" );
506  DestroyWindow( hwnd2 );
507 
508  SetClassLongPtrA( hwnd, GCLP_HMODULE, (LONG_PTR)main_module );
509  DestroyWindow( hwnd );
510 
511  /* null handle means the same thing as main module */
512  cls.lpszMenuName = "null";
513  cls.hInstance = 0;
514  ok( !RegisterClassA( &cls ), "Succeeded registering local class for null instance\n" );
515  ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %d\n", GetLastError() );
516  ok( UnregisterClassA( name, main_module ), "Unregister failed for main module\n" );
517 
518  ok( RegisterClassA( &cls ), "Failed to register local class for null instance\n" );
519  /* must be found with main module handle */
520  check_class( main_module, name, "null" );
521  check_instance( name, main_module, main_module, main_module );
522  check_thread_instance( name, main_module, main_module, main_module );
523  ok( !GetClassInfoA( 0, name, &wc ), "Class found with null instance\n" );
524  ok( GetLastError() == ERROR_CLASS_DOES_NOT_EXIST, "Wrong error code %d\n", GetLastError() );
525  ok( UnregisterClassA( name, 0 ), "Unregister failed for null instance\n" );
526 
527  /* registering for user32 always fails */
528  cls.lpszMenuName = "user32";
529  cls.hInstance = user32;
530  ok( !RegisterClassA( &cls ), "Succeeded registering local class for user32\n" );
531  ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error code %d\n", GetLastError() );
532  cls.style |= CS_GLOBALCLASS;
533  ok( !RegisterClassA( &cls ), "Succeeded registering global class for user32\n" );
534  ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error code %d\n", GetLastError() );
535 
536  /* unregister is OK though */
537  cls.hInstance = main_module;
538  ok( RegisterClassA( &cls ), "Failed to register global class for main module\n" );
539  ok( UnregisterClassA( name, user32 ), "Unregister failed for user32\n" );
540 
541  /* instance doesn't matter for global class */
542  cls.style |= CS_GLOBALCLASS;
543  cls.lpszMenuName = "main_module";
544  cls.hInstance = main_module;
545  ok( RegisterClassA( &cls ), "Failed to register global class for main module\n" );
546  cls.lpszMenuName = "kernel32";
547  cls.hInstance = kernel32;
548  ok( !RegisterClassA( &cls ), "Succeeded registering local class for kernel32\n" );
549  ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %d\n", GetLastError() );
550  /* even if global flag is cleared */
551  hwnd = CreateWindowExA( 0, name, "test", 0, 0, 0, 0, 0, 0, 0, main_module, 0 );
553  ok( !RegisterClassA( &cls ), "Succeeded registering local class for kernel32\n" );
554  ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %d\n", GetLastError() );
555 
556  check_class( main_module, name, "main_module" );
557  check_class( kernel32, name, "main_module" );
558  check_class( 0, name, "main_module" );
559  check_class( (HINSTANCE)0x12345678, name, "main_module" );
560  check_instance( name, main_module, main_module, main_module );
561  check_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, main_module );
562  check_thread_instance( name, main_module, main_module, main_module );
563  check_thread_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, main_module );
564 
565  /* changing the instance for global class doesn't make much difference */
566  SetClassLongPtrA( hwnd, GCLP_HMODULE, 0xdeadbeef );
567  check_instance( name, main_module, main_module, (HINSTANCE)0xdeadbeef );
568  check_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef );
569  check_thread_instance( name, main_module, main_module, (HINSTANCE)0xdeadbeef );
570  check_thread_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef );
571 
572  DestroyWindow( hwnd );
573  ok( UnregisterClassA( name, (HINSTANCE)0x87654321 ), "Unregister failed for main module global\n" );
574  ok( !UnregisterClassA( name, (HINSTANCE)0x87654321 ), "Unregister succeeded the second time\n" );
575  ok( GetLastError() == ERROR_CLASS_DOES_NOT_EXIST, "Wrong error code %d\n", GetLastError() );
576 
577  cls.hInstance = (HINSTANCE)0x12345678;
578  ok( RegisterClassA( &cls ), "Failed to register global class for dummy instance\n" );
579  check_instance( name, main_module, main_module, (HINSTANCE)0x12345678 );
580  check_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, (HINSTANCE)0x12345678 );
581  check_thread_instance( name, main_module, main_module, (HINSTANCE)0x12345678 );
582  check_thread_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, (HINSTANCE)0x12345678 );
583  ok( UnregisterClassA( name, (HINSTANCE)0x87654321 ), "Unregister failed for main module global\n" );
584 
585  /* check system classes */
586 
587  /* we cannot register a global class with the name of a system class */
588  cls.style |= CS_GLOBALCLASS;
589  cls.lpszMenuName = "button_main_module";
590  cls.lpszClassName = "BUTTON";
591  cls.hInstance = main_module;
592  ok( !RegisterClassA( &cls ), "Succeeded registering global button class for main module\n" );
593  ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %d\n", GetLastError() );
594  cls.hInstance = kernel32;
595  ok( !RegisterClassA( &cls ), "Succeeded registering global button class for kernel32\n" );
596  ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %d\n", GetLastError() );
597 
598  /* local class is OK however */
599  cls.style &= ~CS_GLOBALCLASS;
600  cls.lpszMenuName = "button_main_module";
601  cls.hInstance = main_module;
602  ok( RegisterClassA( &cls ), "Failed to register local button class for main module\n" );
603  check_class( main_module, "BUTTON", "button_main_module" );
604  cls.lpszMenuName = "button_kernel32";
605  cls.hInstance = kernel32;
606  ok( RegisterClassA( &cls ), "Failed to register local button class for kernel32\n" );
607  check_class( kernel32, "BUTTON", "button_kernel32" );
608  check_class( main_module, "BUTTON", "button_main_module" );
609  ok( UnregisterClassA( "BUTTON", kernel32 ), "Unregister failed for kernel32 button\n" );
610  ok( UnregisterClassA( "BUTTON", main_module ), "Unregister failed for main module button\n" );
611  /* GetClassInfo sets instance to passed value for global classes */
612  check_instance( "BUTTON", 0, 0, user32 );
613  check_instance( "BUTTON", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 );
614  check_instance( "BUTTON", user32, zero_instance, user32 );
615  check_thread_instance( "BUTTON", 0, 0, user32 );
616  check_thread_instance( "BUTTON", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 );
617  check_thread_instance( "BUTTON", user32, zero_instance, user32 );
618 
619  /* we can unregister system classes */
620  ok( GetClassInfoA( 0, "BUTTON", &wc ), "Button class not found with null instance\n" );
621  ok( GetClassInfoA( kernel32, "BUTTON", &wc ), "Button class not found with kernel32\n" );
622  ok( UnregisterClassA( "BUTTON", (HINSTANCE)0x12345678 ), "Failed to unregister button\n" );
623  ok( !UnregisterClassA( "BUTTON", (HINSTANCE)0x87654321 ), "Unregistered button a second time\n" );
624  ok( GetLastError() == ERROR_CLASS_DOES_NOT_EXIST, "Wrong error code %d\n", GetLastError() );
625  ok( !GetClassInfoA( 0, "BUTTON", &wc ), "Button still exists\n" );
626  /* last error not set reliably */
627 
628  /* we can change the instance of a system class */
629  check_instance( "EDIT", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 );
630  check_thread_instance( "EDIT", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 );
631  hwnd = CreateWindowExA( 0, "EDIT", "test", 0, 0, 0, 0, 0, 0, 0, main_module, 0 );
632  SetClassLongPtrA( hwnd, GCLP_HMODULE, 0xdeadbeef );
633  check_instance( "EDIT", (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0xdeadbeef );
634  check_thread_instance( "EDIT", (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0xdeadbeef );
636 }
637 
638 static void test_builtinproc(void)
639 {
640  /* Edit behaves differently */
641  static const CHAR NORMAL_CLASSES[][10] = {
642  "Button",
643  "Static",
644  "ComboBox",
645  "ComboLBox",
646  "ListBox",
647  "ScrollBar",
648  "#32770", /* dialog */
649  };
650  static const int NUM_NORMAL_CLASSES = (sizeof(NORMAL_CLASSES)/sizeof(NORMAL_CLASSES[0]));
651  static const char classA[] = "deftest";
652  static const WCHAR classW[] = {'d','e','f','t','e','s','t',0};
653  WCHAR unistring[] = {0x142, 0x40e, 0x3b4, 0}; /* a string that would be destroyed by a W->A->W conversion */
654  WNDPROC pDefWindowProcA, pDefWindowProcW;
655  WNDPROC pNtdllDefWindowProcA, pNtdllDefWindowProcW;
656  WNDPROC oldproc;
657  WNDCLASSEXA cls; /* the memory layout of WNDCLASSEXA and WNDCLASSEXW is the same */
658  WCHAR buf[128];
659  ATOM atom;
660  HWND hwnd;
661  int i;
662 
663  pDefWindowProcA = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "DefWindowProcA");
664  pDefWindowProcW = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "DefWindowProcW");
665  pNtdllDefWindowProcA = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtdllDefWindowProc_A");
666  pNtdllDefWindowProcW = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtdllDefWindowProc_W");
667 
668  /* On Vista+, the user32.dll export DefWindowProcA/W is forwarded to */
669  /* ntdll.NtdllDefWindowProc_A/W. However, the wndproc returned by */
670  /* GetClassLong/GetWindowLong points to an unexported user32 function */
671  if (pDefWindowProcA == pNtdllDefWindowProcA &&
672  pDefWindowProcW == pNtdllDefWindowProcW)
673  skip("user32.DefWindowProcX forwarded to ntdll.NtdllDefWindowProc_X\n");
674  else
675  {
676  for (i = 0; i < 4; i++)
677  {
678  ZeroMemory(&cls, sizeof(cls));
679  cls.cbSize = sizeof(cls);
682  if (i & 1)
683  cls.lpfnWndProc = pDefWindowProcA;
684  else
685  cls.lpfnWndProc = pDefWindowProcW;
686 
687  if (i & 2)
688  {
689  cls.lpszClassName = classA;
690  atom = RegisterClassExA(&cls);
691  }
692  else
693  {
694  cls.lpszClassName = (LPCSTR)classW;
695  atom = RegisterClassExW((WNDCLASSEXW *)&cls);
696  }
697  ok(atom != 0, "Couldn't register class, i=%d, %d\n", i, GetLastError());
698 
699  hwnd = CreateWindowA(classA, NULL, 0, 0, 0, 100, 100, NULL, NULL, GetModuleHandleA(NULL), NULL);
700  ok(hwnd != NULL, "Couldn't create window i=%d\n", i);
701 
702  ok(GetWindowLongPtrA(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcA, "Wrong ANSI wndproc: %p vs %p\n",
703  (void *)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), pDefWindowProcA);
704  ok(GetClassLongPtrA(hwnd, GCLP_WNDPROC) == (ULONG_PTR)pDefWindowProcA, "Wrong ANSI wndproc: %p vs %p\n",
705  (void *)GetClassLongPtrA(hwnd, GCLP_WNDPROC), pDefWindowProcA);
706 
707  ok(GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcW, "Wrong Unicode wndproc: %p vs %p\n",
708  (void *)GetWindowLongPtrW(hwnd, GWLP_WNDPROC), pDefWindowProcW);
709  ok(GetClassLongPtrW(hwnd, GCLP_WNDPROC) == (ULONG_PTR)pDefWindowProcW, "Wrong Unicode wndproc: %p vs %p\n",
710  (void *)GetClassLongPtrW(hwnd, GCLP_WNDPROC), pDefWindowProcW);
711 
714  }
715  }
716 
717  /* built-in winproc - window A/W type automatically detected */
718  ZeroMemory(&cls, sizeof(cls));
719  cls.cbSize = sizeof(cls);
722  cls.lpszClassName = classA;
723  cls.lpfnWndProc = pDefWindowProcW;
724  atom = RegisterClassExA(&cls);
725 
729  broken(!IsWindowUnicode(hwnd)) /* Windows 8 and 10 */,
730  "Windows should be Unicode\n");
731  SendMessageW(hwnd, WM_GETTEXT, sizeof(buf) / sizeof(buf[0]), (LPARAM)buf);
732  if (IsWindowUnicode(hwnd))
733  ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
734  else
735  ok(memcmp(buf, unistring, sizeof(unistring)) != 0, "WM_GETTEXT invalid return\n");
736  SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)pDefWindowProcA);
737  ok(IsWindowUnicode(hwnd), "Windows should have remained Unicode\n");
738  if (GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcA)
739  {
740  /* DefWindowProc isn't magic on wow64 */
741  ok(IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd, GWLP_WNDPROC)), "Ansi winproc is not a handle\n");
742  }
743  else
744  {
745  ok(GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcW, "Invalid Unicode winproc\n");
746  ok(GetWindowLongPtrA(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcA, "Invalid Ansi winproc\n");
747  }
749  ok(IsWindowUnicode(hwnd) == FALSE, "SetWindowLongPtrA should have switched window to ANSI\n");
750 
753 
754  /* custom winproc - the same function can be used as both A and W*/
755  ZeroMemory(&cls, sizeof(cls));
756  cls.cbSize = sizeof(cls);
759  cls.lpszClassName = classA;
761  atom = RegisterClassExA(&cls);
762 
765  ok(IsWindowUnicode(hwnd) == FALSE, "Window should be ANSI\n");
767  ok(IsWindowUnicode(hwnd), "SetWindowLongPtrW should have changed window to Unicode\n");
769  ok(IsWindowUnicode(hwnd) == FALSE, "SetWindowLongPtrA should have changed window to ANSI\n");
770 
773 
774  /* For most of the builtin controls both GetWindowLongPtrA and W returns a pointer that is executed directly
775  * by CallWindowProcA/W */
776  for (i = 0; i < NUM_NORMAL_CLASSES; i++)
777  {
778  WNDPROC procA, procW;
779  hwnd = CreateWindowExA(0, NORMAL_CLASSES[i], classA, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 680, 260,
780  NULL, NULL, NULL, 0);
781  ok(hwnd != NULL, "Couldn't create window of class %s\n", NORMAL_CLASSES[i]);
782  SetWindowTextA(hwnd, classA); /* ComboBox needs this */
785  ok(!IS_WNDPROC_HANDLE(procA), "procA should not be a handle for %s (%p)\n", NORMAL_CLASSES[i], procA);
786  ok(!IS_WNDPROC_HANDLE(procW), "procW should not be a handle for %s (%p)\n", NORMAL_CLASSES[i], procW);
787  CallWindowProcA(procA, hwnd, WM_GETTEXT, 120, (LPARAM)buf);
788  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT A/A invalid return for class %s\n", NORMAL_CLASSES[i]);
789  CallWindowProcA(procW, hwnd, WM_GETTEXT, 120, (LPARAM)buf);
790  ok(memcmp(buf, classW, sizeof(classW)) == 0, "WM_GETTEXT A/W invalid return for class %s\n", NORMAL_CLASSES[i]);
791  CallWindowProcW(procA, hwnd, WM_GETTEXT, 120, (LPARAM)buf);
792  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT W/A invalid return for class %s\n", NORMAL_CLASSES[i]);
793  CallWindowProcW(procW, hwnd, WM_GETTEXT, 120, (LPARAM)buf);
794  ok(memcmp(buf, classW, sizeof(classW)) == 0, "WM_GETTEXT W/W invalid return for class %s\n", NORMAL_CLASSES[i]);
795 
797  ok(IS_WNDPROC_HANDLE(oldproc) == FALSE, "Class %s shouldn't return a handle\n", NORMAL_CLASSES[i]);
800  }
801 
802  /* Edit controls are special - they return a wndproc handle when GetWindowLongPtr is called with a different A/W.
803  * On the other hand there is no W->A->W conversion so this control is treated specially. */
805  CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, NULL, 0);
806  /* GetClassLongPtr returns that both the Unicode and ANSI wndproc */
807  ok(IS_WNDPROC_HANDLE(GetClassLongPtrA(hwnd, GCLP_WNDPROC)) == FALSE, "Edit control class should have a Unicode wndproc\n");
808  ok(IS_WNDPROC_HANDLE(GetClassLongPtrW(hwnd, GCLP_WNDPROC)) == FALSE, "Edit control class should have a ANSI wndproc\n");
809  /* But GetWindowLongPtr returns only a handle for the ANSI one */
810  ok(IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd, GWLP_WNDPROC)), "Edit control should return a wndproc handle\n");
811  ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd, GWLP_WNDPROC)), "Edit control shouldn't return a W wndproc handle\n");
813  ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
815  ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
817  ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
818 
821  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
822 
824  /* SetWindowLongPtr returns a wndproc handle - like GetWindowLongPtr */
825  ok(IS_WNDPROC_HANDLE(oldproc), "Edit control should return a wndproc handle\n");
826  ok(IsWindowUnicode(hwnd) == FALSE, "SetWindowLongPtrA should have changed window to ANSI\n");
827  SetWindowTextA(hwnd, classA); /* Windows resets the title to WideStringToMultiByte(unistring) */
828  memset(buf, 0, sizeof(buf));
830  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
832  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
834  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
835 
837  ok(memcmp(buf, classW, sizeof(classW)) == 0, "WM_GETTEXT invalid return\n");
838 
840 
842 
844  CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, NULL, 0);
845 
846  /* GetClassLongPtr returns that both the Unicode and ANSI wndproc */
847  ok(!IS_WNDPROC_HANDLE(GetClassLongPtrA(hwnd, GCLP_WNDPROC)), "Edit control class should have a Unicode wndproc\n");
848  ok(!IS_WNDPROC_HANDLE(GetClassLongPtrW(hwnd, GCLP_WNDPROC)), "Edit control class should have a ANSI wndproc\n");
849  /* But GetWindowLongPtr returns only a handle for the Unicode one */
850  ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd, GWLP_WNDPROC)), "Edit control shouldn't return an A wndproc handle\n");
851  ok(IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd, GWLP_WNDPROC)), "Edit control should return a wndproc handle\n");
853  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
855  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
857  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
858 
860  ok(memcmp(buf, classW, sizeof(classW)) == 0, "WM_GETTEXT invalid return\n");
861 
863  SetWindowTextW(hwnd, unistring);
865  ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
867  ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
869  ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
870 
873  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
874 
876 
878 }
879 
880 
882 {
883  return DefWindowProcA(hWnd, uMsg, wParam, lParam);
884 }
885 
887 {
888  WNDCLASSEXA wcx;
889  ATOM atom = 0;
890 
891  ZeroMemory(&wcx, sizeof(WNDCLASSEXA));
892  wcx.cbSize = sizeof(wcx);
893  wcx.lpfnWndProc = TestDlgProc;
894  wcx.cbClsExtra = 0;
896  wcx.hInstance = hInstance;
900  wcx.lpszClassName = "TestDialog";
901  wcx.lpszMenuName = "TestDialog";
905 
906  atom = RegisterClassExA(&wcx);
907  ok(atom != 0, "RegisterClassEx returned 0\n");
908 
909  return atom;
910 }
911 
912 /* test registering a dialog box created by using the CLASS directive in a
913  resource file, then test creating the dialog using CreateDialogParam. */
915 {
916  HWND hWndMain;
917 
919  {
920  hWndMain = CreateDialogParamA(hInstance, "CLASS_TEST_DIALOG", NULL, 0, 0);
921  ok(hWndMain != NULL, "CreateDialogParam returned NULL\n");
924  }
925 }
926 
927 static const struct
928 {
929  const char name[9];
930  int value;
931  int badvalue;
932 } extra_values[] =
933 {
934  {"#32770",30,30}, /* Dialog */
935 #ifdef _WIN64
936  {"Edit",8,8},
937 #else
938  {"Edit",6,8}, /* Windows XP 64-bit returns 8 also to 32-bit applications */
939 #endif
940 };
941 
942 static void test_extra_values(void)
943 {
944  int i;
945  for(i=0; i< sizeof(extra_values)/sizeof(extra_values[0]); i++)
946  {
947  WNDCLASSEXA wcx;
949 
950  ok( ret, "GetClassInfo (0) failed for global class %s\n", extra_values[i].name);
951  if (!ret) continue;
953  "expected %d, got %d\n", extra_values[i].value, wcx.cbWndExtra);
954  }
955 }
956 
957 static void test_GetClassInfo(void)
958 {
959  static const WCHAR staticW[] = {'s','t','a','t','i','c',0};
960  WNDCLASSA wc;
961  WNDCLASSEXA wcx;
962  BOOL ret;
963 
964  SetLastError(0xdeadbeef);
965  ret = GetClassInfoA(0, "static", &wc);
966  ok(ret, "GetClassInfoA() error %d\n", GetLastError());
967 
968 if (0) { /* crashes under XP */
969  SetLastError(0xdeadbeef);
970  ret = GetClassInfoA(0, "static", NULL);
971  ok(ret, "GetClassInfoA() error %d\n", GetLastError());
972 
973  SetLastError(0xdeadbeef);
974  ret = GetClassInfoW(0, staticW, NULL);
975  ok(ret, "GetClassInfoW() error %d\n", GetLastError());
976 }
977 
978  wcx.cbSize = sizeof(wcx);
979  SetLastError(0xdeadbeef);
980  ret = GetClassInfoExA(0, "static", &wcx);
981  ok(ret, "GetClassInfoExA() error %d\n", GetLastError());
982 
983  SetLastError(0xdeadbeef);
984  ret = GetClassInfoExA(0, "static", NULL);
985  ok(!ret, "GetClassInfoExA() should fail\n");
987  broken(GetLastError() == 0xdeadbeef), /* win9x */
988  "expected ERROR_NOACCESS, got %d\n", GetLastError());
989 
990  SetLastError(0xdeadbeef);
992  ok(!ret, "GetClassInfoExW() should fail\n");
994  broken(GetLastError() == 0xdeadbeef) /* NT4 */ ||
996  "expected ERROR_NOACCESS, got %d\n", GetLastError());
997 
998  wcx.cbSize = 0;
999  wcx.lpfnWndProc = NULL;
1000  SetLastError(0xdeadbeef);
1001  ret = GetClassInfoExA(0, "static", &wcx);
1002  ok(ret, "GetClassInfoExA() error %d\n", GetLastError());
1003  ok(wcx.cbSize == 0, "expected 0, got %u\n", wcx.cbSize);
1004  ok(wcx.lpfnWndProc != NULL, "got null proc\n");
1005 
1006  wcx.cbSize = sizeof(wcx) - 1;
1007  wcx.lpfnWndProc = NULL;
1008  SetLastError(0xdeadbeef);
1009  ret = GetClassInfoExA(0, "static", &wcx);
1010  ok(ret, "GetClassInfoExA() error %d\n", GetLastError());
1011  ok(wcx.cbSize == sizeof(wcx) - 1, "expected sizeof(wcx)-1, got %u\n", wcx.cbSize);
1012  ok(wcx.lpfnWndProc != NULL, "got null proc\n");
1013 
1014  wcx.cbSize = sizeof(wcx) + 1;
1015  wcx.lpfnWndProc = NULL;
1016  SetLastError(0xdeadbeef);
1017  ret = GetClassInfoExA(0, "static", &wcx);
1018  ok(ret, "GetClassInfoExA() error %d\n", GetLastError());
1019  ok(wcx.cbSize == sizeof(wcx) + 1, "expected sizeof(wcx)+1, got %u\n", wcx.cbSize);
1020  ok(wcx.lpfnWndProc != NULL, "got null proc\n");
1021 }
1022 
1023 static void test_icons(void)
1024 {
1025  WNDCLASSEXW wcex, ret_wcex;
1026  WCHAR cls_name[] = {'I','c','o','n','T','e','s','t','C','l','a','s','s',0};
1027  HWND hwnd;
1029  HICON hsmicon, hsmallnew;
1030  ICONINFO icinf;
1031 
1032  memset(&wcex, 0, sizeof wcex);
1033  wcex.cbSize = sizeof wcex;
1035  wcex.hIcon = LoadIconW(0, (LPCWSTR)IDI_APPLICATION);
1036  wcex.hInstance = hinst;
1037  wcex.lpszClassName = cls_name;
1038  ok(RegisterClassExW(&wcex), "RegisterClassExW returned 0\n");
1040  0, 0, 0, 0, NULL, NULL, hinst, 0);
1041  ok(hwnd != NULL, "Window was not created\n");
1042 
1043  ok(GetClassInfoExW(hinst, cls_name, &ret_wcex), "Class info was not retrieved\n");
1044  ok(wcex.hIcon == ret_wcex.hIcon, "Icons don't match\n");
1045  ok(ret_wcex.hIconSm != NULL, "hIconSm should be non-zero handle\n");
1046 
1047  hsmicon = (HICON)GetClassLongPtrW(hwnd, GCLP_HICONSM);
1048  ok(hsmicon != NULL, "GetClassLong should return non-zero handle\n");
1049 
1050  ok(SendMessageA(hwnd, WM_GETICON, ICON_BIG, 0) == 0,
1051  "WM_GETICON with ICON_BIG should not return the class icon\n");
1052  ok(SendMessageA(hwnd, WM_GETICON, ICON_SMALL, 0) == 0,
1053  "WM_GETICON with ICON_SMALL should not return the class icon\n");
1054  ok(SendMessageA(hwnd, WM_GETICON, ICON_SMALL2, 0) == 0,
1055  "WM_GETICON with ICON_SMALL2 should not return the class icon\n");
1056 
1059  ok(!SetClassLongPtrW(hwnd, GCLP_HICONSM, (LONG_PTR)hsmallnew),
1060  "Previous hIconSm should be zero\n");
1061  ok(hsmallnew == (HICON)GetClassLongPtrW(hwnd, GCLP_HICONSM),
1062  "Should return explicitly assigned small icon\n");
1063  ok(!GetIconInfo(hsmicon, &icinf), "Previous small icon should be destroyed\n");
1064 
1066  hsmicon = (HICON)GetClassLongPtrW(hwnd, GCLP_HICONSM);
1067  ok( hsmicon != NULL, "GetClassLong should return non-zero handle\n");
1068 
1070  ok(!GetClassLongPtrW(hwnd, GCLP_HICONSM), "GetClassLong should return zero handle\n");
1071 
1073  hsmicon = (HICON)GetClassLongPtrW(hwnd, GCLP_HICONSM);
1074  ok(hsmicon != NULL, "GetClassLong should return non-zero handle\n");
1076  ok(GetIconInfo(hsmicon, &icinf), "Icon should NOT be destroyed\n");
1077 
1078  DestroyIcon(hsmallnew);
1080 }
1081 
1082 static void create_manifest_file(const char *filename, const char *manifest)
1083 {
1084  WCHAR path[MAX_PATH];
1085  HANDLE file;
1086  DWORD size;
1087 
1090  ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
1092  CloseHandle(file);
1093 }
1094 
1095 static HANDLE create_test_actctx(const char *file)
1096 {
1097  WCHAR path[MAX_PATH];
1098  ACTCTXW actctx;
1099  HANDLE handle;
1100 
1102  memset(&actctx, 0, sizeof(ACTCTXW));
1103  actctx.cbSize = sizeof(ACTCTXW);
1104  actctx.lpSource = path;
1105 
1107  ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError());
1108 
1109  ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize);
1110  ok(actctx.dwFlags == 0, "dwFlags=%d\n", actctx.dwFlags);
1111  ok(actctx.lpSource == path, "lpSource=%p\n", actctx.lpSource);
1112  ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
1113  ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId);
1114  ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
1115  ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName);
1116  ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName);
1117  ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule);
1118 
1119  return handle;
1120 }
1121 static void test_comctl32_class( const char *name )
1122 {
1123  WNDCLASSA wcA;
1124  WNDCLASSW wcW;
1125  BOOL ret;
1126  HMODULE module;
1127  WCHAR nameW[20];
1128  HWND hwnd;
1129 
1130  if (name[0] == '!')
1131  {
1132  char path[MAX_PATH];
1133  ULONG_PTR cookie;
1134  HANDLE context;
1135 
1136  name++;
1137 
1138  GetTempPathA(sizeof(path)/sizeof(path[0]), path);
1139  strcat(path, "comctl32_class.manifest");
1140 
1143  ret = DeleteFileA(path);
1144  ok(ret, "Failed to delete manifest file, error %d.\n", GetLastError());
1145 
1146  module = GetModuleHandleA( "comctl32" );
1147  ok( !module, "comctl32 already loaded\n" );
1148 
1149  ret = ActivateActCtx(context, &cookie);
1150  ok(ret, "Failed to activate context.\n");
1151 
1152  /* Some systems load modules during context activation. In this case skip the rest of the test. */
1153  module = GetModuleHandleA( "comctl32" );
1154  ok( !module || broken(module != NULL) /* Vista/Win7 */, "comctl32 already loaded\n" );
1155  if (module)
1156  {
1157  win_skip("Module loaded during context activation. Skipping tests.\n");
1158  goto skiptest;
1159  }
1160 
1161  ret = GetClassInfoA( 0, name, &wcA );
1162  ok( ret || broken(!ret) /* WinXP */, "GetClassInfoA failed for %s\n", name );
1163  if (!ret)
1164  goto skiptest;
1165 
1166  MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, sizeof(nameW)/sizeof(WCHAR) );
1167  ret = GetClassInfoW( 0, nameW, &wcW );
1168  ok( ret, "GetClassInfoW failed for %s\n", name );
1169  module = GetModuleHandleA( "comctl32" );
1170  ok( module != 0, "comctl32 not loaded\n" );
1171  FreeLibrary( module );
1172  module = GetModuleHandleA( "comctl32" );
1173  ok( !module || broken(module != NULL) /* Vista */, "comctl32 still loaded\n" );
1174  hwnd = CreateWindowA( name, "test", WS_OVERLAPPEDWINDOW, 0, 0, 10, 10, NULL, NULL, NULL, 0 );
1175  ok( hwnd != 0, "failed to create window for %s\n", name );
1176  module = GetModuleHandleA( "comctl32" );
1177  ok( module != 0, "comctl32 not loaded\n" );
1178  DestroyWindow( hwnd );
1179 
1180  skiptest:
1181  ret = DeactivateActCtx(0, cookie);
1182  ok(ret, "Failed to deactivate context.\n");
1184  }
1185  else
1186  {
1187  module = GetModuleHandleA( "comctl32" );
1188  ok( !module, "comctl32 already loaded\n" );
1189  ret = GetClassInfoA( 0, name, &wcA );
1190  ok( ret || broken(!ret) /* <= winxp */, "GetClassInfoA failed for %s\n", name );
1191  if (!ret) return;
1192  MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, sizeof(nameW)/sizeof(WCHAR) );
1193  ret = GetClassInfoW( 0, nameW, &wcW );
1194  ok( ret, "GetClassInfoW failed for %s\n", name );
1195  module = GetModuleHandleA( "comctl32" );
1196  ok( module != 0, "comctl32 not loaded\n" );
1197  FreeLibrary( module );
1198  module = GetModuleHandleA( "comctl32" );
1199  ok( !module, "comctl32 still loaded\n" );
1200  hwnd = CreateWindowA( name, "test", WS_OVERLAPPEDWINDOW, 0, 0, 10, 10, NULL, NULL, NULL, 0 );
1201  ok( hwnd != 0, "failed to create window for %s\n", name );
1202  module = GetModuleHandleA( "comctl32" );
1203  ok( module != 0, "comctl32 not loaded\n" );
1204  DestroyWindow( hwnd );
1205  }
1206 }
1207 
1208 /* verify that comctl32 classes are automatically loaded by user32 */
1209 static void test_comctl32_classes(void)
1210 {
1211  char path_name[MAX_PATH];
1214  char **argv;
1215  int i;
1216 
1217  static const char *classes[] =
1218  {
1222  WC_HEADERA,
1223  HOTKEY_CLASSA,
1224  WC_IPADDRESSA,
1225  WC_LISTVIEWA,
1232  "SysLink",
1237  WC_TREEVIEWA,
1238  UPDOWN_CLASSA,
1239  "!Button",
1240  "!Edit",
1241  "!Static",
1242  "!Listbox",
1243  "!ComboBox",
1244  "!ComboLBox",
1245  };
1246 
1248  for (i = 0; i < sizeof(classes) / sizeof(classes[0]); i++)
1249  {
1250  memset( &startup, 0, sizeof(startup) );
1251  startup.cb = sizeof( startup );
1252  sprintf( path_name, "%s class %s", argv[0], classes[i] );
1254  "CreateProcess failed.\n" );
1255  winetest_wait_child_process( info.hProcess );
1256  CloseHandle( info.hProcess );
1257  CloseHandle( info.hThread );
1258  }
1259 }
1260 
1261 static void test_IME(void)
1262 {
1263  static const WCHAR ime_classW[] = {'I','M','E',0};
1264 
1265  char module_name[MAX_PATH], *ptr;
1267  WNDCLASSW wnd_classw;
1269  SIZE_T size;
1270  BOOL ret;
1271 
1272  if (!GetProcAddress(GetModuleHandleA("user32.dll"), "BroadcastSystemMessageExA"))
1273  {
1274  win_skip("BroadcastSystemMessageExA not available, skipping IME class test\n");
1275  return;
1276  }
1277 
1278  ok(GetModuleHandleA("imm32") != 0, "imm32.dll is not loaded\n");
1279 
1280  ret = GetClassInfoA(NULL, "IME", &wnd_class);
1281  ok(ret, "GetClassInfo failed: %d\n", GetLastError());
1282 
1283  size = VirtualQuery(wnd_class.lpfnWndProc, &mbi, sizeof(mbi));
1284  ok(size == sizeof(mbi), "VirtualQuery returned %ld\n", size);
1285  if (size == sizeof(mbi)) {
1287  ok(size, "GetModuleFileName failed\n");
1288  for (ptr = module_name+size-1; ptr > module_name; ptr--)
1289  if (*ptr == '\\' || *ptr == '/') break;
1290  if (*ptr == '\\' || *ptr=='/') ptr++;
1291  ok(!lstrcmpiA(ptr, "user32.dll") || !lstrcmpiA(ptr, "ntdll.dll"), "IME window proc implemented in %s\n", ptr);
1292  }
1293 
1294  ret = GetClassInfoW(NULL, ime_classW, &wnd_classw);
1295  ok(ret, "GetClassInfo failed: %d\n", GetLastError());
1296 
1297  size = VirtualQuery(wnd_classw.lpfnWndProc, &mbi, sizeof(mbi));
1298  ok(size == sizeof(mbi), "VirtualQuery returned %ld\n", size);
1300  ok(size, "GetModuleFileName failed\n");
1301  for (ptr = module_name+size-1; ptr > module_name; ptr--)
1302  if (*ptr == '\\' || *ptr == '/') break;
1303  if (*ptr == '\\' || *ptr=='/') ptr++;
1304  ok(!lstrcmpiA(ptr, "user32.dll") || !lstrcmpiA(ptr, "ntdll.dll"), "IME window proc implemented in %s\n", ptr);
1305 }
1306 
1307 static void test_actctx_classes(void)
1308 {
1309  static const char main_manifest[] =
1310  "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1311  "<assemblyIdentity version=\"4.3.2.1\" name=\"Wine.WndClass.Test\" type=\"win32\" />"
1312  "<file name=\"file.exe\">"
1313  "<windowClass>MyTestClass</windowClass>"
1314  "</file>"
1315  "</assembly>";
1316  static const char *testclass = "MyTestClass";
1317  WNDCLASSA wc;
1318  ULONG_PTR cookie;
1319  HANDLE context;
1320  BOOL ret;
1321  ATOM class;
1322  HINSTANCE hinst;
1323  char buff[64];
1324  HWND hwnd;
1325  char path[MAX_PATH];
1326 
1327  GetTempPathA(sizeof(path)/sizeof(path[0]), path);
1328  strcat(path, "actctx_classes.manifest");
1329 
1330  create_manifest_file(path, main_manifest);
1332  ret = DeleteFileA(path);
1333  ok(ret, "Failed to delete manifest file, error %d.\n", GetLastError());
1334 
1335  ret = ActivateActCtx(context, &cookie);
1336  ok(ret, "Failed to activate context.\n");
1337 
1338  memset(&wc, 0, sizeof(wc));
1341  wc.lpszClassName = testclass;
1342 
1343  hinst = GetModuleHandleW(0);
1344 
1345  ret = GetClassInfoA(hinst, testclass, &wc);
1346  ok(!ret, "Expected failure.\n");
1347 
1348  class = RegisterClassA(&wc);
1349  ok(class != 0, "Failed to register class.\n");
1350 
1351  /* Class info is available by versioned and regular names. */
1352  ret = GetClassInfoA(hinst, testclass, &wc);
1353  ok(ret, "Failed to get class info.\n");
1354 
1355  hwnd = CreateWindowExA(0, testclass, "test", 0, 0, 0, 0, 0, 0, 0, hinst, 0);
1356  ok(hwnd != NULL, "Failed to create a window.\n");
1357 
1358  ret = GetClassNameA(hwnd, buff, sizeof(buff));
1359  ok(ret, "Failed to get class name.\n");
1360  ok(!strcmp(buff, testclass), "Unexpected class name.\n");
1361 
1362  ret = GetClassInfoA(hinst, "4.3.2.1!MyTestClass", &wc);
1363  ok(ret, "Failed to get class info.\n");
1364 
1365  ret = UnregisterClassA(testclass, hinst);
1366  ok(!ret, "Failed to unregister class.\n");
1367 
1368  ret = DeactivateActCtx(0, cookie);
1369  ok(ret, "Failed to deactivate context.\n");
1370 
1371  ret = GetClassInfoA(hinst, testclass, &wc);
1372  ok(!ret, "Unexpected ret val %d.\n", ret);
1373 
1374  ret = GetClassInfoA(hinst, "4.3.2.1!MyTestClass", &wc);
1375  ok(ret, "Failed to get class info.\n");
1376 
1377  ret = GetClassNameA(hwnd, buff, sizeof(buff));
1378  ok(ret, "Failed to get class name.\n");
1379  ok(!strcmp(buff, testclass), "Unexpected class name.\n");
1380 
1382 
1383  ret = UnregisterClassA("MyTestClass", hinst);
1384  ok(!ret, "Unexpected ret value %d.\n", ret);
1385 
1386  ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst);
1387  ok(ret, "Failed to unregister class.\n");
1388 
1389  /* Register versioned class without active context. */
1390  wc.lpszClassName = "4.3.2.1!MyTestClass";
1391  class = RegisterClassA(&wc);
1392  ok(class != 0, "Failed to register class.\n");
1393 
1394  ret = ActivateActCtx(context, &cookie);
1395  ok(ret, "Failed to activate context.\n");
1396 
1397  wc.lpszClassName = "MyTestClass";
1398  class = RegisterClassA(&wc);
1399  ok(class == 0, "Expected failure.\n");
1400 
1401  ret = DeactivateActCtx(0, cookie);
1402  ok(ret, "Failed to deactivate context.\n");
1403 
1404  ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst);
1405  ok(ret, "Failed to unregister class.\n");
1406 
1407  /* Only versioned name is registered. */
1408  ret = ActivateActCtx(context, &cookie);
1409  ok(ret, "Failed to activate context.\n");
1410 
1411  wc.lpszClassName = "MyTestClass";
1412  class = RegisterClassA(&wc);
1413  ok(class != 0, "Failed to register class\n");
1414 
1415  ret = DeactivateActCtx(0, cookie);
1416  ok(ret, "Failed to deactivate context.\n");
1417 
1418  ret = GetClassInfoA(hinst, "MyTestClass", &wc);
1419  ok(!ret, "Expected failure.\n");
1420 
1421  ret = GetClassInfoA(hinst, "4.3.2.1!MyTestClass", &wc);
1422  ok(ret, "Failed to get class info.\n");
1423 
1424  ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst);
1425  ok(ret, "Failed to unregister class.\n");
1426 
1427  /* Register regular name first, it's not considered when versioned name is registered. */
1428  wc.lpszClassName = "MyTestClass";
1429  class = RegisterClassA(&wc);
1430  ok(class != 0, "Failed to register class.\n");
1431 
1432  ret = ActivateActCtx(context, &cookie);
1433  ok(ret, "Failed to activate context.\n");
1434 
1435  wc.lpszClassName = "MyTestClass";
1436  class = RegisterClassA(&wc);
1437  ok(class != 0, "Failed to register class.\n");
1438 
1439  ret = DeactivateActCtx(0, cookie);
1440  ok(ret, "Failed to deactivate context.\n");
1441 
1442  ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst);
1443  ok(ret, "Failed to unregister class.\n");
1444 
1445  ret = UnregisterClassA("MyTestClass", hinst);
1446  ok(ret, "Failed to unregister class.\n");
1447 
1449 }
1450 
1452 {
1453  char **argv;
1455  int argc = winetest_get_mainargs( &argv );
1456 
1457  if (argc >= 3)
1458  {
1459  test_comctl32_class( argv[2] );
1460  return;
1461  }
1462 
1463  test_IME();
1466 
1467  if (!GetModuleHandleW(0))
1468  {
1469  trace("Class test is incompatible with Win9x implementation, skipping\n");
1470  return;
1471  }
1472 
1476  test_styles();
1477  test_builtinproc();
1478  test_icons();
1481 
1482  /* this test unregisters the Button class so it should be executed at the end */
1483  test_instances();
1484 }
HGDIOBJ WINAPI GetStockObject(_In_ int)
BOOL WINAPI ActivateActCtx(IN HANDLE hActCtx, OUT PULONG_PTR ulCookie)
Definition: actctx.c:237
static void test_actctx_classes(void)
Definition: class.c:1307
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
static const WCHAR classW[]
Definition: lex.c:38
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
static int argc
Definition: ServiceArgs.c:12
#define MAKEINTRESOURCE
Definition: winuser.h:591
#define WC_PAGESCROLLERA
Definition: commctrl.h:4470
static HICON
Definition: imagelist.c:84
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
LPCSTR lpszMenuName
Definition: winuser.h:3184
#define TRUE
Definition: types.h:120
ATOM WINAPI RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
Definition: class.c:1528
#define WC_EDITW
Definition: commctrl.h:4658
#define CloseHandle
Definition: compat.h:398
HMODULE module
Definition: main.cpp:47
#define IMAGE_ICON
Definition: winuser.h:212
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
UINT style
Definition: winuser.h:3150
#define REBARCLASSNAMEA
Definition: commctrl.h:1436
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
HCURSOR hCursor
Definition: winuser.h:3182
WNDPROC lpfnWndProc
Definition: winuser.h:3177
BOOL WINAPI GetClassInfoExA(HINSTANCE hInstance, LPCSTR lpszClass, LPWNDCLASSEXA lpwcx)
Definition: class.c:264
LPCWSTR lpszMenuName
Definition: winuser.h:3158
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static LPCWSTR LPCWSTR module_name
Definition: db.cpp:168
#define CS_DROPSHADOW
Definition: winuser.h:655
Definition: http.c:6587
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
LPCSTR lpszClassName
Definition: winuser.h:3185
WORD ATOM
Definition: dimm.idl:113
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2022
GLsizei const GLchar ** path
Definition: glext.h:7234
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define check_class(inst, name, menu)
Definition: class.c:290
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
static void check_class_(int line, HINSTANCE inst, const char *name, const char *menu_name)
Definition: class.c:274
#define CP_ACP
Definition: compat.h:99
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
int ignore(int trapCode, ppc_trap_frame_t *trap)
Definition: mmuobject.c:296
char CHAR
Definition: xmlstorage.h:175
int WINAPI GetClassNameW(HWND hWnd, LPWSTR lpClassName, int nMaxCount)
Definition: class.c:1025
#define WM_GETTEXT
Definition: winuser.h:1600
BOOL WINAPI UnregisterClassW(LPCWSTR lpClassName, HINSTANCE hInstance)
Definition: class.c:1938
static void ClassTest(HINSTANCE hInstance, BOOL global)
Definition: class.c:93
HWND hWnd
Definition: settings.c:17
BOOL WINAPI GetClassInfoA(HINSTANCE hInstance, LPCSTR lpClassName, LPWNDCLASSA lpWndClass)
Definition: class.c:476
int cbClsExtra
Definition: winuser.h:3139
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
static void test_instances(void)
Definition: class.c:350
#define ARCH
Definition: class.c:52
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1635
#define CS_HREDRAW
Definition: winuser.h:648
LPCSTR lpszMenuName
Definition: winuser.h:3145
static void test_GetClassInfo(void)
Definition: class.c:957
GLuint buffer
Definition: glext.h:5915
#define SM_CYSMICON
Definition: winuser.h:1003
HICON hIcon
Definition: winuser.h:3196
int startup(int argc, const char *argv[])
Definition: startup.c:430
int cbClsExtra
Definition: winuser.h:3152
#define WHITE_BRUSH
Definition: wingdi.h:901
BOOL WINAPI GetClassInfoW(HINSTANCE hInstance, LPCWSTR lpClassName, LPWNDCLASSW lpWndClass)
Definition: class.c:507
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
#define IDI_APPLICATION
Definition: winuser.h:699
UINT_PTR WPARAM
Definition: windef.h:207
#define GetWindowLongPtrW
Definition: winuser.h:4730
HICON hIconSm
Definition: winuser.h:3186
static void test_extra_values(void)
Definition: class.c:942
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
DWORD WINAPI GetClassLongW(HWND hWnd, int nIndex)
Definition: class.c:861
#define GCLP_WNDPROC
Definition: winuser.h:673
#define WC_LISTVIEWA
Definition: commctrl.h:2228
static void create_manifest_file(const char *filename, const char *manifest)
Definition: class.c:1082
#define argv
Definition: mplay32.c:18
char * LPSTR
Definition: xmlstorage.h:182
const char * filename
Definition: ioapi.h:135
#define lstrlenW
Definition: compat.h:407
#define MONTHCAL_CLASSA
Definition: commctrl.h:4148
#define WM_NCCREATE
Definition: winuser.h:1665
BOOL WINAPI DestroyWindow(_In_ HWND)
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4217
#define DWORD
Definition: nt_native.h:44
BOOL WINAPI GetIconInfo(_In_ HICON, _Out_ PICONINFO)
Definition: cursoricon.c:2014
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:548
WPARAM wParam
Definition: combotst.c:138
static void check_thread_instance(const char *name, HINSTANCE inst, HINSTANCE info_inst, HINSTANCE gcl_inst)
Definition: class.c:332
static void check_instance_(int line, const char *name, HINSTANCE inst, HINSTANCE info_inst, HINSTANCE gcl_inst)
Definition: class.c:292
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2029
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
static LRESULT WINAPI TestDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: class.c:881
LRESULT WINAPI CallWindowProcA(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define ICON_SMALL
Definition: tnclass.cpp:48
struct _test_info info[]
Definition: SetCursorPos.c:19
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define GCLP_HMODULE
Definition: winuser.h:671
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define GCL_STYLE
Definition: winuser.h:665
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
int cbWndExtra
Definition: winuser.h:3140
BOOL WINAPI DeactivateActCtx(IN DWORD dwFlags, IN ULONG_PTR ulCookie)
Definition: actctx.c:268
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HINSTANCE hInstance
Definition: charmap.c:20
#define ERROR_NOACCESS
Definition: winerror.h:578
#define WC_EDITA
Definition: commctrl.h:4657
ATOM WINAPI RegisterClassA(CONST WNDCLASSA *lpWndClass)
Definition: class.c:1591
HINSTANCE hInstance
Definition: winuser.h:3180
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define ERROR_CLASS_HAS_WINDOWS
Definition: winerror.h:893
#define WC_IPADDRESSA
Definition: commctrl.h:4445
#define IS_WNDPROC_HANDLE(x)
Definition: class.c:41
static HANDLE create_test_actctx(const char *file)
Definition: class.c:1095
#define GENERIC_WRITE
Definition: nt_native.h:90
WNDPROC lpfnWndProc
Definition: winuser.h:3151
HANDLE WINAPI CopyImage(_In_ HANDLE, _In_ UINT, _In_ int, _In_ int, _In_ UINT)
Definition: cursoricon.c:1956
static PVOID ptr
Definition: dispmode.c:27
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4216
#define CW_USEDEFAULT
Definition: winuser.h:225
#define WC_TREEVIEWA
Definition: commctrl.h:3214
const WCHAR * str
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
static LRESULT WINAPI ClassTest_WndProc2(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: class.c:85
smooth NULL
Definition: ftsmooth.c:416
#define DATETIMEPICK_CLASSA
Definition: commctrl.h:4295
#define ERROR_CLASS_ALREADY_EXISTS
Definition: winerror.h:891
LPCWSTR lpszClassName
Definition: winuser.h:3159
LONG_PTR LPARAM
Definition: windef.h:208
UINT cbSize
Definition: winuser.h:3175
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
Definition: parser.c:48
#define actctx
Definition: kernel32.h:8
#define SetClassLongPtrW
Definition: winuser.h:5166
const char * LPCSTR
Definition: xmlstorage.h:183
#define SW_SHOW
Definition: winuser.h:769
BOOL WINAPI IsWindowUnicode(_In_ HWND)
HBRUSH hbrBackground
Definition: winuser.h:3183
LPCWSTR lpszClassName
Definition: winuser.h:3200
static const WCHAR nameW[]
Definition: main.c:46
#define GetWindowLongPtrA
Definition: winuser.h:4729
#define CS_VREDRAW
Definition: winuser.h:653
static void test_builtinproc(void)
Definition: class.c:638
const char name[9]
Definition: class.c:929
#define GCLP_HICONSM
Definition: winuser.h:670
static void test_comctl32_classes(void)
Definition: class.c:1209
#define FreeLibrary(x)
Definition: compat.h:405
#define HOTKEY_CLASSA
Definition: commctrl.h:2207
#define WAIT_OBJECT_0
Definition: winbase.h:387
GLsizeiptr size
Definition: glext.h:5919
#define trace
Definition: atltest.h:70
int WINAPI GetClassNameA(HWND hWnd, LPSTR lpClassName, int nMaxCount)
Definition: class.c:998
int cbWndExtra
Definition: winuser.h:3153
__wchar_t WCHAR
Definition: xmlstorage.h:180
UINT cbSize
Definition: winuser.h:3190
BOOL WINAPI SetWindowTextA(_In_ HWND, _In_opt_ LPCSTR)
int badvalue
Definition: class.c:931
static char * path_name(DOS_FILE *file)
Definition: check.c:208
VOID WINAPI ReleaseActCtx(IN HANDLE hActCtx)
Definition: actctx.c:208
static const struct @1655 extra_values[]
HINSTANCE gcl_inst
Definition: class.c:320
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4742
#define CS_GLOBALCLASS
Definition: winuser.h:647
GLfloat param
Definition: glext.h:5796
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
const char file[]
Definition: icontest.c:11
int WINAPI GetSystemMetrics(_In_ int)
unsigned long DWORD
Definition: ntddk_ex.h:95
HICON hIcon
Definition: winuser.h:3155
SIZE_T NTAPI VirtualQuery(IN LPCVOID lpAddress, OUT PMEMORY_BASIC_INFORMATION lpBuffer, IN SIZE_T dwLength)
Definition: virtmem.c:220
int cbWndExtra
Definition: winuser.h:3179
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2074
#define SetLastError(x)
Definition: compat.h:409
static LRESULT WINAPI ClassTest_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: class.c:79
int winetest_get_mainargs(char ***pargv)
#define WS_HSCROLL
Definition: pedump.c:628
HINSTANCE hInstance
Definition: winuser.h:3195
#define CS_SAVEBITS
Definition: winuser.h:652
#define SM_CXSMICON
Definition: winuser.h:1002
HANDLE HINSTANCE
Definition: typedefs.h:75
int ret
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
HWND WINAPI CreateDialogParamA(_In_opt_ HINSTANCE, _In_ LPCSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
HICON hIcon
Definition: winuser.h:3181
#define todo_wine
Definition: test.h:154
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define DLGWINDOWEXTRA
Definition: winuser.h:2540
#define GCLP_HICON
Definition: winuser.h:669
HWND hWndMain
Definition: welcome.c:60
#define SetWindowLongPtrA
Definition: winuser.h:5246
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
#define CS_DBLCLKS
Definition: winuser.h:646
#define UPDOWN_CLASSA
Definition: commctrl.h:2090
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LPCSTR lpszClassName
Definition: winuser.h:3146
uint32_t DWORD_PTR
Definition: typedefs.h:63
#define ANIMATE_CLASSA
Definition: commctrl.h:4114
#define SetClassLongPtrA
Definition: winuser.h:5165
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2059
static void test_IME(void)
Definition: class.c:1261
WNDPROC lpfnWndProc
Definition: winuser.h:3192
#define GWLP_WNDPROC
Definition: treelist.c:66
#define broken(x)
Definition: _sntprintf.h:21
DWORD WINAPI SetClassLongW(HWND hWnd, int nIndex, LONG dwNewLong)
Definition: class.c:1719
void winetest_wait_child_process(HANDLE process)
static void test_styles(void)
Definition: class.c:254
ATOM WINAPI RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
Definition: class.c:1574
UINT style
Definition: winuser.h:3137
#define TOOLBARCLASSNAMEA
Definition: commctrl.h:916
#define WC_NATIVEFONTCTLA
Definition: commctrl.h:4579
HCURSOR hCursor
Definition: winuser.h:3156
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2880
static void check_style(const char *name, int must_exist, UINT style, UINT ignore)
Definition: class.c:238
HINSTANCE info_inst
Definition: class.c:320
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define WC_COMBOBOXEXA
Definition: commctrl.h:3754
static const WCHAR staticW[]
Definition: actctx.c:656
#define CREATE_ALWAYS
Definition: disk.h:72
int cbClsExtra
Definition: winuser.h:3178
#define IDI_QUESTION
Definition: winuser.h:701
HANDLE WINAPI LoadImageA(_In_opt_ HINSTANCE, _In_ LPCSTR, _In_ UINT, _In_ int, _In_ int, _In_ UINT)
Definition: cursoricon.c:2147
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2053
HINSTANCE hInstance
Definition: winuser.h:3141
int value
Definition: class.c:930
static const char comctl32_manifest[]
Definition: class.c:55
HINSTANCE inst
Definition: class.c:320
static void test_icons(void)
Definition: class.c:1023
HBRUSH hbrBackground
Definition: winuser.h:3157
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define ok(value,...)
Definition: atltest.h:57
#define TRACKBAR_CLASSA
Definition: commctrl.h:1982
#define TOOLTIPS_CLASSA
Definition: commctrl.h:1680
Definition: services.c:325
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
ATOM WINAPI RegisterClassW(CONST WNDCLASSW *lpWndClass)
Definition: class.c:1621
unsigned int UINT
Definition: ndis.h:50
#define WS_VSCROLL
Definition: pedump.c:627
HANDLE hThread
Definition: wizard.c:27
DWORD WINAPI SetClassLongA(HWND hWnd, int nIndex, LONG dwNewLong)
Definition: class.c:1652
#define MultiByteToWideChar
Definition: compat.h:100
WNDPROC lpfnWndProc
Definition: winuser.h:3138
#define CreateFileW
Definition: compat.h:400
HICON hIconSm
Definition: winuser.h:3201
HINSTANCE hInstance
Definition: winuser.h:3154
#define skip(...)
Definition: atltest.h:64
#define msg(x)
Definition: auth_time.c:54
#define IDC_ARROW
Definition: winuser.h:682
#define GWLP_HINSTANCE
Definition: winuser.h:850
Definition: name.c:36
#define GetClassLongPtrA
Definition: winuser.h:4464
LRESULT WINAPI CallWindowProcW(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx)
Definition: actctx.c:104
START_TEST(class)
Definition: class.c:1451
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:847
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static HINSTANCE hinst
Definition: edit.c:551
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2044
#define GetProcAddress(x, y)
Definition: compat.h:410
static const char cls_name[]
Definition: compobj.c:2470
#define SetWindowLongPtrW
Definition: winuser.h:5247
static const CHAR manifest[]
Definition: v6util.h:39
static void test_comctl32_class(const char *name)
Definition: class.c:1121
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define STATUSCLASSNAMEA
Definition: commctrl.h:1909
LONG_PTR LRESULT
Definition: windef.h:209
static DWORD WINAPI thread_proc(void *param)
Definition: class.c:323
BOOL WINAPI UnregisterClassA(LPCSTR lpClassName, HINSTANCE hInstance)
Definition: class.c:1891
#define INFINITE
Definition: serial.h:102
#define LR_DEFAULTCOLOR
Definition: winuser.h:1077
Arabic default style
Definition: afstyles.h:93
#define memset(x, y, z)
Definition: compat.h:39
BOOL WINAPI GetClassInfoExW(HINSTANCE hInstance, LPCWSTR lpszClass, LPWNDCLASSEXW lpwcx)
Definition: class.c:374
#define win_skip
Definition: test.h:141
static TfClientId tid
LPARAM lParam
Definition: combotst.c:139
#define ERROR_CLASS_DOES_NOT_EXIST
Definition: winerror.h:892
static unsigned char buff[32768]
Definition: fatten.c:17
static BOOL RegisterTestDialog(HINSTANCE hInstance)
Definition: class.c:886
#define GetClassLongPtrW
Definition: winuser.h:4465
#define CS_PARENTDC
Definition: winuser.h:651
static void CreateDialogParamTest(HINSTANCE hInstance)
Definition: class.c:914
WNDCLASSW wnd_class
Definition: startup.c:16
#define PROGRESS_CLASSA
Definition: commctrl.h:2147
#define ICON_BIG
Definition: tnclass.cpp:51
#define NUMCLASSWORDS
Definition: class.c:39
#define WC_TABCONTROLA
Definition: commctrl.h:3906
#define WC_HEADERA
Definition: commctrl.h:608
#define check_instance(name, inst, info_inst, gcl_inst)
Definition: class.c:315
#define ok_(x1, x2)
Definition: atltest.h:61
HICON hIcon
Definition: winuser.h:3142
const char * name
Definition: class.c:319
Definition: fci.c:126