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

时间:2012-01-05 05:30:20

标签: c# .net winapi com

我正在通过COM.

为现有应用开发扩展程序

要扩展的应用程序的当前界面允许创建自定义属性窗口并在该应用程序中使用它们。


现在,我正在使用.NET用于此目的,并且遇到了一些奇怪的问题:

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

    ExApplAPI.AddCustomPropertyWindow(extensionForm.Handle.ToInt32(), "Ololo");

如下所示,属性表实际上已扩展,但之后会发生奇怪的事情。

enter image description here

基本上,如果我切换到Ololo标签,然后返回其他3个标签(AttributesDrawingServices),应用程序会冻结。我也知道冻结发生在一些非托管代码块中。


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

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

enter image description here


将所有内容组合在一起:

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

那么 - 在这种情况下,任何想法/类似问题都解决了/等等吗?

4 个答案:

答案 0 :(得分:4)

.NET中的Forms的Win32 HWND句柄是惰性初始化的。 我认为这可能是一个问题。

您可能会因为访问ExApplAPI.AddCustomPropertyWindow(extensionForm.Handle.ToInt32(), "Ololo");属性而在您的行Handle中创建句柄。 这是真的,documentation承认的是什么。

但是,它会为Form本身创建句柄,但不会创建子控件的句柄(本例中为Button)。可以通过调用CreateControl方法强制执行此操作。请参阅more documentation

我不知道如果没有按钮手柄可能是你问题的原因,但这绝对是我要调查的。

总结一下,我建议您将代码更改为:

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

extensionForm.CreateControl();
ExApplAPI.AddCustomPropertyWindow(extensionForm.Handle.ToInt32(), "Ololo");

答案 1 :(得分:1)

是否抛出任何异常? 当使用WPF和COM时,我们有类似的行为,它通过使用

调用重置双倍计算来解决

[DllImport(“msvcr70.dll”,CallingConvention = CallingConvention.Cdecl)] public static extern int _fpreset();

答案 2 :(得分:0)

资源句柄可能不正确。正如您所提到的,只有当集成表单中至少有一个控件时才会发生这种情况,Ololo选项卡在再次激活时无法找到它的资源。请尝试第一次存储资源句柄,然后每次选项卡处于活动状态时恢复它。

答案 3 :(得分:0)

要理解应用程序挂起的原因,有两件事可能会有所帮助:

  1. 您可以在应用程序挂起时发布UI线程的堆栈跟踪吗?
  2. 哪个线程调用您的代码并实际创建窗口?