NativeMessageBox::showAsync issue with more than 3 buttons

consider this scenario:
I need 4 buttons in the alert
Action 1
Action 2
Action 3
Cancel

Code example:

auto options = juce::MessageBoxOptions()
.withIconType(juce::MessageBoxIconType::QuestionIcon)
.withTitle(“test”)
.withMessage(“msg”)
.withButton(“btn1”) // return 0
.withButton(“btn2”) // return 1
.withButton(“btn3”) // return 2 - close button (X) also returns 2
.withButton(“canc”); // return 3

juce::NativeMessageBox::showAsync(options, [&](int res)
{
auto test = res;
});

The Windows API returns 2 when the window is closed via the X in the top right, resulting in the “btn3” action being performed instead of “cancel.”

This is defined in WinUser.h:
#define IDCANCEL 2

However, you could modify the way the buttonLabels indices are populated in juce_NativeMessageBox_windows.cpp with something like this:

            std::vector<String> buttonStrings;
            std::vector<TASKDIALOG_BUTTON> buttonLabels;
            const int offsetIndex = 1000;

            for (auto i = 0; i < options.getNumButtons(); ++i)
                if (const auto buttonText = options.getButtonText (i); buttonText.isNotEmpty())
                    buttonLabels.push_back ({ (int) buttonLabels.size() + offsetIndex, buttonStrings.emplace_back (buttonText).toWideCharPointer() });

            config.pButtons = buttonLabels.data();
            config.cButtons = (UINT) buttonLabels.size();

            int buttonIndex = 0;
            TaskDialogIndirect (&config, &buttonIndex, nullptr, nullptr);

            if (buttonIndex >= offsetIndex)
                buttonIndex -= offsetIndex;

            return buttonIndex;

If index 2 is skipped, the Windows API no longer shows the closing X.
It could be an additional property set to prevent the closing X from showing.