当控件添加到表单时,应用程序的C#加载项(通过COM)会冻结吗?

Yip*_*Yay 8 .net c# com winapi

我正在通过开发现有应用程序的扩展 COM.

要扩展的应用程序的当前接口允许创建自定义属性窗口并在该应用程序内使用它们.


现在,我正在使用.NET这个目的,并有一些奇怪的问题:

    extensionForm = new Form();
    extensionForm.SetBounds(0, 0, 100, 100);
    extensionForm.Controls.Add(new Button());

    ExApplAPI.AddCustomPropertyWindow(extensionForm.Handle.ToInt32(), "Ololo");
Run Code Online (Sandbox Code Playgroud)

正如你在下面看到的那样,属性表实际上已经扩展,但在那之后,一些奇怪的事情开始发生.

在此输入图像描述

基本上,如果我切换到Ololo选项卡,然后返回到任何其他3个选项卡(Attributes,DrawingServices),应用程序将冻结.我也知道冻结发生在一些非托管代码块中.


另一个有趣的事实是,如果我不写extensionForm.Controls.Add(new Button()) (有或没有暂停/恢复布局调用),一切正常.因此,如果最近构建的表单上没有控件(按钮或任何其他),则它不会冻结.

这是冻结之前窗口Spy++上的日志Ololo(最后一条消息是WM_CTLCOLORBTN,在应用程序冻结之后):

在此输入图像描述


把所有东西组合在一起

  • 只有当我切换Ololo到其他选项卡然后Ololo再次切换到选项卡时才会发生冻结.
  • 只有当集成表单上至少有一个控件时,才会发生冻结,没有控件的表单不会冻结.
  • 应用程序目前没有运行任何托管代码,也没有花费任何CPU时间.

那么 - 在这种情况下帮助我的任何想法/类似问题解决/等?

Kri*_*izz 4

HWND.NET 中窗体的Win32句柄是延迟初始化的。我认为这可能是一个问题。

您可能会争辩说,该句柄是ExApplAPI.AddCustomPropertyWindow(extensionForm.Handle.ToInt32(), "Ololo");由于访问Handle属性而在您的行中创建的。这是事实,也是文档所承认的。

但是,它会为其自身创建句柄,但不会创建Form子控件(在本例中)的句柄。Button这可以通过调用方法来强制CreateControl。查看更多文档

我不知道没有按钮手柄是否是导致您出现问题的原因,但这绝对是我会调查的问题。

总而言之,我建议将您的代码更改为:

extensionForm = new Form();
extensionForm.SetBounds(0, 0, 100, 100);
extensionForm.Controls.Add(new Button());

extensionForm.CreateControl();
ExApplAPI.AddCustomPropertyWindow(extensionForm.Handle.ToInt32(), "Ololo");
Run Code Online (Sandbox Code Playgroud)