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