fddbd0fa20e540c5ec38881b3a70ec0e830cdb64
[reactos.git] / modules / rostests / apitests / user32 / WndProc.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for mismatch with function prototype in window procedure callback.
5 * PROGRAMMERS:
6 */
7
8 #include "precomp.h"
9
10 /* Used wine Redraw test for proof in principle. */
11
12 /* Global variables to trigger exit from loop */
13 static int redrawComplete, WMPAINT_count;
14
15 /*
16 * Force stack corruption when calling from assumed window procedure callback.
17 * Adding (6 and) more will force exception faults and terminate the test program.
18 * The test is with five and this is safe for windows.
19 *
20 * But,,,, ReactOS compiled with GCC can handle this,,,,,,
21 */
22 static LRESULT WINAPI redraw_window_procA(
23 HWND hwnd,
24 UINT msg,
25 WPARAM wparam,
26 LPARAM lparam,
27 DWORD ExtraData,
28 DWORD ExtraData1,
29 DWORD ExtraData2,
30 DWORD ExtraData3)
31 {
32 switch (msg)
33 {
34 case WM_PAINT:
35 trace("doing WM_PAINT %d\n", WMPAINT_count);
36 WMPAINT_count++;
37
38 if (WMPAINT_count > 10 && redrawComplete == 0)
39 {
40 PAINTSTRUCT ps;
41
42 BeginPaint(hwnd, &ps);
43 EndPaint(hwnd, &ps);
44 return 1;
45 }
46
47 // This will force one stack corruption "ret" fault with normal window
48 // procedure callback.
49 #ifdef __MINGW32__
50 asm ("movl $0, %eax\n\t"
51 "leave\n\t"
52 "ret");
53 #elif defined(_M_IX86)
54 //#ifdef _MSC_VER
55 __asm
56 {
57 mov eax, 0
58 leave
59 ret
60 }
61 #else
62 trace("unimplemented\n");
63 #endif
64 }
65
66 return DefWindowProc(hwnd, msg, wparam, lparam);
67 }
68
69 static void test_wndproc(void)
70 {
71 WNDCLASSA cls;
72 HWND hwndMain;
73
74 cls.style = CS_DBLCLKS;
75 cls.lpfnWndProc = (WNDPROC)redraw_window_procA;
76 cls.cbClsExtra = 0;
77 cls.cbWndExtra = 0;
78 cls.hInstance = GetModuleHandleA(NULL);
79 cls.hIcon = NULL;
80 cls.hCursor = LoadCursorA(NULL, IDC_ARROW);
81 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
82 cls.lpszMenuName = NULL;
83 cls.lpszClassName = "RedrawWindowClass";
84
85 if (!RegisterClassA(&cls))
86 {
87 trace("Register failed %d\n", (int)GetLastError());
88 return;
89 }
90
91 hwndMain = CreateWindowA("RedrawWindowClass", "Main Window", WS_OVERLAPPEDWINDOW,
92 CW_USEDEFAULT, 0, 100, 100, NULL, NULL, NULL, NULL);
93
94 ok(WMPAINT_count == 0, "Multiple unexpected WM_PAINT calls %d\n", WMPAINT_count);
95 ShowWindow(hwndMain, SW_SHOW);
96 ok(WMPAINT_count == 0, "Multiple unexpected WM_PAINT calls %d\n", WMPAINT_count);
97 RedrawWindow(hwndMain, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN);
98 ok(WMPAINT_count == 1 || broken(WMPAINT_count == 0), /* sometimes on win9x */
99 "Multiple unexpected WM_PAINT calls %d\n", WMPAINT_count);
100 redrawComplete = TRUE;
101 ok(WMPAINT_count < 10, "RedrawWindow (RDW_UPDATENOW) never completed (%d)\n", WMPAINT_count);
102
103 /* clean up */
104 DestroyWindow(hwndMain);
105 }
106
107 START_TEST(WndProc)
108 {
109 #ifdef __RUNTIME_CHECKS__
110 skip("This test breaks MSVC runtime checks!");
111 return;
112 #endif /* __RUNTIME_CHECKS__ */
113
114 test_wndproc();
115 }