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