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.
