tap-and-hold (TAH) gesture,点按动作是WinCE里面取代右键的动作。 SHRecognizeGesture API是用来判断是否有点按消息的。在直接模式,如果有点按消息,则返回GN_CONTEXTMENU,否则返回0 。 对通知模式,则发送WM_NOTIFY 消息携带GN_CONTEXTMENU 到父窗口。
1.#include "aygshell.h"
2.如果是CWnd窗口接受消息,由于MFC的错误,应该如下处理:
void CMyWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
SHRGINFO shrgi = {0};
shrgi.cbSize = sizeof(SHRGINFO);
shrgi.hwndClient = m_hWnd;
shrgi.ptDown.x = point.x;
shrgi.ptDown.y = point.y;
shrgi.dwFlags = SHRG_RETURNCMD;
if(GN_CONTEXTMENU == ::SHRecognizeGesture(&shrgi))
ContextMenu(point);
else
Default();
}
void CMyCwnd::ContextMenu(CPoint point)
{
CMenu mnuCtxt;
CMenu* pMenu;
CWnd* pWnd;
if(!m_nMenuID)
return;
if(mnuCtxt.LoadMenu(m_nMenuID))
{
pWnd = (m_pWndMenu ? m_pWndMenu : AfxGetMainWnd());
pMenu =
mnuCtxt.GetSubMenu(0);
if(pMenu)
{
ClientToScreen(&point);pMenu->TrackPopupMenu(TPM_LEFTALIGN,
point.x, point.y, pWnd);
}
}
}
注意不要调用CWnd:: OnLButtonDown(UINT nFlags, CPoint point) ,否则由于MFC的错误,会响应两次消息
3.例外:CListCtrl, CTreeCtrl的响应是正确的,如下
BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CMyListCtrl)
ON_WM_LBUTTONDOWN ()
ON_WM_LBUTTONUP ()
ON_NOTIFY_REFLECT (GN_CONTEXTMENU, OnListContextMenu)
.
.
.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// CMyListCtrl::OnListContextMenu
//
// Handles the list context menu
//
void CMyListCtrl::OnListContextMenu(NMHDR* pNMHDR, LRESULT* pResult)
{
CMenu mnuCtxt;
CMenu* pMenu;
CWnd* pWnd;
NMRGINFO* pInfo;
if(!m_nLstMenu)
return;
if(mnuCtxt.LoadMenu(m_nLstMenu))
{
pWnd = (m_pWndMenu ? m_pWndMenu : AfxGetMainWnd());
pMenu = mnuCtxt.GetSubMenu(0);
if(pMenu)
{
UINT uFlags;
CPoint pt;
pInfo = (NMRGINFO*)pNMHDR;
pt = pInfo->ptAction;
ScreenToClient(&pt);
m_iItemOnMenu = HitTest(pt, &uFlags);
//
// Signal this is a tap and hold operation
//
m_bTapAndHold = RUE; pMenu->TrackPopupMenu(TPM_LEFTALIGN, pInfo->ptAction.x,pInfo->ptAction.y, pWnd);
}
}
}
// CMyListCtrl::OnLButtonDown
//
// Special handler for WM_LBUTTONDOWN.
// Check for a tap and hold gesture. Never trust MFC...
//
void CMyListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
m_bTapAndHold = FALSE;
Default();
}
// CMyListCtrl::OnLButtonUp
//
// The user released the stylus
//
void CMyListCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
CListCtrl::OnLButtonUp(nFlags, point);
m_bTapAndHold = FALSE;
}