첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

728x90
반응형

■ 마우스/키보드 후킹하기

------------------------------------------------------------------------------------------------------------------------


TestSolution.zip



[TestLibrary 프로젝트]

 

BlockingQueue.cs

 

 

using System.Collections.Generic;

using System.Threading;

 

namespace TestLibrary

{

    /// <summary>

    /// 차단 큐

    /// </summary>

    /// <typeparam name="TItem">항목 타입</typeparam>

    internal class BlockingQueue<TItem>

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        ///

        /// </summary>

        private Queue<TItem> queue = new Queue<TItem>();

 

        /// <summary>

        /// 세마포어

        /// </summary>

        private Semaphore semaphore = new Semaphore(0, int.MaxValue);

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 큐에 넣기 - Enqueue(item)

 

        /// <summary>

        /// 큐에 넣기

        /// </summary>

        /// <param name="item">항목</param>

        public void Enqueue(TItem item)

        {

            lock(this.queue)

            {

                this.queue.Enqueue(item);

            }

 

            this.semaphore.Release();

        }

 

        #endregion

        #region 큐에서 꺼내기 - Dequeue()

 

        /// <summary>

        /// 큐에서 꺼내기

        /// </summary>

        /// <returns>항목</returns>

        public TItem Dequeue()

        {

            this.semaphore.WaitOne();

 

            lock(this.queue)

            {

                return this.queue.Dequeue();

            }

        }

 

        #endregion

    }

}

 

 

MouseHookEventArgs.cs

 

 

using System;

using System.Runtime.InteropServices;

 

namespace TestLibrary

{

    /// <summary>

    /// 마우스 후킹 이벤트 인자

    /// </summary>

    public class MouseHookEventArgs : EventArgs

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Enumeration

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 윈도우 메시지 - WindowMessage

 

        /// <summary>

        /// 윈도우 메시지

        /// </summary>

        [Serializable]

        public enum WindowMessage

        {

            /// <summary>

            /// WM_LBUTTONDOWN

            /// </summary>

            WM_LBUTTONDOWN = 0x0201,

 

            /// <summary>

            /// WM_LBUTTONUP

            /// </summary>

            WM_LBUTTONUP = 0x0202,

 

            /// <summary>

            /// WM_MOUSEMOVE

            /// </summary>

            WM_MOUSEMOVE = 0x0200,

 

            /// <summary>

            /// WM_MOUSEWHEEL

            /// </summary>

            WM_MOUSEWHEEL = 0x020A,

 

            /// <summary>

            /// WM_MOUSEHWHEEL

            /// </summary>

            WM_MOUSEHWHEEL = 0x020E,

 

            /// <summary>

            /// WM_RBUTTONDOWN

            /// </summary>

            WM_RBUTTONDOWN = 0x0204,

 

            /// <summary>

            /// WM_RBUTTONUP

            /// </summary>

            WM_RBUTTONUP = 0x0205,

 

            /// <summary>

            /// WM_MBUTTONDOWN

            /// </summary>

            WM_MBUTTONDOWN = 0x0207,

 

            /// <summary>

            /// WM_MBUTTONUP

            /// </summary>

            WM_MBUTTONUP = 0x0208

        };

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 메시지 - Message

 

        /// <summary>

        /// 메시지

        /// </summary>

        public WindowMessage Message { get; set; }

 

        #endregion

        #region 데이터 - Data

 

        /// <summary>

        /// 데이터

        /// </summary>

        public WIN32Helper.MSLLHOOKSTRUCT Data { get; set; }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Internal

 

        #region 생성자 - MouseHookEventArgs(wordParameter, longParameter)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="wordParameter">WORD 매개 변수</param>

        /// <param name="longParameter">LONG 매개 변수</param>

        internal MouseHookEventArgs(IntPtr wordParameter, IntPtr longParameter)

        {

            WIN32Helper.MSLLHOOKSTRUCT data = (WIN32Helper.MSLLHOOKSTRUCT)Marshal.PtrToStructure

            (

                longParameter,

                typeof(WIN32Helper.MSLLHOOKSTRUCT)

            );

 

            Message = (WindowMessage)wordParameter;

            Data    = data;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 문자열 구하기 - ToString()

 

        /// <summary>

        /// 문자열 구하기

        /// </summary>

        /// <returns>문자열</returns>

        public override string ToString()

        {

            return string.Format

            (

                "Time : {0}, Message : {1}, Point : ({2},{3})",

                Data.Time,

                Message,

                Data.Point.X,

                Data.Point.Y

            );

        }

 

        #endregion

    }

}

 

 

KeyboardHookEventArgs.cs

 

 

using System;

using System.Runtime.InteropServices;

 

namespace TestLibrary

{

    /// <summary>

    /// 키보드 후킹 이벤트 인자

    /// </summary>

    public class KeyboardHookEventArgs : EventArgs

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Enumeration

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 윈도우 메시지 - WindowMessage

 

        /// <summary>

        /// 윈도우 메시지

        /// </summary>

        [Serializable]

        public enum WindowMessage

        {

            /// <summary>

            /// WM_KEYDOWN

            /// </summary>

            WM_KEYDOWN = 0x0100,

 

            /// <summary>

            /// WM_KEYUP

            /// </summary>

            WM_KEYUP = 0x0101,

 

            /// <summary>

            /// WM_SYSKEYDOWN

            /// </summary>

            WM_SYSKEYDOWN = 0x0104,

 

            /// <summary>

            /// WM_SYSKEYUP

            /// </summary>

            WM_SYSKEYUP = 0x0105

        };

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 메시지 - Message

 

        /// <summary>

        /// 메시지

        /// </summary>

        public WindowMessage Message { get; set; }

 

        #endregion

        #region 데이터 - Data

 

        /// <summary>

        /// 데이터

        /// </summary>

        public WIN32Helper.KBDLLHOOKSTRUCT Data { get; set; }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Internal

 

        #region 생성자 - KeyboardHookEventArgs(wordParameter, longParameter)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="wordParameter">WORD 매개 변수</param>

        /// <param name="longParameter">LONG 매개 변수</param>

        internal KeyboardHookEventArgs(IntPtr wordParameter, IntPtr longParameter)

        {

            WIN32Helper.KBDLLHOOKSTRUCT data = (WIN32Helper.KBDLLHOOKSTRUCT)Marshal.PtrToStructure

            (

                longParameter,

                typeof(WIN32Helper.KBDLLHOOKSTRUCT)

            );

 

            Message = (WindowMessage)wordParameter;

            Data    = data;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 문자열 구하기 - ToString()

 

        /// <summary>

        /// 문자열 구하기

        /// </summary>

        /// <returns>문자열</returns>

        public override string ToString()

        {

            return string.Format

            (

                "Time : {0}, Message : {1}, VirtualKeyCode : {2}, ScanCode : {3}",

                Data.Time,

                Message,

                Data.VirtualKeyCode,

                Data.ScanCode

            );

        }

 

        #endregion

    }

}

 

 

WIN32Helper.cs

 

 

using System;

using System.Runtime.InteropServices;

 

namespace TestLibrary

{

    /// <summary>

    /// WIN32 헬퍼

    /// </summary>

    public sealed class WIN32Helper

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Import

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Internal

 

        #region 확장 윈도우 후킹 설정하기 - SetWindowsHookEx(hookID, hookDelegate, instanceHandle, threadID)

 

        /// <summary>

        /// 확장 윈도우 후킹 설정하기

        /// </summary>

        /// <param name="hookID">후킹 ID</param>

        /// <param name="hookDelegate">후킹 대리자</param>

        /// <param name="instanceHandle">인스턴스 핸들</param>

        /// <param name="threadID">쓰레드 ID</param>

        /// <returns>처리 결과</returns>

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

        internal static extern int SetWindowsHookEx(int hookID, HookDelegate hookDelegate, IntPtr instanceHandle, int threadID);

 

        #endregion

        #region 확장 윈도우 후킹 설정 취소하기 - UnhookWindowsHookEx(hookID)

 

        /// <summary>

        /// 확장 윈도우 후킹 설정 취소하기

        /// </summary>

        /// <param name="hookID">후킹 ID</param>

        /// <returns>처리 결과</returns>

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

        internal static extern bool UnhookWindowsHookEx(int hookID);

 

        #endregion

        #region 확장 다음 후킹 호출하기 - CallNextHookEx(hookID, code, wordParameter, longParameter)

 

        /// <summary>

        /// 확장 다음 후킹 호출하기

        /// </summary>

        /// <param name="hookID">후킹 ID</param>

        /// <param name="code">코드</param>

        /// <param name="wordParameter">WORD 매개 변수</param>

        /// <param name="longParameter">LONG 매개 변수</param>

        /// <returns>처리 결과</returns>

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

        internal static extern int CallNextHookEx(int hookID, int code, IntPtr wordParameter, IntPtr longParameter);

 

        #endregion

        #region 모듈 핸들 구하기 - GetModuleHandle(moduleName)

 

        /// <summary>

        /// 모듈 핸들 구하기

        /// </summary>

        /// <param name="moduleName">모듈명</param>

        /// <returns>모듈 핸들</returns>

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]

        internal static extern IntPtr GetModuleHandle(string moduleName);

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Delegate

        ////////////////////////////////////////////////////////////////////////////////////////// Internal

 

        #region 후킹 대리자 - HookDelegate(code, wordParameter, longParameter)

 

        /// <summary>

        /// 후킹 대리자

        /// </summary>

        /// <param name="code">코드</param>

        /// <param name="wordParameter">WORD 매개 변수</param>

        /// <param name="longParameter">LONG 매개 변수</param>

        /// <returns>처리 결과</returns>

        internal delegate int HookDelegate(int code, IntPtr wordParameter, IntPtr longParameter);

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Structure

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 포인트 - POINT

 

        /// <summary>

        /// 포인트

        /// </summary>

        [StructLayout(LayoutKind.Sequential), Serializable()]

        public struct POINT

        {

            //////////////////////////////////////////////////////////////////////////////////////////////////// Field

            ////////////////////////////////////////////////////////////////////////////////////////// Public

 

            #region Field

 

            /// <summary>

            /// X

            /// </summary>

            public uint X;

 

            /// <summary>

            /// Y

            /// </summary>

            public uint Y;

 

            #endregion

        }

 

        #endregion

        #region 키보드 하위 레벨 후킹 구조체 - KBDLLHOOKSTRUCT

 

        /// <summary>

        /// 키보드 하위 레벨 후킹 구조체

        /// </summary>

        [StructLayout(LayoutKind.Sequential), Serializable()]

        public struct KBDLLHOOKSTRUCT

        {

            //////////////////////////////////////////////////////////////////////////////////////////////////// Field

            ////////////////////////////////////////////////////////////////////////////////////////// Public

 

            #region Field

 

            /// <summary>

            /// 가상 키 코드

            /// </summary>

            public int VirtualKeyCode;

 

            /// <summary>

            /// 스캔 코드

            /// </summary>

            public int ScanCode;

 

            /// <summary>

            /// 플래그

            /// </summary>

            public int Flag;

 

            /// <summary>

            /// 시간

            /// </summary>

            public int Time;

 

            /// <summary>

            /// 부가 정보

            /// </summary>

            public IntPtr ExtraInformation;

 

            #endregion

        }

 

        #endregion

        #region 마우스 하위 레벨 후킹 구조체 - MSLLHOOKSTRUCT

 

        /// <summary>

        /// 마우스 하위 레벨 후킹 구조체

        /// </summary>

        [StructLayout(LayoutKind.Sequential), Serializable()]

        public struct MSLLHOOKSTRUCT

        {

            //////////////////////////////////////////////////////////////////////////////////////////////////// Field

            ////////////////////////////////////////////////////////////////////////////////////////// Public

 

            #region Field

 

            /// <summary>

            /// 포인트

            /// </summary>

            public POINT Point;

 

            /// <summary>

            /// 마우스 데이터

            /// </summary>

            public uint MouseData;

 

            /// <summary>

            /// 플래그

            /// </summary>

            public int Flag;

            

            /// <summary>

            /// 시간

            /// </summary>

            public int Time;

 

            /// <summary>

            /// 부가 정보

            /// </summary>

            public IntPtr ExtraInformation;

 

            #endregion

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Internal

 

        #region Field

 

        /// <summary>

        /// WH_KEYBOARD_LL

        /// </summary>

        internal const int WH_KEYBOARD_LL = 13;

 

        /// <summary>

        /// WH_MOUSE_LL

        /// </summary>

        internal const int WH_MOUSE_LL = 14;

 

        #endregion

    }

}

 

 

HookBase.cs

 

 

using System;

using System.Diagnostics;

using System.Threading;

using System.Windows.Forms;

 

namespace TestLibrary

{

    /// <summary>

    /// 후킹 베이스

    /// </summary>

    /// <typeparam name="TMessage">메시지 타입</typeparam>

    public abstract class HookBase<TMessage>

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region Field

 

        /// <summary>

        /// 후킹 핸들

        /// </summary>

        protected int hookHandle = 0;

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 메시지 차단 큐

        /// </summary>

        private BlockingQueue<TMessage> messageBlockingQueue = new BlockingQueue<TMessage>();

 

        /// <summary>

        /// 메시지 쓰레드

        /// </summary>

        private Thread messageThread = null;

 

        /// <summary>

        /// 잠금 객체

        /// </summary>

        private Object lockObject = new Object();

 

        /// <summary>

        /// 후킹 대리자

        /// </summary>

        private WIN32Helper.HookDelegate hookDelegate = null;

 

        /// <summary>

        /// 유효 여부

        /// </summary>

        private bool isValid = true;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 후킹 ID - HookID

 

        /// <summary>

        /// 후킹 ID

        /// </summary>

        protected abstract int HookID { get; }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - HookBase()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public HookBase()

        {

            this.hookDelegate = new WIN32Helper.HookDelegate(ProcessHook);

 

            Application.ApplicationExit += Application_ApplicationExit;

 

            this.messageThread = new Thread(ProcessMessageThread)

            {

                Name         = "CommonHook",

                IsBackground = true

            };

 

            this.messageThread.Start();

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 후킹 시작하기 - StartHook()

 

        /// <summary>

        /// 후킹 시작하기

        /// </summary>

        /// <returns>처리 결과</returns>

        public bool StartHook()

        {

            lock(this.lockObject)

            {

                if(hookHandle != 0)

                {

                    return false;

                }

 

                this.hookHandle = WIN32Helper.SetWindowsHookEx

                (

                    HookID,

                    this.hookDelegate,

                    HookBase<TMessage>.GetCurrentModuleHandle(),

                    0

                );

 

                return (hookHandle != 0);

            }

        }

 

        #endregion

        #region 후킹 중단하기 - StopHook()

 

        /// <summary>

        /// 후킹 중단하기

        /// </summary>

        public void StopHook()

        {

            lock(this.lockObject)

            {

                if(this.hookHandle == 0)

                {

                    return;

                }

 

                WIN32Helper.UnhookWindowsHookEx(hookHandle);

 

                this.hookHandle = 0;

            }

        }

 

        #endregion

        #region 리소스 해제하기 - Dispose()

 

        /// <summary>

        /// 리소스 해제하기

        /// </summary>

        public void Dispose()

        {

            this.isValid = false;

 

            StopHook();

 

            Application.ApplicationExit -= Application_ApplicationExit;

        }

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 후킹 처리하기 - ProcessHook(code, wordParameter, longParameter)

 

        /// <summary>

        /// 후킹 처리하기

        /// </summary>

        /// <param name="code">코드</param>

        /// <param name="wordParameter">WORD 매개 변수</param>

        /// <param name="longParameter">LONG 매개 변수</param>

        /// <returns>처리 결과</returns>

        protected virtual int ProcessHook(int code, IntPtr wordParameter, IntPtr longParameter)

        {

            if(code >= 0)

            {

                TMessage message = ParseMessage(wordParameter, longParameter);

 

                this.messageBlockingQueue.Enqueue(message);

            }

 

            return WIN32Helper.CallNextHookEx(this.hookHandle, code, wordParameter, longParameter);

        }

 

        #endregion

        #region 메시지 후킹시 처리하기 - OnMessageHooked(message)

 

        /// <summary>

        /// 메시지 후킹시 처리하기

        /// </summary>

        /// <param name="message">메시지</param>

        protected abstract void OnMessageHooked(TMessage message);

 

        #endregion

        #region 메시지 파싱하기 - ParseMessage(wordParameter, longParameter)

 

        /// <summary>

        /// 메시지 파싱하기

        /// </summary>

        /// <param name="wordParameter">WORD 매개 변수</param>

        /// <param name="longParameter">LONG 매개 변수</param>

        /// <returns>메시지</returns>

        protected abstract TMessage ParseMessage(IntPtr wordParameter, IntPtr longParameter);

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        //////////////////////////////////////////////////////////////////////////////// Event

 

        #region 애플리케이션 종료시 처리하기 - Application_ApplicationExit(sender, e)

 

        /// <summary>

        /// 애플리케이션 종료시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void Application_ApplicationExit(object sender, EventArgs e)

        {

            Dispose();

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////// Function

 

        #region 현재 모듈 핸들 구하기 - GetCurrentModuleHandle()

 

        /// <summary>

        /// 현재 모듈 핸들 구하기

        /// </summary>

        /// <returns>현재 모듈 핸들</returns>

        private static IntPtr GetCurrentModuleHandle()

        {

            using(Process process = Process.GetCurrentProcess())

            {

                using(ProcessModule processModule = process.MainModule)

                {

                    return WIN32Helper.GetModuleHandle(processModule.ModuleName);

                }

            }

        }

 

        #endregion

        #region 메시지 쓰레드 처리하기 - ProcessMessageThread()

 

        /// <summary>

        /// 메시지 쓰레드 처리하기

        /// </summary>

        private void ProcessMessageThread()

        {

            while(this.isValid)

            {

                TMessage message = this.messageBlockingQueue.Dequeue();

 

                OnMessageHooked(message);

            }

        }

 

        #endregion

    }

}

 

 

MouseHook.cs

 

 

using System;

 

namespace TestLibrary

{

    /// <summary>

    /// 마우스 후킹

    /// </summary>

    public class MouseHook : HookBase<MouseHookEventArgs>

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Event

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 메시지 후킹시 이벤트 - MessageHooked

 

        /// <summary>

        /// 메시지 후킹시 이벤트

        /// </summary>

        public event EventHandler<MouseHookEventArgs> MessageHooked;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 후킹 ID - HookID

 

        /// <summary>

        /// 후킹 ID

        /// </summary>

        protected override int HookID

        {

            get

            {

                return WIN32Helper.WH_MOUSE_LL;

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 메시지 후킹시 처리하기 - OnMessageHooked(e)

 

        /// <summary>

        /// 메시지 후킹시 처리하기

        /// </summary>

        /// <param name="e">이벤트 인자</param>

        protected override void OnMessageHooked(MouseHookEventArgs e)

        {

            MessageHooked?.Invoke(null, e);

        }

 

        #endregion

        #region 메시지 파싱하기 - ParseMessage(wordParameter, longParameter)

 

        /// <summary>

        /// 메시지 파싱하기

        /// </summary>

        /// <param name="wordParameter">WORD 매개 변수</param>

        /// <param name="longParameter">LONG 매개 변수</param>

        /// <returns>마우스 후킹 이벤트 인자</returns>

        protected override MouseHookEventArgs ParseMessage(IntPtr wordParameter, IntPtr longParameter)

        {

            return new MouseHookEventArgs(wordParameter, longParameter);

        }

 

        #endregion

    }

}

 

 

KeyboardHook.cs

 

 

using System;

 

namespace TestLibrary

{

    /// <summary>

    /// 키보드 후킹

    /// </summary>

    public class KeyboardHook : HookBase<KeyboardHookEventArgs>

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Event

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 메시지 후킹시 이벤트 - MessageHooked

 

        /// <summary>

        /// 메시지 후킹시 이벤트

        /// </summary>

        public event EventHandler<KeyboardHookEventArgs> MessageHooked;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 후킹 ID - HookID

 

        /// <summary>

        /// 후킹 ID

        /// </summary>

        protected override int HookID

        {

            get

            {

                return WIN32Helper.WH_KEYBOARD_LL;

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 메시지 후킹시 처리하기 - OnMessageHooked(e)

 

        /// <summary>

        /// 메시지 후킹시 처리하기

        /// </summary>

        /// <param name="e">이벤트 인자</param>

        protected override void OnMessageHooked(KeyboardHookEventArgs e)

        {

            MessageHooked?.Invoke(null, e);

        }

 

        #endregion

        #region 메시지 파싱하기 - ParseMessage(wordParameter, longParameter)

 

        /// <summary>

        /// 메시지 파싱하기

        /// </summary>

        /// <param name="wordParameter">WORD 매개 변수</param>

        /// <param name="longParameter">LONG 매개 변수</param>

        /// <returns>키보드 후킹 이벤트 인자</returns>

        protected override KeyboardHookEventArgs ParseMessage(IntPtr wordParameter, IntPtr longParameter)

        {

            return new KeyboardHookEventArgs(wordParameter, longParameter);

        }

 

        #endregion

    }

}

 

 

[TestProject 프로젝트]

 

MainForm.cs

 

 

using System;

using System.ComponentModel;

using System.Windows.Forms;

 

using TestLibrary;

 

namespace TestProject

{

    /// <summary>

    /// 메인 폼

    /// </summary>

    public partial class MainForm : Form

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 메시지 추가 대리자 - AddMessageDelegate(message)

 

        /// <summary>

        /// 메시지 추가 대리자

        /// </summary>

        /// <param name="message">메시지</param>

        private delegate void AddMessageDelegate(string message);

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region Field

 

        /// <summary>

        /// 마우스 후킹

        /// </summary>

        private MouseHook mouseHook = new MouseHook();

 

        /// <summary>

        /// 키보드 후킹

        /// </summary>

        private KeyboardHook keyboardHook = new KeyboardHook();

 

        /// <summary>

        /// 메시지 추가 대리자

        /// </summary>

        private AddMessageDelegate addMessageDelegate;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - MainForm()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainForm()

        {

            InitializeComponent();

 

            this.addMessageDelegate = new AddMessageDelegate(AddMessage);

 

            this.mouseHook.MessageHooked    += mouseHook_MessageHooked;

            this.keyboardHook.MessageHooked += keyboardHook_MessageHooked;

            this.startButton.Click          += startButton_Click;

            this.stopButton.Click           += stopButton_Click;

            this.clearButton.Click          += clearButton_Click;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

        //////////////////////////////////////////////////////////////////////////////// Function

 

        #region 종료시 처리하기 - OnClosing(e)

 

        /// <summary>

        /// 종료시 처리하기

        /// </summary>

        /// <param name="e">이벤트 인자</param>

        protected override void OnClosing(CancelEventArgs e)

        {

            this.mouseHook.Dispose();

 

            this.keyboardHook.Dispose();

 

            base.OnClosing(e);

        }

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        //////////////////////////////////////////////////////////////////////////////// Event

 

        #region 마우스 후킹 메시지 후킹시 처리하기 - mouseHook_MessageHooked(sender, e)

 

        /// <summary>

        /// 마우스 후킹 메시지 후킹시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void mouseHook_MessageHooked(object sender, MouseHookEventArgs e)

        {

            BeginInvoke(this.addMessageDelegate, e.ToString());

        }

 

        #endregion

        #region 키보드 후킹 메시지 후킹시 처리하기 - keyboardHook_MessageHooked(sender, e)

 

        /// <summary>

        /// 키보드 후킹 메시지 후킹시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void keyboardHook_MessageHooked(object sender, KeyboardHookEventArgs e)

        {

            BeginInvoke(this.addMessageDelegate, e.ToString());

        }

 

        #endregion

        #region 시작 버튼 클릭시 처리하기 - startButton_Click(sender, e)

 

        /// <summary>

        /// 시작 버튼 클릭시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void startButton_Click(object sender, EventArgs e)

        {

            this.mouseHook.StartHook();

 

            this.keyboardHook.StartHook();

        }

 

        #endregion

        #region 중단 버튼 클릭시 처리하기 - stopButton_Click(sender, e)

 

        /// <summary>

        /// 중단 버튼 클릭시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void stopButton_Click(object sender, EventArgs e)

        {

            this.mouseHook.StopHook();

 

            this.keyboardHook.StopHook();

        }

 

        #endregion

        #region 지우기 버튼 클릭시 처리하기 - clearButton_Click(sender, e)

 

        /// <summary>

        /// 지우기 버튼 클릭시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void clearButton_Click(object sender, EventArgs e)

        {

            this.listBox.Items.Clear();

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////// Function

 

        #region 메시지 추가하기 - AddMessage(message)

 

        /// <summary>

        /// 메시지 추가하기

        /// </summary>

        /// <param name="message">메시지</param>

        private void AddMessage(string message)

        {

            this.listBox.Items.Insert(0, message);

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

728x90
반응형
Posted by 사용자 icodebroker

댓글을 달아 주세요