첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
본 블로그는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 블로그 콘텐츠 향상을 위해 쓰여집니다.

728x90
반응형
728x170

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

댓글을 달아 주세요