繁体   English   中英

FMX 系统消息发送一个指针(?)

[英]FMX System messaging to send a pointer(?)

我正在使用 C++Builder 10.2。

在Android中,我想从各种线程(包括主线程)向主GUI线程发送消息。 在 Windows 中,我可以发布一条消息并将 LPARAM 或 WPARAM 分配给结构或类的某个实例的地址。

我正在尝试使用System.Messaging.TMessageManager来做同样的事情,类似于这里的示例: System.Messaging (C++) 但我只能发送“简单”类型,如UnicodeStringint 我还没有弄清楚如何发送一个指针,假设它甚至是可能的。

我想发送这样的结构/类实例:

class TSendResult
{
public:
    String Message;
    unsigned int Value;
    int Errno;

    __fastcall TSendResult(void);
    __fastcall ~TSendResult();
};

如果这可以做到,我该怎么写? 我设法编译了一个版本,但出现链接器错误:

错误:未定义对“System::Messaging::TMessage__1<TSendResult>”的引用

表单构造函数:

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    TMessageManager* MessageManager = TMessageManager::DefaultManager;
    TMetaClass* MessageClass = __classid(TMessage__1<TSendResult>);
    TMessageListenerMethod ShowReceivedMessagePointer = &(this->MMReceiveAndCallBack);
    MessageManager->SubscribeToMessage(MessageClass, ShowReceivedMessagePointer);
}

按钮点击处理程序:

void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
    ...

    TSendResult *SPtr = new TSendResult();
    SPtr->Message = "All good";
    SPtr->Value = 10;
    SPtr->Errno = 0;
    TMessageManager* MessageManager = TMessageManager::DefaultManager;
    TMessage__1<TSendResult>* Message = new TMessage__1<TSendResult>(*SPtr); // <-- this doesn't look right...
    MessageManager->SendMessage(Sender, Message, false);
}

捕获消息的函数:

void __fastcall TForm1::MMReceiveAndCallBack(System::TObject* const Sender,
        System::Messaging::TMessageBase* const M)
{
    TMessage__1<TSendResult>* Message = dynamic_cast<TMessage__1<TSendResult>*>(M);
    if (Message) {
        ShowMessage(Message->Value.Message);
    }
}

TMessage__1<T>是 Delphi Generic TMessage<T>类的 C++ 类实现。 不幸的是,在 C++ 中使用 Delphi 泛型类时有一个记录限制,这就是为什么您会收到链接器错误的原因:

如何在 C++ 中处理 Delphi 泛型

Delphi 泛型作为模板暴露给 C++。 然而,重要的是要意识到实例化发生在 Delphi 端,而不是在 C++ 中。 因此,您只能将这些模板用于在 Delphi 代码中显式实例化的类型

...

如果 C++ 代码尝试对未在 Delphi 中实例化的类型使用 Delphi 泛型,则会在链接时收到错误。

这就是为什么TMessage__1<UnicodeString>有效但TMessage__1<TSendResult>无效的原因,因为 Delphi RTL 中存在TMessage<UnicodeString>的实例化。 编写您正在查看的C++ 示例的人可能没有意识到这一限制,只是按原样翻译了Delphi 示例

话虽如此,你有两个选择:

  1. 将 Delphi .pas单元添加到您的 C++ 项目,将TSendResult实现为 Delphi record ,并TMessage<TSendResult>定义TMessage<TSendResult>的实例化。 然后你可以使用该单元在你的C ++代码(C ++ Builder将生成一个C ++ .hpp为您的文件时.pas文件编译),例如:
unit MyMessageTypes;

interface

uses
  System.Messaging;

type
  TSendResult = record
    Message: String;
    Value: UInt32;
    Errno: Integer;
  end;

  TSendResultMsg = TMessage<TSendResult>;

implementation

initialization
  TSendResultMsg.Create.Free;
finalization

end.
#include "MyMessageTypes.hpp"

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    TMessageManager::DefaultManager->SubscribeToMessage(__classid(TSendResultMsg), &MMReceiveAndCallBack);
}

void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
    ...

    TSendResult Res;
    Res.Message = _D("All good");
    Res.Value = 10;
    Res.Errno = 0;

    TSendResultMsg *Message = new TSendResultMsg(Res);
    TMessageManager::DefaultManager->SendMessage(this, Message, true);
}

void __fastcall TForm1::MMReceiveAndCallBack(System::TObject* const Sender,
    System::Messaging::TMessageBase* const M)
{
    const TSendResultMsg* Message = static_cast<const TSendResultMsg*>(M);
    ShowMessage(Message->Value.Message);
}
  1. 而不是使用TMessage__1可言,可以改为派生TSendResult直接从TMessageBase ,如:
class TSendResultMsg : public TMessageBase
{
public:
    String Message;
    unsigned int Value;
    int Errno;
};

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    TMessageManager::DefaultManager->SubscribeToMessage(__classid(TSendResultMsg), &MMReceiveAndCallBack);
}

void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
    ...

    TSendResultMsg *Message = new TSendResultMsg;
    Message->Message = _D("All good");
    Message->Value = 10;
    Message->Errno = 0;
    TMessageManager::DefaultManager->SendMessage(this, Message, true);
}

void __fastcall TForm1::MMReceiveAndCallBack(System::TObject* const Sender,
    System::Messaging::TMessageBase* const M)
{
    const TSendResultMsg* Message = static_cast<const TSendResultMsg*>(M);
    ShowMessage(Message->Message);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM