diff --git a/Form1.Designer.cs b/Form1.Designer.cs new file mode 100644 index 0000000..16995d3 --- /dev/null +++ b/Form1.Designer.cs @@ -0,0 +1,658 @@ +namespace MemTestHelper +{ + partial class Form1 + { + /// + /// 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.tab_control = new System.Windows.Forms.TabControl(); + this.tab_main = new System.Windows.Forms.TabPage(); + this.btn_hide = new System.Windows.Forms.Button(); + this.lst_coverage = new System.Windows.Forms.ListView(); + this.hdr_no = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.hdr_coverage = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.hdr_errors = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.lbl_speed_value = new System.Windows.Forms.Label(); + this.lbl_speed = new System.Windows.Forms.Label(); + this.lbl_estimated_time = new System.Windows.Forms.Label(); + this.lbl_estimated = new System.Windows.Forms.Label(); + this.lbl_elapsed_time = new System.Windows.Forms.Label(); + this.lbl_elapsed = new System.Windows.Forms.Label(); + this.btn_show = new System.Windows.Forms.Button(); + this.btn_stop = new System.Windows.Forms.Button(); + this.btn_run = new System.Windows.Forms.Button(); + this.cbo_threads = new System.Windows.Forms.ComboBox(); + this.lbl_num_threads = new System.Windows.Forms.Label(); + this.txt_ram = new System.Windows.Forms.TextBox(); + this.btn_auto_ram = new System.Windows.Forms.Button(); + this.tab_settings = new System.Windows.Forms.TabPage(); + this.chk_start_min = new System.Windows.Forms.CheckBox(); + this.chk_stop_at_total = new System.Windows.Forms.CheckBox(); + this.chk_stop_on_err = new System.Windows.Forms.CheckBox(); + this.txt_stop_at = new System.Windows.Forms.TextBox(); + this.chk_stop_at = new System.Windows.Forms.CheckBox(); + this.cbo_rows = new System.Windows.Forms.ComboBox(); + this.btn_center = new System.Windows.Forms.Button(); + this.ud_y_offset = new System.Windows.Forms.NumericUpDown(); + this.lbl_y_offset = new System.Windows.Forms.Label(); + this.ud_y_spacing = new System.Windows.Forms.NumericUpDown(); + this.lbl_rows = new System.Windows.Forms.Label(); + this.lbl_y_spacing = new System.Windows.Forms.Label(); + this.ud_x_spacing = new System.Windows.Forms.NumericUpDown(); + this.lbl_x_spacing = new System.Windows.Forms.Label(); + this.ud_x_offset = new System.Windows.Forms.NumericUpDown(); + this.lbl_x_offset = new System.Windows.Forms.Label(); + this.tab_about = new System.Windows.Forms.TabPage(); + this.txt_discord = new System.Windows.Forms.TextBox(); + this.lbl_discord = new System.Windows.Forms.Label(); + this.lbl_version = new System.Windows.Forms.Label(); + this.lbl_win_height = new System.Windows.Forms.Label(); + this.ud_win_height = new System.Windows.Forms.NumericUpDown(); + this.tab_control.SuspendLayout(); + this.tab_main.SuspendLayout(); + this.tab_settings.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.ud_y_offset)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.ud_y_spacing)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.ud_x_spacing)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.ud_x_offset)).BeginInit(); + this.tab_about.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.ud_win_height)).BeginInit(); + this.SuspendLayout(); + // + // tab_control + // + this.tab_control.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom))); + this.tab_control.Controls.Add(this.tab_main); + this.tab_control.Controls.Add(this.tab_settings); + this.tab_control.Controls.Add(this.tab_about); + this.tab_control.Location = new System.Drawing.Point(0, 0); + this.tab_control.Margin = new System.Windows.Forms.Padding(0); + this.tab_control.Name = "tab_control"; + this.tab_control.SelectedIndex = 0; + this.tab_control.Size = new System.Drawing.Size(227, 382); + this.tab_control.TabIndex = 0; + // + // tab_main + // + this.tab_main.Controls.Add(this.btn_hide); + this.tab_main.Controls.Add(this.lst_coverage); + this.tab_main.Controls.Add(this.lbl_speed_value); + this.tab_main.Controls.Add(this.lbl_speed); + this.tab_main.Controls.Add(this.lbl_estimated_time); + this.tab_main.Controls.Add(this.lbl_estimated); + this.tab_main.Controls.Add(this.lbl_elapsed_time); + this.tab_main.Controls.Add(this.lbl_elapsed); + this.tab_main.Controls.Add(this.btn_show); + this.tab_main.Controls.Add(this.btn_stop); + this.tab_main.Controls.Add(this.btn_run); + this.tab_main.Controls.Add(this.cbo_threads); + this.tab_main.Controls.Add(this.lbl_num_threads); + this.tab_main.Controls.Add(this.txt_ram); + this.tab_main.Controls.Add(this.btn_auto_ram); + this.tab_main.Location = new System.Drawing.Point(4, 22); + this.tab_main.Margin = new System.Windows.Forms.Padding(0); + this.tab_main.Name = "tab_main"; + this.tab_main.Size = new System.Drawing.Size(219, 356); + this.tab_main.TabIndex = 0; + this.tab_main.Text = "Main"; + this.tab_main.UseVisualStyleBackColor = true; + // + // btn_hide + // + this.btn_hide.Location = new System.Drawing.Point(112, 83); + this.btn_hide.Name = "btn_hide"; + this.btn_hide.Size = new System.Drawing.Size(85, 20); + this.btn_hide.TabIndex = 8; + this.btn_hide.Text = "Hide"; + this.btn_hide.UseVisualStyleBackColor = true; + this.btn_hide.Click += new System.EventHandler(this.btn_hide_Click); + // + // lst_coverage + // + this.lst_coverage.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom))); + this.lst_coverage.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.hdr_no, + this.hdr_coverage, + this.hdr_errors}); + this.lst_coverage.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lst_coverage.Location = new System.Drawing.Point(4, 154); + this.lst_coverage.Name = "lst_coverage"; + this.lst_coverage.Size = new System.Drawing.Size(210, 199); + this.lst_coverage.TabIndex = 7; + this.lst_coverage.UseCompatibleStateImageBehavior = false; + this.lst_coverage.View = System.Windows.Forms.View.Details; + // + // hdr_no + // + this.hdr_no.Text = "No."; + this.hdr_no.Width = 31; + // + // hdr_coverage + // + this.hdr_coverage.Text = "Coverage (%)"; + this.hdr_coverage.Width = 86; + // + // hdr_errors + // + this.hdr_errors.Text = "Errors"; + this.hdr_errors.Width = 70; + // + // lbl_speed_value + // + this.lbl_speed_value.AutoSize = true; + this.lbl_speed_value.Location = new System.Drawing.Point(81, 137); + this.lbl_speed_value.Name = "lbl_speed_value"; + this.lbl_speed_value.Size = new System.Drawing.Size(54, 13); + this.lbl_speed_value.TabIndex = 6; + this.lbl_speed_value.Text = "0.00MB/s"; + // + // lbl_speed + // + this.lbl_speed.AutoSize = true; + this.lbl_speed.Location = new System.Drawing.Point(21, 137); + this.lbl_speed.Name = "lbl_speed"; + this.lbl_speed.Size = new System.Drawing.Size(41, 13); + this.lbl_speed.TabIndex = 6; + this.lbl_speed.Text = "Speed:"; + // + // lbl_estimated_time + // + this.lbl_estimated_time.AutoSize = true; + this.lbl_estimated_time.Location = new System.Drawing.Point(81, 122); + this.lbl_estimated_time.Name = "lbl_estimated_time"; + this.lbl_estimated_time.Size = new System.Drawing.Size(62, 13); + this.lbl_estimated_time.TabIndex = 6; + this.lbl_estimated_time.Text = "00h00m00s"; + // + // lbl_estimated + // + this.lbl_estimated.AutoSize = true; + this.lbl_estimated.Location = new System.Drawing.Point(21, 122); + this.lbl_estimated.Name = "lbl_estimated"; + this.lbl_estimated.Size = new System.Drawing.Size(56, 13); + this.lbl_estimated.TabIndex = 6; + this.lbl_estimated.Text = "Estimated:"; + // + // lbl_elapsed_time + // + this.lbl_elapsed_time.AutoSize = true; + this.lbl_elapsed_time.Location = new System.Drawing.Point(81, 107); + this.lbl_elapsed_time.Name = "lbl_elapsed_time"; + this.lbl_elapsed_time.Size = new System.Drawing.Size(62, 13); + this.lbl_elapsed_time.TabIndex = 6; + this.lbl_elapsed_time.Text = "00h00m00s"; + // + // lbl_elapsed + // + this.lbl_elapsed.AutoSize = true; + this.lbl_elapsed.Location = new System.Drawing.Point(21, 107); + this.lbl_elapsed.Name = "lbl_elapsed"; + this.lbl_elapsed.Size = new System.Drawing.Size(48, 13); + this.lbl_elapsed.TabIndex = 6; + this.lbl_elapsed.Text = "Elapsed:"; + // + // btn_show + // + this.btn_show.Location = new System.Drawing.Point(21, 83); + this.btn_show.Name = "btn_show"; + this.btn_show.Size = new System.Drawing.Size(85, 20); + this.btn_show.TabIndex = 5; + this.btn_show.Text = "Show"; + this.btn_show.UseVisualStyleBackColor = true; + this.btn_show.Click += new System.EventHandler(this.btn_show_Click); + // + // btn_stop + // + this.btn_stop.Enabled = false; + this.btn_stop.Location = new System.Drawing.Point(112, 53); + this.btn_stop.Name = "btn_stop"; + this.btn_stop.Size = new System.Drawing.Size(85, 25); + this.btn_stop.TabIndex = 5; + this.btn_stop.Text = "Stop"; + this.btn_stop.UseVisualStyleBackColor = true; + this.btn_stop.Click += new System.EventHandler(this.btn_stop_Click); + // + // btn_run + // + this.btn_run.Location = new System.Drawing.Point(21, 53); + this.btn_run.Name = "btn_run"; + this.btn_run.Size = new System.Drawing.Size(85, 25); + this.btn_run.TabIndex = 5; + this.btn_run.Text = "Run"; + this.btn_run.UseVisualStyleBackColor = true; + this.btn_run.Click += new System.EventHandler(this.btn_run_Click); + // + // cbo_threads + // + this.cbo_threads.DropDownHeight = 100; + this.cbo_threads.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbo_threads.FormattingEnabled = true; + this.cbo_threads.IntegralHeight = false; + this.cbo_threads.Location = new System.Drawing.Point(146, 28); + this.cbo_threads.Name = "cbo_threads"; + this.cbo_threads.Size = new System.Drawing.Size(50, 21); + this.cbo_threads.TabIndex = 4; + this.cbo_threads.SelectionChangeCommitted += new System.EventHandler(this.cbo_threads_SelectionChangeCommitted); + // + // lbl_num_threads + // + this.lbl_num_threads.AutoSize = true; + this.lbl_num_threads.Location = new System.Drawing.Point(21, 33); + this.lbl_num_threads.Name = "lbl_num_threads"; + this.lbl_num_threads.Size = new System.Drawing.Size(97, 13); + this.lbl_num_threads.TabIndex = 3; + this.lbl_num_threads.Text = "Number of threads:"; + // + // txt_ram + // + this.txt_ram.Location = new System.Drawing.Point(146, 3); + this.txt_ram.Name = "txt_ram"; + this.txt_ram.Size = new System.Drawing.Size(50, 20); + this.txt_ram.TabIndex = 2; + // + // btn_auto_ram + // + this.btn_auto_ram.Location = new System.Drawing.Point(21, 3); + this.btn_auto_ram.Margin = new System.Windows.Forms.Padding(0); + this.btn_auto_ram.Name = "btn_auto_ram"; + this.btn_auto_ram.Size = new System.Drawing.Size(100, 20); + this.btn_auto_ram.TabIndex = 1; + this.btn_auto_ram.Text = "RAM to test (MB):"; + this.btn_auto_ram.UseVisualStyleBackColor = true; + this.btn_auto_ram.Click += new System.EventHandler(this.btn_auto_ram_Click); + // + // tab_settings + // + this.tab_settings.Controls.Add(this.chk_start_min); + this.tab_settings.Controls.Add(this.chk_stop_at_total); + this.tab_settings.Controls.Add(this.chk_stop_on_err); + this.tab_settings.Controls.Add(this.txt_stop_at); + this.tab_settings.Controls.Add(this.chk_stop_at); + this.tab_settings.Controls.Add(this.cbo_rows); + this.tab_settings.Controls.Add(this.btn_center); + this.tab_settings.Controls.Add(this.ud_win_height); + this.tab_settings.Controls.Add(this.ud_y_offset); + this.tab_settings.Controls.Add(this.lbl_win_height); + this.tab_settings.Controls.Add(this.lbl_y_offset); + this.tab_settings.Controls.Add(this.ud_y_spacing); + this.tab_settings.Controls.Add(this.lbl_rows); + this.tab_settings.Controls.Add(this.lbl_y_spacing); + this.tab_settings.Controls.Add(this.ud_x_spacing); + this.tab_settings.Controls.Add(this.lbl_x_spacing); + this.tab_settings.Controls.Add(this.ud_x_offset); + this.tab_settings.Controls.Add(this.lbl_x_offset); + this.tab_settings.Location = new System.Drawing.Point(4, 22); + this.tab_settings.Margin = new System.Windows.Forms.Padding(0); + this.tab_settings.Name = "tab_settings"; + this.tab_settings.Size = new System.Drawing.Size(219, 356); + this.tab_settings.TabIndex = 1; + this.tab_settings.Text = "Settings"; + this.tab_settings.UseVisualStyleBackColor = true; + // + // chk_start_min + // + this.chk_start_min.AutoSize = true; + this.chk_start_min.Checked = true; + this.chk_start_min.CheckState = System.Windows.Forms.CheckState.Checked; + this.chk_start_min.Location = new System.Drawing.Point(21, 181); + this.chk_start_min.Name = "chk_start_min"; + this.chk_start_min.Size = new System.Drawing.Size(96, 17); + this.chk_start_min.TabIndex = 8; + this.chk_start_min.Text = "Start minimised"; + this.chk_start_min.UseVisualStyleBackColor = true; + // + // chk_stop_at_total + // + this.chk_stop_at_total.AutoSize = true; + this.chk_stop_at_total.Enabled = false; + this.chk_stop_at_total.Location = new System.Drawing.Point(156, 134); + this.chk_stop_at_total.Name = "chk_stop_at_total"; + this.chk_stop_at_total.Size = new System.Drawing.Size(50, 17); + this.chk_stop_at_total.TabIndex = 6; + this.chk_stop_at_total.Text = "Total"; + this.chk_stop_at_total.UseVisualStyleBackColor = true; + // + // chk_stop_on_err + // + this.chk_stop_on_err.AutoSize = true; + this.chk_stop_on_err.Checked = true; + this.chk_stop_on_err.CheckState = System.Windows.Forms.CheckState.Checked; + this.chk_stop_on_err.Location = new System.Drawing.Point(21, 157); + this.chk_stop_on_err.Name = "chk_stop_on_err"; + this.chk_stop_on_err.Size = new System.Drawing.Size(87, 17); + this.chk_stop_on_err.TabIndex = 4; + this.chk_stop_on_err.Text = "Stop on error"; + this.chk_stop_on_err.UseVisualStyleBackColor = true; + // + // txt_stop_at + // + this.txt_stop_at.Enabled = false; + this.txt_stop_at.Location = new System.Drawing.Point(100, 131); + this.txt_stop_at.Name = "txt_stop_at"; + this.txt_stop_at.Size = new System.Drawing.Size(50, 20); + this.txt_stop_at.TabIndex = 5; + // + // chk_stop_at + // + this.chk_stop_at.AutoSize = true; + this.chk_stop_at.Location = new System.Drawing.Point(21, 134); + this.chk_stop_at.Name = "chk_stop_at"; + this.chk_stop_at.Size = new System.Drawing.Size(80, 17); + this.chk_stop_at.TabIndex = 4; + this.chk_stop_at.Text = "Stop at (%):"; + this.chk_stop_at.UseVisualStyleBackColor = true; + this.chk_stop_at.CheckedChanged += new System.EventHandler(this.chk_stop_at_CheckedChanged); + // + // cbo_rows + // + this.cbo_rows.DropDownHeight = 100; + this.cbo_rows.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbo_rows.FormattingEnabled = true; + this.cbo_rows.IntegralHeight = false; + this.cbo_rows.Location = new System.Drawing.Point(106, 104); + this.cbo_rows.Name = "cbo_rows"; + this.cbo_rows.Size = new System.Drawing.Size(50, 21); + this.cbo_rows.TabIndex = 3; + this.cbo_rows.SelectionChangeCommitted += new System.EventHandler(this.cbo_rows_SelectionChangeCommitted); + // + // btn_center + // + this.btn_center.Location = new System.Drawing.Point(121, 13); + this.btn_center.Name = "btn_center"; + this.btn_center.Size = new System.Drawing.Size(80, 25); + this.btn_center.TabIndex = 2; + this.btn_center.Text = "Center"; + this.btn_center.UseVisualStyleBackColor = true; + this.btn_center.Click += new System.EventHandler(this.btn_center_Click); + // + // ud_y_offset + // + this.ud_y_offset.Location = new System.Drawing.Point(66, 30); + this.ud_y_offset.Maximum = new decimal(new int[] { + 1000, + 0, + 0, + 0}); + this.ud_y_offset.Minimum = new decimal(new int[] { + 1000, + 0, + 0, + -2147483648}); + this.ud_y_offset.Name = "ud_y_offset"; + this.ud_y_offset.Size = new System.Drawing.Size(50, 20); + this.ud_y_offset.TabIndex = 1; + this.ud_y_offset.ValueChanged += new System.EventHandler(this.offset_changed); + // + // lbl_y_offset + // + this.lbl_y_offset.AutoSize = true; + this.lbl_y_offset.Location = new System.Drawing.Point(21, 33); + this.lbl_y_offset.Name = "lbl_y_offset"; + this.lbl_y_offset.Size = new System.Drawing.Size(46, 13); + this.lbl_y_offset.TabIndex = 0; + this.lbl_y_offset.Text = "Y offset:"; + // + // ud_y_spacing + // + this.ud_y_spacing.Location = new System.Drawing.Point(76, 81); + this.ud_y_spacing.Maximum = new decimal(new int[] { + 1000, + 0, + 0, + 0}); + this.ud_y_spacing.Minimum = new decimal(new int[] { + 1000, + 0, + 0, + -2147483648}); + this.ud_y_spacing.Name = "ud_y_spacing"; + this.ud_y_spacing.Size = new System.Drawing.Size(50, 20); + this.ud_y_spacing.TabIndex = 1; + this.ud_y_spacing.ValueChanged += new System.EventHandler(this.offset_changed); + // + // lbl_rows + // + this.lbl_rows.AutoSize = true; + this.lbl_rows.Location = new System.Drawing.Point(21, 109); + this.lbl_rows.Name = "lbl_rows"; + this.lbl_rows.Size = new System.Drawing.Size(84, 13); + this.lbl_rows.TabIndex = 0; + this.lbl_rows.Text = "Number of rows:"; + // + // lbl_y_spacing + // + this.lbl_y_spacing.AutoSize = true; + this.lbl_y_spacing.Location = new System.Drawing.Point(21, 84); + this.lbl_y_spacing.Name = "lbl_y_spacing"; + this.lbl_y_spacing.Size = new System.Drawing.Size(57, 13); + this.lbl_y_spacing.TabIndex = 0; + this.lbl_y_spacing.Text = "Y spacing:"; + // + // ud_x_spacing + // + this.ud_x_spacing.Location = new System.Drawing.Point(76, 56); + this.ud_x_spacing.Maximum = new decimal(new int[] { + 1000, + 0, + 0, + 0}); + this.ud_x_spacing.Minimum = new decimal(new int[] { + 1000, + 0, + 0, + -2147483648}); + this.ud_x_spacing.Name = "ud_x_spacing"; + this.ud_x_spacing.Size = new System.Drawing.Size(50, 20); + this.ud_x_spacing.TabIndex = 1; + this.ud_x_spacing.ValueChanged += new System.EventHandler(this.offset_changed); + // + // lbl_x_spacing + // + this.lbl_x_spacing.AutoSize = true; + this.lbl_x_spacing.Location = new System.Drawing.Point(21, 59); + this.lbl_x_spacing.Name = "lbl_x_spacing"; + this.lbl_x_spacing.Size = new System.Drawing.Size(57, 13); + this.lbl_x_spacing.TabIndex = 0; + this.lbl_x_spacing.Text = "X spacing:"; + // + // ud_x_offset + // + this.ud_x_offset.Location = new System.Drawing.Point(66, 5); + this.ud_x_offset.Maximum = new decimal(new int[] { + 1000, + 0, + 0, + 0}); + this.ud_x_offset.Minimum = new decimal(new int[] { + 1000, + 0, + 0, + -2147483648}); + this.ud_x_offset.Name = "ud_x_offset"; + this.ud_x_offset.Size = new System.Drawing.Size(50, 20); + this.ud_x_offset.TabIndex = 1; + this.ud_x_offset.ValueChanged += new System.EventHandler(this.offset_changed); + // + // lbl_x_offset + // + this.lbl_x_offset.AutoSize = true; + this.lbl_x_offset.Location = new System.Drawing.Point(21, 8); + this.lbl_x_offset.Name = "lbl_x_offset"; + this.lbl_x_offset.Size = new System.Drawing.Size(46, 13); + this.lbl_x_offset.TabIndex = 0; + this.lbl_x_offset.Text = "X offset:"; + // + // tab_about + // + this.tab_about.Controls.Add(this.txt_discord); + this.tab_about.Controls.Add(this.lbl_discord); + this.tab_about.Controls.Add(this.lbl_version); + this.tab_about.Location = new System.Drawing.Point(4, 22); + this.tab_about.Margin = new System.Windows.Forms.Padding(0); + this.tab_about.Name = "tab_about"; + this.tab_about.Size = new System.Drawing.Size(219, 356); + this.tab_about.TabIndex = 2; + this.tab_about.Text = "About"; + this.tab_about.UseVisualStyleBackColor = true; + // + // txt_discord + // + this.txt_discord.Location = new System.Drawing.Point(100, 145); + this.txt_discord.Name = "txt_discord"; + this.txt_discord.ReadOnly = true; + this.txt_discord.Size = new System.Drawing.Size(80, 20); + this.txt_discord.TabIndex = 1; + this.txt_discord.Text = "∫ntegral#7834"; + // + // lbl_discord + // + this.lbl_discord.AutoSize = true; + this.lbl_discord.Location = new System.Drawing.Point(50, 150); + this.lbl_discord.Name = "lbl_discord"; + this.lbl_discord.Size = new System.Drawing.Size(46, 13); + this.lbl_discord.TabIndex = 0; + this.lbl_discord.Text = "Discord:"; + // + // lbl_version + // + this.lbl_version.AutoSize = true; + this.lbl_version.Location = new System.Drawing.Point(84, 120); + this.lbl_version.Name = "lbl_version"; + this.lbl_version.Size = new System.Drawing.Size(69, 13); + this.lbl_version.TabIndex = 0; + this.lbl_version.Text = "Version 1.9.2"; + // + // lbl_win_height + // + this.lbl_win_height.AutoSize = true; + this.lbl_win_height.Location = new System.Drawing.Point(18, 204); + this.lbl_win_height.Name = "lbl_win_height"; + this.lbl_win_height.Size = new System.Drawing.Size(81, 13); + this.lbl_win_height.TabIndex = 0; + this.lbl_win_height.Text = "Window height:"; + // + // ud_win_height + // + this.ud_win_height.Location = new System.Drawing.Point(100, 202); + this.ud_win_height.Maximum = new decimal(new int[] { + 1000, + 0, + 0, + 0}); + this.ud_win_height.Minimum = new decimal(new int[] { + 420, + 0, + 0, + 0}); + this.ud_win_height.Name = "ud_win_height"; + this.ud_win_height.Size = new System.Drawing.Size(50, 20); + this.ud_win_height.TabIndex = 1; + this.ud_win_height.Value = new decimal(new int[] { + 420, + 0, + 0, + 0}); + this.ud_win_height.ValueChanged += new System.EventHandler(this.ud_win_height_ValueChanged); + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(226, 381); + this.Controls.Add(this.tab_control); + this.MaximizeBox = false; + this.MaximumSize = new System.Drawing.Size(242, 1000); + this.MinimumSize = new System.Drawing.Size(242, 0); + this.Name = "Form1"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "MemTestHelper"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); + this.Load += new System.EventHandler(this.Form1_Load); + this.Resize += new System.EventHandler(this.Form1_Resize); + this.tab_control.ResumeLayout(false); + this.tab_main.ResumeLayout(false); + this.tab_main.PerformLayout(); + this.tab_settings.ResumeLayout(false); + this.tab_settings.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.ud_y_offset)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.ud_y_spacing)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.ud_x_spacing)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.ud_x_offset)).EndInit(); + this.tab_about.ResumeLayout(false); + this.tab_about.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.ud_win_height)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TabControl tab_control; + private System.Windows.Forms.TabPage tab_main; + private System.Windows.Forms.TabPage tab_settings; + private System.Windows.Forms.TabPage tab_about; + private System.Windows.Forms.Button btn_auto_ram; + private System.Windows.Forms.TextBox txt_ram; + private System.Windows.Forms.Label lbl_num_threads; + private System.Windows.Forms.ComboBox cbo_threads; + private System.Windows.Forms.Button btn_show; + private System.Windows.Forms.Button btn_stop; + private System.Windows.Forms.Button btn_run; + private System.Windows.Forms.Label lbl_speed_value; + private System.Windows.Forms.Label lbl_speed; + private System.Windows.Forms.Label lbl_estimated_time; + private System.Windows.Forms.Label lbl_estimated; + private System.Windows.Forms.Label lbl_elapsed_time; + private System.Windows.Forms.Label lbl_elapsed; + private System.Windows.Forms.ListView lst_coverage; + private System.Windows.Forms.ColumnHeader hdr_no; + private System.Windows.Forms.ColumnHeader hdr_coverage; + private System.Windows.Forms.ColumnHeader hdr_errors; + private System.Windows.Forms.Label lbl_x_offset; + private System.Windows.Forms.NumericUpDown ud_x_offset; + private System.Windows.Forms.NumericUpDown ud_y_offset; + private System.Windows.Forms.Label lbl_y_offset; + private System.Windows.Forms.NumericUpDown ud_y_spacing; + private System.Windows.Forms.Label lbl_y_spacing; + private System.Windows.Forms.NumericUpDown ud_x_spacing; + private System.Windows.Forms.Label lbl_x_spacing; + private System.Windows.Forms.Button btn_center; + private System.Windows.Forms.ComboBox cbo_rows; + private System.Windows.Forms.Label lbl_rows; + private System.Windows.Forms.CheckBox chk_stop_at_total; + private System.Windows.Forms.TextBox txt_stop_at; + private System.Windows.Forms.CheckBox chk_stop_at; + private System.Windows.Forms.CheckBox chk_stop_on_err; + private System.Windows.Forms.TextBox txt_discord; + private System.Windows.Forms.Label lbl_discord; + private System.Windows.Forms.Label lbl_version; + private System.Windows.Forms.CheckBox chk_start_min; + private System.Windows.Forms.Button btn_hide; + private System.Windows.Forms.NumericUpDown ud_win_height; + private System.Windows.Forms.Label lbl_win_height; + } +} + diff --git a/Form1.cs b/Form1.cs new file mode 100644 index 0000000..842e1b1 --- /dev/null +++ b/Form1.cs @@ -0,0 +1,1016 @@ +using Microsoft.VisualBasic.Devices; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Forms; + +namespace MemTestHelper +{ + public partial class Form1 : Form + { + public Form1() + { + InitializeComponent(); + + init_cbo_threads(); + init_lst_coverage(); + init_cbo_rows(); + center_xy_offsets(); + + bw_coverage = new BackgroundWorker(); + bw_coverage.WorkerSupportsCancellation = true; + bw_coverage.DoWork += new DoWorkEventHandler(delegate (object o, DoWorkEventArgs args) + { + BackgroundWorker worker = o as BackgroundWorker; + + while (!worker.CancellationPending) + { + update_coverage_info(); + Thread.Sleep(UPDATE_INTERVAL); + } + + args.Cancel = true; + }); + bw_coverage.RunWorkerCompleted += + new RunWorkerCompletedEventHandler(delegate (object o, RunWorkerCompletedEventArgs args) + { + // wait for all MemTests to stop completely + while (is_any_memtest_stopping()) + Thread.Sleep(100); + + update_coverage_info(false); + }); + + timer = new System.Timers.Timer(1000); + timer.Elapsed += new System.Timers.ElapsedEventHandler(delegate + (object sender, System.Timers.ElapsedEventArgs e) + { + Invoke(new MethodInvoker(delegate + { + int threads = (int)cbo_threads.SelectedItem; + var elapsed = e.SignalTime - start_time; + + lbl_elapsed_time.Text = String.Format("{0:00}h{1:00}m{2:00}s", + (int)(elapsed.TotalHours), + elapsed.Minutes, + elapsed.Seconds); + + double total_coverage = 0; + for (int i = 1; i <= threads; i++) + { + var info = get_coverage_info(memtest_states[i - 1].proc.MainWindowHandle); + if (info == null) continue; + + total_coverage += info.Item1; + } + + if (total_coverage == 0) return; + + double diff = elapsed.TotalMilliseconds, + est = 0; + int cov = 0; + // use user input coverage % + if (chk_stop_at.Checked) + { + cov = Convert.ToInt32(txt_stop_at.Text); + + if (chk_stop_at_total.Checked) + est = (diff / total_coverage * cov) - diff; + else + { + // calculate average coverage and use that to estimate + double avg = total_coverage / threads; + est = (diff / avg * cov) - diff; + } + } + else + { + // calculate average coverage and use that to estimate + double avg = total_coverage / threads; + // round up to next multiple of 100 + cov = ((int)(avg / 100) + 1) * 100; + est = (diff / avg * cov) - diff; + } + + TimeSpan est_time = TimeSpan.FromMilliseconds(est); + lbl_estimated_time.Text = String.Format("{0:00}h{1:00}m{2:00}s to {3}%", + (int)(est_time.TotalHours), + est_time.Minutes, + est_time.Seconds, + cov); + + int ram = Convert.ToInt32(txt_ram.Text); + double speed = (total_coverage / 100) * ram / (diff / 1000); + lbl_speed_value.Text = $"{speed:f2}MB/s"; + })); + }); + } + + // event handling + + private void Form1_Load(object sender, EventArgs e) + { + load_cfg(); + update_form_height(); + update_lst_coverage_items(); + } + + private void Form1_FormClosing(object sender, FormClosingEventArgs e) + { + close_memtests(); + save_cfg(); + } + + private void Form1_Resize(object sender, EventArgs e) + { + int threads = (int)cbo_threads.SelectedItem; + switch (WindowState) + { + // minimise MemTest instances + case FormWindowState.Minimized: + run_in_background(new MethodInvoker(delegate + { + for (int i = 0; i < threads; i++) + { + if (memtest_states[i] != null) + { + IntPtr hwnd = memtest_states[i].proc.MainWindowHandle; + + if (!IsIconic(hwnd)) + ShowWindow(hwnd, SW_MINIMIZE); + + Thread.Sleep(10); + } + } + })); + break; + + // restore previous state of MemTest instances + case FormWindowState.Normal: + run_in_background(new MethodInvoker(delegate + { + /* + * is_minimised is true when user clicked the hide button + * this means that the memtest instances should be kept minimised + */ + if (!is_minimised) + { + for (int i = 0; i < threads; i++) + { + if (memtest_states[i] != null) + { + IntPtr hwnd = memtest_states[i].proc.MainWindowHandle; + + ShowWindow(hwnd, SW_RESTORE); + + Thread.Sleep(10); + } + } + + // user may have changed offsets while minimised + move_memtests(); + + // hack to bring form to top + TopMost = true; + Thread.Sleep(10); + TopMost = false; + } + })); + break; + } + } + + private void btn_auto_ram_Click(object sender, EventArgs e) + { + UInt64 free = new ComputerInfo().AvailablePhysicalMemory / (1024 * 1024); + txt_ram.Text = free.ToString(); + } + + private void btn_run_Click(object sender, EventArgs e) + { + if (!File.Exists(MEMTEST_EXE)) + { + MessageBox.Show(MEMTEST_EXE + " not found"); + return; + } + + if (!validate_input()) return; + + btn_auto_ram.Enabled = false; + txt_ram.Enabled = false; + cbo_threads.Enabled = false; + //cbo_rows.Enabled = false; + btn_run.Enabled = false; + btn_stop.Enabled = true; + chk_stop_at.Enabled = false; + txt_stop_at.Enabled = false; + chk_stop_at_total.Enabled = false; + chk_stop_on_err.Enabled = false; + chk_start_min.Enabled = false; + + // run in background as start_memtests can block + run_in_background(new MethodInvoker(delegate + { + start_memtests(); + + if (!bw_coverage.IsBusy) + bw_coverage.RunWorkerAsync(); + start_time = DateTime.Now; + timer.Start(); + + Activate(); + })); + } + + private void btn_stop_Click(object sender, EventArgs e) + { + Parallel.For(0, (int)cbo_threads.SelectedItem, i => + { + if (!memtest_states[i].is_finished) + ControlClick(memtest_states[i].proc.MainWindowHandle, MEMTEST_BTN_STOP); + }); + + bw_coverage.CancelAsync(); + timer.Stop(); + + btn_auto_ram.Enabled = true; + txt_ram.Enabled = true; + cbo_threads.Enabled = true; + //cbo_rows.Enabled = true; + btn_run.Enabled = true; + btn_stop.Enabled = false; + chk_stop_at.Enabled = true; + if (chk_stop_at.Checked) + { + txt_stop_at.Enabled = true; + chk_stop_at_total.Enabled = true; + } + chk_stop_on_err.Enabled = true; + chk_start_min.Enabled = true; + + // wait for all memtests to fully stop + while (is_any_memtest_stopping()) + Thread.Sleep(100); + + MessageBox.Show("MemTest finished"); + } + + private void btn_show_Click(object sender, EventArgs e) + { + // run in background as Thread.Sleep can lockup the GUI + int threads = (int)cbo_threads.SelectedItem; + run_in_background(new MethodInvoker(delegate + { + for (int i = 0; i < threads; i++) + { + if (memtest_states[i] != null) + { + IntPtr hwnd = memtest_states[i].proc.MainWindowHandle; + + if (IsIconic(hwnd)) + ShowWindow(hwnd, SW_RESTORE); + else + SetForegroundWindow(hwnd); + + Thread.Sleep(10); + } + } + + is_minimised = false; + + // user may have changed offsets while minimised + move_memtests(); + + Activate(); + })); + } + + private void btn_hide_Click(object sender, EventArgs e) + { + int threads = (int)cbo_threads.SelectedItem; + run_in_background(new MethodInvoker(delegate + { + for (int i = 0; i < threads; i++) + { + if (memtest_states[i] != null) + { + IntPtr hwnd = memtest_states[i].proc.MainWindowHandle; + + if (!IsIconic(hwnd)) + ShowWindow(hwnd, SW_MINIMIZE); + + Thread.Sleep(10); + } + } + + is_minimised = true; + })); + } + + private void offset_changed(object sender, EventArgs e) + { + run_in_background(new MethodInvoker(delegate { move_memtests(); })); + } + + private void btn_center_Click(object sender, EventArgs e) + { + center_xy_offsets(); + } + + private void cbo_rows_SelectionChangeCommitted(object sender, EventArgs e) + { + center_xy_offsets(); + } + + private void cbo_threads_SelectionChangeCommitted(object sender, EventArgs e) + { + update_lst_coverage_items(); + + cbo_rows.Items.Clear(); + init_cbo_rows(); + center_xy_offsets(); + } + + private void chk_stop_at_CheckedChanged(object sender, EventArgs e) + { + if (chk_stop_at.Checked) + { + txt_stop_at.Enabled = true; + chk_stop_at_total.Enabled = true; + } + else + { + txt_stop_at.Enabled = false; + chk_stop_at_total.Enabled = false; + } + } + + private void ud_win_height_ValueChanged(object sender, EventArgs e) + { + update_form_height(); + } + + // helper functions + + // TODO: error checking + private bool load_cfg() + { + string[] valid_keys = { "ram", "threads", "x_offset", "y_offset", + "x_spacing", "y_spacing", "rows", "stop_at", + "stop_at_value", "stop_at_total", "stop_on_error", + "start_min", "win_height" }; + + try + { + string[] lines = File.ReadAllLines(CFG_FILENAME); + Dictionary cfg = new Dictionary(); + + foreach (string l in lines) + { + string[] s = l.Split('='); + if (s.Length != 2) continue; + s[0] = s[0].Trim(); + s[1] = s[1].Trim(); + + if (valid_keys.Contains(s[0])) + { + if (s[1].Length == 0) continue; + + int v; + if (Int32.TryParse(s[1], out v)) + cfg.Add(s[0], v); + else return false; + } + else return false; + } + + foreach (KeyValuePair kv in cfg) + { + switch (kv.Key) + { + case "ram": + txt_ram.Text = kv.Value.ToString(); + break; + case "threads": + cbo_threads.SelectedItem = kv.Value; + break; + + case "x_offset": + ud_x_offset.Value = kv.Value; + break; + case "y_offset": + ud_y_offset.Value = kv.Value; + break; + + case "x_spacing": + ud_x_spacing.Value = kv.Value; + break; + case "y_spacing": + ud_y_spacing.Value = kv.Value; + break; + + case "stop_at": + chk_stop_at.Checked = kv.Value != 0; + break; + case "stop_at_value": + txt_stop_at.Text = kv.Value.ToString(); + break; + case "stop_at_total": + chk_stop_at_total.Checked = kv.Value != 0; + break; + + case "stop_on_error": + chk_stop_on_err.Checked = kv.Value != 0; + break; + + case "start_min": + chk_start_min.Checked = kv.Value != 0; + break; + + case "win_height": + ud_win_height.Value = kv.Value; + break; + } + } + } + catch(FileNotFoundException e) + { + return false; + } + + return true; + } + + private bool save_cfg() + { + try { + var file = new StreamWriter(CFG_FILENAME); + List lines = new List(); + + lines.Add($"ram = {txt_ram.Text}"); + lines.Add($"threads = {(int)cbo_threads.SelectedItem}"); + + lines.Add($"x_offset = {ud_x_offset.Value}"); + lines.Add($"y_offset = {ud_y_offset.Value}"); + lines.Add($"x_spacing = {ud_x_spacing.Value}"); + lines.Add($"y_spacing = {ud_y_spacing.Value}"); + lines.Add($"rows = {cbo_rows.SelectedItem}"); + + lines.Add(string.Format("stop_at = {0}", chk_stop_at.Checked ? 1 : 0)); + lines.Add($"stop_at_value = {txt_stop_at.Text}"); + lines.Add(string.Format("stop_at_total = {0}", chk_stop_at_total.Checked ? 1 : 0)); + lines.Add(string.Format("stop_on_error = {0}", chk_stop_on_err.Checked ? 1 : 0)); + + lines.Add(string.Format("start_min = {0}", chk_start_min.Checked ? 1 : 0)); + + lines.Add($"win_height = {ud_win_height.Value}"); + + foreach (string l in lines) + file.WriteLine(l); + + file.Close(); + } + catch (Exception e) + { + return false; + } + + return true; + } + + private void update_form_height() + { + Size = new Size(Size.Width, (int)ud_win_height.Value); + } + + private bool validate_input() + { + ComputerInfo ci = new ComputerInfo(); + UInt64 total_ram = ci.TotalPhysicalMemory / (1024 * 1024), + avail_ram = ci.AvailablePhysicalMemory / (1024 * 1024); + + string str_ram = txt_ram.Text; + // automatically input available ram if empty + if (str_ram.Length == 0) + { + str_ram = avail_ram.ToString(); + txt_ram.Text = str_ram; + } + else + { + if (!str_ram.All(char.IsDigit)) + { + show_error_msgbox("Amount of RAM must be an integer"); + return false; + } + } + + int threads = (int)cbo_threads.SelectedItem, + ram = Convert.ToInt32(str_ram); + if (ram < threads) + { + show_error_msgbox($"Amount of RAM must be greater than {threads}"); + return false; + } + + if (ram > MEMTEST_MAX_RAM * threads) + { + show_error_msgbox( + $"Amount of RAM must be at most {MEMTEST_MAX_RAM * threads}\n" + + "Try increasing the number of threads\n" + + "or reducing amount of RAM" + ); + return false; + } + + if ((UInt64)ram > total_ram) + { + show_error_msgbox($"Amount of RAM exceeds total RAM ({total_ram})"); + return false; + } + + if ((UInt64)ram > avail_ram) + { + var res = MessageBox.Show( + $"Amount of RAM exceeds available RAM ({avail_ram})\n" + + "This will cause RAM to be paged to your storage,\n" + + "which may make MemTest really slow.\n" + + "Continue?", + "Warning", + MessageBoxButtons.YesNo, + MessageBoxIcon.Warning + ); + if (res == DialogResult.No) + return false; + } + + // validate stop at % and error count + if (chk_stop_at.Checked) + { + string str_stop_at = txt_stop_at.Text; + + if (str_stop_at == "") + { + show_error_msgbox("Please enter stop at (%)"); + return false; + } + + if (!str_stop_at.All(char.IsDigit)) + { + show_error_msgbox("Stop at (%) must be an integer"); + return false; + } + + int stop_at = Convert.ToInt32(str_stop_at); + if (stop_at <= 0) + { + show_error_msgbox("Stop at (%) must be greater than 0"); + return false; + } + } + + return true; + } + + private void init_lst_coverage() + { + for (int i = 0; i <= (int)cbo_threads.SelectedItem; i++) + { + string[] row = { i.ToString(), "-", "-" }; + // first row is total + if (i == 0) row[0] = "T"; + + lst_coverage.Items.Add(new ListViewItem(row)); + } + } + + private void update_lst_coverage_items() + { + int threads = (int)cbo_threads.SelectedItem; + var items = lst_coverage.Items; + if (threads < items.Count) + { + for (int i = items.Count - 1; i > threads; i--) + items.RemoveAt(i); + } + else + { + for (int i = items.Count; i <= threads; i++) + { + string[] row = { i.ToString(), "-", "-" }; + lst_coverage.Items.Add(new ListViewItem(row)); + } + } + } + + private void init_cbo_threads() + { + for (int i = 0; i < MAX_THREADS; i++) + cbo_threads.Items.Add(i + 1); + + cbo_threads.SelectedItem = NUM_THREADS; + } + + private void init_cbo_rows() + { + int threads = (int)cbo_threads.SelectedItem; + + for (int i = 1; i <= threads; i++) + { + if (threads % i == 0) + cbo_rows.Items.Add(i); + } + + cbo_rows.SelectedItem = threads % 2 == 0 ? 2 : 1; + } + + void center_xy_offsets() + { + Rectangle screen = Screen.FromControl(this).Bounds; + int rows = (int)cbo_rows.SelectedItem, + cols = (int)cbo_threads.SelectedItem / rows, + x_offset = (screen.Width - MEMTEST_WIDTH * cols) / 2, + y_offset = (screen.Height - MEMTEST_HEIGHT * rows) / 2; + + ud_x_offset.Value = x_offset; + ud_y_offset.Value = y_offset; + } + + private void start_memtests() + { + close_all_memtests(); + + int threads = (int)cbo_threads.SelectedItem; + Parallel.For(0, threads, i => + { + MemTestState state = new MemTestState(); + state.proc = Process.Start(MEMTEST_EXE); + state.is_finished = false; + memtest_states[i] = state; + + Thread.Sleep(threads * 25); + + IntPtr hwnd = memtest_states[i].proc.MainWindowHandle; + double ram = Convert.ToDouble(txt_ram.Text) / threads; + + ControlSetText(hwnd, MEMTEST_EDT_RAM, $"{ram:f2}"); + ControlSetText(hwnd, MEMTEST_STATIC_FREE_VER, "Modified version by ∫ntegral#7834"); + ControlClick(hwnd, MEMTEST_BTN_START); + + if (chk_start_min.Checked) + ShowWindow(hwnd, SW_MINIMIZE); + }); + } + + private void move_memtests() + { + int x_offset = (int)ud_x_offset.Value, + y_offset = (int)ud_y_offset.Value, + x_spacing = (int)ud_x_spacing.Value - 5, + y_spacing = (int)ud_y_spacing.Value - 3, + rows = (int)cbo_rows.SelectedItem, + cols = (int)cbo_threads.SelectedItem / rows; + + Parallel.For(0, (int)cbo_threads.SelectedItem, i => + { + MemTestState state = memtest_states[i]; + if (state == null) return; + + IntPtr hwnd = state.proc.MainWindowHandle; + int r = i / cols, + c = i % cols, + x = c * MEMTEST_WIDTH + c * x_spacing + x_offset, + y = r * MEMTEST_HEIGHT + r * y_spacing + y_offset; + + MoveWindow(hwnd, x, y, MEMTEST_WIDTH, MEMTEST_HEIGHT, true); + }); + } + + private void close_memtests() + { + Parallel.ForEach(memtest_states, s => + { + try { + if (s != null) s.proc.Kill(); + } + catch (Exception) { } + }); + } + + private void close_all_memtests() + { + // remove the .exe + string name = MEMTEST_EXE.Substring(0, MEMTEST_EXE.Length - 4); + var procs = Process.GetProcessesByName(name); + Parallel.ForEach(procs, p => { p.Kill(); }); + } + + // returns (coverage, errors) + private Tuple get_coverage_info(IntPtr hwnd) + { + string str = ControlGetText(hwnd, MEMTEST_STATIC_COVERAGE); + if (str == "") return null; + + // Test over. 47.3% Coverage, 0 Errors + // ^^^^^^^^^^^^^^^^^^^^^^^^ + int start = str.IndexOfAny("0123456789".ToCharArray()); + if (start == -1) return null; + str = str.Substring(start); + + // 47.3% Coverage, 0 Errors + // ^^^^ + double coverage = Convert.ToDouble(str.Split("%".ToCharArray())[0]); + + // 47.3% Coverage, 0 Errors + // ^^^^^^^^ + start = str.IndexOf("Coverage, ") + "Coverage, ".Length; + str = str.Substring(start); + // 0 Errors + // ^ + int errors = Convert.ToInt32(str.Substring(0, str.IndexOf(" Errors"))); + + return Tuple.Create(coverage, errors); + } + + private void update_coverage_info(bool should_check = true) + { + lst_coverage.Invoke(new MethodInvoker(delegate + { + int threads = (int)cbo_threads.SelectedItem; + double total_coverage = 0; + int total_errors = 0; + + // total is index 0 + for (int i = 1; i <= threads; i++) + { + var hwnd = memtest_states[i - 1].proc.MainWindowHandle; + var info = get_coverage_info(hwnd); + if (info == null) continue; + double coverage = info.Item1; + int errors = info.Item2; + + lst_coverage.Items[i].SubItems[1].Text = string.Format("{0:f1}", coverage); + lst_coverage.Items[i].SubItems[2].Text = errors.ToString(); + + if (should_check) + { + // check coverage % + if (chk_stop_at.Checked && !chk_stop_at_total.Checked) + { + int stop_at = Convert.ToInt32(txt_stop_at.Text); + if (coverage > stop_at) + { + if (!memtest_states[i - 1].is_finished) + { + ControlClick(memtest_states[i - 1].proc.MainWindowHandle, + MEMTEST_BTN_STOP); + memtest_states[i - 1].is_finished = true; + } + } + } + + // check error count + if (chk_stop_on_err.Checked) + { + if (errors > 0) + { + lst_coverage.Items[i].SubItems[1].ForeColor = Color.Red; + + click_btn_stop(); + } + } + } + + total_coverage += coverage; + total_errors += errors; + } + + // update the total coverage and errors + lst_coverage.Items[0].SubItems[1].Text = string.Format("{0:f1}", total_coverage); + lst_coverage.Items[0].SubItems[2].Text = total_errors.ToString(); + + if (should_check) + { + // check total coverage + if (chk_stop_at.Checked && chk_stop_at_total.Checked) + { + int stop_at = Convert.ToInt32(txt_stop_at.Text); + if (total_coverage > stop_at) + click_btn_stop(); + } + + if (is_all_finished()) + click_btn_stop(); + } + })); + } + + /* + * MemTest can take a while to stop, + * which causes the total to return 0 + */ + private bool is_any_memtest_stopping() + { + for (int i = 0; i < (int)cbo_threads.SelectedItem; i++) + { + IntPtr hwnd = memtest_states[i].proc.MainWindowHandle; + string str = ControlGetText(hwnd, MEMTEST_STATIC_COVERAGE); + if (str != "" && str.Contains("Ending")) return true; + } + + return false; + } + + /* + * PerformClick() only works if the button is visible + * switch to main tab and PerformClick() then switch + * back to the tab that the user was on + */ + private void click_btn_stop() + { + var curr_tab = tab_control.SelectedTab; + if (curr_tab != tab_main) + tab_control.SelectedTab = tab_main; + + btn_stop.PerformClick(); + tab_control.SelectedTab = curr_tab; + } + + private void show_error_msgbox(string msg) + { + MessageBox.Show( + msg, + "Error", + MessageBoxButtons.OK, + MessageBoxIcon.Error + ); + } + + private bool is_all_finished() + { + for (int i = 0; i < (int)cbo_threads.SelectedItem; i++) + { + if (!memtest_states[i].is_finished) + return false; + } + + return true; + } + + private void run_in_background(Delegate method) + { + BackgroundWorker bw = new BackgroundWorker(); + bw.DoWork += new DoWorkEventHandler(delegate (object s, DoWorkEventArgs args) + { + Invoke(method); + }); + bw.RunWorkerAsync(); + } + + /* + * class_name should be + * tries to split class_name as above + * returns (, ) if possible + * otherwise, returns null + */ + private Tuple split_class_name(string class_name) + { + Regex regex = new Regex(@"([a-zA-Z]+)(\d+)"); + Match match = regex.Match(class_name); + + if (!match.Success) return null; + + return Tuple.Create( + match.Groups[1].Value, + Convert.ToInt32(match.Groups[2].Value) + ); + } + + /* + * class_name should be + * where is the name of the class to find + * is the nth window with that matches (1 indexed) + * e.g. Edit1 + * returns the handle to the window if found + * otherwise, returns IntPtr.Zero + */ + private IntPtr find_window(IntPtr hwnd_parent, string class_name) + { + if (hwnd_parent == IntPtr.Zero) + return IntPtr.Zero; + + var name = split_class_name(class_name); + if (name == null) return IntPtr.Zero; + + IntPtr hwnd = IntPtr.Zero; + for (int i = 0; i < name.Item2; i++) + hwnd = FindWindowEx(hwnd_parent, hwnd, name.Item1, null); + + return hwnd; + } + + // emulate AutoIT Control functions + private bool ControlClick(IntPtr hwnd_parent, string class_name) + { + IntPtr hwnd = find_window(hwnd_parent, class_name); + if (hwnd == IntPtr.Zero) return false; + SendNotifyMessage(hwnd, WM_LBUTTONDOWN, IntPtr.Zero, null); + SendNotifyMessage(hwnd, WM_LBUTTONUP, IntPtr.Zero, null); + return true; + } + + private bool ControlSetText(IntPtr hwnd_parent, string class_name, string text) + { + IntPtr hwnd = find_window(hwnd_parent, class_name); + if (hwnd == IntPtr.Zero) return false; + SendMessage(hwnd, WM_SETTEXT, IntPtr.Zero, text); + return true; + } + + private string ControlGetText(IntPtr hwnd, string class_name) + { + IntPtr hwnd_control = find_window(hwnd, class_name); + if (hwnd_control == IntPtr.Zero) return null; + int len = GetWindowTextLength(hwnd_control); + StringBuilder str = new StringBuilder(len + 1); + GetWindowText(hwnd_control, str, str.Capacity); + return str.ToString(); + } + + [DllImport("user32.dll", SetLastError = true)] + internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); + + [DllImport("user32.dll", SetLastError = true)] + static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); + + // blocks + [DllImport("user32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam); + + // doesn't block + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + static extern bool SendNotifyMessage(IntPtr hWnd, int Msg, IntPtr wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); + + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + static extern int GetWindowTextLength(IntPtr hWnd); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool SetForegroundWindow(IntPtr hWnd); + + [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)] + static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); + + // is minimised + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool IsIconic(IntPtr hWnd); + + public const int WM_SETTEXT = 0xC, WM_LBUTTONDOWN = 0x201, WM_LBUTTONUP = 0x202, + SW_SHOW = 5, SW_RESTORE = 9, SW_MINIMIZE = 6; + + private static int NUM_THREADS = Convert.ToInt32(System.Environment.GetEnvironmentVariable("NUMBER_OF_PROCESSORS")), + MAX_THREADS = NUM_THREADS * 4, + UPDATE_INTERVAL = 200; // interval (in ms) for coverage info list + + private const string MEMTEST_EXE = "memtest_6.0_no_nag.exe", + MEMTEST_BTN_START = "Button1", + MEMTEST_BTN_STOP = "Button2", + MEMTEST_EDT_RAM = "Edit1", + MEMTEST_STATIC_COVERAGE = "Static1", + // If you find this free version useful... + MEMTEST_STATIC_FREE_VER = "Static2", + CFG_FILENAME = "MemTestHelper.cfg"; + + private const int MEMTEST_WIDTH = 217, + MEMTEST_HEIGHT = 247, + MEMTEST_MAX_RAM = 2048; + + private MemTestState[] memtest_states = new MemTestState[MAX_THREADS]; + private BackgroundWorker bw_coverage; + private DateTime start_time; + private System.Timers.Timer timer; + private bool is_minimised = true; + + class MemTestState + { + public Process proc; + public bool is_finished; + } + } +} diff --git a/Form1.resx b/Form1.resx new file mode 100644 index 0000000..29dcb1b --- /dev/null +++ b/Form1.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