Files
2026-06-01 13:23:34 +09:00

348 lines
14 KiB
C#

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;
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="errorLine">ログのエラー行</param>
/// <param name="dateTime">日時</param>
/// <param name="kyouretsu">強烈画面</param>
/// <param name="autoCloseSec">自動で閉じる秒数</param>
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);
}
/// <summary>
/// フォームロード時
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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);
}
/// <summary>
/// ボーダーメニュークリック時
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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();
}
}
/// <summary>
/// タイトルメニュークリック時
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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, "重大エラー検知");
}
/// <summary>
/// フォーム閉じるとき
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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;
}
}
/// <summary>
/// 所属メニュークリック時
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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);
}
}
/// <summary>
/// 強烈モードメニュークリック時
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void KyoretsuModeMenu_Click(object sender, EventArgs e)
{
IniHelper.WriteValue(null, this.Name, "KyoretsuMode", KyoretsuModeMenu.Checked ? "0" : "1");
}
/// <summary>
/// ポップアップメニュー開くとき
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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;
// }
//}
}
}