问题出现环境:继承自CWnd的窗口类,自定义Create。
发现此窗口无论不响应WM_LBUTTONDBLCLK事件,只响应WM_LBUTTONDOWN事件。
查看了文档中关于CWnd::OnLButtonDblClk内容,详细如下:
Only windows that have the CS_DBLCLKS WNDCLASS style will receive OnLButtonDblClk calls. This is the default for Microsoft Foundation Class windows. Windows calls OnLButtonDblClk when the user presses, releases, and then presses the left mouse button again within the system's double-click time limit. Double-clicking the left mouse button actually generates four events: WM_LBUTTONDOWN, WM_LBUTTONUP messages, the WM_LBUTTONDBLCLK call, and another WM_LBUTTONUP message when the button is released.
大意是双击是窗口类的一个风格,双击产生个鼠标事件,在最后WM_LBUTTONUP按起前调用了WM_LBUTTONDBLCLK。
看来问题所在是因为没有注册窗口类的CS_DBLCLKS,因为我是建立自定义窗口,所以框架没有默认创建,看来需要手工创建了。
MFC提供了PreCreateWindow函数,此函数在windows窗口被创建并把它的指针attach到CWnd对象前,由framework先调用。
具体从wincore.cpp摘录:
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
int x, int y, int nWidth, int nHeight,
HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)
{
ASSERT(lpszClassName == NULL || AfxIsValidString(lpszClassName) ||
AfxIsValidAtom(lpszClassName));
ENSURE_ARG(lpszWindowName == NULL || AfxIsValidString(lpszWindowName));
// allow modification of several common create parameters
CREATESTRUCT cs;
cs.dwExStyle = dwExStyle;
cs.lpszClass = lpszClassName;
cs.lpszName = lpszWindowName;
cs.style = dwStyle;
cs.x = x;
cs.y = y;
cs.cx = nWidth;
cs.cy = nHeight;
cs.hwndParent = hWndParent;
cs.hMenu = nIDorHMenu;
cs.hInstance = AfxGetInstanceHandle();
cs.lpCreateParams = lpParam;
if (!PreCreateWindow(cs))
{
PostNcDestroy();
return FALSE;
}
AfxHookWindowCreate(this);
HWND hWnd = ::AfxCtxCreateWindowEx(cs.dwExStyle, cs.lpszClass,
cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);
#ifdef _DEBUG
if (hWnd == NULL)
{
TRACE(traceAppMsg, 0, "Warning: Window creation failed: GetLastError returns 0x%8.8X/n",
GetLastError());
}
#endif
if (!AfxUnhookWindowCreate())
PostNcDestroy(); // cleanup if CreateWindowEx fails too soon
if (hWnd == NULL)
return FALSE;
ASSERT(hWnd == m_hWnd); // should have been set in send msg hook
return TRUE;
}
// for child windows
BOOL CWnd::PreCreateWindow(CREATESTRUCT& cs)
{
if (cs.lpszClass == NULL)
{
// make sure the default window class is registered
VERIFY(AfxDeferRegisterClass(AFX_WND_REG));
// no WNDCLASS provided - use child window default
ASSERT(cs.style & WS_CHILD);
cs.lpszClass = _afxWnd;
}
return TRUE;
}
所以我增加了CS_DBLCLKS风格。
代码如下:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,::LoadCursor(NULL, IDC_ARROW),HBRUSH(COLOR_WINDOW+1),NULL);
return CWnd::PreCreateWindow(cs);
}
最后在代码中添加相关的双击处理代码:
ON_WM_LBUTTONDBLCLK()
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
void CMainFrame::OnLButtonDblClk(UINT nFlags, CPoint point)
{
}