/// <include file='doc\ThreadExceptionDialog.uex' path='docs/doc[@for="ThreadExceptionDialog.ThreadExceptionDialog"]/*' /> /// <devdoc> /// <para> /// Initializes a new instance of the <see cref='System.Windows.Forms.ThreadExceptionDialog'/> class. /// /// </para> /// </devdoc> public ThreadExceptionDialog(Exception t) { if (DpiHelper.EnableThreadExceptionDialogHighDpiImprovements) { scaledMaxWidth = DpiHelper.LogicalToDeviceUnitsX(MAXWIDTH); scaledMaxHeight = DpiHelper.LogicalToDeviceUnitsY(MAXHEIGHT); scaledPaddingWidth = DpiHelper.LogicalToDeviceUnitsX(PADDINGWIDTH); scaledPaddingHeight = DpiHelper.LogicalToDeviceUnitsY(PADDINGHEIGHT); scaledMaxTextWidth = DpiHelper.LogicalToDeviceUnitsX(MAXTEXTWIDTH); scaledMaxTextHeight = DpiHelper.LogicalToDeviceUnitsY(MAXTEXTHEIGHT); scaledButtonTopPadding = DpiHelper.LogicalToDeviceUnitsY(BUTTONTOPPADDING); scaledButtonDetailsLeftPadding = DpiHelper.LogicalToDeviceUnitsX(BUTTONDETAILS_LEFTPADDING); scaledMessageTopPadding = DpiHelper.LogicalToDeviceUnitsY(MESSAGE_TOPPADDING); scaledHeightPadding = DpiHelper.LogicalToDeviceUnitsY(HEIGHTPADDING); scaledButtonWidth = DpiHelper.LogicalToDeviceUnitsX(BUTTONWIDTH); scaledButtonHeight = DpiHelper.LogicalToDeviceUnitsY(BUTTONHEIGHT); scaledButtonAlignmentWidth = DpiHelper.LogicalToDeviceUnitsX(BUTTONALIGNMENTWIDTH); scaledButtonAlignmentPadding = DpiHelper.LogicalToDeviceUnitsX(BUTTONALIGNMENTPADDING); scaledDetailsWidthPadding = DpiHelper.LogicalToDeviceUnitsX(DETAILSWIDTHPADDING); scaledDetailsHeight = DpiHelper.LogicalToDeviceUnitsY(DETAILSHEIGHT); scaledPictureWidth = DpiHelper.LogicalToDeviceUnitsX(PICTUREWIDTH); scaledPictureHeight = DpiHelper.LogicalToDeviceUnitsY(PICTUREHEIGHT); scaledExceptionMessageVerticalPadding = DpiHelper.LogicalToDeviceUnitsY(EXCEPTIONMESSAGEVERTICALPADDING); } string messageRes; string messageText; Button[] buttons; bool detailAnchor = false; WarningException w = t as WarningException; if (w != null) { messageRes = SR.ExDlgWarningText; messageText = w.Message; if (w.HelpUrl == null) { buttons = new Button[] { continueButton }; } else { buttons = new Button[] { continueButton, helpButton }; } } else { messageText = t.Message; detailAnchor = true; if (Application.AllowQuit) { if (t is SecurityException) { messageRes = "ExDlgSecurityErrorText"; } else { messageRes = "ExDlgErrorText"; } buttons = new Button[] { detailsButton, continueButton, quitButton }; } else { if (t is SecurityException) { messageRes = "ExDlgSecurityContinueErrorText"; } else { messageRes = "ExDlgContinueErrorText"; } buttons = new Button[] { detailsButton, continueButton }; } } if (messageText.Length == 0) { messageText = t.GetType().Name; } if (t is SecurityException) { messageText = SR.GetString(messageRes, t.GetType().Name, Trim(messageText)); } else { messageText = SR.GetString(messageRes, Trim(messageText)); } StringBuilder detailsTextBuilder = new StringBuilder(); string newline = "\r\n"; string separator = SR.GetString(SR.ExDlgMsgSeperator); string sectionseparator = SR.GetString(SR.ExDlgMsgSectionSeperator); if (Application.CustomThreadExceptionHandlerAttached) { detailsTextBuilder.Append(SR.GetString(SR.ExDlgMsgHeaderNonSwitchable)); } else { detailsTextBuilder.Append(SR.GetString(SR.ExDlgMsgHeaderSwitchable)); } detailsTextBuilder.Append(string.Format(CultureInfo.CurrentCulture, sectionseparator, SR.GetString(SR.ExDlgMsgExceptionSection))); detailsTextBuilder.Append(t.ToString()); detailsTextBuilder.Append(newline); detailsTextBuilder.Append(newline); detailsTextBuilder.Append(string.Format(CultureInfo.CurrentCulture, sectionseparator, SR.GetString(SR.ExDlgMsgLoadedAssembliesSection))); new FileIOPermission(PermissionState.Unrestricted).Assert(); try { foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { AssemblyName name = asm.GetName(); string fileVer = SR.GetString(SR.NotAvailable); try { // bug 113573 -- if there's a path with an escaped value in it // like c:\temp\foo%2fbar, the AssemblyName call will unescape it to // c:\temp\foo\bar, which is wrong, and this will fail. It doesn't look like the // assembly name class handles this properly -- even the "CodeBase" property is un-escaped // so we can't circumvent this. // if (name.EscapedCodeBase != null && name.EscapedCodeBase.Length > 0) { Uri codeBase = new Uri(name.EscapedCodeBase); if (codeBase.Scheme == "file") { fileVer = FileVersionInfo.GetVersionInfo(NativeMethods.GetLocalPath(name.EscapedCodeBase)).FileVersion; } } } catch (System.IO.FileNotFoundException) { } detailsTextBuilder.Append(SR.GetString(SR.ExDlgMsgLoadedAssembliesEntry, name.Name, name.Version, fileVer, name.EscapedCodeBase)); detailsTextBuilder.Append(separator); } } finally { CodeAccessPermission.RevertAssert(); } detailsTextBuilder.Append(string.Format(CultureInfo.CurrentCulture, sectionseparator, SR.GetString(SR.ExDlgMsgJITDebuggingSection))); if (Application.CustomThreadExceptionHandlerAttached) { detailsTextBuilder.Append(SR.GetString(SR.ExDlgMsgFooterNonSwitchable)); } else { detailsTextBuilder.Append(SR.GetString(SR.ExDlgMsgFooterSwitchable)); } detailsTextBuilder.Append(newline); detailsTextBuilder.Append(newline); string detailsText = detailsTextBuilder.ToString(); Graphics g = message.CreateGraphicsInternal(); Size textSize = new Size(scaledMaxWidth - scaledPaddingWidth, int.MaxValue); if (DpiHelper.EnableThreadExceptionDialogHighDpiImprovements && (Label.UseCompatibleTextRenderingDefault == false)) { // we need to measure string using API that matches the rendering engine - TextRenderer.MeasureText for GDI textSize = Size.Ceiling(TextRenderer.MeasureText(messageText, Font, textSize, TextFormatFlags.WordBreak)); } else { // if HighDpi improvements are not enabled, or rendering mode is GDI+, use Graphics.MeasureString textSize = Size.Ceiling(g.MeasureString(messageText, Font, textSize.Width)); } textSize.Height += scaledExceptionMessageVerticalPadding; g.Dispose(); if (textSize.Width < scaledMaxTextWidth) { textSize.Width = scaledMaxTextWidth; } if (textSize.Height > scaledMaxHeight) { textSize.Height = scaledMaxHeight; } int width = textSize.Width + scaledPaddingWidth; int buttonTop = Math.Max(textSize.Height, scaledMaxTextHeight) + scaledPaddingHeight; // SECREVIEW : We must get a hold of the parent to get at it's text // : to make this dialog look like the parent. // IntSecurity.GetParent.Assert(); try { Form activeForm = Form.ActiveForm; if (activeForm == null || activeForm.Text.Length == 0) { Text = SR.GetString(SR.ExDlgCaption); } else { Text = SR.GetString(SR.ExDlgCaption2, activeForm.Text); } } finally { CodeAccessPermission.RevertAssert(); } AcceptButton = continueButton; CancelButton = continueButton; FormBorderStyle = FormBorderStyle.FixedDialog; MaximizeBox = false; MinimizeBox = false; StartPosition = FormStartPosition.CenterScreen; Icon = null; ClientSize = new Size(width, buttonTop + scaledButtonTopPadding); TopMost = true; pictureBox.Location = new Point(0, 0); pictureBox.Size = new Size(scaledPictureWidth, scaledPictureHeight); pictureBox.SizeMode = PictureBoxSizeMode.CenterImage; if (t is SecurityException) { pictureBox.Image = SystemIcons.Information.ToBitmap(); } else { pictureBox.Image = SystemIcons.Error.ToBitmap(); } Controls.Add(pictureBox); message.SetBounds(scaledPictureWidth, scaledMessageTopPadding + (scaledMaxTextHeight - Math.Min(textSize.Height, scaledMaxTextHeight)) / 2, textSize.Width, textSize.Height); message.Text = messageText; Controls.Add(message); continueButton.Text = SR.GetString(SR.ExDlgContinue); continueButton.FlatStyle = FlatStyle.Standard; continueButton.DialogResult = DialogResult.Cancel; quitButton.Text = SR.GetString(SR.ExDlgQuit); quitButton.FlatStyle = FlatStyle.Standard; quitButton.DialogResult = DialogResult.Abort; helpButton.Text = SR.GetString(SR.ExDlgHelp); helpButton.FlatStyle = FlatStyle.Standard; helpButton.DialogResult = DialogResult.Yes; detailsButton.Text = SR.GetString(SR.ExDlgShowDetails); detailsButton.FlatStyle = FlatStyle.Standard; detailsButton.Click += new EventHandler(DetailsClick); Button b = null; int startIndex = 0; if (detailAnchor) { b = detailsButton; expandImage = new Bitmap(this.GetType(), "down.bmp"); expandImage.MakeTransparent(); collapseImage = new Bitmap(this.GetType(), "up.bmp"); collapseImage.MakeTransparent(); if (DpiHelper.EnableThreadExceptionDialogHighDpiImprovements) { DpiHelper.ScaleBitmapLogicalToDevice(ref expandImage); DpiHelper.ScaleBitmapLogicalToDevice(ref collapseImage); } b.SetBounds(scaledButtonDetailsLeftPadding, buttonTop, scaledButtonWidth, scaledButtonHeight); b.Image = expandImage; b.ImageAlign = ContentAlignment.MiddleLeft; Controls.Add(b); startIndex = 1; } int buttonLeft = (width - scaledButtonDetailsLeftPadding - ((buttons.Length - startIndex) * scaledButtonAlignmentWidth - scaledButtonAlignmentPadding)); for (int i = startIndex; i < buttons.Length; i++) { b = buttons[i]; b.SetBounds(buttonLeft, buttonTop, scaledButtonWidth, scaledButtonHeight); Controls.Add(b); buttonLeft += scaledButtonAlignmentWidth; } details.Text = detailsText; details.ScrollBars = ScrollBars.Both; details.Multiline = true; details.ReadOnly = true; details.WordWrap = false; details.TabStop = false; details.AcceptsReturn = false; details.SetBounds(scaledButtonDetailsLeftPadding, buttonTop + scaledButtonTopPadding, width - scaledDetailsWidthPadding, scaledDetailsHeight); Controls.Add(details); }