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 } 148