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