- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试将 C++ Builder 应用与 .NET 服务应用连接,并希望 .NET 服务应用能够将事件发送回 C++ Builder 应用。
是否有可以处理 COM 事件的 C++ Builder 应用程序的工作示例?
最佳答案
DocWiki 中存在关于处理 COM 事件的错误。搜集了一些各地的例子,放在一起供大家引用。
.NET 应用程序具有以下内容:
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace IPractLib01
{
//
// GUID's to use for the COM objects.
[Guid("ACD03FE3-E506-4D87-BF8B-CC1F52E1FF0C")]
public interface IManagedInterface
{
int SendMessage(
string message
);
}
// Source interface with "event handlers" for COM objects to implement
[Guid("1ACAB463-55A3-4B3F-BE10-6252CDD93CE8")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] // use InterfaceIsDual to get callbacks by other than InvokeEvent()
public interface IIntelliPractEvents
{
[DispId(1)] void MessageReceived();
[DispId(2)] void MessageTextReceived(string message);
}
// Delegates for the events
public delegate void MessageReceivedEventHandler();
public delegate void MessageTextReceivedEventHandler(string message);
[Guid("1F4A7EDA-EE2A-4EA3-B213-A1911C5F766E")]
[ComSourceInterfaces(typeof(IIntelliPractEvents))]
public class IPractLib01Class : IManagedInterface
{
public event MessageReceivedEventHandler MessageReceived;
public event MessageTextReceivedEventHandler MessageTextReceived;
public int SendMessage(string message)
{
if (MessageReceived != null)
{
MessageReceived();
}
if (MessageTextReceived != null)
{
int len = message.Length;
string newMessage = "The message is '" + message + "', and the length of the message is " + len;
MessageTextReceived(newMessage);
}
return 0;
}
}
}
C++ Builder 应用程序包含:
#include "Unit1.h"
#include "IPractLib01_TLB.h" // created with Component/Import Component/Import a Type Library
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// to register the assembly dll:
// regasm IPractLib01.dll /tlb /verbose
// Need to run regasm as administrator, due to need to modify registry. If a regular user login was used to map drives, the mappings are not normally seen by the administrator login. Use "net use" in the administrator login to map them for the administrator
static TCOM_IPractLib01Class iplClass;
// The DocWiki does not take the address of the DIID_, but that does not compile
class MyEventSinkClass : public TEventDispatcher<MyEventSinkClass, &DIID_IIntelliPractEvents>
{
public:
MyEventSinkClass(IUnknown* sourceClass);
~MyEventSinkClass();
// declare the methods of DIID_IIntelliPractEvents here
void __fastcall MessageReceived();
void __fastcall MessageTextReceived(BSTR message/*[in]*/);
virtual HRESULT InvokeEvent(DISPID id, TVariant* params = 0);
IUnknown* theSource_;
};
static MyEventSinkClass* theEventSink = NULL;
static void ConnectNetHandler(void)
{
if (!iplClass)
iplClass = CoIPractLib01Class::Create();
if (!theEventSink) {
theEventSink = new MyEventSinkClass(iplClass);
}
}
// All of the events come through InvokeEvent -- change the interface to InterfaceIsDual if you want events through the other routines
HRESULT MyEventSinkClass::InvokeEvent(DISPID id, TVariant* params)
{
ShowMessage("got InvokeEvent with DISPID " + String(id));
// params would need better handling in a real app
if (params) {
String st = params->operator WideString();
ShowMessage("String is " + st);
}
return 0;
}
MyEventSinkClass::MyEventSinkClass(IUnknown* sourceClass)
{
theSource_ = sourceClass;
ConnectEvents(sourceClass);
}
MyEventSinkClass::~MyEventSinkClass()
{
DisconnectEvents(theSource_);
}
// These two routines do not get called with InterfaceIsDispatch; change that to InterfaceIsDual for these routines to be called.
void __fastcall MyEventSinkClass::MessageReceived()
{
ShowMessage("Message handler received");
}
void __fastcall MyEventSinkClass::MessageTextReceived(BSTR message/*[in]*/)
{
ShowMessage(String("Message handler received with message: ") + message);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ConnectNetHandler();
long result = -1;
TCOMIManagedInterface mif = iplClass;
if (!mif) {
ShowMessage("Unable to connect to interface");
return;
}
String theMessage = "the message";
mif->SendMessage(WideString(theMessage).c_bstr(), &result);
// check the IErrorInfo
// (Microsoft: Making a COM call that goes through a proxy-stub will clear any existing error object for the calling thread)
IErrorInfo *pperrinfo = NULL;
HRESULT hr = GetErrorInfo(0, &pperrinfo);
if (SUCCEEDED(hr) && pperrinfo) {
WideString wideStringMessage, wideStringDescription; // WideString is a wrapper for BSTR
pperrinfo->GetSource(&wideStringMessage);
pperrinfo->GetDescription(&wideStringDescription);
ShowMessage("Got error from " + String(wideStringMessage) + "; error description: " + String(wideStringDescription));
}
.NET代码创建的DLL必须在regasm/tlb注册生成类型库,才能让C++ Builder创建实现COM的单元。但是,一旦创建了应用程序,就不需要在部署它的系统上调用 regasm。
关于c++ - C++ Builder 中是否有 COM 事件处理的工作示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34563863/
我正在开发一个应用程序,我成功地消除了除一个错误之外的所有错误: no suitable constructor found for builder 更改为“意图” https://file.io/O
我可以在 C++Builder 6 中成功编译以下代码片段,但我无法在 RAD Studio Seattle 中编译它: unsigned long x = 50; String s = In
我有一个项目(新开始),其中 C++ Builder 没有在任何断点处停止。我已确保我处于 Debug模式(未发布),链接器->完整调试信息 = True,C++ 编译器->调试配置,C++ 编译器-
我们想在正在开发的 C++ builder XE 应用程序中绘制大型控制流程图。 这些图表将以编程方式生成并以交互方式显示给用户(用户可以滚动大流程图、选择节点等)。节点必须能够显示自定义组件(如 T
我有以下问题 午餐时 FlashBuilder.exe (BURRITO):它崩溃并创建一个错误日志文件,例如: hs_err_pid7084.log 及以下 但是当我咀嚼 FlashBuilderC
我有一个大型 Flash Builder 项目,它是更大 (.net) 解决方案的一部分。对于整个项目,我通常有一个前进的开发分支,以及一个或多个错误修复分支。考虑到 Flash Builder 不想
乘数(自动布局中约束的属性)有什么作用? 最佳答案 约束中两个值之间的关系由以下公式确定: b = am + c 其中 a 和 b 是要关联的两个值,m 是乘数,c code> 是常量。 例如,如果
我们的开发团队使用 Borland C++ Builder 6 和 CodeGear C++ Builder 2007(以及 Visual Studio)。我听到很多评论说 Builder 2007
我想阐明我对构建器模式的使用,特别是构建器类型是如何创建的。在示例中,它只是假定构建器的类型并创建它。但是,我在“ChartBuilderFactory”类中创建了一个 CreateBuilder 方
首先,我对 Java 比较陌生,所以我问的可能是微不足道的,但我在这里或其他地方找不到答案。 为简单起见,假设我有以下类层次结构: class Shape { protected Shape(
我试图在另一个 AlertDialog 中打开一个 AlertDialog,但它不起作用,知道为什么它不起作用吗? String items[] = {"Details","Edit","Delete
我有一个包含 Form1 和 Form2 的程序。如何单击按钮从 form1 打开 form2? 最佳答案 更多信息 在你的 Project.cpp 中有这个:Application->CreateF
每当我使用 C++ Builder(XE4 版,但以前的版本也这样做)在 Release模式下构建 Win32 EXE 时,它总是创建一个导出目录并为我的项目中的每个单元导出一个 Initialize
我正在尝试在我的试用版 flashbuilder 上启用设计模式,但找不到任何选项, 我已经查看了 Windows 菜单,但没有启用设计模式, 和首选项,但首选项对话框中没有 Flex 来启用其设计模
我目前正在将一个大型 RAD Studio 2010 项目迁移到 XE4。作为其中的一部分,我正在重新创建许多项目文件。我想借此机会确保我们对预编译头使用最好的机制,因为似乎有几种方法可以做到这一点。
我观看了“Interface Builder 中的新增功能” session 视频并尝试复制显示的代码,但不幸的是,当我将 View 分配给具有 @IBDesignable 的自定义类时,出现 2 个
这个问题在这里已经有了答案: Why is NotificationCompat needed? (3 个答案) 关闭 5 年前。 我看到的几乎所有 Android 通知示例代码似乎都使用了 Not
我正在使用 fcm 从我的 Android 应用程序发送通知,并且我已经实现了它要求我提供的所有库。 val topic = "highScores" // See docum
我正在尝试在Flash Builder 4.6中进行项目范围内的查找和替换,但是对我而言,如何实现这一点并不明显。 我试过Edit-> Find/Replace然后全部替换,但它仅替换当前打开的文件中
帮助我在 XCode4 中取消 fubar 界面构建器。 我在 interface-builder 中创建了一个按钮,并在 View 的代码中为它定义了一个 IBAction 方法。它运行良好。然后我
我是一名优秀的程序员,十分优秀!