키보드 후킹을 해서 alt키를 ctrl키로 변경해서 넘겨받을수있을까요?

키보드 후킹을 해서 사용자가 alt키와 enter , 커서키…등을

입력을 받아서

이를 ctrl키로 변경해서

다음 객체로 넘길려고 합니다.

예를들어

alt+enter → ctrl+enter
alt+cursor → ctrl+cursor
alt+home → ctrl+home

이런식으로 말입니다.

그래서 텍스트박스에서

  private void textBox5_KeyDown(object sender, KeyEventArgs e)
  {
      if (e.KeyCode == Keys.S && System.Windows.Forms.Control.ModifierKeys == Keys.Control)
          MessageBox.Show("text ctrl +s ");

      if (e.KeyCode == Keys.N && System.Windows.Forms.Control.ModifierKeys == Keys.Control)
          MessageBox.Show("text ctrl +N ");
  }

받아서 처리하려고합니다만

잘되질않습니다.

여러 소스들을 참고해서 적용시켜보았지만

System.Windows.Forms.Control.ModifierKeys → 여기에는 원래 사용자가

누른키 즉 alt 키값이 들어오는것 같습니다.

해보신 고수님들 계신가요?

이클래스를 이용했습니다.

public class KeyboardHook
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private const int WM_SYSKEYDOWN = 0x0104;

private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

private LowLevelKeyboardProc keyboardProc;
private IntPtr hookId = IntPtr.Zero;

public event EventHandler<KeyEventArgs> KeyDown;

public void Start()
{
    keyboardProc = HookCallback;
    hookId = SetHook(keyboardProc);
}

public void Stop()
{
    UnhookWindowsHookEx(hookId);
}

private IntPtr SetHook(LowLevelKeyboardProc proc)
{
    using (Process curProcess = Process.GetCurrentProcess())
    using (ProcessModule curModule = curProcess.MainModule)
    {
        return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
    }
}

private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0 && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN))
    {
        int vkCode = Marshal.ReadInt32(lParam);

        // alt 키값인 경우 control 키로 변경
        if (vkCode == (int)Keys.Alt || vkCode == 164)
            vkCode = (int)Keys.Control;

        KeyEventArgs args = new KeyEventArgs((Keys)vkCode);
        KeyDown?.Invoke(this, args);

        if (args.Handled)
            return (IntPtr)1;
    }

    if ( wParam == (IntPtr)WM_KEYDOWN)
    {
        int vkCode = Marshal.ReadInt32(lParam);

        // alt 키값인 경우 control 키로 변경
        if (vkCode == (int)Keys.Alt)
            vkCode = (int)Keys.Control;

        KeyEventArgs args = new KeyEventArgs((Keys)vkCode);
        KeyDown?.Invoke(this, args);

        if (args.Handled)
            return (IntPtr)1;
    }


    return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam);
}

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);

}

하고자하시는게 어떤건지는 잘 모르겠지만 소프트웨어적으로는 오토핫키를 쓰시거나 오토핫키 라이브러리를 쓰시는게 편할거구요
괴상한 키보드를 쓰시느라 문제가 생긴거라면 한번 키보드가 QMK를 지원하는지를 보세요

댓글 감사합니다.
오토핫키는 github 에서 있는건가요?

원하는것은
사용자가 alt+enter 를 입력했을때
프로그램이 control+enter로 받아서 처리하는겁니다.

기존사용자가 alt+enter를 사용해서
프로그램에서 alt+enter를 적용하였으나

alt+enter를 누르면 작업관리자에서 사용자 개체가 20-30씩 늘어나게
되어서 (원인을 모릅니다만 폼안에 htmwyswic mshtml관련된 컨트롤이 원인일것 같은??)
작업자는 alt+enter를 수백번씩 칩니다.

그리하여 사용자개체가 엄청나게 늘어나서 프로그램이 멈춰버리고요

ctrl+enter 시에는 그런 증상이 없고요

사용자에게 ctl+enter로 바꾸어라고했지만 절대 바꾸지 않겠다고 하니…답이 없네요

그래서 강제로 키를 바꾸어서 사용자는 alt+enter를 누르지만

프로그램은 ctrl+enter를 받아서 처리하도록 해볼려구 하려는겁니다. ^^

오토핫키에대한 정보좀 부탁드립니다.

(e.KeyCode == Keys.S && System.Windows.Forms.Control.ModifierKeys == Keys.Control)

위 코드는 아래와 같이 수정되어야 합니다.

(e.KeyCode == Keys.S && e.Control)

alt + enter 일 때의 코드도 이러한 문제가 포함되어 있을 듯 합니다.

추가:
아니군요. 코드 정의만 보고, 형식인 줄 알았는데, Getter 였군요.

텍스트 박스에서 키값을 받아서 하려면 이렇게 되지 않나요 ?

private void TextBox1_KeyDown(object sender, KeyEventArgs e)
    {
        // Alt + Enter가 눌렸을 때
        if (e.Alt && e.KeyCode == Keys.Enter)
        {
            // Ctrl + Enter로 변환
            SendKeys.SendWait("^{ENTER}");
            e.Handled = true; // 이벤트 처리 완료
        }
    }

여러모로 어처구니없는 상황이니 정론이 별 의미가 없겠군요
아마 예상하기로는 프로그램 스스로가 자기가 받은 입력이벤트를 변조해 다시 받는것이 된다고 해도,
이를통해 Alt키 조합의 입력에서부터 발생하는 통제바깥의 동작이 우회되느냐는 또 모를문제같네요.

오토핫키는 C#개발과 별개로 윈도우상의 여러 키보드입력 등을 후킹해 동작을 바꾸거나 매크로를 실행시키는등의 범용적인 개인사용자용 스크립트및 백그라운드엔진이구요

오토핫키를 활용해 프로그램의 외부에서부터 키입력을 변경한 후 프로그램이 변경된 키입력을 인식하는것부터 테스트해보면 어떨까 싶어요
리서치해보시면 특정프로세스에 대한 Alt+Enter입력만 후킹 되도록 구성가능할겁니다.

이부터 확인해보신뒤에 오토핫키를 프로젝트에 내장시킨다거나 하는등의 고도화도 생각해봄직 하네요

상황을 보면… alt+enter 시 사용자 개체가 늘어나는 것이 문제라면
사용자 개체가 늘어나는 상황을 해결하는게 방법이 아닐까요?ㅅ?

뭔가 사용자 개체를 증가시킬만한 input 이 유지되고 있는데 이를 우회하면
또 다른 input 에 의해 문제가 재발할 가능성이 있어 보여요.

1 Like

댓글 감사합니다.

네 그게 제일 좋은 방법입니다.
그런데 지금까지 파악을 하는중인데
솔직히… 모르겠습니다.

동적으로 생성 시키는것도 아니구요 디자인타임에 올려두고
데이터를 넣고 빼고 넣고 빼는 것만 하는것입니다만
특이한것은 htmlwyswic 방식으로
쓰는 건데 정말 알다가도 모르겠습니다.

폼을 올려두고
문제가 되는 컨트롤을 올리고
텍스트박스 하나 올려서
alt+enter해보면 아무런 루틴도 없어도

사용자 개체가 증가합니다.

염치없지만 혹시나 여력이 되신다면 간단한 프로젝트만들어서 한번 올려볼까요?

댓글감사합니다.

댓글 감사합니다.

저도 잠시 검색해봤는데

스크립트 언어 같은거인가 싶네요?

좀더 알아봐야 할것 같습니다. 좋은 대안이 되었으면 좋겠습니다.

저 이벤트가 발생하기전에

이미 키값이 바뀌어서 들어와야 될것 같아요.

그래서 후킹을 생각한거구요.