private int PrivateShow(IntPtr hwndOwner, out bool verificationFlagChecked, out int radioButtonResult) { verificationFlagChecked = false; radioButtonResult = 0; int result; if (!TaskDialog.IsAvailable) { // Hand it off to emulator. _emulateTaskDialog = new EmulateTaskDialog(this); try { if (hwndOwner == IntPtr.Zero) { _emulateTaskDialog.ShowDialog(); } else { _emulateTaskDialog.ShowDialog(new WindowHandleWrapper(hwndOwner)); } verificationFlagChecked = _emulateTaskDialog.TaskDialogVerificationFlagChecked; radioButtonResult = _emulateTaskDialog.TaskDialogRadioButtonResult; result = _emulateTaskDialog.TaskDialogResult; } finally { _emulateTaskDialog.Dispose(); _emulateTaskDialog = null; } return(result); } NativeMethods.TASKDIALOGCONFIG config = new NativeMethods.TASKDIALOGCONFIG(); try { config.cbSize = (uint)Marshal.SizeOf(typeof(NativeMethods.TASKDIALOGCONFIG)); config.hwndParent = hwndOwner; config.dwFlags = _flags; config.dwCommonButtons = CommonButtons; config.pszWindowTitle = WindowTitle; config.MainIcon = (IntPtr)MainIcon; if (CustomMainIcon != null) { config.dwFlags |= NativeMethods.TASKDIALOG_FLAGS.TDF_USE_HICON_MAIN; config.MainIcon = CustomMainIcon.Handle; } if (!string.IsNullOrEmpty(MainInstruction)) { config.pszMainInstruction = MainInstruction; } if (!string.IsNullOrEmpty(Content)) { config.pszContent = Content; } TaskDialogButton[] customButtons = Buttons.ToArray(); if (customButtons.Length > 0) { // Hand marshal the buttons array. int elementSize = Marshal.SizeOf(typeof(TaskDialogButton)); config.pButtons = Marshal.AllocHGlobal(elementSize * customButtons.Length); for (int i = 0; i < customButtons.Length; i++) { Marshal.StructureToPtr(customButtons[i], (IntPtr)((long)config.pButtons + elementSize * i), false); config.cButtons++; } } TaskDialogButton[] customRadioButtons = RadioButtons.ToArray(); if (customRadioButtons.Length > 0) { // Hand marshal the buttons array. int elementSize = Marshal.SizeOf(typeof(TaskDialogButton)); config.pRadioButtons = Marshal.AllocHGlobal(elementSize * customRadioButtons.Length); for (int i = 0; i < customRadioButtons.Length; i++) { Marshal.StructureToPtr(customRadioButtons[i], (IntPtr)((long)config.pRadioButtons + (elementSize * i)), false); config.cRadioButtons++; } } config.nDefaultButton = DefaultButton; config.nDefaultRadioButton = DefaultRadioButton; if (!string.IsNullOrEmpty(VerificationText)) { config.pszVerificationText = VerificationText; } if (!string.IsNullOrEmpty(ExpandedInformation)) { config.pszExpandedInformation = ExpandedInformation; } if (!string.IsNullOrEmpty(ExpandedControlText)) { config.pszExpandedControlText = ExpandedControlText; } if (!string.IsNullOrEmpty(CollapsedControlText)) { config.pszCollapsedControlText = CollapsedControlText; } config.FooterIcon = (IntPtr)FooterIcon; if (CustomFooterIcon != null) { config.dwFlags |= NativeMethods.TASKDIALOG_FLAGS.TDF_USE_HICON_FOOTER; config.FooterIcon = CustomFooterIcon.Handle; } if (!string.IsNullOrEmpty(Footer)) { config.pszFooter = Footer; } // If our user has asked for a callback then we need to ask for one to // translate to the friendly version. if (Callback != null) { config.pfCallback = PrivateCallback; } config.cxWidth = Width; using (new ActivationContext()) { // The call all this mucking about is here for. NativeMethods.TaskDialogIndirect(ref config, out result, out radioButtonResult, out verificationFlagChecked); } } finally { // Free the unmanged memory needed for the button arrays. // There is the possiblity of leaking memory if the app-domain is destroyed in a non clean way // and the hosting OS process is kept alive but fixing this would require using hardening techniques // that are not required for the users of this class. if (config.pButtons != IntPtr.Zero) { int elementSize = Marshal.SizeOf(typeof(TaskDialogButton)); for (int i = 0; i < config.cButtons; i++) { Marshal.DestroyStructure((IntPtr)((long)config.pButtons + (elementSize * i)), typeof(TaskDialogButton)); } Marshal.FreeHGlobal(config.pButtons); } if (config.pRadioButtons != IntPtr.Zero) { int elementSize = Marshal.SizeOf(typeof(TaskDialogButton)); for (int i = 0; i < config.cRadioButtons; i++) { Marshal.DestroyStructure((IntPtr)((long)config.pRadioButtons + (elementSize * i)), typeof(TaskDialogButton)); } Marshal.FreeHGlobal(config.pRadioButtons); } } return(result); }