热键管理



#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;
  }
};


猜你喜欢

转载自blog.csdn.net/zgl7903/article/details/78816861