2

我有一个与 AppDomain 和 Windows 消息有关的问题。

要在 Internet Explorer 中托管的网页,其中包含 .Net WinForms UserControl 派生控件 - HelloWorldCtl。此控件位于 C# 编写的程序集 - HelloWorldControl.dll 中。该控件使用来自另一个用 C++/CLR 编写的程序集的代码 - HelloWorldLibCPP.dll。

HelloWorldCtl 加载 HelloWorldLibCPP.dll 并调用将创建 Win32 本机窗口的代码并将该窗口放置在 HelloWorldCtl 的区域中。

导航到网页,HelloWorldCtl 加载,我可以看到它以及 HelloWorldCtl 区域中心的本机窗口。

C# 控件和本机窗口都有一些消息处理程序,并且消息都可以正常工作并到达 C# 控件的窗口和本机窗口;鼠标点击、重新绘制等等……但是,本机窗口的一些消息处理程序需要调用作为本机窗口父级的 C# 控件上的方法。这是使用 C# 控件实现的接口完成的,并且本机窗口通过将其存储在 GCHandle 中(来自 System::Runtime::InteropServices)来保存对它的引用。我为 GCHandle 使用了 gcroot<> 模板。

当本机窗口中的代码尝试使用 GCHandle 调用 C# 控件上的任何方法时,此时会发生故障。(c++ 代码使用 /clr 编译为托管代码。)

抛出的异常是:

“无法跨 AppDomain 传递 GCHandle”

我放了一些调试代码来在 C# 和本机窗口中显示 CurrentDomain 的 Id 和 FriendName,我发现这些 AppDomain 并不相同。

在原生窗口的创建过程中,CurrentDomain 与 C# 控件相同,但是当原生窗口接收消息并处理这些消息时,CurrentDomain 与 C# 控件不同。

这种状况可以改变吗?是否可以让两个本机窗口消息处理程序在与 C# 控件相同的 AppDomain 中运行?

也许还有其他建议?

谢谢,罗杰

4

1 回答 1

1

实际上,我确实找到了解决问题的方法。我成功地实现了我的代码,其方式与“Mirality Systems 的 Mirality 的想法、随机想法和沉思”博客中“跨 AppDomains 的非托管回调”主题下的以下帖子中描述的方式类似。

祝你好运,罗杰

http://lambert.geek.nz/2007/05/29/unmanaged-appdomain-callback/

于 2010-07-06T17:05:42.600 回答