【问题标题】:MFC - Cannot Post Message to a custom class derived from CWndMFC - 无法将消息发布到从 CWnd 派生的自定义类
【发布时间】:2014-08-09 08:48:50
【问题描述】:

我有一个从 CWnd 派生的自定义类,我想从工作线程向其发布消息。我正在使用 PostMessage 函数来实现这一点。 PostMessage 的第一个参数是我的类的 HWND 类型句柄,下一个是我想要处理的消息。对于第一个参数,我使用 GetSafeHwnd() 函数生成我的类的句柄,对于第二个参数,我使用 WM_USER+3。此外,我在我的类头文件中声明了一个消息映射,并在 BEGIN_MESSAGE_MAP 和 END_MESSAGE_MAP 块内为消息处理程序添加了一个条目。但是,我的处理程序没有被调用。我还检查了 PostMessage 函数的返回值,是 1,表示成功。

这是我的代码:

在 MyClass.h 中

class CMyClass : CWnd
{
....
.... 
public:
void InitHandle();

protected:
afx_msg LRESULT OnMessageReceived(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
} 

在 MyClass.cpp 中

#define WM_MY_MESSAGE WM_USER+3

HWND handleToMyClassWindow;

BEGIN_MESSAGE_MAP(CMyClass, CWnd)
    ON_MESSAGE(WM_MY_MESSAGE, OnMessageReceived)
END_MESSAGE_MAP()

LRESULT CMyClass::OnMessageReceived(WPARAM wParam, LPARAM lParam)
{ .... }

void CMyClass::InitHandle()
{ 
    handleToMyClassWindow = GetSafeHwnd();
}

工作线程内部

UINT WorkerThreadFunction(LPVOID pParam )
{ 
....
PostMessage(handleToMyClassWindow, WM_MY_MESSAGE, NULL, NULL);
....
}

我的问题是,不调用 OnMessageReceived 处理程序的可能原因是什么。

附言

我注意调用对象调用 InitHandle() 函数。

我用我的程序的 View 类(从 CView 派生)尝试了相同的技术,它在那里工作,但在这里失败了。

【问题讨论】:

  • 不要使用WM_USER,使用WM_APPWM_USER 范围也被一些标准控件使用 - 您可能已经注册了两次相同的消息。
  • @MarkRansom,我试过 WM_APP,还是不行。此外,如果我将处理程序添加到程序的 View 类中,我的代码可以工作,但如果添加到我的自定义类,则它不起作用。
  • 这里还有一件有趣的事情:在类资源管理器中,我右键单击 CMyClass,然后打开属性框。我在 CMyClass 的消息列表中没有看到我的消息。
  • 另外,我的班级需要有消息循环吗?我在我的程序的 View 类中尝试了相同类型的代码,它成功了,消息被发布了。我的 View 类没有消息循环(至少据我所知)。但是我想知道,如果没有消息循环,如何处理消息?
  • 在不了解 Windows API 的情况下试图理解 MFC 是徒劳的。您可能应该阅读Prerequisites for learning MFC programming

标签: c++ winapi visual-c++ mfc message-queue


【解决方案1】:

如果窗口尚未创建,则不能发布到窗口。如果您实际上没有使用您的类创建窗口,GetSafeHwnd() 将返回 NULL。

【讨论】:

  • 我查了一下,确实是这样。
  • 能否给我一些关于如何为 CMyClass 创建窗口的提示?对于 CMyClass,我不需要 GUI,所以我希望窗口保持不可见。
  • 调用它的 CreateWindow。
  • 该类没有 CreateWindow 函数。我确实在 CWnd 中看到了 Create 函数。我尝试了以下方法,但没有奏效。我在生产线上遇到运行时异常。创建(L"CMyClass", L"dkjfhsfd", WS_CHILD | WS_VISIBLE, CRect(0, 0, 20, 20), this);
  • 第一个参数是窗口类名,与C++类名无关。您可以使用内置的窗口类名称,例如“STATIC”,如 MSDN 页面中所示的 CWnd::Create。并且您将“this”作为其父窗口传递。仅当“this”是一个已经具有有效 HWND 的窗口时才有效。
猜你喜欢
  • 2012-02-03
  • 1970-01-01
  • 1970-01-01
  • 2011-09-05
  • 1970-01-01
  • 2016-10-22
  • 2020-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多