C++ BEGIN#U MESSAGE#U MAP导致C++;Builder 10.1将崩溃到桌面

C++ BEGIN#U MESSAGE#U MAP导致C++;Builder 10.1将崩溃到桌面,c++,c++builder-10.1-berlin,C++,C++builder 10.1 Berlin,我正在编写一个VCL组件,TGIcon,以模拟windows桌面中的图标,它一直工作正常,直到我决定将MouseEnter和MouseLeave事件添加到该组件。我遵循以下指南: 这是我的代码(标题): 每当我试图将组件放在表单上时,IDE(C++Builder初学者)就会崩溃到桌面。我已经追踪到问题的根源是“开始消息映射…结束消息映射”部分。如果我将该部分注释掉,则该组件工作正常 我曾经在C++Builder XE5(Professional)中使用相同的组件,但由于该组件归我不再合作的公司所

我正在编写一个VCL组件,TGIcon,以模拟windows桌面中的图标,它一直工作正常,直到我决定将MouseEnter和MouseLeave事件添加到该组件。我遵循以下指南:

这是我的代码(标题):

每当我试图将组件放在表单上时,IDE(C++Builder初学者)就会崩溃到桌面。我已经追踪到问题的根源是“开始消息映射…结束消息映射”部分。如果我将该部分注释掉,则该组件工作正常

我曾经在C++Builder XE5(Professional)中使用相同的组件,但由于该组件归我不再合作的公司所有,我没有该组件的二进制文件,因此我必须在这里重新编写。就我所记得的,我所做的与我在XE5中写的完全相同,一个可以工作,但这个会使IDE崩溃,没有错误消息,没有访问冲突,只有简单的CTD。

有人能帮忙吗?在C++ Builder 10.1(柏林)入门版中有什么需要我做的吗?这是C++Builder的一个bug,还是在初学者版中无法做到,只能在“付费”版中做到??或者这种方法已经过时了?如果是这样,请告诉我如何“现代化”的C++ Builder做它。
提前感谢。

您的
消息\u MAP
被错误终止。在
END\u MESSAGE\u MAP
宏中,必须指定组件派生自的基类(
tgraphicscontrol

MESSAGE\u MAP
只是覆盖虚拟
Dispatch()
方法的一种奇特方式,其中:

  • BEGIN\u MESSAGE\u MAP
    声明并打开覆盖的方法,并打开一个
    开关
    语句
  • MESSAGE\u HANDLER
    (如果项目使用ATL,则使用
    VCL\u MESSAGE\u HANDLER
    )为
    开关声明
    case
    语句
  • END\u MESSAGE\u MAP
    为未处理的消息调用指定类的
    Dispatch()
    方法,关闭
    开关
    ,并关闭重写的方法

下面是来自
sysmac.h
的声明:

#define BEGIN_MESSAGE_MAP   virtual void __fastcall Dispatch(void *Message) \
        {                                           \
          switch  (((PMessage)Message)->Msg)        \
          {

所以,这个代码:

BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(CM_MOUSEENTER, TMessage, CMMouseEnter)
    MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, CMMouseLeave)
END_MESSAGE_MAP(TGIcon) // <-- error!

您的
消息\u映射
被错误终止。在
END\u MESSAGE\u MAP
宏中,必须指定组件派生自的基类(
tgraphicscontrol

MESSAGE\u MAP
只是覆盖虚拟
Dispatch()
方法的一种奇特方式,其中:

  • BEGIN\u MESSAGE\u MAP
    声明并打开覆盖的方法,并打开一个
    开关
    语句
  • MESSAGE\u HANDLER
    (如果项目使用ATL,则使用
    VCL\u MESSAGE\u HANDLER
    )为
    开关声明
    case
    语句
  • END\u MESSAGE\u MAP
    为未处理的消息调用指定类的
    Dispatch()
    方法,关闭
    开关
    ,并关闭重写的方法

下面是来自
sysmac.h
的声明:

#define BEGIN_MESSAGE_MAP   virtual void __fastcall Dispatch(void *Message) \
        {                                           \
          switch  (((PMessage)Message)->Msg)        \
          {

所以,这个代码:

BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(CM_MOUSEENTER, TMessage, CMMouseEnter)
    MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, CMMouseLeave)
END_MESSAGE_MAP(TGIcon) // <-- error!

你提供的链接是一篇非常古老的文章(几乎有20年历史了)。我关心的是如何使用
\uu fastcall
调用约定。我已经有一段时间没有使用这些消息处理程序了,因此下面的语句可能不正确,但这些函数可能应该使用
\uu stdcall
约定(或者根本不使用)。至少,你可以试一试。有关这些调用约定的更多上下文,请参见,例如,尝试了u stdcall,仍然是CTD。我知道文章是旧的,自从C++ Builder 6以来,我一直使用这种类型的事件处理。当我在XE5投诉BEGIN_消息_地图的内联代码时,我就知道它已经过时了,但Embarcadero根本没有更新这方面的任何信息,至少我无法通过谷歌找到任何信息。无论如何,谢谢。你提供的链接是一篇非常古老的文章(几乎有20年历史了)。我关心的是如何使用
\uu fastcall
调用约定。我已经有一段时间没有使用这些消息处理程序了,因此下面的语句可能不正确,但这些函数可能应该使用
\uu stdcall
约定(或者根本不使用)。至少,你可以试一试。有关这些调用约定的更多上下文,请参见,例如,尝试了u stdcall,仍然是CTD。我知道文章是旧的,自从C++ Builder 6以来,我一直使用这种类型的事件处理。当我在XE5投诉BEGIN_消息_地图的内联代码时,我就知道它已经过时了,但Embarcadero根本没有更新这方面的任何信息,至少我无法通过谷歌找到任何信息。无论如何,谢谢。是的,真的……我真傻,竟然忘了这件事。。。案子解决了,非常感谢,雷米·勒博。是的,的确……我真傻,竟然忘了这件事。。。案子解决了,谢谢你,雷米·勒博。
BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(CM_MOUSEENTER, TMessage, CMMouseEnter)
    MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, CMMouseLeave)
END_MESSAGE_MAP(TGIcon) // <-- error!
virtual void __fastcall Dispatch(void *Message)
{
    switch (((PMessage)Message)->Msg)
    {
        case CM_MOUSEENTER:
            CMMouseEnter(*((TMessage *)Message));
            break;

        case CM_MOUSELEAVE:
            CMMouseLeave(*((TMessage *)Message));
            break;

        default:
            TGIcon::Dispatch(Message); // <-- recursive loop!
            break;
    }
}
BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(CM_MOUSEENTER, TMessage, CMMouseEnter)
    MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, CMMouseLeave)
END_MESSAGE_MAP(TGraphicControl) // <-- fixed!