C++实现全局鼠标、键盘消息hook,支持事件
生活随笔
收集整理的這篇文章主要介紹了
C++实现全局鼠标、键盘消息hook,支持事件
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目前在開發一個小的界面程序,需要用到消息hook于是寫了一個CGlobalWindowMsgHook類,使用起來非常方便,現拿出來與大家分享。
頭文件:
1: #pragma once 2:? 3: #include "EventDelegate.h" 4:? 5: / 6: // CGlobalWindowMsgHook 全局 Windows 消息 Hook 7: // 8:? 9: class CKeyEventArgs : public CEventArgs 10: { 11: public: 12: CKeyEventArgs (DWORD code); 13:? 14: DWORD vkCode; 15: }; 16:? 17: // Specifies constants that define which mouse button was pressed. 18: enum MouseButtons 19: { 20: None = 0, // No mouse button was pressed. 21: Left = 1048576, // The left mouse button was pressed. 22: Right = 2097152, // The right mouse button was pressed. 23: Middle = 4194304, // The middle mouse button was pressed. 24: XButton1 = 8388608, // The first XButton was pressed. 25: XButton2 = 16777216,// The second XButton was pressed. 26: }; 27:? 28: class CMouseEventArgs : public CEventArgs 29: { 30: public: 31: CMouseEventArgs (MouseButtons button1, int clicks1, int x1, int y1, int delta1); 32:? 33: MouseButtons button; int clicks; int x; int y; int delta; 34: }; 35:? 36: // void handler (IEventSource* sender, CMouseEventArgs* e); 37: DEFINE_EVENT_HANDLER (CMouseEventDelegate, CMouseEventArgs); 38:? 39: // void handler (IEventSource* sender, CKeyEventArgs* e); 40: DEFINE_EVENT_HANDLER (CKeyEventDelegate, CKeyEventArgs); 41:? 42: class CGlobalWindowMsgHook : public IEventSource 43: { 44: private: 45: CGlobalWindowMsgHook (void); 46:? 47: public: 48: ~CGlobalWindowMsgHook (void); 49:? 50: // 獲取消息hook實例 51: static CGlobalWindowMsgHook* instance (void); 52:? 53: // Occours when the hook captures a mouse click 54: CMouseEventDelegate MouseClick; 55:? 56: // Occours when the hook captures a mouse double click 57: CMouseEventDelegate MouseDblClick; 58:? 59: // Occours when the hook captures the mouse wheel 60: CMouseEventDelegate MouseWheel; 61:? 62: // Occours when the hook captures the press of a mouse button 63: CMouseEventDelegate MouseDown; 64:? 65: // Occours when the hook captures the release of a mouse button 66: CMouseEventDelegate MouseUp; 67:? 68: // Occours when the hook captures the mouse moving over the screen 69: CMouseEventDelegate MouseMove; 70:? 71: // Occours when a key is pressed 72: CKeyEventDelegate KeyDown; 73:? 74: // Occours when a key is released 75: CKeyEventDelegate KeyUp; 76:? 77: // Occours when a key is pressed 78: CKeyEventDelegate KeyPress; 79:? 80: protected: 81: static LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam); 82: static LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam); 83:? 84: static HHOOK _hMouseHook; 85: static HHOOK _hKeyboardHook; 86:? 87: static std::auto_ptr<CGlobalWindowMsgHook> _pInstance; 88: };實現文件:
1: #include "stdafx.h" 2: #include "GlobalWindowMsgHook.h" 3:? 4: / 5: // CGlobalWindowMsgHook 全局 Windows 消息 Hook 6: // 7:? 8: CKeyEventArgs::CKeyEventArgs (DWORD code) 9: { 10: vkCode = code; 11: } 12:? 13: CMouseEventArgs::CMouseEventArgs (MouseButtons button1, int clicks1, int x1, int y1, int delta1) 14: { 15: button = button1; 16: clicks = clicks1; 17: x = x1; y = y1; delta = delta1; 18: } 19:? 20: HHOOK CGlobalWindowMsgHook::_hMouseHook = NULL; 21: HHOOK CGlobalWindowMsgHook::_hKeyboardHook = NULL; 22:? 23: std::auto_ptr<CGlobalWindowMsgHook> CGlobalWindowMsgHook::_pInstance; 24:? 25: CGlobalWindowMsgHook::CGlobalWindowMsgHook (void) 26: { 27: _hMouseHook = SetWindowsHookEx (WH_MOUSE_LL, MouseProc, NULL, NULL); 28: _hKeyboardHook = SetWindowsHookEx (WH_KEYBOARD_LL, KeyboardProc, NULL, NULL); 29: } 30:? 31: CGlobalWindowMsgHook::~CGlobalWindowMsgHook (void) 32: { 33: if (_hMouseHook) 34: { 35: UnhookWindowsHookEx (_hMouseHook); 36: } 37:? 38: if (_hKeyboardHook) 39: { 40: UnhookWindowsHookEx (_hKeyboardHook); 41: } 42: } 43:? 44: // 獲取消息hook實例 45: CGlobalWindowMsgHook* CGlobalWindowMsgHook::instance (void) 46: { 47: if (!_pInstance.get()) 48: { 49: _pInstance.reset (new CGlobalWindowMsgHook ()); 50: } 51:? 52: return _pInstance.get(); 53: } 54:? 55: LRESULT CGlobalWindowMsgHook::KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 56: { 57: CGlobalWindowMsgHook* This = instance(); 58: PKBDLLHOOKSTRUCT hookStruct = (PKBDLLHOOKSTRUCT)lParam; 59: BOOL bHandled = FALSE; 60:? 61: int msg = wParam; 62: if (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) 63: { 64: CKeyEventArgs e (hookStruct->vkCode); 65: This->KeyDown.Fire (This, &e); 66: bHandled = e.bHandled; 67: } 68: else if (msg == WM_KEYUP || msg == WM_SYSKEYUP) 69: { 70: CKeyEventArgs e (hookStruct->vkCode); 71: This->KeyUp.Fire (This, &e); 72: bHandled = e.bHandled; 73: } 74:? 75: if (msg == WM_KEYDOWN && This->KeyPress.GetCount ()) 76: { 77: BYTE keyState[256] = { 0 }; 78: BYTE buffer[2] = { 0 }; 79: GetKeyboardState(keyState); 80: int conversion = ToAscii(hookStruct->vkCode, hookStruct->scanCode, keyState, (LPWORD) buffer, hookStruct->flags); 81:? 82: if (conversion == 1 || conversion == 2) 83: { 84: BOOL shift = (GetKeyState(VK_SHIFT) & 0x80) == 0x80; 85: BOOL capital = GetKeyState(VK_CAPITAL) != 0; 86: CHAR c = (CHAR)buffer[0]; 87: if ((shift ^ capital) && isalpha(c)) 88: { 89: c = tolower(c); 90: } 91: CKeyEventArgs e (c); 92: This->KeyPress.Fire (This, &e); 93: bHandled |= e.bHandled; 94: } 95: } 96:? 97: return bHandled ? 1 : CallNextHookEx(_hKeyboardHook, nCode, wParam, lParam); 98: } 99:? 100: LRESULT CGlobalWindowMsgHook::MouseProc(int nCode, WPARAM wParam, LPARAM lParam) 101: { 102: CGlobalWindowMsgHook* This = instance(); 103: PMSLLHOOKSTRUCT hookStruct = (PMSLLHOOKSTRUCT)lParam; 104:? 105: int msg = wParam; 106: int x = hookStruct->pt.x; 107: int y = hookStruct->pt.y; 108: int delta = (short)((hookStruct->mouseData >> 16) & 0xffff); 109: 110: if (msg == WM_MOUSEWHEEL) 111: { 112: This->MouseWheel.Fire (This, &CMouseEventArgs (None, 0, x, y, delta)); 113: } 114: else if (msg == WM_MOUSEMOVE) 115: { 116: This->MouseMove.Fire (This, &CMouseEventArgs (None, 0, x, y, delta)); 117: } 118: else if (msg == WM_LBUTTONDBLCLK) 119: { 120: This->MouseDblClick.Fire (This, &CMouseEventArgs (Left, 0, x, y, delta)); 121: } 122: else if (msg == WM_LBUTTONDOWN) 123: { 124: This->MouseDown.Fire (This, &CMouseEventArgs (Left, 0, x, y, delta)); 125: } 126: else if (msg == WM_LBUTTONUP) 127: { 128: This->MouseUp.Fire (This, &CMouseEventArgs (Left, 0, x, y, delta)); 129: This->MouseClick.Fire (This, &CMouseEventArgs (Left, 0, x, y, delta)); 130: } 131: else if (msg == WM_MBUTTONDBLCLK) 132: { 133: This->MouseDblClick.Fire (This, &CMouseEventArgs (Middle, 0, x, y, delta)); 134: } 135: else if (msg == WM_MBUTTONDOWN) 136: { 137: This->MouseDown.Fire (This, &CMouseEventArgs (Middle, 0, x, y, delta)); 138: } 139: else if (msg == WM_MBUTTONUP) 140: { 141: This->MouseUp.Fire (This, &CMouseEventArgs (Middle, 0, x, y, delta)); 142: } 143: else if (msg == WM_RBUTTONDBLCLK) 144: { 145: This->MouseDblClick.Fire (This, &CMouseEventArgs (Right, 0, x, y, delta)); 146: } 147: else if (msg == WM_RBUTTONDOWN) 148: { 149: This->MouseDown.Fire (This, &CMouseEventArgs (Right, 0, x, y, delta)); 150: } 151: else if (msg == WM_RBUTTONUP) 152: { 153: This->MouseUp.Fire (This, &CMouseEventArgs (Right, 0, x, y, delta)); 154: } 155: else if (msg == WM_XBUTTONDBLCLK) 156: { 157: This->MouseDblClick.Fire (This, &CMouseEventArgs (XButton1, 0, x, y, delta)); 158: } 159: else if (msg == WM_XBUTTONDOWN) 160: { 161: This->MouseDown.Fire (This, &CMouseEventArgs (XButton1, 0, x, y, delta)); 162: } 163: else if (msg == WM_XBUTTONUP) 164: { 165: This->MouseUp.Fire (This, &CMouseEventArgs (XButton1, 0, x, y, delta)); 166: } 167: 168: return CallNextHookEx(_hMouseHook, nCode, wParam, lParam); 169: }使用方法:
?
1: class CPopupPanelManager 2: { 3: protected: 4: // 首先在使用類中定義要實現的事件句柄 5: void _keyboardHook_KeyDown(IEventSource* sender, CKeyEventArgs* e); 6: void _mouseHook_MouseWheel(IEventSource* sender, CMouseEventArgs* e); 7: void _mouseHook_MouseDown(IEventSource* sender, CMouseEventArgs* e); 8: } 9:? 10: // 然后在實現在添加登記事件處理、注銷事件處理的代碼 11: CPopupPanelManager::CPopupPanelManager (void) 12: { 13: // 注冊hook 14: CGlobalWindowMsgHook* hook = CGlobalWindowMsgHook::instance(); 15: hook->MouseDown += MakeDelegate (this, &CPopupPanelManager::_mouseHook_MouseDown); 16: hook->MouseWheel += MakeDelegate (this, &CPopupPanelManager::_mouseHook_MouseWheel); 17: hook->KeyDown += MakeDelegate (this, &CPopupPanelManager::_keyboardHook_KeyDown); 18: } 19:? 20: CPopupPanelManager::~CPopupPanelManager (void) 21: { 22: // 取消hook 23: CGlobalWindowMsgHook* hook = CGlobalWindowMsgHook::instance(); 24: hook->MouseDown -= MakeDelegate (this, &CPopupPanelManager::_mouseHook_MouseDown); 25: hook->MouseWheel -= MakeDelegate (this, &CPopupPanelManager::_mouseHook_MouseWheel); 26: hook->KeyDown -= MakeDelegate (this, &CPopupPanelManager::_keyboardHook_KeyDown); 27: } 28:? 29: // 最后在cpp上實現句柄 30: void CPopupPanelManager::_mouseHook_MouseDown(IEventSource* sender, CMouseEventArgs* e) 31: { 32:? 33: } 34:? 35:? 36: void CPopupPanelManager::_mouseHook_MouseWheel(IEventSource* sender, CMouseEventArgs* e) 37: { 38:? 39: } 40:? 41: void CPopupPanelManager::_keyboardHook_KeyDown(IEventSource* sender, CKeyEventArgs* e) 42: { 43: if (e->vkCode == VK_ESCAPE) 44: { 45: 46: } 47: }轉載于:https://www.cnblogs.com/ihaoqi/p/3239223.html
總結
以上是生活随笔為你收集整理的C++实现全局鼠标、键盘消息hook,支持事件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenGL-渲染管线的流程(有图有真相
- 下一篇: 酷炫Jquery收集