MFC如何让自定义类能够响应消息

吴一奇 2017-07-02 04:46:06
如题。
我自定义了一个类,继承自CWnd,想让它响应MouseMove消息,在Class Wizard里可以添加消息响应函数,但是移动鼠标,并不会进入函数。

到底是什么原因呢?
...全文
490 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
zgl7903 2017-07-06
  • 打赏
  • 举报
回复

#if !defined(AFX_MYWND_H__B293370D_6107_4EE1_88EB_E8D48C70CB76__INCLUDED_)
#define AFX_MYWND_H__B293370D_6107_4EE1_88EB_E8D48C70CB76__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MyWnd.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CMyWnd window

class CMyWnd : public CWnd
{
  DECLARE_DYNAMIC(CMyWnd)
    
    // Construction
public:
  CMyWnd();
  
  // Attributes
public:
  CPoint m_MousePos;
  
  // Operations
public:
  
  // Overrides
  // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CMyWnd)
public:
  virtual BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
protected:
  virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
  //}}AFX_VIRTUAL
  
  // Implementation
public:
  virtual ~CMyWnd();
  
  // Generated message map functions
protected:
  //{{AFX_MSG(CMyWnd)
  afx_msg void OnMouseMove(UINT nFlags, CPoint point);
  //}}AFX_MSG
  DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MYWND_H__B293370D_6107_4EE1_88EB_E8D48C70CB76__INCLUDED_)


// MyWnd.cpp : implementation file
//

#include "stdafx.h"
#include "MyWnd.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMyWnd
IMPLEMENT_DYNAMIC(CMyWnd, CWnd)

CMyWnd::CMyWnd()
{
  m_MousePos.x = m_MousePos.y = 0;
}

CMyWnd::~CMyWnd()
{
}

//消息映射模式
BEGIN_MESSAGE_MAP(CMyWnd, CWnd)
//{{AFX_MSG_MAP(CMyWnd)
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CMyWnd message handlers

BOOL CMyWnd::Create(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
{
  // TODO: Add your specialized code here and/or call the base class
  LPCTSTR lpszClassName = AfxRegisterWndClass(CS_OWNDC|CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS);
  
  return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
}

void CMyWnd::OnMouseMove(UINT nFlags, CPoint point) 
{
  // TODO: Add your message handler code here and/or call default
  m_MousePos = point;
  Invalidate(FALSE);
  CWnd::OnMouseMove(nFlags, point);
}

//重载WindowProc
LRESULT CMyWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
  // TODO: Add your specialized code here and/or call the base class
  switch(message)
  {
  case(WM_ERASEBKGND):
    {
      return TRUE;
    }
  case(WM_PAINT):
    {
      PAINTSTRUCT ps;
      CDC *pDC = BeginPaint(&ps);
      int nSaveDc = pDC->SaveDC();
      
      CRect rcRect;
      GetClientRect(&rcRect);
      
      pDC->FillSolidRect(&rcRect, RGB(255, 0, 0));
      
      
      CString szStr;
      szStr.Format(_T("x=%d y=%d\n"), m_MousePos.x, m_MousePos.y);
      
      pDC->SetTextColor(RGB(0, 255, 0));
      pDC->SetBkMode(TRANSPARENT);
      
      CFont m_Font;
      m_Font.CreatePointFont(120, _T("Arial"));
      CFont *pOldFont = pDC->SelectObject(&m_Font);
      
      pDC->DrawText(szStr, rcRect, DT_VCENTER|DT_CENTER|DT_SINGLELINE);
      
      pDC->SelectObject(pOldFont);
      pDC->RestoreDC(nSaveDc);
      EndPaint(&ps);
      return 0;
    }
  }
  
  return CWnd::WindowProc(message, wParam, lParam);
}

//测试类
#include "MyWnd.h"

class CSDI3View : public CView
{
protected:
  CMyWnd m_MyWnd;
public:
  virtual void OnInitialUpdate();
  virtual BOOL DestroyWindow();
……

void CSDI3View::OnInitialUpdate()
{
  CView::OnInitialUpdate();

  m_MyWnd.Create(_T("Test my Window"), WS_CHILD|WS_VISIBLE|WS_BORDER, 
    CRect(0,0, 200, 200), this, 1024);
}

BOOL CSDI3View::DestroyWindow() 
{
  // TODO: Add your specialized code here and/or call the base class
  if(m_MyWnd.m_hWnd)
    m_MyWnd.DestroyWindow();
  
  return CView::DestroyWindow();
}

zgl7903 2017-07-05
  • 打赏
  • 举报
回复
引用 15 楼 wu_nan_nan 的回复:
[quote=引用 14 楼 zgl7903 的回复:] 这个自定义类是怎么创建启动的? Create ? SubclassWindow?
这个类本身使用Class wizard的创建的。 我好像并没有创建这个类的对象。在View类里定义这个类的对象行吗[/quote] 你得给他一个可以展现的机会
吴一奇 2017-07-05
  • 打赏
  • 举报
回复
引用 14 楼 zgl7903 的回复:
这个自定义类是怎么创建启动的? Create ? SubclassWindow?
这个类本身使用Class wizard的创建的。 我好像并没有创建这个类的对象。在View类里定义这个类的对象行吗
吴一奇 2017-07-05
  • 打赏
  • 举报
回复
引用 18 楼 zhujinqiang 的回复:
如楼上所说,需要消息映射。
不是消息映射的问题
吴一奇 2017-07-05
  • 打赏
  • 举报
回复
引用 17 楼 zgl7903 的回复:
[quote=引用 15 楼 wu_nan_nan 的回复:] [quote=引用 14 楼 zgl7903 的回复:] 这个自定义类是怎么创建启动的? Create ? SubclassWindow?
这个类本身使用Class wizard的创建的。 我好像并没有创建这个类的对象。在View类里定义这个类的对象行吗[/quote] 你得给他一个可以展现的机会 [/quote] 我当然知道要“给他一个可以展现的机会”,就是不知道该怎么给啊
zgl7903 2017-07-05
  • 打赏
  • 举报
回复
这个自定义类是怎么创建启动的? Create ? SubclassWindow?
zhujinqiang 2017-07-05
  • 打赏
  • 举报
回复
如楼上所说,需要消息映射。
吴一奇 2017-07-04
  • 打赏
  • 举报
回复
引用 9 楼 u012556050 的回复:
你这个类需要跟Dialog啥的界面关联上。 然后再这个界面上移动鼠标。
我的工程是单文档,不是Dialog based,不知道该怎么关联
吴一奇 2017-07-04
  • 打赏
  • 举报
回复
引用 8 楼 zgl7903 的回复:
重载WindowProc 或者 完善 消息映射部分 //.h DECLARE_MESSAGE_MAP() //.cpp BEGIN_MESSAGE_MAP( CMyWindow, CWnd ) //{{AFX_MSG_MAP( CMyWindow ) ON_WM_PAINT() ON_COMMAND( IDM_ABOUT, OnAbout ) ON_WM_MOUSEMOVE( ) //}}AFX_MSG_MAP END_MESSAGE_MAP( )
我用类向导生成消息响应函数,上面这些message map里的内容都有
吴一奇 2017-07-04
  • 打赏
  • 举报
回复
引用 7 楼 pcradio 的回复:
要完全掌握MFC机制,你需要看《深入浅出MFC》然后加上自己看MFC源代码。
嗯,以前囫囵吞枣的看过。
worldy 2017-07-04
  • 打赏
  • 举报
回复
MFC类,需要消息映射,消息才会进入类 BEGIN_MESSAGE_MAP(CHelloWorldView, CView) // 标准打印命令 ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CHelloWorldView::OnFilePrintPreview) ON_WM_ERASEBKGND() ON_COMMAND(ID_FLIP_IMAGE, &CHelloWorldView::OnFlipImage) ......................... END_MESSAGE_MAP()
zgl7903 2017-07-03
  • 打赏
  • 举报
回复
重载WindowProc 或者 完善 消息映射部分 //.h DECLARE_MESSAGE_MAP() //.cpp BEGIN_MESSAGE_MAP( CMyWindow, CWnd ) //{{AFX_MSG_MAP( CMyWindow ) ON_WM_PAINT() ON_COMMAND( IDM_ABOUT, OnAbout ) ON_WM_MOUSEMOVE( ) //}}AFX_MSG_MAP END_MESSAGE_MAP( )
jedy_woody 2017-07-03
  • 打赏
  • 举报
回复
你这个类需要跟Dialog啥的界面关联上。 然后再这个界面上移动鼠标。
阿源是少年 2017-07-03
  • 打赏
  • 举报
回复
要完全掌握MFC机制,你需要看《深入浅出MFC》然后加上自己看MFC源代码。
阿源是少年 2017-07-03
  • 打赏
  • 举报
回复
创建CWnd之后并没有绑定到HWND内核对象,需要手动调用CWnd::Create函数创建HWND已完成绑定,或者通过CWnd::SubclassWindow子类化到一个已经存在的HWND窗口,其实你只要明白一点就好了,MFC里的窗口类CWnd就干一件事情,保存一个Win32窗口的句柄HWND到其成员变量m_hWnd,然后通过SetWindowLong去替换Win32窗口的窗口过程到其类静态函数WindowProc以实现消息拦截,拦截后的消息就用其成员函数进行处理了,比如CWnd::OnMouseMove,就是拦截的WM_MOUSEMOVE
真相重于对错 2017-07-02
  • 打赏
  • 举报
回复
一两句话很难说清楚 建议看侯杰的《深入浅出MFC》
吴一奇 2017-07-02
  • 打赏
  • 举报
回复
引用 2 楼 homesos 的回复:
重载一下消息方法试试呢 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
为什么呢
吴一奇 2017-07-02
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
1 你的类必须要有个窗口, 2 Mouse Move 一定在你的窗口内
具体该怎么操作呢,我对这块比较陌生,还麻烦您指点一下
homesos 2017-07-02
  • 打赏
  • 举报
回复
重载一下消息方法试试呢 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
schlafenhamster 2017-07-02
  • 打赏
  • 举报
回复
1 你的类必须要有个窗口, 2 Mouse Move 一定在你的窗口内

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧