1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * PURPOSE:         Test for GetMessageTime and GetTickCount
5  * PROGRAMMERS:     Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6  */
7 #include "precomp.h"
8 
9 #define TIMER_ID 999
10 #define TIMER_INTERVAL 500  /* 500 milliseconds */
11 
12 #define MOUSE_LOCATION_X(x) ((DWORD)(x) * 0xFFFF / GetSystemMetrics(SM_CXSCREEN))
13 #define MOUSE_LOCATION_Y(y) ((DWORD)(y) * 0xFFFF / GetSystemMetrics(SM_CYSCREEN))
14 
15 #define WIN_X   50
16 #define WIN_Y   50
17 #define WIN_CX  100
18 #define WIN_CY  100
19 
20 static INT s_nCount = 0;
21 static LONG s_nMsgTime = 0;
22 
23 static LRESULT CALLBACK
WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)24 WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
25 {
26     static BOOL s_bReach_WM_MOUSEMOVE;
27     static BOOL s_bReach_WM_LBUTTONDOWN;
28     static BOOL s_bReach_WM_LBUTTONUP;
29     switch (uMsg)
30     {
31         case WM_CREATE:
32             s_nCount = 0;
33             s_nMsgTime = GetMessageTime();
34             SetTimer(hwnd, TIMER_ID, TIMER_INTERVAL, NULL);
35             s_bReach_WM_MOUSEMOVE = FALSE;
36             s_bReach_WM_LBUTTONDOWN = FALSE;
37             s_bReach_WM_LBUTTONUP = FALSE;
38             break;
39         case WM_TIMER:
40             if (s_nCount == 5)
41             {
42                 KillTimer(hwnd, TIMER_ID);
43                 DestroyWindow(hwnd);
44                 break;
45             }
46             if (s_nCount != 0)
47             {
48                 ok(GetMessageTime() - s_nMsgTime >= TIMER_INTERVAL / 2,
49                    "GetMessageTime() is wrong, compared to previous one\n");
50                 ok(GetTickCount() - (DWORD)GetMessageTime() < TIMER_INTERVAL / 2,
51                    "GetMessageTime() is wrong, compared to GetTickCount()\n");
52             }
53             s_nMsgTime = GetMessageTime();
54             ok(s_nMsgTime != 0, "message time was zero.\n");
55             s_nCount++;
56             if (s_nCount == 5)
57             {
58                 mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
59                             MOUSE_LOCATION_X(WIN_X + WIN_CX / 2),
60                             MOUSE_LOCATION_Y(WIN_Y + WIN_CY / 2),
61                             0, 0);
62                 mouse_event(MOUSEEVENTF_MOVE, 1, 1, 0, 0);
63                 mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
64                 mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
65             }
66             break;
67         case WM_MOUSEMOVE:
68             trace("WM_MOUSEMOVE\n");
69             ok_int(s_nCount, 5);
70             // This test randomly fails on Windows 2003
71             //ok(GetMessageTime() - s_nMsgTime < TIMER_INTERVAL,
72             //   "GetMessageTime() is wrong, compared to previous one\n");
73             ok(GetTickCount() - (DWORD)GetMessageTime() < TIMER_INTERVAL / 2,
74                "GetMessageTime() is wrong, compared to GetTickCount()\n");
75             s_bReach_WM_MOUSEMOVE = TRUE;
76             break;
77         case WM_LBUTTONDOWN:
78             trace("WM_LBUTTONDOWN\n");
79             ok_int(s_nCount, 5);
80             ok(GetMessageTime() - s_nMsgTime < TIMER_INTERVAL,
81                "GetMessageTime() is wrong, compared to previous one\n");
82             ok(GetTickCount() - (DWORD)GetMessageTime() < TIMER_INTERVAL / 2,
83                "GetMessageTime() is wrong, compared to GetTickCount()\n");
84             s_bReach_WM_LBUTTONDOWN = TRUE;
85             break;
86         case WM_LBUTTONUP:
87             trace("WM_LBUTTONUP\n");
88             ok_int(s_nCount, 5);
89             ok(GetMessageTime() - s_nMsgTime < TIMER_INTERVAL,
90                "GetMessageTime() is wrong, compared to previous one\n");
91             ok(GetTickCount() - (DWORD)GetMessageTime() < TIMER_INTERVAL / 2,
92                "GetMessageTime() is wrong, compared to GetTickCount()\n");
93             s_bReach_WM_LBUTTONUP = TRUE;
94             break;
95         case WM_DESTROY:
96             ok_int(s_bReach_WM_MOUSEMOVE, TRUE);
97             ok_int(s_bReach_WM_LBUTTONDOWN, TRUE);
98             ok_int(s_bReach_WM_LBUTTONUP, TRUE);
99             PostQuitMessage(0);
100             break;
101         default:
102             return DefWindowProcW(hwnd, uMsg, wParam, lParam);
103     }
104     return 0;
105 }
106 
START_TEST(GetMessageTime)107 START_TEST(GetMessageTime)
108 {
109     static const WCHAR s_szName[] = L"MessageTimeTestWindow";
110     WNDCLASSW wc;
111     ATOM atom;
112     HWND hwnd;
113     MSG msg;
114     BOOL bRet;
115 
116     mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
117                 MOUSE_LOCATION_X(1), MOUSE_LOCATION_Y(1),
118                 0, 0);
119 
120     ZeroMemory(&wc, sizeof(wc));
121     wc.lpfnWndProc = WindowProc;
122     wc.hInstance = GetModuleHandleW(NULL);
123     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
124     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
125     wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
126     wc.lpszClassName = s_szName;
127     atom = RegisterClassW(&wc);
128     ok(atom != 0, "RegisterClassW\n");
129 
130     hwnd = CreateWindowW(s_szName, s_szName,
131                          WS_OVERLAPPEDWINDOW,
132                          WIN_X, WIN_Y, WIN_CX, WIN_CY,
133                          NULL, NULL, GetModuleHandleW(NULL), NULL);
134     ok(hwnd != NULL, "CreateWindowW\n");
135 
136     if (hwnd)
137     {
138         ShowWindow(hwnd, SW_SHOWNORMAL);
139         UpdateWindow(hwnd);
140 
141         while (GetMessageW(&msg, NULL, 0, 0))
142         {
143             TranslateMessage(&msg);
144             DispatchMessageW(&msg);
145         }
146     }
147     else
148     {
149         skip("hwnd was NULL.\n");
150     }
151 
152     bRet = UnregisterClassW(s_szName, GetModuleHandleW(NULL));
153     ok_int(bRet, 1);
154 
155     ok_int(s_nCount, 5);
156     ok(s_nMsgTime != 0, "message time was zero.\n");
157 }
158