기능 추가 Ctrl +Shift + P
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019WT2pzDE45iP4QMAAo7cyzmain
parent
9962c4e7dd
commit
e7f39a7bc1
149
Program.cs
149
Program.cs
|
|
@ -247,6 +247,64 @@ namespace WindowsKeyInfo
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>제한 화면에서 Ctrl+Shift+P로 여는 마스터 암호 입력 창 (틀리면 알림 후 다시 입력)</summary>
|
||||
internal sealed class MasterPasswordDialog : Form
|
||||
{
|
||||
private readonly TextBox _box;
|
||||
|
||||
public MasterPasswordDialog()
|
||||
{
|
||||
Text = "Windows Key";
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.CenterParent;
|
||||
AutoScaleMode = AutoScaleMode.Dpi;
|
||||
Font = new Font("맑은 고딕", 9.5f);
|
||||
ClientSize = new Size(360, 130);
|
||||
|
||||
var lbl = new Label
|
||||
{
|
||||
Text = "마스터 암호를 입력하세요.",
|
||||
Location = new Point(14, 14),
|
||||
Size = new Size(332, 22)
|
||||
};
|
||||
_box = new TextBox
|
||||
{
|
||||
Location = new Point(14, 42),
|
||||
Size = new Size(332, 28),
|
||||
UseSystemPasswordChar = true
|
||||
};
|
||||
|
||||
var btnOk = new Button { Text = "확인", Location = new Point(126, 84), Size = new Size(108, 32) };
|
||||
btnOk.Click += (s, e) => TryAccept();
|
||||
var btnCancel = new Button { Text = "취소", Location = new Point(240, 84), Size = new Size(106, 32), DialogResult = DialogResult.Cancel };
|
||||
|
||||
Controls.Add(lbl);
|
||||
Controls.Add(_box);
|
||||
Controls.Add(btnOk);
|
||||
Controls.Add(btnCancel);
|
||||
AcceptButton = btnOk;
|
||||
CancelButton = btnCancel;
|
||||
ActiveControl = _box;
|
||||
}
|
||||
|
||||
private void TryAccept()
|
||||
{
|
||||
if (PasswordStore.Verify(_box.Text))
|
||||
{
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
MessageBox.Show(this, "암호가 틀렸습니다.", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
_box.Clear();
|
||||
_box.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>암호 변경 창 (새 암호 한 번 입력)</summary>
|
||||
internal sealed class ChangePasswordDialog : Form
|
||||
{
|
||||
|
|
@ -409,15 +467,24 @@ namespace WindowsKeyInfo
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>메인 창 (WinForms). fullMode=false면 키 정보 4줄 + 복사/파일로 저장/닫기만 표시</summary>
|
||||
/// <summary>메인 창 (WinForms). 제한 모드면 키 정보 4줄 + 복사/파일로 저장/닫기만 표시,
|
||||
/// 제한 모드에서 Ctrl+Shift+P → 마스터 암호 입력 → 맞으면 그 자리에서 전체 화면으로 전환</summary>
|
||||
internal sealed class MainForm : Form
|
||||
{
|
||||
private const Keys UnlockShortcut = Keys.Control | Keys.Shift | Keys.P;
|
||||
|
||||
private readonly KeyReader.KeyInfo _info;
|
||||
private readonly TextBox _txtProductName;
|
||||
private readonly TextBox _txtProductId;
|
||||
private readonly TextBox _txtInstalledKey;
|
||||
private readonly TextBox _txtBackupKey;
|
||||
|
||||
// 전체 모드에서만 보이는 컨트롤
|
||||
private readonly Button _btnChangePw;
|
||||
private readonly FlowLayoutPanel _phone;
|
||||
private readonly FlowLayoutPanel _links;
|
||||
private bool _fullMode;
|
||||
|
||||
public MainForm(bool fullMode)
|
||||
{
|
||||
Text = "Windows 제품 키 백업";
|
||||
|
|
@ -426,7 +493,7 @@ namespace WindowsKeyInfo
|
|||
StartPosition = FormStartPosition.CenterScreen;
|
||||
AutoScaleMode = AutoScaleMode.Dpi;
|
||||
Font = new Font("맑은 고딕", 9.5f);
|
||||
ClientSize = fullMode ? new Size(560, 344) : new Size(560, 240);
|
||||
ClientSize = new Size(560, 344);
|
||||
|
||||
var table = new TableLayoutPanel
|
||||
{
|
||||
|
|
@ -465,20 +532,12 @@ namespace WindowsKeyInfo
|
|||
buttons.Controls.Add(btnSave);
|
||||
buttons.Controls.Add(btnCopy);
|
||||
|
||||
if (fullMode)
|
||||
{
|
||||
var btnChangePw = MakeButton("암호 변경");
|
||||
btnChangePw.Click += (s, e) => ChangePassword();
|
||||
buttons.Controls.Add(btnChangePw);
|
||||
}
|
||||
_btnChangePw = MakeButton("암호 변경");
|
||||
_btnChangePw.Click += (s, e) => ChangePassword();
|
||||
buttons.Controls.Add(_btnChangePw);
|
||||
|
||||
Controls.Add(table);
|
||||
Controls.Add(buttons);
|
||||
|
||||
if (fullMode)
|
||||
{
|
||||
// 화면 하단 바로가기 버튼 (기본 브라우저로 열기)
|
||||
var links = new FlowLayoutPanel
|
||||
_links = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Bottom,
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
|
|
@ -496,13 +555,13 @@ namespace WindowsKeyInfo
|
|||
var btnGetCidInfo = MakeLinkButton("GETCID.INFO", "https://getcid.info/");
|
||||
var btnGetCidUs = MakeLinkButton("GETCID.US", "https://getcid.us/");
|
||||
|
||||
links.Controls.Add(lblLinks);
|
||||
links.Controls.Add(btnGetCidMe);
|
||||
links.Controls.Add(btnGetCidInfo);
|
||||
links.Controls.Add(btnGetCidUs);
|
||||
_links.Controls.Add(lblLinks);
|
||||
_links.Controls.Add(btnGetCidMe);
|
||||
_links.Controls.Add(btnGetCidInfo);
|
||||
_links.Controls.Add(btnGetCidUs);
|
||||
|
||||
// 전화 인증 (slmgr 명령어 방식 — slui 4 창이 막혀 있어도 동작)
|
||||
var phone = new FlowLayoutPanel
|
||||
_phone = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Bottom,
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
|
|
@ -520,9 +579,9 @@ namespace WindowsKeyInfo
|
|||
var btnEnterCid = MakeActionButton("② 확인 ID 입력");
|
||||
btnEnterCid.Click += (s, e) => EnterConfirmationId();
|
||||
|
||||
phone.Controls.Add(lblPhone);
|
||||
phone.Controls.Add(btnShowIid);
|
||||
phone.Controls.Add(btnEnterCid);
|
||||
_phone.Controls.Add(lblPhone);
|
||||
_phone.Controls.Add(btnShowIid);
|
||||
_phone.Controls.Add(btnEnterCid);
|
||||
|
||||
var tip = new ToolTip();
|
||||
tip.SetToolTip(btnShowIid, "설치 ID(Installation ID)를 확인합니다 (slmgr /dti)");
|
||||
|
|
@ -532,10 +591,10 @@ namespace WindowsKeyInfo
|
|||
tip.SetToolTip(btnGetCidUs, "https://getcid.us/");
|
||||
|
||||
// Dock=Bottom 은 나중에 추가한 것이 더 아래에 배치됨
|
||||
Controls.Add(phone);
|
||||
Controls.Add(links);
|
||||
}
|
||||
|
||||
Controls.Add(table);
|
||||
Controls.Add(buttons);
|
||||
Controls.Add(_phone);
|
||||
Controls.Add(_links);
|
||||
CancelButton = btnClose;
|
||||
|
||||
try
|
||||
|
|
@ -560,6 +619,44 @@ namespace WindowsKeyInfo
|
|||
_txtProductId.Text = _info.ProductId;
|
||||
_txtInstalledKey.Text = _info.InstalledKey;
|
||||
_txtBackupKey.Text = _info.BackupKey;
|
||||
|
||||
// 처음 표시 모드 (DPI 배율 적용 전이므로 기준 크기로 지정)
|
||||
_fullMode = fullMode;
|
||||
_btnChangePw.Visible = fullMode;
|
||||
_phone.Visible = fullMode;
|
||||
_links.Visible = fullMode;
|
||||
ClientSize = new Size(560, fullMode ? 344 : 240);
|
||||
}
|
||||
|
||||
/// <summary>제한 모드 → 전체 모드 전환 (실행 중, DPI 배율이 적용된 실제 크기 기준으로 창 높이 증가)</summary>
|
||||
private void SwitchToFullMode()
|
||||
{
|
||||
if (_fullMode) return;
|
||||
_fullMode = true;
|
||||
|
||||
float scale = _phone.Height / 44f; // 현재 DPI 배율
|
||||
int extra = _phone.Height + _links.Height + (int)Math.Round(10 * scale); // 344 - 240 = 104 = 44 + 50 + 10
|
||||
|
||||
SuspendLayout();
|
||||
_btnChangePw.Visible = true;
|
||||
_phone.Visible = true;
|
||||
_links.Visible = true;
|
||||
ClientSize = new Size(ClientSize.Width, ClientSize.Height + extra);
|
||||
ResumeLayout(true);
|
||||
}
|
||||
|
||||
/// <summary>제한 모드에서 Ctrl+Shift+P → 마스터 암호 입력 창</summary>
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||
{
|
||||
if (keyData == UnlockShortcut && !_fullMode)
|
||||
{
|
||||
using (var dlg = new MasterPasswordDialog())
|
||||
{
|
||||
if (dlg.ShowDialog(this) == DialogResult.OK) SwitchToFullMode();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
private static TextBox AddRow(TableLayoutPanel table, int row, string caption, bool monospace)
|
||||
|
|
|
|||
Loading…
Reference in New Issue