[ROSTESTS] Add a test for the MB_SERVICE_NOTIFICATION flag of the MessageBox*() APIs.
[reactos.git] / modules / rostests / win32 / user32 / messagebox / messagebox.c
1 /*
2 * PROJECT: ReactOS Tests
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Tests the undocumented user32.dll API SoftModalMessageBox()
5 * and the MB_SERVICE_NOTIFICATION flag of the MessageBox*() APIs.
6 * COPYRIGHT: Copyright 2018 Hermes Belusca-Maito
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <conio.h>
12
13 #include <windef.h>
14 #include <winbase.h>
15 #include <winuser.h>
16
17 #include "resource.h"
18
19 /* Adjust according to your platform! -- ReactOS is currently compatible with Windows Server 2003 */
20 #undef _WIN32_WINNT
21 #define _WIN32_WINNT _WIN32_WINNT_WS03 // _WIN32_WINNT_WIN2K // _WIN32_WINNT_WS03 // _WIN32_WINNT_WIN7
22
23 typedef struct _MSGBOXDATA
24 {
25 MSGBOXPARAMSW mbp; // Size: 0x28 (x86), 0x50 (x64)
26 HWND hwndOwner; // Will be converted to PWND
27 #if defined(_WIN32) && (_WIN32_WINNT >= _WIN32_WINNT_WIN7) /* (NTDDI_VERSION >= NTDDI_WIN7) */
28 DWORD dwPadding;
29 #endif
30 WORD wLanguageId;
31 INT* pidButton; // Array of button IDs
32 LPCWSTR* ppszButtonText; // Array of button text strings
33 DWORD dwButtons; // Number of buttons
34 UINT uDefButton; // Default button ID
35 UINT uCancelId; // Button ID corresponding to Cancel action
36 #if (_WIN32_WINNT >= _WIN32_WINNT_WINXP) /* (NTDDI_VERSION >= NTDDI_WINXP) */
37 DWORD dwTimeout; // Message box timeout
38 #endif
39 DWORD dwReserved0;
40 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN7) /* (NTDDI_VERSION >= NTDDI_WIN7) */
41 DWORD dwReserved[4];
42 #endif
43 } MSGBOXDATA, *PMSGBOXDATA, *LPMSGBOXDATA;
44
45
46 #if defined(_WIN64)
47
48 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN7) /* (NTDDI_VERSION >= NTDDI_WIN7) */
49 C_ASSERT(sizeof(MSGBOXDATA) == 0x98);
50 #elif (_WIN32_WINNT <= _WIN32_WINNT_WS03) /* (NTDDI_VERSION == NTDDI_WS03) */
51 C_ASSERT(sizeof(MSGBOXDATA) == 0x88);
52 #endif
53
54 #else
55
56 #if (_WIN32_WINNT <= _WIN32_WINNT_WIN2K) /* (NTDDI_VERSION <= NTDDI_WIN2KSP4) */
57 C_ASSERT(sizeof(MSGBOXDATA) == 0x48);
58 #elif (_WIN32_WINNT >= _WIN32_WINNT_WIN7) /* (NTDDI_VERSION >= NTDDI_WIN7) */
59 C_ASSERT(sizeof(MSGBOXDATA) == 0x60);
60 #else // (_WIN32_WINNT == _WIN32_WINNT_WINXP || _WIN32_WINNT == _WIN32_WINNT_WS03) /* (NTDDI_VERSION == NTDDI_WS03) */
61 C_ASSERT(sizeof(MSGBOXDATA) == 0x4C);
62 #endif
63
64 #endif
65
66
67 //
68 // Example taken from http://rsdn.org/forum/winapi/3273168.1
69 // See also http://www.vbforums.com/showthread.php?840593-Message-Box-with-Four-Buttons
70 //
71 void TestSoftModalMsgBox(void)
72 {
73 typedef int (WINAPI *SOFTMODALMESSAGEBOX)(LPMSGBOXDATA lpMsgBoxData);
74 // int WINAPI SoftModalMessageBox(IN LPMSGBOXDATA lpMsgBoxData);
75 SOFTMODALMESSAGEBOX SoftModalMessageBox = NULL;
76
77 MSGBOXDATA data;
78 int res = 0;
79
80 INT pids[] =
81 {
82 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 /*, 2*/
83 };
84 /* NOTE: Buttons do NOT support resource IDs specifications! */
85 LPCWSTR ppText[] =
86 {
87 L"Button 1", L"Button 2", L"Button 3", L"Button 4", L"Button 5", L"Button 6", L"Button 7", L"Button 8", L"Button 9", L"Button 10", L"Button 11", L"Button 12", L"Button 13"
88 };
89
90 ZeroMemory(&data, sizeof(data));
91 data.mbp.cbSize = sizeof(data.mbp);
92 data.mbp.hwndOwner = FindWindowW(L"Shell_TrayWnd", NULL);
93 data.mbp.hInstance = GetModuleHandleW(NULL);
94 data.mbp.lpszText = L"This is a message box made using the undocumented SoftModalMessageBox() API.";
95 data.mbp.lpszCaption = MAKEINTRESOURCEW(IDS_RES_CAPTION); // L"SoftModalMessageBox";
96 data.mbp.lpfnMsgBoxCallback = NULL; // SoftModalMessageBoxCallback;
97 data.mbp.dwStyle = MB_ICONINFORMATION | MB_RETRYCANCEL;
98
99 data.wLanguageId = 0;
100 data.pidButton = pids;
101 data.ppszButtonText = ppText;
102 data.dwButtons = _countof(pids);
103 data.uDefButton = 2;
104 data.uCancelId = 0;
105 #if (_WIN32_WINNT >= _WIN32_WINNT_WINXP) /* (NTDDI_VERSION >= NTDDI_WINXP) */
106 data.dwTimeout = 3 * 1000;
107 #endif
108
109 SoftModalMessageBox = (SOFTMODALMESSAGEBOX)GetProcAddress(GetModuleHandleW(L"user32.dll"), "SoftModalMessageBox");
110 if (!SoftModalMessageBox)
111 {
112 printf("SoftModalMessageBoxW not found in user32.dll\n");
113 }
114 else
115 {
116 res = SoftModalMessageBox(&data);
117 printf("Returned value = %i\n", res);
118 }
119 }
120
121 void TestMsgBoxServiceNotification(void)
122 {
123 int res;
124
125 res = MessageBoxW(NULL, L"Hello World!", L"MB_SERVICE_NOTIFICATION",
126 MB_YESNOCANCEL | MB_DEFBUTTON3 | MB_ICONINFORMATION | /* MB_DEFAULT_DESKTOP_ONLY | */ MB_SERVICE_NOTIFICATION);
127 printf("Returned value = %i\n", res);
128 }
129
130 int wmain(int argc, WCHAR* argv[])
131 {
132 printf("Testing SoftModalMessageBox()...\n");
133 TestSoftModalMsgBox();
134 printf("\n");
135
136 printf("Press any key to continue...\n");
137 _getch();
138 printf("\n");
139
140 printf("Testing MB_SERVICE_NOTIFICATION...\n");
141 TestMsgBoxServiceNotification();
142 printf("\n");
143
144 printf("Press any key to quit...\n");
145 _getch();
146 return 0;
147 }