ReactOS  0.4.15-dev-976-g0f66c66
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 #include <stdlib.h>
22 #include <stdarg.h>
23 #include <stdio.h>
24 
25 #include "wine/test.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winnls.h"
29 #include "winreg.h"
30 #include "wingdi.h"
31 #include "winuser.h"
32 #include "commctrl.h"
33 
34 #define NUMCLASSWORDS 4
35 
36 #define IS_WNDPROC_HANDLE(x) (((ULONG_PTR)(x) >> 16) == (~0u >> 16))
37 
38 #ifdef __i386__
39 #define ARCH "x86"
40 #elif defined __x86_64__
41 #define ARCH "amd64"
42 #elif defined __arm__
43 #define ARCH "arm"
44 #elif defined __aarch64__
45 #define ARCH "arm64"
46 #else
47 #define ARCH "none"
48 #endif
49 
50 static const char comctl32_manifest[] =
51 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
52 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n"
53 " <assemblyIdentity\n"
54 " type=\"win32\"\n"
55 " name=\"Wine.User32.Tests\"\n"
56 " version=\"1.0.0.0\"\n"
57 " processorArchitecture=\"" ARCH "\"\n"
58 " />\n"
59 "<description>Wine comctl32 test suite</description>\n"
60 "<dependency>\n"
61 " <dependentAssembly>\n"
62 " <assemblyIdentity\n"
63 " type=\"win32\"\n"
64 " name=\"microsoft.windows.common-controls\"\n"
65 " version=\"6.0.0.0\"\n"
66 " processorArchitecture=\"" ARCH "\"\n"
67 " publicKeyToken=\"6595b64144ccf1df\"\n"
68 " language=\"*\"\n"
69 " />\n"
70 "</dependentAssembly>\n"
71 "</dependency>\n"
72 "</assembly>\n";
73 
75 {
76  if (msg == WM_NCCREATE) return 1;
77  return DefWindowProcW (hWnd, msg, wParam, lParam);
78 }
79 
81 {
82  if (msg == WM_NCCREATE) return 1;
83  return DefWindowProcA (hWnd, msg, wParam, lParam);
84 }
85 
86 /***********************************************************************
87  */
88 static void ClassTest(HINSTANCE hInstance, BOOL global)
89 {
90  WNDCLASSW cls, wc;
91  static const WCHAR className[] = {'T','e','s','t','C','l','a','s','s',0};
92  static const WCHAR winName[] = {'W','i','n','C','l','a','s','s','T','e','s','t',0};
93  ATOM test_atom;
94  HWND hTestWnd;
95  LONG i;
96  WCHAR str[20];
97  ATOM classatom;
98 
99  cls.style = CS_HREDRAW | CS_VREDRAW | (global?CS_GLOBALCLASS:0);
101  cls.cbClsExtra = NUMCLASSWORDS*sizeof(DWORD);
102  cls.cbWndExtra = 12;
103  cls.hInstance = hInstance;
105  cls.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW);
107  cls.lpszMenuName = 0;
108  cls.lpszClassName = className;
109 
110  classatom=RegisterClassW(&cls);
111  if (!classatom && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
112  return;
113  ok(classatom, "failed to register class\n");
114 
115  ok(GetClipboardFormatNameW(classatom, str, ARRAY_SIZE(str)) != 0, "atom not found\n");
116 
117  ok(!RegisterClassW (&cls),
118  "RegisterClass of the same class should fail for the second time\n");
119 
120  /* Setup windows */
121  hTestWnd = CreateWindowW (className, winName,
123  CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0,
124  0, hInstance, 0);
125 
126  ok(hTestWnd!=0, "Failed to create window\n");
127 
128  /* test initial values of valid classwords */
129  for(i=0; i<NUMCLASSWORDS; i++)
130  {
131  SetLastError(0);
132  ok(!GetClassLongW(hTestWnd,i*sizeof (DWORD)),
133  "GetClassLongW initial value nonzero!\n");
134  ok(!GetLastError(),
135  "GetClassLongW failed!\n");
136  }
137 
138  if (0)
139  {
140  /*
141  * GetClassLongW(hTestWnd, NUMCLASSWORDS*sizeof(DWORD))
142  * does not fail on Win 98, though MSDN says it should
143  */
144  SetLastError(0);
145  GetClassLongW(hTestWnd, NUMCLASSWORDS*sizeof(DWORD));
146  ok(GetLastError(),
147  "GetClassLongW() with invalid offset did not fail\n");
148  }
149 
150  /* set values of valid class words */
151  for(i=0; i<NUMCLASSWORDS; i++)
152  {
153  SetLastError(0);
154  ok(!SetClassLongW(hTestWnd,i*sizeof(DWORD),i+1),
155  "GetClassLongW(%d) initial value nonzero!\n",i);
156  ok(!GetLastError(),
157  "SetClassLongW(%d) failed!\n",i);
158  }
159 
160  /* test values of valid classwords that we set */
161  for(i=0; i<NUMCLASSWORDS; i++)
162  {
163  SetLastError(0);
164  ok( (i+1) == GetClassLongW(hTestWnd,i*sizeof (DWORD)),
165  "GetClassLongW value doesn't match what was set!\n");
166  ok(!GetLastError(),
167  "GetClassLongW failed!\n");
168  }
169 
170  /* check GetClassName */
171  i = GetClassNameW(hTestWnd, str, ARRAY_SIZE(str));
172  ok(i == lstrlenW(className),
173  "GetClassName returned incorrect length\n");
174  ok(!lstrcmpW(className,str),
175  "GetClassName returned incorrect name for this window's class\n");
176 
177  /* check GetClassInfo with our hInstance */
178  if((test_atom = GetClassInfoW(hInstance, str, &wc)))
179  {
180  ok(test_atom == classatom,
181  "class atom did not match\n");
182  ok(wc.cbClsExtra == cls.cbClsExtra,
183  "cbClsExtra did not match\n");
184  ok(wc.cbWndExtra == cls.cbWndExtra,
185  "cbWndExtra did not match\n");
186  ok(wc.hbrBackground == cls.hbrBackground,
187  "hbrBackground did not match\n");
188  ok(wc.hCursor== cls.hCursor,
189  "hCursor did not match\n");
190  ok(wc.hInstance== cls.hInstance,
191  "hInstance did not match\n");
192  }
193  else
194  ok(FALSE,"GetClassInfo (hinstance) failed!\n");
195 
196  /* check GetClassInfo with zero hInstance */
197  if(global)
198  {
199  if((test_atom = GetClassInfoW(0, str, &wc)))
200  {
201  ok(test_atom == classatom,
202  "class atom did not match %x != %x\n", test_atom, classatom);
203  ok(wc.cbClsExtra == cls.cbClsExtra,
204  "cbClsExtra did not match %x!=%x\n",wc.cbClsExtra,cls.cbClsExtra);
205  ok(wc.cbWndExtra == cls.cbWndExtra,
206  "cbWndExtra did not match %x!=%x\n",wc.cbWndExtra,cls.cbWndExtra);
207  ok(wc.hbrBackground == cls.hbrBackground,
208  "hbrBackground did not match %p!=%p\n",wc.hbrBackground,cls.hbrBackground);
209  ok(wc.hCursor== cls.hCursor,
210  "hCursor did not match %p!=%p\n",wc.hCursor,cls.hCursor);
211  ok(!wc.hInstance,
212  "hInstance not zero for global class %p\n",wc.hInstance);
213  }
214  else
215  ok(FALSE,"GetClassInfo (0) failed for global class!\n");
216  }
217  else
218  {
219  ok(!GetClassInfoW(0, str, &wc),
220  "GetClassInfo (0) succeeded for local class!\n");
221  }
222 
223  ok(!UnregisterClassW(className, hInstance),
224  "Unregister class succeeded with window existing\n");
225 
226  ok(DestroyWindow(hTestWnd),
227  "DestroyWindow() failed!\n");
228 
229  ok(UnregisterClassW(className, hInstance),
230  "UnregisterClass() failed\n");
231 
232  ok(GetClipboardFormatNameW(classatom, str, ARRAY_SIZE(str)) == 0,
233  "atom still found\n");
234  return;
235 }
236 
237 static void check_style( const char *name, int must_exist, UINT style, UINT ignore )
238 {
239  WNDCLASSA wc;
240 
241  if (GetClassInfoA( 0, name, &wc ))
242  {
243  ok( !(~wc.style & style & ~ignore), "System class %s is missing bits %x (%08x/%08x)\n",
244  name, ~wc.style & style, wc.style, style );
245  ok( !(wc.style & ~style), "System class %s has extra bits %x (%08x/%08x)\n",
246  name, wc.style & ~style, wc.style, style );
247  }
248  else
249  ok( !must_exist, "System class %s does not exist\n", name );
250 }
251 
252 /* test styles of system classes */
253 static void test_styles(void)
254 {
255  /* check style bits */
256  check_style( "Button", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, 0 );
257  check_style( "ComboBox", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, 0 );
258  check_style( "Edit", 1, CS_PARENTDC | CS_DBLCLKS, 0 );
259  check_style( "ListBox", 1, CS_PARENTDC | CS_DBLCLKS, CS_PARENTDC /*FIXME*/ );
260  check_style( "MDIClient", 1, 0, 0 );
261  check_style( "ScrollBar", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, 0 );
262  check_style( "Static", 1, CS_PARENTDC | CS_DBLCLKS, 0 );
263  check_style( "ComboLBox", 1, CS_SAVEBITS | CS_DBLCLKS, 0 );
264  check_style( "DDEMLEvent", 0, 0, 0 );
265  check_style( "Message", 0, 0, 0 );
266  check_style( "#32768", 1, CS_DROPSHADOW | CS_SAVEBITS | CS_DBLCLKS, CS_DROPSHADOW ); /* menu */
267  check_style( "#32769", 1, CS_DBLCLKS, 0 ); /* desktop */
268  check_style( "#32770", 1, CS_SAVEBITS | CS_DBLCLKS, 0 ); /* dialog */
269  todo_wine { check_style( "#32771", 1, CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW, 0 ); } /* task switch */
270  check_style( "#32772", 1, 0, 0 ); /* icon title */
271 }
272 
273 static void check_class_(int line, HINSTANCE inst, const char *name, const char *menu_name)
274 {
275  WNDCLASSA wc;
276  UINT atom = GetClassInfoA(inst,name,&wc);
277  ok_(__FILE__,line)( atom, "Class %s %p not found\n", name, inst );
278  if (atom)
279  {
280  if (wc.lpszMenuName && menu_name)
281  ok_(__FILE__,line)( !strcmp( menu_name, wc.lpszMenuName ),
282  "Wrong name %s/%s for class %s %p\n",
283  wc.lpszMenuName, menu_name, name, inst );
284  else
285  ok_(__FILE__,line)( !menu_name == !wc.lpszMenuName, "Wrong name %p/%p for class %s %p\n",
286  wc.lpszMenuName, menu_name, name, inst );
287  }
288 }
289 #define check_class(inst,name,menu) check_class_(__LINE__,inst,name,menu)
290 
291 static void check_instance_( int line, const char *name, HINSTANCE inst,
292  HINSTANCE info_inst, HINSTANCE gcl_inst )
293 {
294  WNDCLASSA wc;
295  HWND hwnd;
296 
297  ok_(__FILE__,line)( GetClassInfoA( inst, name, &wc ), "Couldn't find class %s inst %p\n", name, inst );
298  ok_(__FILE__,line)( wc.hInstance == info_inst, "Wrong info instance %p/%p for class %s\n",
299  wc.hInstance, info_inst, name );
300  hwnd = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, inst, 0 );
301  ok_(__FILE__,line)( hwnd != NULL, "Couldn't create window for class %s inst %p\n", name, inst );
302  ok_(__FILE__,line)( (HINSTANCE)GetClassLongPtrA( hwnd, GCLP_HMODULE ) == gcl_inst,
303  "Wrong GCL instance %p/%p for class %s\n",
304  (HINSTANCE)GetClassLongPtrA( hwnd, GCLP_HMODULE ), gcl_inst, name );
305  ok_(__FILE__,line)( (HINSTANCE)GetWindowLongPtrA( hwnd, GWLP_HINSTANCE ) == inst,
306  "Wrong GWL instance %p/%p for window %s\n",
308  ok_(__FILE__,line)(!UnregisterClassA(name, inst),
309  "UnregisterClassA should fail while exists a class window\n");
311  "GetLastError() should be set to ERROR_CLASS_HAS_WINDOWS not %d\n", GetLastError());
313 }
314 #define check_instance(name,inst,info_inst,gcl_inst) check_instance_(__LINE__,name,inst,info_inst,gcl_inst)
315 
317 {
318  const char *name;
320 };
321 
323 {
324  struct class_info *class_info = param;
325 
327 
328  return 0;
329 }
330 
332 {
333  HANDLE hThread;
334  DWORD tid;
335  struct class_info class_info;
336 
337  class_info.name = name;
338  class_info.inst = inst;
341 
343  ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
344  ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
346 }
347 
348 /* test various instance parameters */
349 static void test_instances(void)
350 {
351  WNDCLASSA cls, wc;
352  WNDCLASSEXA wcexA;
353  HWND hwnd, hwnd2;
354  const char *name = "__test__";
355  HINSTANCE kernel32 = GetModuleHandleA("kernel32");
356  HINSTANCE user32 = GetModuleHandleA("user32");
357  HINSTANCE main_module = GetModuleHandleA(NULL);
358  HINSTANCE zero_instance = 0;
359  DWORD r;
360  char buffer[0x10];
361 
362  memset( &cls, 0, sizeof(cls) );
363  cls.style = CS_HREDRAW | CS_VREDRAW;
365  cls.cbClsExtra = 0;
366  cls.cbWndExtra = 0;
367  cls.lpszClassName = name;
368 
369  cls.lpszMenuName = "main_module";
370  cls.hInstance = main_module;
371 
372  ok( RegisterClassA( &cls ), "Failed to register local class for main module\n" );
373  check_class( main_module, name, "main_module" );
374  check_instance( name, main_module, main_module, main_module );
375  check_thread_instance( name, main_module, main_module, main_module );
376 
377  cls.lpszMenuName = "kernel32";
378  cls.hInstance = kernel32;
379  ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" );
380  check_class( kernel32, name, "kernel32" );
381  check_class( main_module, name, "main_module" );
382  check_instance( name, kernel32, kernel32, kernel32 );
383  check_thread_instance( name, kernel32, kernel32, kernel32 );
384  ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
385 
386  ZeroMemory(&wcexA, sizeof(wcexA));
387  wcexA.lpfnWndProc = DefWindowProcA;
388  wcexA.lpszClassName = "__classex_test__";
389  SetLastError(0xdeadbeef);
390  wcexA.cbSize = sizeof(wcexA) - 1;
391  ok( ((RegisterClassExA( &wcexA ) == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)),
392  "Succeeded with invalid number of cbSize bytes\n");
393  SetLastError(0xdeadbeef);
394  wcexA.cbSize = sizeof(wcexA) + 1;
395  ok( ((RegisterClassExA( &wcexA ) == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)),
396  "Succeeded with invalid number of cbSize bytes\n");
397  SetLastError(0xdeadbeef);
398  wcexA.cbSize = sizeof(wcexA);
399  ok( RegisterClassExA( &wcexA ), "Failed with valid number of cbSize bytes\n");
400  wcexA.cbSize = 0xdeadbeef;
401  ok( GetClassInfoExA(main_module, wcexA.lpszClassName, &wcexA), "GetClassInfoEx failed\n");
402  ok( wcexA.cbSize == 0xdeadbeef, "GetClassInfoEx returned wrong cbSize value %d\n", wcexA.cbSize);
403  UnregisterClassA(wcexA.lpszClassName, main_module);
404 
405  /* Bug 2631 - Supplying an invalid number of bytes fails */
406  cls.cbClsExtra = 0;
407  cls.cbWndExtra = -1;
408  SetLastError(0xdeadbeef);
409  ok( ((RegisterClassA( &cls ) == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)),
410  "Failed with invalid number of WndExtra bytes\n");
411 
412  cls.cbClsExtra = -1;
413  cls.cbWndExtra = 0;
414  SetLastError(0xdeadbeef);
415  ok( ((RegisterClassA( &cls ) == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)),
416  "Failed with invalid number of ClsExtra bytes\n");
417 
418  cls.cbClsExtra = -1;
419  cls.cbWndExtra = -1;
420  SetLastError(0xdeadbeef);
421  ok( ((RegisterClassA( &cls ) == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)),
422  "Failed with invalid number of ClsExtra and cbWndExtra bytes\n");
423 
424  cls.cbClsExtra = 0;
425  cls.cbWndExtra = 0;
426  SetLastError(0xdeadbeef);
427 
428  /* setting global flag doesn't change status of class */
429  hwnd = CreateWindowExA( 0, name, "test", 0, 0, 0, 0, 0, 0, 0, main_module, 0 );
430  ok( hwnd != 0, "CreateWindow failed error %u\n", GetLastError());
432  cls.lpszMenuName = "kernel32";
433  cls.hInstance = kernel32;
434  ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" );
435  check_class( kernel32, name, "kernel32" );
436  check_class( main_module, name, "main_module" );
437  check_instance( name, kernel32, kernel32, kernel32 );
438  check_instance( name, main_module, main_module, main_module );
439  check_thread_instance( name, kernel32, kernel32, kernel32 );
440  check_thread_instance( name, main_module, main_module, main_module );
441  ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
442 
443  /* changing the instance doesn't make it global */
445  ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" );
446  check_class( kernel32, name, "kernel32" );
447  check_instance( name, kernel32, kernel32, kernel32 );
448  check_thread_instance( name, kernel32, kernel32, kernel32 );
449  ok( !GetClassInfoA( 0, name, &wc ), "Class found with null instance\n" );
450  ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
451 
452  /* GetClassInfo with instance 0 finds user32 instance */
454  ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" );
455  if (!GetClassInfoA( 0, name, &wc )) zero_instance = user32; /* instance 0 not supported on wow64 */
456  else
457  {
458  check_instance( name, 0, 0, kernel32 );
459  check_thread_instance( name, 0, 0, kernel32 );
460  }
461  check_class( kernel32, name, "kernel32" );
462  check_class( user32, name, "main_module" );
463  check_class( zero_instance, name, "main_module" );
464  check_instance( name, kernel32, kernel32, kernel32 );
465  check_instance( name, user32, zero_instance, user32 );
466  check_thread_instance( name, kernel32, kernel32, kernel32 );
467  check_thread_instance( name, user32, zero_instance, user32 );
468  ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
469 
470  SetClassLongPtrA( hwnd, GCLP_HMODULE, 0x12345678 );
471  ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" );
472  check_class( kernel32, name, "kernel32" );
473  check_class( (HINSTANCE)0x12345678, name, "main_module" );
474  check_instance( name, kernel32, kernel32, kernel32 );
475  check_instance( name, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678 );
476  check_thread_instance( name, kernel32, kernel32, kernel32 );
477  check_thread_instance( name, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678 );
478  ok( !GetClassInfoA( 0, name, &wc ), "Class found with null instance\n" );
479 
480  /* creating a window with instance 0 uses the first class found */
481  cls.hInstance = (HINSTANCE)0xdeadbeef;
482  cls.lpszMenuName = "deadbeef";
483  cls.style = 3;
484  ok( RegisterClassA( &cls ), "Failed to register local class for deadbeef\n" );
485  hwnd2 = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, NULL, 0 );
486  ok( GetClassLongPtrA( hwnd2, GCLP_HMODULE ) == 0xdeadbeef,
487  "Didn't get deadbeef class for null instance\n" );
488  DestroyWindow( hwnd2 );
489  ok( UnregisterClassA( name, (HINSTANCE)0xdeadbeef ), "Unregister failed for deadbeef\n" );
490 
491  hwnd2 = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, NULL, 0 );
492  ok( (HINSTANCE)GetClassLongPtrA( hwnd2, GCLP_HMODULE ) == kernel32,
493  "Didn't get kernel32 class for null instance\n" );
494  DestroyWindow( hwnd2 );
495 
496  r = GetClassNameA( hwnd, buffer, 4 );
497  ok( r == 3, "expected 3, got %d\n", r );
498  ok( !strcmp( buffer, "__t"), "name wrong: %s\n", buffer );
499 
500  ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
501 
502  hwnd2 = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, NULL, 0 );
503  ok( GetClassLongPtrA( hwnd2, GCLP_HMODULE ) == 0x12345678,
504  "Didn't get 12345678 class for null instance\n" );
505  DestroyWindow( hwnd2 );
506 
507  SetClassLongPtrA( hwnd, GCLP_HMODULE, (LONG_PTR)main_module );
508  DestroyWindow( hwnd );
509 
510  /* null handle means the same thing as main module */
511  cls.lpszMenuName = "null";
512  cls.hInstance = 0;
513  ok( !RegisterClassA( &cls ), "Succeeded registering local class for null instance\n" );
514  ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %d\n", GetLastError() );
515  ok( UnregisterClassA( name, main_module ), "Unregister failed for main module\n" );
516 
517  ok( RegisterClassA( &cls ), "Failed to register local class for null instance\n" );
518  /* must be found with main module handle */
519  check_class( main_module, name, "null" );
520  check_instance( name, main_module, main_module, main_module );
521  check_thread_instance( name, main_module, main_module, main_module );
522  ok( !GetClassInfoA( 0, name, &wc ), "Class found with null instance\n" );
523  ok( GetLastError() == ERROR_CLASS_DOES_NOT_EXIST, "Wrong error code %d\n", GetLastError() );
524  ok( UnregisterClassA( name, 0 ), "Unregister failed for null instance\n" );
525 
526  /* registering for user32 always fails */
527  cls.lpszMenuName = "user32";
528  cls.hInstance = user32;
529  ok( !RegisterClassA( &cls ), "Succeeded registering local class for user32\n" );
530  ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error code %d\n", GetLastError() );
531  cls.style |= CS_GLOBALCLASS;
532  ok( !RegisterClassA( &cls ), "Succeeded registering global class for user32\n" );
533  ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error code %d\n", GetLastError() );
534 
535  /* unregister is OK though */
536  cls.hInstance = main_module;
537  ok( RegisterClassA( &cls ), "Failed to register global class for main module\n" );
538  ok( UnregisterClassA( name, user32 ), "Unregister failed for user32\n" );
539 
540  /* instance doesn't matter for global class */
541  cls.style |= CS_GLOBALCLASS;
542  cls.lpszMenuName = "main_module";
543  cls.hInstance = main_module;
544  ok( RegisterClassA( &cls ), "Failed to register global class for main module\n" );
545  cls.lpszMenuName = "kernel32";
546  cls.hInstance = kernel32;
547  ok( !RegisterClassA( &cls ), "Succeeded registering local class for kernel32\n" );
548  ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %d\n", GetLastError() );
549  /* even if global flag is cleared */
550  hwnd = CreateWindowExA( 0, name, "test", 0, 0, 0, 0, 0, 0, 0, main_module, 0 );
552  ok( !RegisterClassA( &cls ), "Succeeded registering local class for kernel32\n" );
553  ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %d\n", GetLastError() );
554 
555  check_class( main_module, name, "main_module" );
556  check_class( kernel32, name, "main_module" );
557  check_class( 0, name, "main_module" );
558  check_class( (HINSTANCE)0x12345678, name, "main_module" );
559  check_instance( name, main_module, main_module, main_module );
560  check_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, main_module );
561  check_thread_instance( name, main_module, main_module, main_module );
562  check_thread_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, main_module );
563 
564  /* changing the instance for global class doesn't make much difference */
565  SetClassLongPtrA( hwnd, GCLP_HMODULE, 0xdeadbeef );
566  check_instance( name, main_module, main_module, (HINSTANCE)0xdeadbeef );
567  check_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef );
568  check_thread_instance( name, main_module, main_module, (HINSTANCE)0xdeadbeef );
569  check_thread_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef );
570 
571  DestroyWindow( hwnd );
572  ok( UnregisterClassA( name, (HINSTANCE)0x87654321 ), "Unregister failed for main module global\n" );
573  ok( !UnregisterClassA( name, (HINSTANCE)0x87654321 ), "Unregister succeeded the second time\n" );
574  ok( GetLastError() == ERROR_CLASS_DOES_NOT_EXIST, "Wrong error code %d\n", GetLastError() );
575 
576  cls.hInstance = (HINSTANCE)0x12345678;
577  ok( RegisterClassA( &cls ), "Failed to register global class for dummy instance\n" );
578  check_instance( name, main_module, main_module, (HINSTANCE)0x12345678 );
579  check_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, (HINSTANCE)0x12345678 );
580  check_thread_instance( name, main_module, main_module, (HINSTANCE)0x12345678 );
581  check_thread_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, (HINSTANCE)0x12345678 );
582  ok( UnregisterClassA( name, (HINSTANCE)0x87654321 ), "Unregister failed for main module global\n" );
583 
584  /* check system classes */
585 
586  /* we cannot register a global class with the name of a system class */
587  cls.style |= CS_GLOBALCLASS;
588  cls.lpszMenuName = "button_main_module";
589  cls.lpszClassName = "BUTTON";
590  cls.hInstance = main_module;
591  ok( !RegisterClassA( &cls ), "Succeeded registering global button class for main module\n" );
592  ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %d\n", GetLastError() );
593  cls.hInstance = kernel32;
594  ok( !RegisterClassA( &cls ), "Succeeded registering global button class for kernel32\n" );
595  ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %d\n", GetLastError() );
596 
597  /* local class is OK however */
598  cls.style &= ~CS_GLOBALCLASS;
599  cls.lpszMenuName = "button_main_module";
600  cls.hInstance = main_module;
601  ok( RegisterClassA( &cls ), "Failed to register local button class for main module\n" );
602  check_class( main_module, "BUTTON", "button_main_module" );
603  cls.lpszMenuName = "button_kernel32";
604  cls.hInstance = kernel32;
605  ok( RegisterClassA( &cls ), "Failed to register local button class for kernel32\n" );
606  check_class( kernel32, "BUTTON", "button_kernel32" );
607  check_class( main_module, "BUTTON", "button_main_module" );
608  ok( UnregisterClassA( "BUTTON", kernel32 ), "Unregister failed for kernel32 button\n" );
609  ok( UnregisterClassA( "BUTTON", main_module ), "Unregister failed for main module button\n" );
610  /* GetClassInfo sets instance to passed value for global classes */
611  check_instance( "BUTTON", 0, 0, user32 );
612  check_instance( "BUTTON", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 );
613  check_instance( "BUTTON", user32, zero_instance, user32 );
614  check_thread_instance( "BUTTON", 0, 0, user32 );
615  check_thread_instance( "BUTTON", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 );
616  check_thread_instance( "BUTTON", user32, zero_instance, user32 );
617 
618  /* we can unregister system classes */
619  ok( GetClassInfoA( 0, "BUTTON", &wc ), "Button class not found with null instance\n" );
620  ok( GetClassInfoA( kernel32, "BUTTON", &wc ), "Button class not found with kernel32\n" );
621  ok( UnregisterClassA( "BUTTON", (HINSTANCE)0x12345678 ), "Failed to unregister button\n" );
622  ok( !UnregisterClassA( "BUTTON", (HINSTANCE)0x87654321 ), "Unregistered button a second time\n" );
623  ok( GetLastError() == ERROR_CLASS_DOES_NOT_EXIST, "Wrong error code %d\n", GetLastError() );
624  ok( !GetClassInfoA( 0, "BUTTON", &wc ), "Button still exists\n" );
625  /* last error not set reliably */
626 
627  /* we can change the instance of a system class */
628  check_instance( "EDIT", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 );
629  check_thread_instance( "EDIT", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 );
630  hwnd = CreateWindowExA( 0, "EDIT", "test", 0, 0, 0, 0, 0, 0, 0, main_module, 0 );
631  SetClassLongPtrA( hwnd, GCLP_HMODULE, 0xdeadbeef );
632  check_instance( "EDIT", (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0xdeadbeef );
633  check_thread_instance( "EDIT", (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0xdeadbeef );
635 }
636 
637 static void test_builtinproc(void)
638 {
639  /* Edit behaves differently */
640  static const CHAR NORMAL_CLASSES[][10] = {
641  "Button",
642  "Static",
643  "ComboBox",
644  "ComboLBox",
645  "ListBox",
646  "ScrollBar",
647  "#32770", /* dialog */
648  };
649  static const char classA[] = "deftest";
650  static const WCHAR classW[] = {'d','e','f','t','e','s','t',0};
651  WCHAR unistring[] = {0x142, 0x40e, 0x3b4, 0}; /* a string that would be destroyed by a W->A->W conversion */
652  WNDPROC pDefWindowProcA, pDefWindowProcW;
653  WNDPROC pNtdllDefWindowProcA, pNtdllDefWindowProcW;
654  WNDPROC oldproc;
655  WNDCLASSEXA cls; /* the memory layout of WNDCLASSEXA and WNDCLASSEXW is the same */
656  WCHAR buf[128];
657  ATOM atom;
658  HWND hwnd;
659  unsigned int i;
660 
661  pDefWindowProcA = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "DefWindowProcA");
662  pDefWindowProcW = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "DefWindowProcW");
663  pNtdllDefWindowProcA = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtdllDefWindowProc_A");
664  pNtdllDefWindowProcW = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtdllDefWindowProc_W");
665 
666  /* On Vista+, the user32.dll export DefWindowProcA/W is forwarded to */
667  /* ntdll.NtdllDefWindowProc_A/W. However, the wndproc returned by */
668  /* GetClassLong/GetWindowLong points to an unexported user32 function */
669  if (pDefWindowProcA == pNtdllDefWindowProcA &&
670  pDefWindowProcW == pNtdllDefWindowProcW)
671  skip("user32.DefWindowProcX forwarded to ntdll.NtdllDefWindowProc_X\n");
672  else
673  {
674  for (i = 0; i < 4; i++)
675  {
676  ZeroMemory(&cls, sizeof(cls));
677  cls.cbSize = sizeof(cls);
680  if (i & 1)
681  cls.lpfnWndProc = pDefWindowProcA;
682  else
683  cls.lpfnWndProc = pDefWindowProcW;
684 
685  if (i & 2)
686  {
687  cls.lpszClassName = classA;
688  atom = RegisterClassExA(&cls);
689  }
690  else
691  {
692  cls.lpszClassName = (LPCSTR)classW;
693  atom = RegisterClassExW((WNDCLASSEXW *)&cls);
694  }
695  ok(atom != 0, "Couldn't register class, i=%d, %d\n", i, GetLastError());
696 
697  hwnd = CreateWindowA(classA, NULL, 0, 0, 0, 100, 100, NULL, NULL, GetModuleHandleA(NULL), NULL);
698  ok(hwnd != NULL, "Couldn't create window i=%d\n", i);
699 
700  ok(GetWindowLongPtrA(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcA, "Wrong ANSI wndproc: %p vs %p\n",
701  (void *)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), pDefWindowProcA);
702  ok(GetClassLongPtrA(hwnd, GCLP_WNDPROC) == (ULONG_PTR)pDefWindowProcA, "Wrong ANSI wndproc: %p vs %p\n",
703  (void *)GetClassLongPtrA(hwnd, GCLP_WNDPROC), pDefWindowProcA);
704 
705  ok(GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcW, "Wrong Unicode wndproc: %p vs %p\n",
706  (void *)GetWindowLongPtrW(hwnd, GWLP_WNDPROC), pDefWindowProcW);
707  ok(GetClassLongPtrW(hwnd, GCLP_WNDPROC) == (ULONG_PTR)pDefWindowProcW, "Wrong Unicode wndproc: %p vs %p\n",
708  (void *)GetClassLongPtrW(hwnd, GCLP_WNDPROC), pDefWindowProcW);
709 
712  }
713  }
714 
715  /* built-in winproc - window A/W type automatically detected */
716  ZeroMemory(&cls, sizeof(cls));
717  cls.cbSize = sizeof(cls);
720  cls.lpszClassName = classA;
721  cls.lpfnWndProc = pDefWindowProcW;
722  atom = RegisterClassExA(&cls);
723 
727  broken(!IsWindowUnicode(hwnd)) /* Windows 8 and 10 */,
728  "Windows should be Unicode\n");
730  if (IsWindowUnicode(hwnd))
731  ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
732  else
733  ok(memcmp(buf, unistring, sizeof(unistring)) != 0, "WM_GETTEXT invalid return\n");
734  SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)pDefWindowProcA);
735  ok(IsWindowUnicode(hwnd), "Windows should have remained Unicode\n");
736  if (GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcA)
737  {
738  /* DefWindowProc isn't magic on wow64 */
739  ok(IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd, GWLP_WNDPROC)), "Ansi winproc is not a handle\n");
740  }
741  else
742  {
743  ok(GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcW, "Invalid Unicode winproc\n");
744  ok(GetWindowLongPtrA(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcA, "Invalid Ansi winproc\n");
745  }
747  ok(IsWindowUnicode(hwnd) == FALSE, "SetWindowLongPtrA should have switched window to ANSI\n");
748 
751 
752  /* custom winproc - the same function can be used as both A and W*/
753  ZeroMemory(&cls, sizeof(cls));
754  cls.cbSize = sizeof(cls);
757  cls.lpszClassName = classA;
759  atom = RegisterClassExA(&cls);
760 
763  ok(IsWindowUnicode(hwnd) == FALSE, "Window should be ANSI\n");
765  ok(IsWindowUnicode(hwnd), "SetWindowLongPtrW should have changed window to Unicode\n");
767  ok(IsWindowUnicode(hwnd) == FALSE, "SetWindowLongPtrA should have changed window to ANSI\n");
768 
771 
772  /* For most of the builtin controls both GetWindowLongPtrA and W returns a pointer that is executed directly
773  * by CallWindowProcA/W */
774  for (i = 0; i < ARRAY_SIZE(NORMAL_CLASSES); i++)
775  {
776  WNDPROC procA, procW;
777  hwnd = CreateWindowExA(0, NORMAL_CLASSES[i], classA, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 680, 260,
778  NULL, NULL, NULL, 0);
779  ok(hwnd != NULL, "Couldn't create window of class %s\n", NORMAL_CLASSES[i]);
780  SetWindowTextA(hwnd, classA); /* ComboBox needs this */
783  ok(!IS_WNDPROC_HANDLE(procA), "procA should not be a handle for %s (%p)\n", NORMAL_CLASSES[i], procA);
784  ok(!IS_WNDPROC_HANDLE(procW), "procW should not be a handle for %s (%p)\n", NORMAL_CLASSES[i], procW);
785  CallWindowProcA(procA, hwnd, WM_GETTEXT, 120, (LPARAM)buf);
786  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT A/A invalid return for class %s\n", NORMAL_CLASSES[i]);
787  CallWindowProcA(procW, hwnd, WM_GETTEXT, 120, (LPARAM)buf);
788  ok(memcmp(buf, classW, sizeof(classW)) == 0, "WM_GETTEXT A/W invalid return for class %s\n", NORMAL_CLASSES[i]);
789  CallWindowProcW(procA, hwnd, WM_GETTEXT, 120, (LPARAM)buf);
790  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT W/A invalid return for class %s\n", NORMAL_CLASSES[i]);
791  CallWindowProcW(procW, hwnd, WM_GETTEXT, 120, (LPARAM)buf);
792  ok(memcmp(buf, classW, sizeof(classW)) == 0, "WM_GETTEXT W/W invalid return for class %s\n", NORMAL_CLASSES[i]);
793 
795  ok(IS_WNDPROC_HANDLE(oldproc) == FALSE, "Class %s shouldn't return a handle\n", NORMAL_CLASSES[i]);
798  }
799 
800  /* Edit controls are special - they return a wndproc handle when GetWindowLongPtr is called with a different A/W.
801  * On the other hand there is no W->A->W conversion so this control is treated specially. */
803  CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, NULL, 0);
804  /* GetClassLongPtr returns that both the Unicode and ANSI wndproc */
805  ok(IS_WNDPROC_HANDLE(GetClassLongPtrA(hwnd, GCLP_WNDPROC)) == FALSE, "Edit control class should have a Unicode wndproc\n");
806  ok(IS_WNDPROC_HANDLE(GetClassLongPtrW(hwnd, GCLP_WNDPROC)) == FALSE, "Edit control class should have a ANSI wndproc\n");
807  /* But GetWindowLongPtr returns only a handle for the ANSI one */
808  ok(IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd, GWLP_WNDPROC)), "Edit control should return a wndproc handle\n");
809  ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd, GWLP_WNDPROC)), "Edit control shouldn't return a W wndproc handle\n");
811  ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\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");
816 
819  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
820 
822  /* SetWindowLongPtr returns a wndproc handle - like GetWindowLongPtr */
823  ok(IS_WNDPROC_HANDLE(oldproc), "Edit control should return a wndproc handle\n");
824  ok(IsWindowUnicode(hwnd) == FALSE, "SetWindowLongPtrA should have changed window to ANSI\n");
825  SetWindowTextA(hwnd, classA); /* Windows resets the title to WideStringToMultiByte(unistring) */
826  memset(buf, 0, sizeof(buf));
828  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
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");
833 
835  ok(memcmp(buf, classW, sizeof(classW)) == 0, "WM_GETTEXT invalid return\n");
836 
838 
840 
842  CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, NULL, 0);
843 
844  /* GetClassLongPtr returns that both the Unicode and ANSI wndproc */
845  ok(!IS_WNDPROC_HANDLE(GetClassLongPtrA(hwnd, GCLP_WNDPROC)), "Edit control class should have a Unicode wndproc\n");
846  ok(!IS_WNDPROC_HANDLE(GetClassLongPtrW(hwnd, GCLP_WNDPROC)), "Edit control class should have a ANSI wndproc\n");
847  /* But GetWindowLongPtr returns only a handle for the Unicode one */
848  ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd, GWLP_WNDPROC)), "Edit control shouldn't return an A wndproc handle\n");
849  ok(IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd, GWLP_WNDPROC)), "Edit control should return a wndproc handle\n");
851  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\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");
856 
858  ok(memcmp(buf, classW, sizeof(classW)) == 0, "WM_GETTEXT invalid return\n");
859 
861  SetWindowTextW(hwnd, unistring);
863  ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
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");
868 
871  ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
872 
874 
876 }
877 
878 
880 {
881  return DefDlgProcA(hWnd, uMsg, wParam, lParam);
882 }
883 
885 {
886  WNDCLASSEXA wcx;
887  ATOM atom = 0;
888 
889  ZeroMemory(&wcx, sizeof(WNDCLASSEXA));
890  wcx.cbSize = sizeof(wcx);
891  wcx.lpfnWndProc = TestDlgProc;
892  wcx.cbClsExtra = 0;
894  wcx.hInstance = hInstance;
898  wcx.lpszClassName = "TestDialog";
899  wcx.lpszMenuName = "TestDialog";
903 
904  atom = RegisterClassExA(&wcx);
905  ok(atom != 0, "RegisterClassEx returned 0\n");
906 
907  return atom;
908 }
909 
910 /* test registering a dialog box created by using the CLASS directive in a
911  resource file, then test creating the dialog using CreateDialogParam. */
913 {
914  HWND hWndMain;
915 
917  {
918  hWndMain = CreateDialogParamA(hInstance, "CLASS_TEST_DIALOG", NULL, 0, 0);
919  ok(hWndMain != NULL, "CreateDialogParam returned NULL\n");
922  }
923 }
924 
925 static const struct
926 {
927  const char name[9];
928  int value;
929  int badvalue;
930 } extra_values[] =
931 {
932  {"#32770",30,30}, /* Dialog */
933 #ifdef _WIN64
934  {"Edit",8,8},
935 #else
936  {"Edit",6,8}, /* Windows XP 64-bit returns 8 also to 32-bit applications */
937 #endif
938 };
939 
940 static void test_extra_values(void)
941 {
942  int i;
943  for(i = 0; i < ARRAY_SIZE(extra_values); i++)
944  {
945  WNDCLASSEXA wcx;
947 
948  ok( ret, "GetClassInfo (0) failed for global class %s\n", extra_values[i].name);
949  if (!ret) continue;
951  "expected %d, got %d\n", extra_values[i].value, wcx.cbWndExtra);
952  }
953 }
954 
955 static void test_GetClassInfo(void)
956 {
957  static const WCHAR staticW[] = {'s','t','a','t','i','c',0};
958  WNDCLASSA wc;
959  WNDCLASSEXA wcx;
960  BOOL ret;
961 
962  SetLastError(0xdeadbeef);
963  ret = GetClassInfoA(0, "static", &wc);
964  ok(ret, "GetClassInfoA() error %d\n", GetLastError());
965 
966 if (0) { /* crashes under XP */
967  SetLastError(0xdeadbeef);
968  ret = GetClassInfoA(0, "static", NULL);
969  ok(ret, "GetClassInfoA() error %d\n", GetLastError());
970 
971  SetLastError(0xdeadbeef);
972  ret = GetClassInfoW(0, staticW, NULL);
973  ok(ret, "GetClassInfoW() error %d\n", GetLastError());
974 }
975 
976  wcx.cbSize = sizeof(wcx);
977  SetLastError(0xdeadbeef);
978  ret = GetClassInfoExA(0, "static", &wcx);
979  ok(ret, "GetClassInfoExA() error %d\n", GetLastError());
980 
981  SetLastError(0xdeadbeef);
982  ret = GetClassInfoExA(0, "static", NULL);
983  ok(!ret, "GetClassInfoExA() should fail\n");
985  broken(GetLastError() == 0xdeadbeef), /* win9x */
986  "expected ERROR_NOACCESS, got %d\n", GetLastError());
987 
988  SetLastError(0xdeadbeef);
990  ok(!ret, "GetClassInfoExW() should fail\n");
992  broken(GetLastError() == 0xdeadbeef) /* NT4 */ ||
994  "expected ERROR_NOACCESS, got %d\n", GetLastError());
995 
996  wcx.cbSize = 0;
997  wcx.lpfnWndProc = NULL;
998  SetLastError(0xdeadbeef);
999  ret = GetClassInfoExA(0, "static", &wcx);
1000  ok(ret, "GetClassInfoExA() error %d\n", GetLastError());
1001  ok(GetLastError() == 0xdeadbeef, "Unexpected error code %d\n", GetLastError());
1002  ok(wcx.cbSize == 0, "expected 0, got %u\n", wcx.cbSize);
1003  ok(wcx.lpfnWndProc != NULL, "got null proc\n");
1004 
1005  wcx.cbSize = sizeof(wcx) - 1;
1006  wcx.lpfnWndProc = NULL;
1007  SetLastError(0xdeadbeef);
1008  ret = GetClassInfoExA(0, "static", &wcx);
1009  ok(ret, "GetClassInfoExA() error %d\n", GetLastError());
1010  ok(wcx.cbSize == sizeof(wcx) - 1, "expected sizeof(wcx)-1, got %u\n", wcx.cbSize);
1011  ok(wcx.lpfnWndProc != NULL, "got null proc\n");
1012 
1013  wcx.cbSize = sizeof(wcx) + 1;
1014  wcx.lpfnWndProc = NULL;
1015  SetLastError(0xdeadbeef);
1016  ret = GetClassInfoExA(0, "static", &wcx);
1017  ok(ret, "GetClassInfoExA() error %d\n", GetLastError());
1018  ok(wcx.cbSize == sizeof(wcx) + 1, "expected sizeof(wcx)+1, got %u\n", wcx.cbSize);
1019  ok(wcx.lpfnWndProc != NULL, "got null proc\n");
1020 }
1021 
1022 static void test_icons(void)
1023 {
1024  WNDCLASSEXW wcex, ret_wcex;
1025  WCHAR cls_name[] = {'I','c','o','n','T','e','s','t','C','l','a','s','s',0};
1026  HWND hwnd;
1028  HICON hsmicon, hsmallnew;
1029  ICONINFO icinf;
1030 
1031  memset(&wcex, 0, sizeof wcex);
1032  wcex.cbSize = sizeof wcex;
1034  wcex.hIcon = LoadIconW(0, (LPCWSTR)IDI_APPLICATION);
1035  wcex.hInstance = hinst;
1036  wcex.lpszClassName = cls_name;
1037  ok(RegisterClassExW(&wcex), "RegisterClassExW returned 0\n");
1039  0, 0, 0, 0, NULL, NULL, hinst, 0);
1040  ok(hwnd != NULL, "Window was not created\n");
1041 
1042  ok(GetClassInfoExW(hinst, cls_name, &ret_wcex), "Class info was not retrieved\n");
1043  ok(wcex.hIcon == ret_wcex.hIcon, "Icons don't match\n");
1044  ok(ret_wcex.hIconSm != NULL, "hIconSm should be non-zero handle\n");
1045 
1046  hsmicon = (HICON)GetClassLongPtrW(hwnd, GCLP_HICONSM);
1047  ok(hsmicon != NULL, "GetClassLong should return non-zero handle\n");
1048 
1049  ok(SendMessageA(hwnd, WM_GETICON, ICON_BIG, 0) == 0,
1050  "WM_GETICON with ICON_BIG should not return the class icon\n");
1051  ok(SendMessageA(hwnd, WM_GETICON, ICON_SMALL, 0) == 0,
1052  "WM_GETICON with ICON_SMALL should not return the class icon\n");
1053  ok(SendMessageA(hwnd, WM_GETICON, ICON_SMALL2, 0) == 0,
1054  "WM_GETICON with ICON_SMALL2 should not return the class icon\n");
1055 
1058  ok(!SetClassLongPtrW(hwnd, GCLP_HICONSM, (LONG_PTR)hsmallnew),
1059  "Previous hIconSm should be zero\n");
1060  ok(hsmallnew == (HICON)GetClassLongPtrW(hwnd, GCLP_HICONSM),
1061  "Should return explicitly assigned small icon\n");
1062  ok(!GetIconInfo(hsmicon, &icinf), "Previous small icon should be destroyed\n");
1063 
1065  hsmicon = (HICON)GetClassLongPtrW(hwnd, GCLP_HICONSM);
1066  ok( hsmicon != NULL, "GetClassLong should return non-zero handle\n");
1067 
1069  ok(!GetClassLongPtrW(hwnd, GCLP_HICONSM), "GetClassLong should return zero handle\n");
1070 
1072  hsmicon = (HICON)GetClassLongPtrW(hwnd, GCLP_HICONSM);
1073  ok(hsmicon != NULL, "GetClassLong should return non-zero handle\n");
1075  ok(GetIconInfo(hsmicon, &icinf), "Icon should NOT be destroyed\n");
1076 
1077  DestroyIcon(hsmallnew);
1079 }
1080 
1081 static void create_manifest_file(const char *filename, const char *manifest)
1082 {
1083  WCHAR path[MAX_PATH];
1084  HANDLE file;
1085  DWORD size;
1086 
1089  ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
1091  CloseHandle(file);
1092 }
1093 
1094 static HANDLE create_test_actctx(const char *file)
1095 {
1096  WCHAR path[MAX_PATH];
1097  ACTCTXW actctx;
1098  HANDLE handle;
1099 
1101  memset(&actctx, 0, sizeof(ACTCTXW));
1102  actctx.cbSize = sizeof(ACTCTXW);
1103  actctx.lpSource = path;
1104 
1106  ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError());
1107 
1108  ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize);
1109  ok(actctx.dwFlags == 0, "dwFlags=%d\n", actctx.dwFlags);
1110  ok(actctx.lpSource == path, "lpSource=%p\n", actctx.lpSource);
1111  ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
1112  ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId);
1113  ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
1114  ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName);
1115  ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName);
1116  ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule);
1117 
1118  return handle;
1119 }
1120 static void test_comctl32_class( const char *name )
1121 {
1122  WNDCLASSA wcA;
1123  WNDCLASSW wcW;
1124  BOOL ret;
1125  HMODULE module;
1126  WCHAR nameW[20];
1127  HWND hwnd;
1128 
1129  if (name[0] == '!')
1130  {
1131  char path[MAX_PATH];
1132  ULONG_PTR cookie;
1133  HANDLE context;
1134 
1135  name++;
1136 
1138  strcat(path, "comctl32_class.manifest");
1139 
1142  ret = DeleteFileA(path);
1143  ok(ret, "Failed to delete manifest file, error %d.\n", GetLastError());
1144 
1145  module = GetModuleHandleA( "comctl32" );
1146  ok( !module, "comctl32 already loaded\n" );
1147 
1149  ok(ret, "Failed to activate context.\n");
1150 
1151  /* Some systems load modules during context activation. In this case skip the rest of the test. */
1152  module = GetModuleHandleA( "comctl32" );
1153  ok( !module || broken(module != NULL) /* Vista/Win7 */, "comctl32 already loaded\n" );
1154  if (module)
1155  {
1156  win_skip("Module loaded during context activation. Skipping tests.\n");
1157  goto skiptest;
1158  }
1159 
1160  ret = GetClassInfoA( 0, name, &wcA );
1161  ok( ret || broken(!ret) /* WinXP */, "GetClassInfoA failed for %s\n", name );
1162  if (!ret)
1163  goto skiptest;
1164 
1166  ret = GetClassInfoW( 0, nameW, &wcW );
1167  ok( ret, "GetClassInfoW failed for %s\n", name );
1168  module = GetModuleHandleA( "comctl32" );
1169  ok( module != 0, "comctl32 not loaded\n" );
1170  FreeLibrary( module );
1171  module = GetModuleHandleA( "comctl32" );
1172  ok( !module || broken(module != NULL) /* Vista */, "comctl32 still loaded\n" );
1173  hwnd = CreateWindowA( name, "test", WS_OVERLAPPEDWINDOW, 0, 0, 10, 10, NULL, NULL, NULL, 0 );
1174  ok( hwnd != 0, "failed to create window for %s\n", name );
1175  module = GetModuleHandleA( "comctl32" );
1176  ok( module != 0, "comctl32 not loaded\n" );
1177  DestroyWindow( hwnd );
1178 
1179  skiptest:
1180  ret = DeactivateActCtx(0, cookie);
1181  ok(ret, "Failed to deactivate context.\n");
1183  }
1184  else
1185  {
1186  module = GetModuleHandleA( "comctl32" );
1187  ok( !module, "comctl32 already loaded\n" );
1188  ret = GetClassInfoA( 0, name, &wcA );
1189  ok( ret || broken(!ret) /* <= winxp */, "GetClassInfoA failed for %s\n", name );
1190  if (!ret) return;
1192  ret = GetClassInfoW( 0, nameW, &wcW );
1193  ok( ret, "GetClassInfoW failed for %s\n", name );
1194  module = GetModuleHandleA( "comctl32" );
1195  ok( module != 0, "comctl32 not loaded\n" );
1196  FreeLibrary( module );
1197  module = GetModuleHandleA( "comctl32" );
1198  ok( !module, "comctl32 still loaded\n" );
1199  hwnd = CreateWindowA( name, "test", WS_OVERLAPPEDWINDOW, 0, 0, 10, 10, NULL, NULL, NULL, 0 );
1200  ok( hwnd != 0, "failed to create window for %s\n", name );
1201  module = GetModuleHandleA( "comctl32" );
1202  ok( module != 0, "comctl32 not loaded\n" );
1203  DestroyWindow( hwnd );
1204  }
1205 }
1206 
1207 /* verify that comctl32 classes are automatically loaded by user32 */
1208 static void test_comctl32_classes(void)
1209 {
1210  char path_name[MAX_PATH];
1213  char **argv;
1214  int i;
1215 
1216  static const char *classes[] =
1217  {
1221  WC_HEADERA,
1222  HOTKEY_CLASSA,
1223  WC_IPADDRESSA,
1224  WC_LISTVIEWA,
1231  "SysLink",
1236  WC_TREEVIEWA,
1237  UPDOWN_CLASSA,
1238  "!Button",
1239  "!Edit",
1240  "!Static",
1241  "!Listbox",
1242  "!ComboBox",
1243  "!ComboLBox",
1244  };
1245 
1247  for (i = 0; i < ARRAY_SIZE(classes); i++)
1248  {
1249  memset( &startup, 0, sizeof(startup) );
1250  startup.cb = sizeof( startup );
1251  sprintf( path_name, "%s class %s", argv[0], classes[i] );
1253  "CreateProcess failed.\n" );
1254  winetest_wait_child_process( info.hProcess );
1255  CloseHandle( info.hProcess );
1256  CloseHandle( info.hThread );
1257  }
1258 }
1259 
1260 static void test_IME(void)
1261 {
1262  static const WCHAR ime_classW[] = {'I','M','E',0};
1263 
1264  char module_name[MAX_PATH], *ptr;
1266  WNDCLASSW wnd_classw;
1268  SIZE_T size;
1269  BOOL ret;
1270 
1271  if (!GetProcAddress(GetModuleHandleA("user32.dll"), "BroadcastSystemMessageExA"))
1272  {
1273  win_skip("BroadcastSystemMessageExA not available, skipping IME class test\n");
1274  return;
1275  }
1276 
1277  ok(GetModuleHandleA("imm32") != 0, "imm32.dll is not loaded\n");
1278 
1279  ret = GetClassInfoA(NULL, "IME", &wnd_class);
1280  ok(ret, "GetClassInfo failed: %d\n", GetLastError());
1281 
1282  size = VirtualQuery(wnd_class.lpfnWndProc, &mbi, sizeof(mbi));
1283  ok(size == sizeof(mbi), "VirtualQuery returned %ld\n", size);
1284  if (size == sizeof(mbi)) {
1286  ok(size, "GetModuleFileName failed\n");
1287  for (ptr = module_name+size-1; ptr > module_name; ptr--)
1288  if (*ptr == '\\' || *ptr == '/') break;
1289  if (*ptr == '\\' || *ptr=='/') ptr++;
1290  ok(!lstrcmpiA(ptr, "user32.dll") || !lstrcmpiA(ptr, "ntdll.dll"), "IME window proc implemented in %s\n", ptr);
1291  }
1292 
1293  ret = GetClassInfoW(NULL, ime_classW, &wnd_classw);
1294  ok(ret, "GetClassInfo failed: %d\n", GetLastError());
1295 
1296  size = VirtualQuery(wnd_classw.lpfnWndProc, &mbi, sizeof(mbi));
1297  ok(size == sizeof(mbi), "VirtualQuery returned %ld\n", size);
1299  ok(size, "GetModuleFileName failed\n");
1300  for (ptr = module_name+size-1; ptr > module_name; ptr--)
1301  if (*ptr == '\\' || *ptr == '/') break;
1302  if (*ptr == '\\' || *ptr=='/') ptr++;
1303  ok(!lstrcmpiA(ptr, "user32.dll") || !lstrcmpiA(ptr, "ntdll.dll"), "IME window proc implemented in %s\n", ptr);
1304 }
1305 
1306 static void test_actctx_classes(void)
1307 {
1308  static const char main_manifest[] =
1309  "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
1310  "<assemblyIdentity version=\"4.3.2.1\" name=\"Wine.WndClass.Test\" type=\"win32\" />"
1311  "<file name=\"file.exe\">"
1312  "<windowClass>MyTestClass</windowClass>"
1313  "</file>"
1314  "</assembly>";
1315  static const char *testclass = "MyTestClass";
1316  WNDCLASSA wc;
1317  ULONG_PTR cookie;
1318  HANDLE context;
1319  BOOL ret;
1320  ATOM class;
1321  HINSTANCE hinst;
1322  char buff[64];
1323  HWND hwnd, hwnd2;
1324  char path[MAX_PATH];
1325 
1327  strcat(path, "actctx_classes.manifest");
1328 
1329  create_manifest_file(path, main_manifest);
1331  ret = DeleteFileA(path);
1332  ok(ret, "Failed to delete manifest file, error %d.\n", GetLastError());
1333 
1335  ok(ret, "Failed to activate context.\n");
1336 
1337  memset(&wc, 0, sizeof(wc));
1340  wc.lpszClassName = testclass;
1341 
1342  hinst = GetModuleHandleW(0);
1343 
1344  ret = GetClassInfoA(hinst, testclass, &wc);
1345  ok(!ret, "Expected failure.\n");
1346 
1347  class = RegisterClassA(&wc);
1348  ok(class != 0, "Failed to register class.\n");
1349 
1350  /* Class info is available by versioned and regular names. */
1351  ret = GetClassInfoA(hinst, testclass, &wc);
1352  ok(ret, "Failed to get class info.\n");
1353 
1354  hwnd = CreateWindowExA(0, testclass, "test", 0, 0, 0, 0, 0, 0, 0, hinst, 0);
1355  ok(hwnd != NULL, "Failed to create a window.\n");
1356 
1357  hwnd2 = FindWindowExA(NULL, NULL, "MyTestClass", NULL);
1358  ok(hwnd2 == hwnd, "Failed to find test window.\n");
1359 
1360  hwnd2 = FindWindowExA(NULL, NULL, "4.3.2.1!MyTestClass", NULL);
1361  ok(hwnd2 == NULL, "Unexpected find result %p.\n", hwnd2);
1362 
1363  ret = GetClassNameA(hwnd, buff, sizeof(buff));
1364  ok(ret, "Failed to get class name.\n");
1365  ok(!strcmp(buff, testclass), "Unexpected class name.\n");
1366 
1367  ret = GetClassInfoA(hinst, "4.3.2.1!MyTestClass", &wc);
1368  ok(ret, "Failed to get class info.\n");
1369 
1370  ret = UnregisterClassA(testclass, hinst);
1371  ok(!ret, "Failed to unregister class.\n");
1372 
1373  ret = DeactivateActCtx(0, cookie);
1374  ok(ret, "Failed to deactivate context.\n");
1375 
1376  ret = GetClassInfoA(hinst, testclass, &wc);
1377  ok(!ret, "Unexpected ret val %d.\n", ret);
1378 
1379  ret = GetClassInfoA(hinst, "4.3.2.1!MyTestClass", &wc);
1380  ok(ret, "Failed to get class info.\n");
1381 
1382  ret = GetClassNameA(hwnd, buff, sizeof(buff));
1383  ok(ret, "Failed to get class name.\n");
1384  ok(!strcmp(buff, testclass), "Unexpected class name.\n");
1385 
1387 
1388  hwnd = CreateWindowExA(0, "4.3.2.1!MyTestClass", "test", 0, 0, 0, 0, 0, 0, 0, hinst, 0);
1389  ok(hwnd != NULL, "Failed to create a window.\n");
1390 
1391  hwnd2 = FindWindowExA(NULL, NULL, "MyTestClass", NULL);
1392  ok(hwnd2 == hwnd, "Failed to find test window.\n");
1393 
1394  hwnd2 = FindWindowExA(NULL, NULL, "4.3.2.1!MyTestClass", NULL);
1395  ok(hwnd2 == NULL, "Unexpected find result %p.\n", hwnd2);
1396 
1398 
1399  ret = UnregisterClassA("MyTestClass", hinst);
1400  ok(!ret, "Unexpected ret value %d.\n", ret);
1401 
1402  ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst);
1403  ok(ret, "Failed to unregister class.\n");
1404 
1405  /* Register versioned class without active context. */
1406  wc.lpszClassName = "4.3.2.1!MyTestClass";
1407  class = RegisterClassA(&wc);
1408  ok(class != 0, "Failed to register class.\n");
1409 
1411  ok(ret, "Failed to activate context.\n");
1412 
1413  wc.lpszClassName = "MyTestClass";
1414  class = RegisterClassA(&wc);
1415  ok(class == 0, "Expected failure.\n");
1416 
1417  ret = DeactivateActCtx(0, cookie);
1418  ok(ret, "Failed to deactivate context.\n");
1419 
1420  ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst);
1421  ok(ret, "Failed to unregister class.\n");
1422 
1423  /* Only versioned name is registered. */
1425  ok(ret, "Failed to activate context.\n");
1426 
1427  wc.lpszClassName = "MyTestClass";
1428  class = RegisterClassA(&wc);
1429  ok(class != 0, "Failed to register class\n");
1430 
1431  ret = DeactivateActCtx(0, cookie);
1432  ok(ret, "Failed to deactivate context.\n");
1433 
1434  ret = GetClassInfoA(hinst, "MyTestClass", &wc);
1435  ok(!ret, "Expected failure.\n");
1436 
1437  ret = GetClassInfoA(hinst, "4.3.2.1!MyTestClass", &wc);
1438  ok(ret, "Failed to get class info.\n");
1439 
1440  ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst);
1441  ok(ret, "Failed to unregister class.\n");
1442 
1443  /* Register regular name first, it's not considered when versioned name is registered. */
1444  wc.lpszClassName = "MyTestClass";
1445  class = RegisterClassA(&wc);
1446  ok(class != 0, "Failed to register class.\n");
1447 
1449  ok(ret, "Failed to activate context.\n");
1450 
1451  wc.lpszClassName = "MyTestClass";
1452  class = RegisterClassA(&wc);
1453  ok(class != 0, "Failed to register class.\n");
1454 
1455  ret = DeactivateActCtx(0, cookie);
1456  ok(ret, "Failed to deactivate context.\n");
1457 
1458  ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst);
1459  ok(ret, "Failed to unregister class.\n");
1460 
1461  ret = UnregisterClassA("MyTestClass", hinst);
1462  ok(ret, "Failed to unregister class.\n");
1463 
1465 }
1466 
1468 {
1469  char **argv;
1471  int argc = winetest_get_mainargs( &argv );
1472 
1473  if (argc >= 3)
1474  {
1475  test_comctl32_class( argv[2] );
1476  return;
1477  }
1478 
1479  test_IME();
1482 
1483  if (!GetModuleHandleW(0))
1484  {
1485  trace("Class test is incompatible with Win9x implementation, skipping\n");
1486  return;
1487  }
1488 
1492  test_styles();
1493  test_builtinproc();
1494  test_icons();
1497 
1498  /* this test unregisters the Button class so it should be executed at the end */
1499  test_instances();
1500 }
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:1306
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
static const WCHAR classW[]
Definition: lex.c:40
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:4494
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:3185
ATOM WINAPI RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
Definition: class.c:1528
#define WC_EDITW
Definition: commctrl.h:4683
#define CloseHandle
Definition: compat.h:487
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:3151
#define REBARCLASSNAMEA
Definition: commctrl.h:1460
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
HCURSOR hCursor
Definition: winuser.h:3183
WNDPROC lpfnWndProc
Definition: winuser.h:3178
BOOL WINAPI GetClassInfoExA(HINSTANCE hInstance, LPCSTR lpszClass, LPWNDCLASSEXA lpwcx)
Definition: class.c:264
LPCWSTR lpszMenuName
Definition: winuser.h:3159
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:7094
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
LPCSTR lpszClassName
Definition: winuser.h:3186
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
#define TRUE
Definition: types.h:120
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:289
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
LRESULT WINAPI DefDlgProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
static void check_class_(int line, HINSTANCE inst, const char *name, const char *menu_name)
Definition: class.c:273
#define CP_ACP
Definition: compat.h:109
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:88
HWND hWnd
Definition: settings.c:17
BOOL WINAPI GetClassInfoA(HINSTANCE hInstance, LPCSTR lpClassName, LPWNDCLASSA lpWndClass)
Definition: class.c:476
int cbClsExtra
Definition: winuser.h:3140
#define INVALID_HANDLE_VALUE
Definition: compat.h:479
static void test_instances(void)
Definition: class.c:349
#define ARCH
Definition: class.c:47
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1648
#define CS_HREDRAW
Definition: winuser.h:648
LPCSTR lpszMenuName
Definition: winuser.h:3146
static void test_GetClassInfo(void)
Definition: class.c:955
GLuint buffer
Definition: glext.h:5915
#define SM_CYSMICON
Definition: winuser.h:1003
HICON hIcon
Definition: winuser.h:3197
int startup(int argc, const char *argv[])
Definition: startup.c:430
int cbClsExtra
Definition: winuser.h:3153
#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:4804
HICON hIconSm
Definition: winuser.h:3187
static void test_extra_values(void)
Definition: class.c:940
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:2252
static void create_manifest_file(const char *filename, const char *manifest)
Definition: class.c:1081
#define argv
Definition: mplay32.c:18
char * LPSTR
Definition: xmlstorage.h:182
const char * filename
Definition: ioapi.h:135
#define lstrlenW
Definition: compat.h:498
#define MONTHCAL_CLASSA
Definition: commctrl.h:4172
#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:4291
#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:539
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:331
static void check_instance_(int line, const char *name, HINSTANCE inst, HINSTANCE info_inst, HINSTANCE gcl_inst)
Definition: class.c:291
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:879
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:65
int WINAPI GetClipboardFormatNameW(_In_ UINT format, _Out_writes_(cchMaxCount) LPWSTR lpszFormatName, _In_ int cchMaxCount)
#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
static const struct @1697 extra_values[]
int cbWndExtra
Definition: winuser.h:3141
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:4682
ATOM WINAPI RegisterClassA(CONST WNDCLASSA *lpWndClass)
Definition: class.c:1591
#define FALSE
Definition: types.h:117
HINSTANCE hInstance
Definition: winuser.h:3181
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:4469
#define IS_WNDPROC_HANDLE(x)
Definition: class.c:36
static HANDLE create_test_actctx(const char *file)
Definition: class.c:1094
#define GENERIC_WRITE
Definition: nt_native.h:90
WNDPROC lpfnWndProc
Definition: winuser.h:3152
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:4290
#define CW_USEDEFAULT
Definition: winuser.h:225
#define WC_TREEVIEWA
Definition: commctrl.h:3238
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:80
smooth NULL
Definition: ftsmooth.c:416
#define DATETIMEPICK_CLASSA
Definition: commctrl.h:4319
#define ERROR_CLASS_ALREADY_EXISTS
Definition: winerror.h:891
LPCWSTR lpszClassName
Definition: winuser.h:3160
LONG_PTR LPARAM
Definition: windef.h:208
UINT cbSize
Definition: winuser.h:3176
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:5240
const char * LPCSTR
Definition: xmlstorage.h:183
#define SW_SHOW
Definition: winuser.h:769
BOOL WINAPI IsWindowUnicode(_In_ HWND)
HBRUSH hbrBackground
Definition: winuser.h:3184
LPCWSTR lpszClassName
Definition: winuser.h:3201
static const WCHAR nameW[]
Definition: main.c:46
#define GetWindowLongPtrA
Definition: winuser.h:4803
#define CS_VREDRAW
Definition: winuser.h:653
static void test_builtinproc(void)
Definition: class.c:637
const char name[9]
Definition: class.c:927
#define GCLP_HICONSM
Definition: winuser.h:670
static void test_comctl32_classes(void)
Definition: class.c:1208
#define FreeLibrary(x)
Definition: compat.h:496
#define HOTKEY_CLASSA
Definition: commctrl.h:2231
#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:3154
__wchar_t WCHAR
Definition: xmlstorage.h:180
UINT cbSize
Definition: winuser.h:3191
BOOL WINAPI SetWindowTextA(_In_ HWND, _In_opt_ LPCSTR)
int badvalue
Definition: class.c:929
static char * path_name(DOS_FILE *file)
Definition: check.c:208
VOID WINAPI ReleaseActCtx(IN HANDLE hActCtx)
Definition: actctx.c:208
HINSTANCE gcl_inst
Definition: class.c:319
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:4744
#define CS_GLOBALCLASS
Definition: winuser.h:647
GLfloat param
Definition: glext.h:5796
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
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:3156
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:3180
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2074
#define SetLastError(x)
Definition: compat.h:500
static LRESULT WINAPI ClassTest_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: class.c:74
int winetest_get_mainargs(char ***pargv)
#define WS_HSCROLL
Definition: pedump.c:628
HINSTANCE hInstance
Definition: winuser.h:3196
#define CS_SAVEBITS
Definition: winuser.h:652
#define SM_CXSMICON
Definition: winuser.h:1002
HANDLE HINSTANCE
Definition: typedefs.h:77
int ret
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
HWND WINAPI CreateDialogParamA(_In_opt_ HINSTANCE, _In_ LPCSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
HICON hIcon
Definition: winuser.h:3182
#define todo_wine
Definition: test.h:162
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:5320
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
#define CS_DBLCLKS
Definition: winuser.h:646
#define UPDOWN_CLASSA
Definition: commctrl.h:2114
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LPCSTR lpszClassName
Definition: winuser.h:3147
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define ANIMATE_CLASSA
Definition: commctrl.h:4138
#define SetClassLongPtrA
Definition: winuser.h:5239
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2059
static void test_IME(void)
Definition: class.c:1260
WNDPROC lpfnWndProc
Definition: winuser.h:3193
#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:253
ATOM WINAPI RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
Definition: class.c:1574
UINT style
Definition: winuser.h:3138
#define TOOLBARCLASSNAMEA
Definition: commctrl.h:940
#define WC_NATIVEFONTCTLA
Definition: commctrl.h:4603
HCURSOR hCursor
Definition: winuser.h:3157
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2881
static void check_style(const char *name, int must_exist, UINT style, UINT ignore)
Definition: class.c:237
HINSTANCE info_inst
Definition: class.c:319
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define WC_COMBOBOXEXA
Definition: commctrl.h:3778
static const WCHAR staticW[]
Definition: actctx.c:656
#define CREATE_ALWAYS
Definition: disk.h:72
int cbClsExtra
Definition: winuser.h:3179
#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:3142
int value
Definition: class.c:928
#define ARRAY_SIZE(a)
Definition: main.h:24
static const char comctl32_manifest[]
Definition: class.c:50
HINSTANCE inst
Definition: class.c:319
static void test_icons(void)
Definition: class.c:1022
HBRUSH hbrBackground
Definition: winuser.h:3158
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define ok(value,...)
Definition: atltest.h:57
#define TRACKBAR_CLASSA
Definition: commctrl.h:2006
#define TOOLTIPS_CLASSA
Definition: commctrl.h:1704
Definition: cookie.c:33
__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:110
WNDPROC lpfnWndProc
Definition: winuser.h:3139
#define CreateFileW
Definition: compat.h:489
HICON hIconSm
Definition: winuser.h:3202
HINSTANCE hInstance
Definition: winuser.h:3155
#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:38
#define GetClassLongPtrA
Definition: winuser.h:4538
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:1467
HWND WINAPI FindWindowExA(_In_opt_ HWND, _In_opt_ HWND, _In_opt_ LPCSTR, _In_opt_ LPCSTR)
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
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:102
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2044
#define GetProcAddress(x, y)
Definition: compat.h:501
static const char cls_name[]
Definition: compobj.c:2476
#define SetWindowLongPtrW
Definition: winuser.h:5321
static const CHAR manifest[]
Definition: v6util.h:39
static void test_comctl32_class(const char *name)
Definition: class.c:1120
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define STATUSCLASSNAMEA
Definition: commctrl.h:1933
LONG_PTR LRESULT
Definition: windef.h:209
static DWORD WINAPI thread_proc(void *param)
Definition: class.c:322
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:149
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:884
#define GetClassLongPtrW
Definition: winuser.h:4539
#define CS_PARENTDC
Definition: winuser.h:651
static void CreateDialogParamTest(HINSTANCE hInstance)
Definition: class.c:912
WNDCLASSW wnd_class
Definition: startup.c:16
#define PROGRESS_CLASSA
Definition: commctrl.h:2171
#define ICON_BIG
Definition: tnclass.cpp:51
#define NUMCLASSWORDS
Definition: class.c:34
#define WC_TABCONTROLA
Definition: commctrl.h:3930
#define WC_HEADERA
Definition: commctrl.h:619
#define check_instance(name, inst, info_inst, gcl_inst)
Definition: class.c:314
#define ok_(x1, x2)
Definition: atltest.h:61
HICON hIcon
Definition: winuser.h:3143
const char * name
Definition: class.c:318
Definition: fci.c:126