using KssSmaPlaLib.Ini; using KssSmaPlaLib.Input.Gamen; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace KssSmaPlaLib.Alert.Gamen { public class AlertForm : Form { private const string INI_KEY_BORDER = "Border"; private const string INI_KEY_TITLE = "Title"; private const string INI_KEY_ATTRIBUTE = "Attribute"; private readonly Timer _autoClose = new Timer(); private readonly Label _title = new Label(); private readonly Label _detail = new Label(); private readonly Timer _pulse = new Timer(); private ContextMenuStrip PopupMenu; private IContainer components; private ToolStripMenuItem BorderMenu; private ToolStripMenuItem TitleMenu; private ToolStripMenuItem ShozokuMenu; private ToolStripMenuItem KyoretsuModeMenu; private int _pulseStep = 0; /// /// コンストラクタ /// /// ログのエラー行 /// 日時 /// 強烈画面 /// 自動で閉じる秒数 public AlertForm( string errorLine, DateTime dateTime, bool kyouretsu = true, int autoCloseSec = 0) { InitializeComponent(); if (kyouretsu || IniHelper.ReadValue(null, this.Name, "KyoretsuMode") == "1") { // ****** ここ本番強烈処理 ****** IniHelper.WriteValue(null, this.Name, INI_KEY_BORDER, "1"); if (string.IsNullOrEmpty(IniHelper.ReadValue(null, this.Name, INI_KEY_BORDER))) { FormBorderStyle = FormBorderStyle.None; } else { FormBorderStyle = FormBorderStyle.Sizable; } TopMost = true; //WindowState = FormWindowState.Normal; WindowState = FormWindowState.Maximized; //Bounds = GetAllScreensBounds(); // 全画面(マルチモニタ) // ****** ここ本番強烈処理 ****** } BackColor = Color.FromArgb(220, 0, 0); // 深紅 Cursor = Cursors.Hand; MouseDown += All_MouseDown; // タイトル _title.Text = IniHelper.ReadValue(null, this.Name, INI_KEY_TITLE, "(タイトル未設定)"); var attribute = IniHelper.ReadValue(null, this.Name, INI_KEY_ATTRIBUTE, "のぼぼ工房"); if(!string.IsNullOrEmpty(attribute)) { _title.Text += " - " + attribute; } _title.Font = new Font("Yu Gothic UI", 72, FontStyle.Bold); _title.ForeColor = Color.White; _title.AutoSize = true; //false; _title.MaximumSize = new Size(Screen.PrimaryScreen.Bounds.Width, 0); // 左記Widthを超えると自動改行 _title.TextAlign = ContentAlignment.MiddleCenter; _title.Dock = DockStyle.Top; // 高さはFormLoadにて変更する(フォームのHeightがまだデザイン時のものだから) //_title.Height = Height / 3; _title.MouseDown += All_MouseDown; // 詳細 _detail.Text = $"[{dateTime:yyyy/MM/dd HH:mm:ss.fff}]\r\n{errorLine}"; _detail.Font = new Font("Consolas", 28, FontStyle.Regular); _detail.ForeColor = Color.White; _detail.AutoSize = false; _detail.TextAlign = ContentAlignment.MiddleCenter; _detail.Dock = DockStyle.Fill; _detail.MouseDown += All_MouseDown; Controls.Add(_detail); Controls.Add(_title); // フェードイン風(パルスで脈動) _pulse.Interval = 60; _pulse.Tick += (_, __) => { _pulseStep++; //int alpha = 200 + (int)(55 * Math.Sin(_pulseStep / 3.0)); //BackColor = Color.FromArgb(Math.Clamp(alpha, 180, 255), 120, 0, 0); // ほんのり血の脈動(控えめ) // 180〜255にクランプ //int a = Math.Min(255, Math.Max(180, alpha)); //BackColor = Color.FromArgb(a, 120, 0, 0); // ほんのり血の脈動(控えめ) int r = Math.Min(255, Math.Max(120, 120 + (int)(60 * Math.Sin(_pulseStep / 3.0)))); BackColor = Color.FromArgb(255, r, 0, 0); //_title.ForeColor = (alpha % 2 == 0) ? Color.White : Color.GhostWhite; _title.ForeColor = (r % 2 == 0) ? Color.White : Color.GhostWhite; Invalidate(); }; _pulse.Start(); // 自動クローズ(10秒) if (autoCloseSec != 0) { _autoClose.Interval = autoCloseSec * 1000; _autoClose.Tick += (_, __) => Close(); _autoClose.Start(); } KeyPreview = true; MouseDown += All_MouseDown; Shown += AlertForm_Shown; // 前面に確実に Activate(); BringToFront(); Focus(); } private void AlertForm_Shown(object sender, EventArgs e) { // タスクバー点滅(アクティブになったらすぐ消えるが、ならなければずっと点滅) WindowFlasherUxer.Flash(this.Handle); } /// /// フォームロード時 /// /// /// private void AlertForm_Load(object sender, EventArgs e) { // 高さはFormLoadにて変更する(コンストラクタではフォームのHeightがまだデザイン時のものだから) _title.Height = Height / 3; } // マルチスクリーンの時全てを足したサイズになる! private Rectangle GetAllScreensBounds() { int minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue; foreach (var s in Screen.AllScreens) { var b = s.Bounds; minX = Math.Min(minX, b.Left); minY = Math.Min(minY, b.Top); maxX = Math.Max(maxX, b.Right); maxY = Math.Max(maxY, b.Bottom); } return new Rectangle(minX, minY, maxX - minX, maxY - minY); } private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.PopupMenu = new System.Windows.Forms.ContextMenuStrip(this.components); this.BorderMenu = new System.Windows.Forms.ToolStripMenuItem(); this.TitleMenu = new System.Windows.Forms.ToolStripMenuItem(); this.ShozokuMenu = new System.Windows.Forms.ToolStripMenuItem(); this.KyoretsuModeMenu = new System.Windows.Forms.ToolStripMenuItem(); this.PopupMenu.SuspendLayout(); this.SuspendLayout(); // // PopupMenu // this.PopupMenu.Font = new System.Drawing.Font("メイリオ", 11F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(128))); this.PopupMenu.ImageScalingSize = new System.Drawing.Size(24, 24); this.PopupMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.BorderMenu, this.TitleMenu, this.ShozokuMenu, this.KyoretsuModeMenu}); this.PopupMenu.Name = "PopupMenu"; this.PopupMenu.Size = new System.Drawing.Size(241, 197); this.PopupMenu.Opening += new System.ComponentModel.CancelEventHandler(this.PopupMenu_Opening); // // BorderMenu // this.BorderMenu.Name = "BorderMenu"; this.BorderMenu.Size = new System.Drawing.Size(240, 40); this.BorderMenu.Text = "ボーダー..."; this.BorderMenu.Click += new System.EventHandler(this.BorderMenu_Click); // // TitleMenu // this.TitleMenu.Name = "TitleMenu"; this.TitleMenu.Size = new System.Drawing.Size(240, 40); this.TitleMenu.Text = "タイトル..."; this.TitleMenu.Click += new System.EventHandler(this.TitleMenu_Click); // // ShozokuMenu // this.ShozokuMenu.Name = "ShozokuMenu"; this.ShozokuMenu.Size = new System.Drawing.Size(240, 40); this.ShozokuMenu.Text = "所属..."; this.ShozokuMenu.Click += new System.EventHandler(this.ShozokuMenu_Click); // // KyoretsuModeMenu // this.KyoretsuModeMenu.Name = "KyoretsuModeMenu"; this.KyoretsuModeMenu.Size = new System.Drawing.Size(240, 40); this.KyoretsuModeMenu.Text = "強烈モード?"; this.KyoretsuModeMenu.Click += new System.EventHandler(this.KyoretsuModeMenu_Click); // // AlertForm // this.ClientSize = new System.Drawing.Size(278, 244); this.ContextMenuStrip = this.PopupMenu; this.Name = "AlertForm"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.AlertForm_FormClosing); this.Load += new System.EventHandler(this.AlertForm_Load); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.AlertForm_KeyDown); this.PopupMenu.ResumeLayout(false); this.ResumeLayout(false); } /// /// ボーダーメニュークリック時 /// /// /// private void BorderMenu_Click(object sender, EventArgs e) { using (var frm = new TextInputForm( IniHelper.ReadValue(null, this.Name, INI_KEY_BORDER))) { if (frm.ShowDialog(this) == DialogResult.Cancel) return; IniHelper.WriteValue(null, this.Name, INI_KEY_BORDER, frm.EditedText); } } private void All_MouseDown(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) return; this.Close(); } private void AlertForm_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Escape) { Close(); } } /// /// タイトルメニュークリック時 /// /// /// private void TitleMenu_Click(object sender, EventArgs e) { using (var frm = new TextInputForm( IniHelper.ReadValue(null, this.Name, INI_KEY_TITLE))) { if (frm.ShowDialog(this) == DialogResult.Cancel) return; IniHelper.WriteValue(null, this.Name, INI_KEY_TITLE, frm.EditedText); } _title.Text = IniHelper.ReadValue(null, this.Name, INI_KEY_TITLE, "重大エラー検知"); } /// /// フォーム閉じるとき /// /// /// private void AlertForm_FormClosing(object sender, FormClosingEventArgs e) { if ( MessageBox.Show( this, "アラート画面を閉じますか?", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.No) { // Noのとき閉じない e.Cancel = true; return; } } /// /// 所属メニュークリック時 /// /// /// private void ShozokuMenu_Click(object sender, EventArgs e) { using (var frm = new TextInputForm( IniHelper.ReadValue(null, this.Name, INI_KEY_ATTRIBUTE))) { if (frm.ShowDialog(this) == DialogResult.Cancel) return; IniHelper.WriteValue(null, this.Name, INI_KEY_ATTRIBUTE, frm.EditedText); } } /// /// 強烈モードメニュークリック時 /// /// /// private void KyoretsuModeMenu_Click(object sender, EventArgs e) { IniHelper.WriteValue(null, this.Name, "KyoretsuMode", KyoretsuModeMenu.Checked ? "0" : "1"); } /// /// ポップアップメニュー開くとき /// /// /// private void PopupMenu_Opening(object sender, CancelEventArgs e) { KyoretsuModeMenu.Checked = IniHelper.ReadValue(null, this.Name, "KyoretsuMode") == "1"; } //protected override CreateParams CreateParams //{ // get // { // var cp = base.CreateParams; // cp.ExStyle |= 0x00000080; // WS_EX_TOPMOSTを強調(常に最前面) // return cp; // } //} } }