JJServiceManagerEnt/Windows/CodeConfirmWindow.cs

167 lines
6.1 KiB
C#

using System.Security.Cryptography;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace JJServiceManager
{
/// <summary>
/// 위험 작업 확인창: 무작위 숫자 6자리를 보여주고, 그 숫자를 정확히 입력해야만 확인됨
/// (Windows 강제종료 / Windows 재시작)
/// </summary>
public sealed class CodeConfirmWindow : Window
{
private readonly string _code;
private readonly TextBox _input;
private readonly Button _ok;
private readonly TextBlock _hint;
public CodeConfirmWindow(string title, string message, string actionText)
{
_code = RandomNumberGenerator.GetInt32(0, 1_000_000).ToString("D6");
Title = title;
Width = 440;
SizeToContent = SizeToContent.Height;
ResizeMode = ResizeMode.NoResize;
WindowStartupLocation = WindowStartupLocation.CenterOwner;
ShowInTaskbar = false;
Topmost = true;
FontFamily = new FontFamily("Malgun Gothic");
FontSize = 13;
Background = Brushes2.Make("#FAFAFA");
AppIcon.Apply(this);
var root = new StackPanel { Margin = new Thickness(20, 18, 20, 16) };
// 경고 문구
root.Children.Add(new TextBlock
{
Text = "⚠ " + message,
TextWrapping = TextWrapping.Wrap,
Foreground = Brushes2.Make("#B71C1C"),
FontWeight = FontWeights.SemiBold,
Margin = new Thickness(0, 0, 0, 14)
});
root.Children.Add(new TextBlock
{
Text = "계속하려면 아래 숫자 6자리를 그대로 입력하세요.",
Foreground = Brushes2.Make("#455A64"),
Margin = new Thickness(0, 0, 0, 8)
});
// 무작위 숫자 (복사할 수 없는 글자로 표시)
var codeBox = new Border
{
Background = Brushes2.Make("#FFF8E1"),
BorderBrush = Brushes2.Make("#FFB300"),
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(4),
Padding = new Thickness(0, 8, 0, 8),
Margin = new Thickness(0, 0, 0, 12),
Child = new TextBlock
{
Text = string.Join(" ", _code.ToCharArray()),
FontFamily = new FontFamily("Consolas"),
FontSize = 30,
FontWeight = FontWeights.Bold,
Foreground = Brushes2.Make("#E65100"),
HorizontalAlignment = HorizontalAlignment.Center,
IsHitTestVisible = false
}
};
root.Children.Add(codeBox);
// 입력칸 (숫자만, 붙여넣기 불가)
_input = new TextBox
{
MaxLength = 6,
FontFamily = new FontFamily("Consolas"),
FontSize = 24,
Height = 42,
HorizontalContentAlignment = HorizontalAlignment.Center,
VerticalContentAlignment = VerticalAlignment.Center,
ToolTip = "위의 숫자 6자리를 입력"
};
InputMethod.SetIsInputMethodEnabled(_input, false);
_input.PreviewTextInput += (s, e) =>
{
foreach (var c in e.Text)
if (c < '0' || c > '9') { e.Handled = true; return; }
};
DataObject.AddPastingHandler(_input, (s, e) => e.CancelCommand());
_input.TextChanged += (s, e) => UpdateState();
root.Children.Add(_input);
_hint = new TextBlock
{
Text = " ",
Foreground = Brushes2.Make("#C62828"),
Margin = new Thickness(0, 6, 0, 0),
HorizontalAlignment = HorizontalAlignment.Center
};
root.Children.Add(_hint);
// 버튼
var buttons = new StackPanel
{
Orientation = Orientation.Horizontal,
HorizontalAlignment = HorizontalAlignment.Right,
Margin = new Thickness(0, 10, 0, 0)
};
_ok = new Button { Content = actionText, IsEnabled = false, MinWidth = 110 };
_ok.SetResourceReference(StyleProperty, "DangerButton");
_ok.Click += (s, e) => Submit();
var cancel = new Button { Content = "취소", MinWidth = 80, IsCancel = true };
buttons.Children.Add(_ok);
buttons.Children.Add(cancel);
root.Children.Add(buttons);
Content = root;
Loaded += (s, e) => _input.Focus();
PreviewKeyDown += (s, e) =>
{
if (e.Key == Key.Enter)
{
e.Handled = true;
Submit();
}
};
}
private void UpdateState()
{
var t = _input.Text;
_ok.IsEnabled = t == _code;
if (t.Length == 6 && t != _code) _hint.Text = "숫자가 다릅니다. 다시 입력하세요.";
else _hint.Text = " ";
}
private void Submit()
{
if (_input.Text == _code)
{
DialogResult = true;
}
else
{
_hint.Text = _input.Text.Length == 0 ? "숫자를 입력하세요." : "숫자가 다릅니다. 다시 입력하세요.";
_input.SelectAll();
_input.Focus();
}
}
/// <summary>확인창을 띄우고, 숫자를 정확히 입력해 확인했으면 true</summary>
public static bool Ask(Window owner, string title, string message, string actionText)
{
var w = new CodeConfirmWindow(title, message, actionText);
if (owner != null && owner.IsVisible) w.Owner = owner;
else w.WindowStartupLocation = WindowStartupLocation.CenterScreen;
return w.ShowDialog() == true;
}
}
}