예제 #1
0
        private void ShowErrorDialogWithHelp(
            IWin32Window parent,
            string caption,
            string message,
            string details,
            IHelpTopic helpTopic)
        {
            Debug.Assert(!(parent is Control) || !((Control)parent).InvokeRequired);

            using (ApplicationTraceSources.Default.TraceMethod().WithParameters(caption, message, details))
            {
                var config = new UnsafeNativeMethods.TASKDIALOGCONFIG()
                {
                    cbSize                 = (uint)Marshal.SizeOf(typeof(UnsafeNativeMethods.TASKDIALOGCONFIG)),
                    hwndParent             = parent?.Handle ?? IntPtr.Zero,
                    dwFlags                = 0,
                    dwCommonButtons        = UnsafeNativeMethods.TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_OK_BUTTON,
                    pszWindowTitle         = "An error occured",
                    MainIcon               = TaskDialogIcons.TD_ERROR_ICON,
                    pszMainInstruction     = caption,
                    pszContent             = message,
                    pszExpandedInformation = details.ToString()
                };

                if (helpTopic != null)
                {
                    //
                    // Add hyperlinked footer text.
                    //

                    config.FooterIcon = TaskDialogIcons.TD_INFORMATION_ICON;
                    config.dwFlags   |= UnsafeNativeMethods.TASKDIALOG_FLAGS.TDF_EXPAND_FOOTER_AREA |
                                        UnsafeNativeMethods.TASKDIALOG_FLAGS.TDF_ENABLE_HYPERLINKS;
                    config.pszFooter  = $"For more information, see <A HREF=\"#\">{helpTopic.Title}</A>";
                    config.pfCallback = (hwnd, notification, wParam, lParam, refData) =>
                    {
                        if (notification == UnsafeNativeMethods.TASKDIALOG_NOTIFICATIONS.TDN_HYPERLINK_CLICKED)
                        {
                            this.serviceProvider.GetService <HelpService>().OpenTopic(helpTopic);
                        }

                        return(0); // S_OK;
                    };
                }

                UnsafeNativeMethods.TaskDialogIndirect(
                    ref config,
                    out int buttonPressed,
                    out int radioButtonPressed,
                    out bool verificationFlagPressed);
            }
        }
예제 #2
0
        public int ShowOptionsTaskDialog(
            IWin32Window parent,
            IntPtr mainIcon,
            string windowTitle,
            string mainInstruction,
            string content,
            string details,
            IList <string> optionCaptions,
            string verificationText,
            out bool verificationFlagPressed)
        {
            // The options to show.
            var options = optionCaptions
                          .Select(caption => Marshal.StringToHGlobalUni(caption))
                          .ToArray();

            // Wrap each option by a TASKDIALOG_BUTTON_RAW structure and
            // marshal them one by one into a native memory buffer.
            var buttonsBuffer = Marshal.AllocHGlobal(
                Marshal.SizeOf <UnsafeNativeMethods.TASKDIALOG_BUTTON_RAW>() * options.Length);

            var currentButton = buttonsBuffer;

            for (int i = 0; i < options.Length; i++)
            {
                Marshal.StructureToPtr <UnsafeNativeMethods.TASKDIALOG_BUTTON_RAW>(
                    new UnsafeNativeMethods.TASKDIALOG_BUTTON_RAW()
                {
                    nButtonID     = ButtonIdOffset + i, // Add offset to avoid conflict with IDOK/IDCANCEL.
                    pszButtonText = options[i]
                },
                    currentButton,
                    false);
                currentButton += Marshal.SizeOf <UnsafeNativeMethods.TASKDIALOG_BUTTON_RAW>();
            }

            try
            {
                var config = new UnsafeNativeMethods.TASKDIALOGCONFIG()
                {
                    cbSize          = (uint)Marshal.SizeOf(typeof(UnsafeNativeMethods.TASKDIALOGCONFIG)),
                    hwndParent      = parent.Handle,
                    dwFlags         = UnsafeNativeMethods.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS,
                    dwCommonButtons = UnsafeNativeMethods.TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_OK_BUTTON |
                                      UnsafeNativeMethods.TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_CANCEL_BUTTON,
                    pszWindowTitle         = windowTitle,
                    MainIcon               = mainIcon,
                    pszMainInstruction     = mainInstruction,
                    pszContent             = content,
                    pButtons               = buttonsBuffer,
                    cButtons               = (uint)options.Length,
                    pszExpandedInformation = details,
                    pszVerificationText    = verificationText
                };

                UnsafeNativeMethods.TaskDialogIndirect(
                    ref config,
                    out int buttonPressed,
                    out int radioButtonPressed,
                    out verificationFlagPressed);

                if (buttonPressed == UnsafeNativeMethods.IDOK)
                {
                    // Pick first option.
                    return(0);
                }
                else if (buttonPressed >= ButtonIdOffset)
                {
                    // Option selected.
                    return(buttonPressed - ButtonIdOffset);
                }
                else
                {
                    throw new OperationCanceledException("Task dialog was cancelled");
                }
            }
            finally
            {
                foreach (var option in options)
                {
                    Marshal.FreeHGlobal(option);
                }

                Marshal.FreeHGlobal(buttonsBuffer);
            }
        }