From 1008f6f2deeee26ebd3edea8611a74bd662faf0f Mon Sep 17 00:00:00 2001 From: Evan Dixon Date: Tue, 17 Jan 2017 18:21:14 -0600 Subject: [PATCH] Added ErrorWindow --- pk3DS/Misc/ErrorWindow.Designer.cs | 129 ++++++++++++++++++++++++++ pk3DS/Misc/ErrorWindow.cs | 139 +++++++++++++++++++++++++++++ pk3DS/Misc/ErrorWindow.resx | 120 +++++++++++++++++++++++++ pk3DS/Program.cs | 67 +++++++++++++- pk3DS/pk3DS.csproj | 11 +++ 5 files changed, 465 insertions(+), 1 deletion(-) create mode 100644 pk3DS/Misc/ErrorWindow.Designer.cs create mode 100644 pk3DS/Misc/ErrorWindow.cs create mode 100644 pk3DS/Misc/ErrorWindow.resx diff --git a/pk3DS/Misc/ErrorWindow.Designer.cs b/pk3DS/Misc/ErrorWindow.Designer.cs new file mode 100644 index 0000000..f759ab1 --- /dev/null +++ b/pk3DS/Misc/ErrorWindow.Designer.cs @@ -0,0 +1,129 @@ +namespace pk3DS +{ + partial class ErrorWindow + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.B_Continue = new System.Windows.Forms.Button(); + this.B_Abort = new System.Windows.Forms.Button(); + this.B_CopyToClipboard = new System.Windows.Forms.Button(); + this.L_ProvideInfo = new System.Windows.Forms.Label(); + this.L_Message = new System.Windows.Forms.Label(); + this.T_ExceptionDetails = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // B_Continue + // + this.B_Continue.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.B_Continue.Location = new System.Drawing.Point(332, 203); + this.B_Continue.Name = "B_Continue"; + this.B_Continue.Size = new System.Drawing.Size(75, 23); + this.B_Continue.TabIndex = 11; + this.B_Continue.Text = "Continue"; + this.B_Continue.UseVisualStyleBackColor = true; + // + // B_Abort + // + this.B_Abort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.B_Abort.Location = new System.Drawing.Point(413, 203); + this.B_Abort.Name = "B_Abort"; + this.B_Abort.Size = new System.Drawing.Size(75, 23); + this.B_Abort.TabIndex = 10; + this.B_Abort.Text = "Abort"; + this.B_Abort.UseVisualStyleBackColor = true; + // + // B_CopyToClipboard + // + this.B_CopyToClipboard.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.B_CopyToClipboard.Location = new System.Drawing.Point(13, 203); + this.B_CopyToClipboard.Name = "B_CopyToClipboard"; + this.B_CopyToClipboard.Size = new System.Drawing.Size(164, 23); + this.B_CopyToClipboard.TabIndex = 9; + this.B_CopyToClipboard.Text = "Copy to Clipboard"; + this.B_CopyToClipboard.UseVisualStyleBackColor = true; + // + // L_ProvideInfo + // + this.L_ProvideInfo.AutoSize = true; + this.L_ProvideInfo.Location = new System.Drawing.Point(10, 38); + this.L_ProvideInfo.Name = "L_ProvideInfo"; + this.L_ProvideInfo.Size = new System.Drawing.Size(269, 13); + this.L_ProvideInfo.TabIndex = 8; + this.L_ProvideInfo.Text = "Please provide this information when reporting this error:"; + // + // L_Message + // + this.L_Message.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.L_Message.Location = new System.Drawing.Point(10, 11); + this.L_Message.Name = "L_Message"; + this.L_Message.Size = new System.Drawing.Size(478, 27); + this.L_Message.TabIndex = 7; + this.L_Message.Text = "An unknown error has occurred."; + // + // T_ExceptionDetails + // + this.T_ExceptionDetails.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.T_ExceptionDetails.Location = new System.Drawing.Point(13, 54); + this.T_ExceptionDetails.Multiline = true; + this.T_ExceptionDetails.Name = "T_ExceptionDetails"; + this.T_ExceptionDetails.ReadOnly = true; + this.T_ExceptionDetails.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.T_ExceptionDetails.Size = new System.Drawing.Size(475, 143); + this.T_ExceptionDetails.TabIndex = 6; + // + // ErrorWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(499, 236); + this.Controls.Add(this.B_Continue); + this.Controls.Add(this.B_Abort); + this.Controls.Add(this.B_CopyToClipboard); + this.Controls.Add(this.L_ProvideInfo); + this.Controls.Add(this.L_Message); + this.Controls.Add(this.T_ExceptionDetails); + this.MinimumSize = new System.Drawing.Size(515, 275); + this.Name = "ErrorWindow"; + this.Text = "Error"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button B_Continue; + private System.Windows.Forms.Button B_Abort; + private System.Windows.Forms.Button B_CopyToClipboard; + private System.Windows.Forms.Label L_ProvideInfo; + private System.Windows.Forms.Label L_Message; + private System.Windows.Forms.TextBox T_ExceptionDetails; + } +} \ No newline at end of file diff --git a/pk3DS/Misc/ErrorWindow.cs b/pk3DS/Misc/ErrorWindow.cs new file mode 100644 index 0000000..b4c51e7 --- /dev/null +++ b/pk3DS/Misc/ErrorWindow.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace pk3DS +{ + public partial class ErrorWindow : Form + { + public static DialogResult ShowErrorDialog(string friendlyMessage, Exception ex, bool allowContinue) + { + var lang = System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName; + var dialog = new ErrorWindow(lang) + { + ShowContinue = allowContinue, + Message = friendlyMessage, + Error = ex + }; + var dialogResult = dialog.ShowDialog(); + if (dialogResult == DialogResult.Abort) + { + Environment.Exit(1); + } + return dialogResult; + } + + public ErrorWindow() + { + InitializeComponent(); + } + + public ErrorWindow(string lang) : this() + { + Util.TranslateInterface(this, lang); + } + + /// + /// Gets or sets whether or not the "Continue" button is visible. + /// + /// For UI exceptions, continuing could be safe. + /// For application exceptions, continuing is not possible, so the button should not be shown. + public bool ShowContinue + { + get + { + return B_Continue.Visible; + } + set + { + B_Continue.Visible = value; + } + } + + /// + /// Friendly, context-specific method shown to the user. + /// + /// This property is intended to be a user-friendly context-specific message about what went wrong. + /// For example: "An error occurred while attempting to automatically load the save file." + public string Message + { + get + { + return L_Message.Text; + } + set + { + L_Message.Text = value; + } + } + + public Exception Error + { + get + { + return _error; + } + set + { + _error = value; + UpdateExceptionDetailsMessage(); + } + } + private Exception _error; + + private void UpdateExceptionDetailsMessage() + { + var details = new StringBuilder(); + details.AppendLine("Exception Details:"); + details.AppendLine(Error.ToString()); + details.AppendLine(); + + details.AppendLine("Loaded Assemblies:"); + details.AppendLine("--------------------"); + try + { + foreach (var item in AppDomain.CurrentDomain.GetAssemblies()) + { + details.AppendLine(item.FullName); + details.AppendLine(item.Location); + details.AppendLine(); + } + } + catch (Exception ex) + { + details.AppendLine("An error occurred while listing the Loaded Assemblies:"); + details.AppendLine(ex.ToString()); + } + details.AppendLine("--------------------"); + + // Include message in case it contains important information, like a file path. + details.AppendLine("User Message:"); + details.AppendLine(Message); + + T_ExceptionDetails.Text = details.ToString(); + } + + private void btnCopyToClipboard_Click(object sender, EventArgs e) + { + Clipboard.SetText(T_ExceptionDetails.Text); + } + + private void B_Continue_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.OK; + Close(); + } + + private void B_Abort_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Abort; + Close(); + } + + } +} diff --git a/pk3DS/Misc/ErrorWindow.resx b/pk3DS/Misc/ErrorWindow.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/pk3DS/Misc/ErrorWindow.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/pk3DS/Program.cs b/pk3DS/Program.cs index b916c18..12bc7c3 100644 --- a/pk3DS/Program.cs +++ b/pk3DS/Program.cs @@ -1,19 +1,84 @@ using System; +using System.Threading; using System.Windows.Forms; namespace pk3DS { static class Program { + /// /// The main entry point for the application. /// [STAThread] - static void Main() + private static void Main() { + // Add the event handler for handling UI thread exceptions to the event. + Application.ThreadException += UIThreadException; + + // Set the unhandled exception mode to force all Windows Forms errors to go through our handler. + Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); + + // Add the event handler for handling non-UI thread exceptions to the event. + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + + // Run the application Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Main()); } + + // Handle the UI exceptions by showing a dialog box, and asking the user whether or not they wish to abort execution. + private static void UIThreadException(object sender, ThreadExceptionEventArgs t) + { + DialogResult result = DialogResult.Cancel; + try + { + // Todo: make this translatable + ErrorWindow.ShowErrorDialog("An unhandled exception has occurred.\nYou can continue running the program (albeit with potential side-effects), but please report this error.", t.Exception, true); + } + catch + { + try + { + // Todo: make this translatable + MessageBox.Show("A fatal error has occurred in PKHeX, and the details could not be displayed. Please report this to the author.", "PKHeX Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); + } + finally + { + Application.Exit(); + } + } + + // Exits the program when the user clicks Abort. + if (result == DialogResult.Abort) + Application.Exit(); + } + + // Handle the UI exceptions by showing a dialog box, and asking the user whether + // or not they wish to abort execution. + // NOTE: This exception cannot be kept from terminating the application - it can only + // log the event, and inform the user about it. + private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + try + { + var ex = (Exception)e.ExceptionObject; + // Todo: make this translatable + ErrorWindow.ShowErrorDialog("An unhandled exception has occurred.\nThe program must now close.", ex, false); + } + catch + { + try + { + // Todo: make this translatable + MessageBox.Show("A fatal non-UI error has occurred in PKHeX, and the details could not be displayed. Please report this to the author.", "PKHeX Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); + } + finally + { + Application.Exit(); + } + } + } } } diff --git a/pk3DS/pk3DS.csproj b/pk3DS/pk3DS.csproj index d924ba6..bcf5e67 100644 --- a/pk3DS/pk3DS.csproj +++ b/pk3DS/pk3DS.csproj @@ -62,8 +62,10 @@ + + @@ -88,6 +90,12 @@ + + Form + + + ErrorWindow.cs + @@ -406,6 +414,9 @@ About.cs + + ErrorWindow.cs + EggMoveEditor7.cs