首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我能否获得使用hwnd / NativeWindow设置NativeWindow表单所有者的行为?

我能否获得使用hwnd / NativeWindow设置NativeWindow表单所有者的行为?
EN

Stack Overflow用户
提问于 2008-10-17 20:07:34
回答 2查看 6.1K关注 0票数 6

我的应用程序是vb6可执行文件,但是系统中的一些较新的表单是用C#编写的。我希望能够使用主应用程序窗口的句柄设置C#窗体的所有者属性,以便在我的应用程序和其他应用程序之间来回切换时,对话框保持在顶部。

我可以得到主应用程序窗口的hwnd。我不知道我能从那里做什么?

更新08年10月20日17:06:

史考特,

谢谢你的回应。我忽略了Show/ShowDialog方法参数不是Form类型-我只查看了Owner属性。

我对上面使用的代码做了一些修改--我们有一个组件,它通常加载表单并调用ShowDialog。我的代码如下所示:

代码语言:javascript
复制
Form launchTarget = FormFactory.GetForm(xxx);  // psuedo-code for generic form loader
launchTarget.StartPosition = FormStartPosition.CenterParent;
IWin32Window parentWindow = GetWindowFromHwnd(hwnd);

launchTarget.ShowDialog(parentWindow);

GetWindowFromHwnd是一个方法包装的代码版本:

代码语言:javascript
复制
private IWin32Window GetWindowFromHost(int hwnd)
{
    IWin32Window window = null;
    IntPtr handle = new IntPtr(hwnd);

    try
    {
        NativeWindow nativeWindow = new NativeWindow();
        nativeWindow.AssignHandle(handle);
        window = nativeWindow;
    }
    finally
    {
        handle = IntPtr.Zero;
    }

    return window;
}

不幸的是,这不是我所希望的。表单确实可以正常显示,但是它没有显示在正确的位置,当我选择离开并返回到父窗口时,它也没有显示在顶部。我们的modals没有在任务栏中显示任务,因此窗口似乎“消失”了(尽管它仍然存在于alt窗口列表中)。对我来说,这表明我可能没有正确的人力资源。如果您有任何其他建议,请回复。再次感谢。

更新2008年11月10日16:25

一个后续的注释--如果您在try/finally中将其输入到方法调用中,如Scott的第2篇文章中所述,那么finally块中的调用应该是:

代码语言:javascript
复制
parentWindow.ReleaseHandle();
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2008-10-17 20:36:13

因此,您正在从C#调用VB6 Windows窗体类,这意味着您可能在使用Show()ShowDialog(),对吗?这两个方法都接受一个IWin32Window参数,它只定义一个返回名为IntPtr属性句柄的对象。

So...you需要为您的Windows类添加一个重载的构造函数(或ShowDialog方法),这些类将long作为参数,以便将VB6 hwnd传递给表单。一旦进入C#代码,就需要从hwnd创建一个IntPtr,并将其分配给NativeWindow对象,然后作为所有者传递它。

类似于这个的东西应该可以工作,尽管它还没有经过测试:

代码语言:javascript
复制
public DialogResult ShowDialog(long hwnd)
{
   IntPtr handle = new IntPtr(hwnd);
   try
   {
      NativeWindow nativeWindow = new NativeWindow();

      nativeWindow.AssignHandle(handle);
      return this.ShowDialog(nativeWindow);
   }
   finally
   {
      handle = IntPtr.Zero;
   }
}
票数 9
EN

Stack Overflow用户

发布于 2008-10-20 17:27:56

这太长了不能发表评论..。

我认为您正在运行的问题是您如何包装我在ShowDialog重载中显示的代码。如果您遵循您的GetWindowFromHost代码所做的操作,则可以执行以下步骤:

  1. 根据给定的hwnd创建一个新的IntPtr。
  2. 创建一个新的NativeWindow对象,并将它的句柄指定为IntPtr。
  3. 将IntPtr(在最后一个块中)设置为IntPtr.Zero.

我想是这个最后的障碍给你带来了麻烦。在我的代码中,对this.ShowDialog(nativeWindow)的调用完成后,将运行finally块。此时,句柄(IntPtr)不再被使用。在您的代码中,您将返回一个应该仍然保存对该IWin32Window的引用的IntPtr,该引用在您调用launchTarget.ShowDialog(parentWindow)时是IntPtr.Zero。

尝试更改代码如下:

代码语言:javascript
复制
private NativeWindow GetWindowFromHost(int hwnd)
{
   IntPtr handle = new IntPtr(hwnd);
   NativeWindow nativeWindow = new NativeWindow();
   nativeWindow.AssignHandle(handle);
   return window;
}

然后将调用代码改为如下所示:

代码语言:javascript
复制
Form launchTarget = FormFactory.GetForm(xxx);  // psuedo-code for generic form 
loaderlaunchTarget.StartPosition = FormStartPosition.CenterParent;
NativeWindow parentWindow = GetWindowFromHwnd(hwnd);

try
{
   launchTarget.ShowDialog(parentWindow);
}
finally
{
   parentWindow.DestroyHandle();
}

这些更改应该可以工作,但这也是未经测试的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/213661

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档