如何获取承载COM控件的表单的句柄

时间:2014-12-11 14:02:55

标签: .net delphi winapi com sendmessage

我有一个可视化的DotNet-Control,我在Delphi项目中用作COM-Control 现在我想获得在DotNet中托管这个DotNet组件的delphi表单的句柄。 当然 - 我可以使用类似setParentHandle(pHandle:hwnd)的东西将Form的句柄从Delphi传递到DotNet;我定义的方法,但这不是我想在这里做的方式。

是否有任何Winapi调用可以为我提供在DotNet中绘制内容的组件的句柄?

我想使用这个句柄,以便将DotNetComponent本身无法处理的消息发送到Delphi表单。

2 个答案:

答案 0 :(得分:0)

通常,当主机窗口包含可视ActiveX控件时,主机会实现IOleClientSite接口,并通过其IOleObject::SetClientSite()实现将其传递给控件。控件可以查询IOleClientSite IOleWindowIOleInPlaceSiteGetWindow(),并调用其IOleObject方法获取主机的HWND。

我不知道如何在.NET层实现SetClientSite(),但这就是COM / ActiveX层的工作方式。因此,.NET控件可能有一种方法可以覆盖自己的IOleClientSite方法,或提供其他方法来访问主机的{{1}}接口。

答案 1 :(得分:0)

我在C#中使用WinApi的GetParent方法解决了这个问题。

[DllImport("user32.dll")]
private static extern IntPtr GetParent(IntPtr hWnd);

protected override void WndProc(ref Message m){

    // 0x20a is the Message constant for WM_MOUSEWHEEL (Scrolling on your control)
    if(m.Msg == 0x20a){
      IntPtr hWnd= GetParent(this.Handle);
      SendMessage(hWnd, m.Msg, m.WParam, m.LParam);
    }
    else
        base.WndProc(ref m);
}

备注:将所有邮件转发到父控件会破坏您的控件,因为它不再能够收到自己的邮件。