WinRT: Fix native MessageBox not closing

The message box buttons need to be added inside the XAML thread.
Otherwise QWinRTMessageDialogHelper::onCompleted will not be triggered.

To successfully emit the clicked signal across different threads do not
exit the eventloop.

Change-Id: Ie884bdfe0dc64132559755083dae50c2aa43d80b
Task-number: QTBUG-48209
Reviewed-by: Oliver Wolff <oliver.wolff@theqtcompany.com>
This commit is contained in:
Maurice Kalinowski 2015-09-21 20:40:13 +02:00
parent 676edc006e
commit 72d0c62d14

View File

@ -133,45 +133,46 @@ bool QWinRTMessageDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModa
RETURN_FALSE_IF_FAILED("Failed to create dialog");
}
// Add Buttons
ComPtr<IVector<IUICommand *>> dialogCommands;
hr = dialog->get_Commands(&dialogCommands);
RETURN_FALSE_IF_FAILED("Failed to get dialog commands");
// If no button is specified we need to create one to get close notification
int buttons = options->standardButtons();
if (buttons == 0)
buttons = Ok;
for (int i = FirstButton; i < LastButton; i<<=1) {
if (!(buttons & i))
continue;
// Add native command
const QString label = d->theme->standardButtonText(i);
HStringReference nativeLabel(reinterpret_cast<LPCWSTR>(label.utf16()), label.size());
ComPtr<IUICommand> command;
hr = commandFactory->Create(nativeLabel.Get(), &command);
RETURN_FALSE_IF_FAILED("Failed to create message box command");
ComPtr<IInspectable> id = Make<CommandId>(static_cast<StandardButton>(i));
hr = command->put_Id(id.Get());
RETURN_FALSE_IF_FAILED("Failed to set command ID");
hr = dialogCommands->Append(command.Get());
if (hr == E_BOUNDS) {
qErrnoWarning(hr, "The WinRT message dialog supports a maximum of three buttons");
continue;
}
RETURN_FALSE_IF_FAILED("Failed to append message box command");
if (i == Abort || i == Cancel || i == Close) {
quint32 size;
hr = dialogCommands->get_Size(&size);
RETURN_FALSE_IF_FAILED("Failed to get command list size");
hr = dialog->put_CancelCommandIndex(size - 1);
RETURN_FALSE_IF_FAILED("Failed to set cancel index");
}
}
hr = QEventDispatcherWinRT::runOnXamlThread([this, d, dialog]() {
hr = QEventDispatcherWinRT::runOnXamlThread([this, d, options, commandFactory, dialog]() {
HRESULT hr;
// Add Buttons
ComPtr<IVector<IUICommand *>> dialogCommands;
hr = dialog->get_Commands(&dialogCommands);
RETURN_HR_IF_FAILED("Failed to get dialog commands");
// If no button is specified we need to create one to get close notification
int buttons = options->standardButtons();
if (buttons == 0)
buttons = Ok;
for (int i = FirstButton; i < LastButton; i<<=1) {
if (!(buttons & i))
continue;
// Add native command
const QString label = d->theme->standardButtonText(i);
HStringReference nativeLabel(reinterpret_cast<LPCWSTR>(label.utf16()), label.size());
ComPtr<IUICommand> command;
hr = commandFactory->Create(nativeLabel.Get(), &command);
RETURN_HR_IF_FAILED("Failed to create message box command");
ComPtr<IInspectable> id = Make<CommandId>(static_cast<StandardButton>(i));
hr = command->put_Id(id.Get());
RETURN_HR_IF_FAILED("Failed to set command ID");
hr = dialogCommands->Append(command.Get());
if (hr == E_BOUNDS) {
qErrnoWarning(hr, "The WinRT message dialog supports a maximum of three buttons");
continue;
}
RETURN_HR_IF_FAILED("Failed to append message box command");
if (i == Abort || i == Cancel || i == Close) {
quint32 size;
hr = dialogCommands->get_Size(&size);
RETURN_HR_IF_FAILED("Failed to get command list size");
hr = dialog->put_CancelCommandIndex(size - 1);
RETURN_HR_IF_FAILED("Failed to set cancel index");
}
}
ComPtr<IAsyncOperation<IUICommand *>> op;
hr = dialog->ShowAsync(&op);
RETURN_HR_IF_FAILED("Failed to show dialog");
@ -206,8 +207,7 @@ HRESULT QWinRTMessageDialogHelper::onCompleted(IAsyncOperation<IUICommand *> *as
Q_UNUSED(status);
Q_D(QWinRTMessageDialogHelper);
if (d->loop.isRunning())
d->loop.exit();
QEventLoopLocker locker(&d->loop);
d->shown = false;