1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * PURPOSE:         Test for RealGetWindowClass
5  * PROGRAMMERS:     Gregor Gullwi
6  */
7 
8 #include "precomp.h"
9 
10 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
11 
12 static PWSTR ControlsList[] =
13 {
14   L"Button\0",
15   L"Edit\0",
16   L"Static\0",
17   L"ListBox\0",
18   L"ScrollBar\0",
19   L"ComboBox\0",
20   L"MDIClient\0",
21   L"ComboLBox\0",
22   L"DDEMLEvent\0",
23   L"DDEMLMom\0",
24   L"DMGClass\0",
25   L"DDEMLAnsiClient\0",
26   L"DDEMLUnicodeClient\0",
27   L"DDEMLAnsiServer\0",
28   L"DDEMLUnicodeServer\0",
29   L"IME\0",
30   L"\0",//L"Ghost\0", // Vista+, Ghost is registered after "Message" in XP/W2k3 Win32k.sys.
31 };
32 
33 typedef struct _TestData
34 {
35     BOOL    OverrideWndProc;            /* TRUE if lpfnWndProc should be overridden */
36     LPCSTR  ClassName;                  /* Name of the new class to register */
37     DWORD   WndExtra;                   /* Remove these WNDCLASS::cbWndExtra flags */
38     BOOL    ExpectsHwnd;                /* TRUE if a HWND should be created to run tests on */
39     LPCSTR  ExpectedClassNameBefore;    /* Expected class name before any dialog function is called */
40     LPCSTR  ExpectedClassNameAfter;     /* Expected class name after any dialog function is called */
41 } TestData;
42 
43 static TestData RealClassTestData[] =
44 {
45     {
46         TRUE,
47         "OverrideWndProc_with_DLGWINDOWEXTRA_TRUE",
48         0,
49         TRUE,
50         "OverrideWndProc_with_DLGWINDOWEXTRA_TRUE",
51         "#32770",
52     },
53     {
54         TRUE,
55         "OverrideWndProc_without_DLGWINDOWEXTRA_TRUE",
56         DLGWINDOWEXTRA,
57         TRUE,
58         "OverrideWndProc_without_DLGWINDOWEXTRA_TRUE",
59         "OverrideWndProc_without_DLGWINDOWEXTRA_TRUE",
60     },
61     {
62         FALSE,
63         "DefaultWndProc_with_DLGWINDOWEXTRA_FALSE",
64         0,
65         TRUE,
66         "#32770",
67         "#32770",
68     },
69     {
70         FALSE,
71         "DefaultWndProc_without_DLGWINDOWEXTRA_FALSE",
72         DLGWINDOWEXTRA,
73         FALSE,
74         "N/A",
75         "N/A",
76     },
77 };
78 
79 //
80 // The Control Class Atoms are consecitively issued.
81 //
82 
83 void Test_ClassAtoms()
84 {
85     ATOM atom;
86     int i;
87     WNDCLASSW cls;
88 
89     // Initialize starting Atom number.
90     atom = GetClassInfoW(NULL, ControlsList[0], &cls);
91     if (!atom)
92     {
93        skip( "No reference Atom\n" );
94        return;
95     }
96 
97     trace("First Control Class Atom 0x%x\n",atom);
98 
99     for (i = 0; i < 17; atom++ ,i++)
100     {
101         if (lstrcmpW(ControlsList[i],L"\0"))
102         {
103            ATOM test_atom = GetClassInfoW(NULL, ControlsList[i], &cls);
104            // Skip unregistered Classes.
105            if (test_atom)
106            {
107               ok(test_atom == atom, "%S class atom did not match %x:%x\n",ControlsList[i],test_atom,atom);
108               ok(!lstrcmpW(cls.lpszClassName,ControlsList[i]),"GetClassName returned incorrect name\n");
109            }
110         }
111     }
112 }
113 
114 void Test_RealGetWindowClass()
115 {
116     int testNo;
117     UINT Result;
118     CHAR Buffer[1024];
119 
120     Result = RealGetWindowClass( NULL, Buffer, ARRAY_SIZE(Buffer) );
121     ok(Result == 0, "Result = %d\n", Result);
122     ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "GetLastError() = %ld\n", GetLastError());
123 
124     for (testNo = 0; testNo < ARRAY_SIZE(RealClassTestData); testNo++)
125     {
126         ATOM atom;
127         WNDCLASSA cls;
128         HWND hWnd;
129 
130         /* Register classes, "derived" from built-in dialog, with and without the DLGWINDOWEXTRA flag set */
131         GetClassInfoA(0, "#32770", &cls);
132         if (RealClassTestData[testNo].OverrideWndProc)
133             cls.lpfnWndProc = DefWindowProcA;
134         cls.lpszClassName = RealClassTestData[testNo].ClassName;
135         cls.cbWndExtra &= ~RealClassTestData[testNo].WndExtra;
136         atom = RegisterClassA (&cls);
137         if (atom == 0) return;
138 
139         /* Create a window */
140         hWnd = CreateWindowEx( WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR |
141                                WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT | WS_EX_APPWINDOW,
142                                RealClassTestData[testNo].ClassName,
143                                RealClassTestData[testNo].ClassName,
144                                WS_POPUPWINDOW | WS_CLIPSIBLINGS | WS_DLGFRAME | WS_OVERLAPPED |
145                                WS_MINIMIZEBOX | WS_MAXIMIZEBOX | DS_3DLOOK | DS_SETFONT | DS_MODALFRAME,
146                                CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
147                                NULL, NULL, 0, 0);
148 
149         /* Do we expect a HWND at all? */
150         if (RealClassTestData[testNo].ExpectsHwnd)
151         {
152             ok(hWnd != NULL, "\n");
153 
154             if (hWnd != NULL)
155             {
156                 /* Get the "real" class name */
157                 Result = RealGetWindowClass( hWnd, Buffer, ARRAY_SIZE(Buffer) );
158                 printf("Buffer: %s\nExpectedClassNameBefore(%d): %s\n", Buffer, testNo, RealClassTestData[testNo].ExpectedClassNameBefore);
159                 ok( Result != 0, "\n" );
160                 ok( strcmp( Buffer, RealClassTestData[testNo].ExpectedClassNameBefore ) == 0, "\n" );
161 
162                 /* Call a function that requires a dialog window */
163                 DefDlgProcA( hWnd, DM_SETDEFID, IDCANCEL, 0 );
164 
165                 /* Get the "real" class name again */
166                 Result = RealGetWindowClass( hWnd, Buffer, ARRAY_SIZE(Buffer) );
167                 printf("Buffer: %s\nExpectedClassNameAfter(%d): %s\n", Buffer, testNo, RealClassTestData[testNo].ExpectedClassNameAfter);
168                 ok( Result != 0, "\n" );
169                 ok( strcmp( Buffer, RealClassTestData[testNo].ExpectedClassNameAfter ) == 0, "\n" );
170             }
171         }
172         else
173         {
174             ok(hWnd == NULL, "\n");
175         }
176 
177         /* Cleanup */
178         DestroyWindow(hWnd);
179         UnregisterClass(RealClassTestData[testNo].ClassName, 0);
180     }
181 
182 }
183 
184 START_TEST(RealGetWindowClass)
185 {
186     Test_ClassAtoms();
187     Test_RealGetWindowClass();
188 }
189