ReactOS 0.4.16-dev-1338-g8aab5a9
TrackPopupMenuEx.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
4 * PURPOSE: Tests for TrackPopupMenuEx
5 * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#include "precomp.h"
9#include <versionhelpers.h>
10
11#define CLASSNAME L"TrackPopupMenuEx tests"
12#define MENUCLASS L"#32768"
13
14#define VALID_TPM_FLAGS ( \
15 TPM_LAYOUTRTL | TPM_NOANIMATION | TPM_VERNEGANIMATION | TPM_VERPOSANIMATION | \
16 TPM_HORNEGANIMATION | TPM_HORPOSANIMATION | TPM_RETURNCMD | \
17 TPM_NONOTIFY | TPM_VERTICAL | TPM_BOTTOMALIGN | TPM_VCENTERALIGN | \
18 TPM_RIGHTALIGN | TPM_CENTERALIGN | TPM_RIGHTBUTTON | TPM_RECURSE \
19)
20
21#ifndef TPM_WORKAREA
22#define TPM_WORKAREA 0x10000
23#endif
24
25static VOID
27{
29 HMENU hMenu = CreatePopupMenu();
30 BOOL ret;
31
32 ret = AppendMenuW(hMenu, MF_STRING, 100, L"(Dummy)");
33 ok_int(ret, TRUE);
34
35 INT iBit;
37 for (iBit = 0; iBit < sizeof(DWORD) * CHAR_BIT; ++iBit)
38 {
39 uFlags = (1 << iBit);
41 {
42 SetLastError(0xBEEFCAFE);
43 ret = TrackPopupMenuEx(hMenu, uFlags, 0, 0, hwnd, NULL);
47 else
49 }
50 }
51
52 DestroyMenu(hMenu);
53}
54
55static VOID
57{
59 HMENU hMenu = CreatePopupMenu();
62 BOOL ret;
63
64 ZeroMemory(&params, sizeof(params));
65
66 ret = AppendMenuW(hMenu, MF_STRING, 100, L"(Dummy)");
67 ok_int(ret, TRUE);
68
69 SetLastError(0xBEEFCAFE);
70 params.cbSize = 0;
71 ret = TrackPopupMenuEx(hMenu, uFlags, 0, 0, hwnd, &params);
74
75 SetLastError(0xBEEFCAFE);
76 params.cbSize = sizeof(params) - 1;
77 ret = TrackPopupMenuEx(hMenu, uFlags, 0, 0, hwnd, &params);
80
81 SetLastError(0xBEEFCAFE);
82 params.cbSize = sizeof(params) + 1;
83 ret = TrackPopupMenuEx(hMenu, uFlags, 0, 0, hwnd, &params);
86
87 DestroyMenu(hMenu);
88}
89
90#define DELAY 100
91#define INTERVAL 300
92
93typedef enum tagAUTO_CLICK
94{
100
101typedef enum tagAUTO_KEY
102{
107
108static VOID
110{
111 if (type == AUTO_KEY_DOWN_UP)
112 {
113 AutoKey(AUTO_KEY_DOWN, vKey);
114 AutoKey(AUTO_KEY_UP, vKey);
115 return;
116 }
117
118 INPUT input;
119 ZeroMemory(&input, sizeof(input));
120
121 input.type = INPUT_KEYBOARD;
122 input.ki.wVk = vKey;
123 input.ki.dwFlags = ((type == AUTO_KEY_UP) ? KEYEVENTF_KEYUP : 0);
124 SendInput(1, &input, sizeof(INPUT));
125 Sleep(DELAY);
126}
127
128static VOID
130{
131 INPUT input;
132 ZeroMemory(&input, sizeof(input));
133
134 INT nScreenWidth = GetSystemMetrics(SM_CXSCREEN) - 1;
135 INT nScreenHeight = GetSystemMetrics(SM_CYSCREEN) - 1;
136
137 input.type = INPUT_MOUSE;
138 input.mi.dx = (LONG)(x * (65535.0f / nScreenWidth));
139 input.mi.dy = (LONG)(y * (65535.0f / nScreenHeight));
141 SendInput(1, &input, sizeof(INPUT));
142 Sleep(DELAY);
143
144 input.mi.dx = input.mi.dy = 0;
145
146 INT i, count = 1;
147 switch (type)
148 {
150 count = 2;
151 // FALL THROUGH
152 case AUTO_LEFT_CLICK:
153 {
154 for (i = 0; i < count; ++i)
155 {
156 input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
157 SendInput(1, &input, sizeof(INPUT));
158 Sleep(DELAY);
159
160 input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
161 SendInput(1, &input, sizeof(INPUT));
162 Sleep(DELAY);
163 }
164 break;
165 }
167 count = 2;
168 // FALL THROUGH
169 case AUTO_RIGHT_CLICK:
170 {
171 for (i = 0; i < count; ++i)
172 {
173 input.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
174 SendInput(1, &input, sizeof(INPUT));
175 Sleep(DELAY);
176
177 input.mi.dwFlags = MOUSEEVENTF_RIGHTUP;
178 SendInput(1, &input, sizeof(INPUT));
179 Sleep(DELAY);
180 }
181 break;
182 }
183 }
184}
185
186static POINT
188{
189 POINT pt = { (prc->left + prc->right) / 2, (prc->top + prc->bottom) / 2 };
190 return pt;
191}
192
193typedef struct tagCOUNTMENUWND
194{
197
198static BOOL CALLBACK
200{
201 if (!IsWindowVisible(hwnd))
202 return TRUE;
203
204 WCHAR szClass[64];
205 GetClassNameW(hwnd, szClass, _countof(szClass));
206 if (lstrcmpiW(szClass, MENUCLASS) != 0)
207 return TRUE;
208
210 pData->nMenuCount += 1;
211 return TRUE;
212}
213
214static INT
216{
217 COUNTMENUWND data = { 0 };
219 return data.nMenuCount;
220}
221
222static DWORD WINAPI
224{
225 HWND hwnd = (HWND)arg;
226
227 ok_int(CountMenuWnds(), 0);
228
229 RECT rc;
230 GetWindowRect(hwnd, &rc);
231 POINT pt = CenterPoint(&rc);
232
235
236 ok_int(CountMenuWnds(), 1);
237
240
241 ok_int(CountMenuWnds(), 1);
242
245
246 ok_int(CountMenuWnds(), 0);
247
248 PostMessageW(hwnd, WM_CLOSE, 0, 0);
249 return 0;
250}
251
252static VOID
254{
256
257 POINT pt;
259
260 HMENU hMenu = CreatePopupMenu();
261 BOOL ret = AppendMenuW(hMenu, MF_STRING, 100, L"(Dummy)");
262 ok_int(ret, TRUE);
263
265 INT nCmdID = (INT)TrackPopupMenuEx(hMenu, uFlags, pt.x, pt.y, hwnd, NULL);
266
267 ok_int(nCmdID, 100);
268
269 DestroyMenu(hMenu);
270}
271
272static LRESULT CALLBACK
274{
275 switch (uMsg)
276 {
277 case WM_CREATE:
278 return 0;
279 case WM_RBUTTONDOWN:
281 break;
282 case WM_DESTROY:
284 break;
285 default:
286 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
287 }
288 return 0;
289}
290
291static VOID
293{
295
296 WNDCLASSW wc = { 0, WindowProc };
297 wc.hInstance = hInstance;
300 wc.hbrBackground = (HBRUSH)UlongToHandle(COLOR_3DFACE + 1);
302 if (!RegisterClassW(&wc))
303 {
304 skip("RegisterClassW failed\n");
305 return;
306 }
307
310 0, 0, 320, 200, NULL, NULL, hInstance, NULL);
311 if (!hwnd)
312 {
313 skip("CreateWindowW failed\n");
314 return;
315 }
316
319
321 if (!hThread)
322 {
323 skip("CreateThread failed\n");
325 return;
326 }
328
329 MSG msg;
330 while (GetMessageW(&msg, NULL, 0, 0))
331 {
334 }
335}
336
338{
342}
tagAUTO_CLICK
Definition: MenuUI.c:30
enum tagAUTO_KEY AUTO_KEY
tagAUTO_KEY
Definition: MenuUI.c:38
enum tagAUTO_CLICK AUTO_CLICK
static BOOL CALLBACK CountMenuWndProc(HWND hwnd, LPARAM lParam)
struct tagCOUNTMENUWND * PCOUNTMENUWND
@ AUTO_RIGHT_CLICK
@ AUTO_LEFT_DOUBLE_CLICK
@ AUTO_RIGHT_DOUBLE_CLICK
@ AUTO_LEFT_CLICK
#define CLASSNAME
static VOID TEST_InvalidSize(VOID)
struct tagCOUNTMENUWND COUNTMENUWND
static INT CountMenuWnds(VOID)
enum tagAUTO_KEY AUTO_KEY
#define DELAY
#define MENUCLASS
static VOID TEST_InvalidFlags(VOID)
static VOID AutoClick(AUTO_CLICK type, INT x, INT y)
static VOID AutoKey(AUTO_KEY type, UINT vKey)
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static VOID TEST_Tracking(VOID)
@ AUTO_KEY_DOWN_UP
@ AUTO_KEY_DOWN
@ AUTO_KEY_UP
#define TPM_WORKAREA
enum tagAUTO_CLICK AUTO_CLICK
#define INTERVAL
static DWORD WINAPI TEST_Tracking_ThreadFunc(LPVOID arg)
static VOID OnRButtonDown(HWND hwnd)
#define VALID_TPM_FLAGS
static POINT CenterPoint(const RECT *prc)
Arabic default style
Definition: afstyles.h:94
#define skip(...)
Definition: atltest.h:64
#define ok_err(error)
Definition: atltest.h:124
#define START_TEST(x)
Definition: atltest.h:75
#define ok_int(expression, result)
Definition: atltest.h:134
#define msg(x)
Definition: auth_time.c:54
#define UlongToHandle(ul)
Definition: basetsd.h:97
HINSTANCE hInstance
Definition: charmap.c:19
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT uFlags
Definition: api.c:59
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
HANDLE HWND
Definition: compat.h:19
#define CALLBACK
Definition: compat.h:35
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
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:137
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4265
#define CHAR_BIT
Definition: urlcache.c:62
#define pt(x, y)
Definition: drawing.c:79
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLenum GLenum input
Definition: glext.h:9031
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
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
unsigned int UINT
Definition: ndis.h:50
HANDLE hThread
Definition: wizard.c:28
#define DWORD
Definition: nt_native.h:44
_Out_ LPRECT prc
Definition: ntgdi.h:1658
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
long LONG
Definition: pedump.c:60
#define INT
Definition: polytest.cpp:20
#define _countof(array)
Definition: sndvol32.h:70
LPCWSTR lpszClassName
Definition: winuser.h:3261
HBRUSH hbrBackground
Definition: winuser.h:3259
HICON hIcon
Definition: winuser.h:3257
HINSTANCE hInstance
Definition: winuser.h:3256
HCURSOR hCursor
Definition: winuser.h:3258
INT nMenuCount
Definition: MenuUI.c:137
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT
Definition: typedefs.h:58
VERSIONHELPERAPI IsWindows7OrGreater()
UINT WINAPI SendInput(UINT, LPINPUT, int)
Definition: ntwrapper.h:344
#define INPUT_KEYBOARD
Definition: winable.h:10
#define INPUT_MOUSE
Definition: winable.h:9
#define ZeroMemory
Definition: winbase.h:1753
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
#define SW_SHOWNORMAL
Definition: winuser.h:781
#define MOUSEEVENTF_ABSOLUTE
Definition: winuser.h:1205
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
#define WM_CLOSE
Definition: winuser.h:1640
BOOL WINAPI TranslateMessage(_In_ const MSG *)
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define SM_CYSCREEN
Definition: winuser.h:971
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define MOUSEEVENTF_LEFTUP
Definition: winuser.h:1196
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define TPM_RIGHTBUTTON
Definition: winuser.h:2399
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define WM_CREATE
Definition: winuser.h:1627
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define MF_STRING
Definition: winuser.h:138
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define IDC_ARROW
Definition: winuser.h:695
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:3032
#define MOUSEEVENTF_RIGHTUP
Definition: winuser.h:1198
BOOL WINAPI TrackPopupMenuEx(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _In_ HWND, _In_opt_ LPTPMPARAMS)
#define IDI_APPLICATION
Definition: winuser.h:712
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
#define WM_RBUTTONDOWN
Definition: winuser.h:1798
#define MOUSEEVENTF_MOVE
Definition: winuser.h:1194
#define MOUSEEVENTF_LEFTDOWN
Definition: winuser.h:1195
#define VK_RETURN
Definition: winuser.h:2220
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)
#define LoadIcon
Definition: winuser.h:5898
BOOL WINAPI UpdateWindow(_In_ HWND)
#define LoadCursor
Definition: winuser.h:5897
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4392
BOOL WINAPI DestroyMenu(_In_ HMENU)
int WINAPI GetClassNameW(_In_ HWND hWnd, _Out_writes_to_(nMaxCount, return) LPWSTR lpClassName, _In_ int nMaxCount)
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
#define VK_DOWN
Definition: winuser.h:2246
#define MOUSEEVENTF_RIGHTDOWN
Definition: winuser.h:1197
#define WM_DESTROY
Definition: winuser.h:1628
#define SM_CXSCREEN
Definition: winuser.h:970
#define TPM_RETURNCMD
Definition: winuser.h:2406
BOOL WINAPI IsWindowVisible(_In_ HWND)
BOOL WINAPI DestroyWindow(_In_ HWND)
int WINAPI GetSystemMetrics(_In_ int)
#define KEYEVENTF_KEYUP
Definition: winuser.h:1113
BOOL WINAPI AppendMenuW(_In_ HMENU, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCWSTR)
#define COLOR_3DFACE
Definition: winuser.h:940
__wchar_t WCHAR
Definition: xmlstorage.h:180