热键管理



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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值