diff --git a/Program.cs b/Program.cs index ba6af1d..def494b 100644 --- a/Program.cs +++ b/Program.cs @@ -2,6 +2,7 @@ using System; using System.Drawing; using System.IO; using System.Security.Cryptography; +using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; using Microsoft.Win32; @@ -50,8 +51,8 @@ namespace WindowsKeyInfo private const int HashSize = 32; // 내장 마스터 암호 (변경 불가) — 원문 대신 솔트와 해시만 보관 - private static readonly byte[] BuiltInSalt = Convert.FromBase64String("R2lR1GEm7i5aAldpu9RynQ=="); - private static readonly byte[] BuiltInHash = Convert.FromBase64String("r5zE7lvhdNTDklWIrkDd47Vhqq8lVBt9So8aYMLGFnY="); + private static readonly byte[] BuiltInSalt = Convert.FromBase64String("nkeJJJqcUJ+4KYuNEcYFiQ=="); + private static readonly byte[] BuiltInHash = Convert.FromBase64String("9Y8DuoR8YwDoIak79Wt0db3truf7+Z0rMPhEPY2c6og="); /// 내장 암호 또는 사용자 지정 암호 중 하나와 일치하면 true public static bool Verify(string password) @@ -179,6 +180,100 @@ namespace WindowsKeyInfo } } + /// 암호 입력칸용: 들어가면 영문 입력 + Caps Lock 끔, 나가면(창 닫힘 포함) 원래 입력 방식으로 복구 + internal static class EnglishInput + { + [DllImport("imm32.dll")] private static extern IntPtr ImmGetContext(IntPtr hWnd); + [DllImport("imm32.dll")] private static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC); + [DllImport("imm32.dll")] private static extern bool ImmGetConversionStatus(IntPtr hIMC, out int conversion, out int sentence); + [DllImport("imm32.dll")] private static extern bool ImmSetConversionStatus(IntPtr hIMC, int conversion, int sentence); + [DllImport("user32.dll")] private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo); + + private const int ImeCmodeNative = 0x0001; // 한글 모드 비트 + private const byte VkCapital = 0x14; + private const uint KeyEventFKeyUp = 0x0002; + + public static void Attach(TextBox box) + { + InputLanguage saved = null; + bool active = false; + + box.ImeMode = ImeMode.Alpha; + + Action restore = () => + { + if (!active) return; + active = false; + try + { + if (saved != null && !saved.Equals(InputLanguage.CurrentInputLanguage)) + InputLanguage.CurrentInputLanguage = saved; + } + catch { } + }; + + box.Enter += (s, e) => + { + if (active) return; + active = true; + saved = InputLanguage.CurrentInputLanguage; + + try + { + // 1) 영어 키보드가 설치돼 있으면 그쪽으로 전환 + InputLanguage english = null; + foreach (InputLanguage lang in InputLanguage.InstalledInputLanguages) + { + if (lang.Culture.TwoLetterISOLanguageName == "en") { english = lang; break; } + } + if (english != null && !english.Equals(InputLanguage.CurrentInputLanguage)) + InputLanguage.CurrentInputLanguage = english; + } + catch { } + + // 2) 영어 키보드가 없으면(또는 여전히 한글 IME면) IME를 영문 모드로 + SetImeAlphanumeric(box); + + // 3) Caps Lock이 켜져 있으면 끔 + TurnOffCapsLock(); + }; + + box.Leave += (s, e) => restore(); + box.HandleDestroyed += (s, e) => restore(); + } + + private static void SetImeAlphanumeric(Control c) + { + try + { + IntPtr himc = ImmGetContext(c.Handle); + if (himc == IntPtr.Zero) return; + try + { + int conv, sent; + if (ImmGetConversionStatus(himc, out conv, out sent) && (conv & ImeCmodeNative) != 0) + ImmSetConversionStatus(himc, conv & ~ImeCmodeNative, sent); + } + finally + { + ImmReleaseContext(c.Handle, himc); + } + } + catch { } + } + + private static void TurnOffCapsLock() + { + try + { + if (!Control.IsKeyLocked(Keys.CapsLock)) return; + keybd_event(VkCapital, 0x45, 0, UIntPtr.Zero); + keybd_event(VkCapital, 0x45, KeyEventFKeyUp, UIntPtr.Zero); + } + catch { } + } + } + /// 처음 알림창: "Windows Key" + [확인]만 표시, 입력은 화면 밖 숨은 칸으로 받음 internal sealed class UnlockDialog : Form { @@ -224,6 +319,8 @@ namespace WindowsKeyInfo ShortcutsEnabled = false }; + EnglishInput.Attach(_hidden); + Controls.Add(lbl); Controls.Add(btnOk); Controls.Add(_hidden); @@ -285,6 +382,7 @@ namespace WindowsKeyInfo Controls.Add(_box); Controls.Add(btnOk); Controls.Add(btnCancel); + EnglishInput.Attach(_box); AcceptButton = btnOk; CancelButton = btnCancel; ActiveControl = _box; @@ -344,6 +442,7 @@ namespace WindowsKeyInfo Controls.Add(_box); Controls.Add(btnOk); Controls.Add(btnCancel); + EnglishInput.Attach(_box); AcceptButton = btnOk; CancelButton = btnCancel; }