热键管理

来源:互联网 发布:企业模拟经营软件 编辑:程序博客网 时间:2024/05/18 22:16



#include <afxtempl.h>class CWndHotKeyManage{protected:  typedef struct _tagWKItem_t  {    HWND hWnd;         // window to receive hot-key notification    int id;            // identifier of hot key    UINT fsModifiers;  // key-modifier flags    UINT vk;           // virtual-key code    BOOL bFocusActive; //    _tagWKItem_t()    {      memset(this, 0, sizeof(*this));    }  }WKITEM, *LPWKITEM;  CArray <WKITEM, const WKITEM &> m_WKList;  CRITICAL_SECTION m_Lock;protected:  void Lock()  {    EnterCriticalSection(&m_Lock);  }  void Unlock()  {    LeaveCriticalSection(&m_Lock);  }   INT_PTR FindItem(HWND hWnd, int id)  {    INT_PTR iFound=-1;    for(INT_PTR i=0; i<m_WKList.GetSize(); i++)    {      WKITEM *p = &m_WKList[i];      if(hWnd == p->hWnd  && id == p->id)      {        iFound = i;        break;      }    }    return iFound;  }public:  CWndHotKeyManage()  {    InitializeCriticalSection(&m_Lock);  }  virtual ~CWndHotKeyManage()  {    Lock();    m_WKList.RemoveAll();    Unlock();    DeleteCriticalSection(&m_Lock);  }public:  BOOL RegisterHotKey(HWND hWnd, int id,  UINT fsModifiers, UINT vk, BOOL bActive=FALSE)  {    BOOL bRet = FALSE;    WKITEM NewItem;    NewItem.hWnd = hWnd;    NewItem.id = id;    NewItem.fsModifiers = fsModifiers;    NewItem.vk = vk;    NewItem.bFocusActive = bActive;    Lock();        int iPos = FindItem(hWnd, id);    if(iPos >= 0)    {      m_WKList.SetAt(iPos, NewItem);      bRet = TRUE;    }    else    {      m_WKList.Add(NewItem);      bRet = TRUE;    }    Unlock();    return bRet;  }  BOOL UnregisterHotKey(HWND hWnd,  int id)  {    Lock();    int iPos = FindItem(hWnd, id);    if(iPos >= 0)    {      m_WKList.RemoveAt(iPos);    }    Unlock();    return TRUE;  }public:  BOOL TranslateMessage(LPMSG lpMsg)  {    BOOL bRet = 0;    do    {      if(!(lpMsg->message == WM_KEYDOWN         || lpMsg->message == WM_SYSKEYDOWN))        break;      UINT vKeyKey = lpMsg->wParam;      BOOL bCtlKey = GetKeyState(VK_CONTROL);      BOOL bSftKey = GetKeyState(VK_SHIFT);      BOOL bAltKey = GetKeyState(VK_MENU);      BOOL bWinKey = GetKeyState(VK_LWIN) || GetKeyState(VK_RWIN);      Lock();      for(INT_PTR i=0; i<m_WKList.GetSize(); i++)      {        WKITEM *p = &m_WKList[i];        //匹配窗口        if(!(p->hWnd == NULL || lpMsg->hwnd == p->hWnd))        {          TRACE(_T("wnd:%p %p\n"), p->hWnd, lpMsg->hwnd);          continue;        }        //要求激活?        if(p->bFocusActive           && GetFocus() != lpMsg->hwnd)        {          TRACE(_T("FocusWnd %p %p\n"), GetFocus(), lpMsg->hwnd);          continue;        }        //匹配主键        if(p->vk != vKeyKey)        {          TRACE(_T("MainKey %u %u\n"), p->vk, vKeyKey);          continue;        }        //Control        BOOL bCtrlMf = (p->fsModifiers & MOD_CONTROL)?TRUE:FALSE;        if(bCtrlMf != bCtlKey)        {          TRACE(_T("Contrl %d %d\n"), bCtrlMf, bCtlKey);          continue;        }        //Shift        BOOL bShiftMf = (p->fsModifiers & MOD_SHIFT)?TRUE:FALSE;        if(bShiftMf != bSftKey)        {          TRACE(_T("Shift %d %d\n"), bShiftMf, bSftKey);          continue;        }        //Alt        BOOL bAltMf = (p->fsModifiers & MOD_ALT)?TRUE:FALSE;        if(bAltMf != bAltKey)        {          TRACE(_T("Alt %d %d\n"), bAltMf, bAltKey);          continue;        }        //Win        BOOL bWinMf = (p->fsModifiers & MOD_WIN)?TRUE:FALSE;        if(bWinMf != bWinKey)        {          TRACE(_T("Win %d %d\n"), bWinMf, bWinKey);          continue;        }        //完全匹配        LPARAM lParam = MAKELPARAM(p->fsModifiers, p->vk);        PostMessage(lpMsg->hwnd, WM_HOTKEY, p->id, lParam);        bRet = TRUE;        break;      }      Unlock();    }while(0);    return bRet;  }};