본문 바로가기

Mobile Develop/Windows Phone / Mobile

[.Net CF] 옴니아에서 하드웨어 키 감지


이번에 옴니아2에서 프로그램 실행 도중 하드웨어 키 입력 시 변경되는 문제 때문에

고민고민하다가 찾아둔 내용이라 백업 겸 작성합니다

 우선 출처는 데브피아 입니다 (http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=7083&MAEULNo=911&no=41648&ref=41520)

하드웨어 키를 입력 받기 위해서 .Net CF에서는 Hardware 컨트롤이 존제합니다만...
옴니아2에서 사용자가 변경할 수 있는 키는 단 한개로
(물론 직접 레지스트리를 수정하거나 해서 하드웨어 키를 지정할 수 는 있지만요)

HardwareButton bt;
bt.HardwareKey = HardwareKeys.ApplicationKey1;

이런식으로 선언하여 KeyDown에서 감지하기에는 통화버튼, 종료버튼, 볼륨조절, 잠금버튼, 카메라 버튼 과 같은 키 입력은 감지를 하지 못합니다

또한 키 입력을 막기 위해서

AllKeys(TRUE);

라는 것을 사용하지만, 이렇게 하면 모든 하드웨어 키 이벤트가 막히는 상황인지라...
찾다보니 API를 이용한 키보드 후킹으로 조건을 분리하여 처리하는 것을 찾았습니다

 

이예찬 (blackmagic2) 

네이티브 메소드를 이용했습니다^^

Sunscape 라는 프로그램에서 발췌(?) 했는데요,,


        public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("coredll.dll")]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

        [DllImport("coredll.dll")]
        public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);

        public struct KBDLLHOOKSTRUCT
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public IntPtr dwExtraInfo;
        }

 

이 소스를 추가해 주시교요,,


        private readonly NativeMethods.HookProc HookProcedure;
        private readonly int hHook;

이 소스를 선언부에 선언 해 주시구,,

 

Form 클래스의 생성자 메소드에


            HookProcedure = KeyboardHookProc;
            hHook = NativeMethods.SetWindowsHookEx(20, HookProcedure, IntPtr.Zero, 0);

를 추가해 주세요

 


        private static int KeyboardHookProc(int code, IntPtr wParam, IntPtr lParam)
        {
            NativeMethods.KBDLLHOOKSTRUCT hookStruct = (NativeMethods.KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(NativeMethods.KBDLLHOOKSTRUCT));
            if (code >= 0)
            {
            }
            return 1;
        }

그다음 이 함수를 추가해 주시면 됩니다^^
if문 사이에 특정한 키가 눌리면 이벤트를 발생시키는 구문을 넣으면 될 것 같군요^^;

 

잠기기는 하다만,,, 확실히 완벽한지는 잘 모르겠군요^^

완벽한지는 모르겠다고 하셨지만..  정말 잘 됩니다
KeyboardHookProc에 모든 코드를 처리하지 않고 return 1;로 하였기 때문에 전부 키가 막히는데요
이걸 약간 고치면 하드웨어 키 마다 각각 다른 작업을 처리할 수 있게 변경이 가능합니다

/// 0x72 : call button
/// 0x73 : end button
if (hookStruct.vkCode == 0x72 || hookStruct.vkCode == 0x73)
{
     SystemSettings.ScreenOrientation = ScreenOrientation.Angle0;
}
/// 0x5b : Home Button
else if (hookStruct.vkCode == 0x5b)
{
     SystemSettings.ScreenOrientation = ScreenOrientation.Angle0;
     main_VisibleForm();
}

return 0;

저는 이런식으로 고쳤는데요, 분기점이 많은 것 도 아니라서 그냥 if문으로 분리 했습니다
hookStruct에 있는 vkCode를 참조하시면 입력받는 하드웨어 버튼의 키가 나오네요
일단 옴니아1, 옴니아2에서 정상 동작 합니다
마지막에 return 0를 해준 것은 1로 해주면 통화버튼을 눌렀을 때, 키패드창이 안나타나서 return 0로 변경한 것 입니다