如何在我的WPF应用程序中将Win32浮动窗口放在用户控件中?

时间:2014-04-03 12:03:40

标签: c# wpf winapi interop

使用从HwndHost派生的类和一些巫毒代码:

protected override HandleRef BuildWindowCore(HandleRef hwndHost)
{
  CheckGuestValidity();
  var guestHwnd = new HandleRef(GuestHwnd, _guestHwnd);
  Win32.SetWindowStyle(guestHwnd.Handle, WindowStyles.WS_CHILD | Win32.GetWindowStyle(guestHwnd.Handle));
  WindowsFormsHost.EnableWindowsFormsInterop();
  System.Windows.Forms.Application.EnableVisualStyles();
  Win32.SetParent(guestHwnd.Handle, hwndHost.Handle);
  Win32.SetWindowStyle(_guestHwnd, Win32.GetWindowStyle(_guestHwnd) & ~WindowStyles.WS_CAPTION);
  return guestHwnd;
}

我已经设法从Delphi COM服务器获得一个无父(Windows'主窗口除外)窗口,以采用我的WPF应用程序窗口作为它的父窗口。问题是它位于我的WPF窗口最底部的所有其他用户控件等下面。我想调整大小并将其放置在TabControl中的选项卡上的矩形内。我怎么能这样做?我意识到它需要一些调整大小和定位Win32 API调用,甚至可能是一些低级别的Windows消息,但我已经为它做好了准备。

1 个答案:

答案 0 :(得分:0)

首先,我找到了一个方便的小类来在坐标系之间进行转换。对于问题How do I convert a WPF size to physical pixels?

,这是@ Lu55的回答,而不是被接受的回答

然后,我的WindowHostView XAML看起来像这样:

<Grid x:Name="WindowContainer" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Coral" >
  <delphi:Win32WindowHost x:Name="Host" />
</Grid>

Win32WindowHost类包含我的问题中包含的代码。

现在我在WindowHostView内有一个简洁的小例程,以便将访客窗口放入主机的边界。

private void PositionGuestWindow(IntPtr hWnd)
{
  var rect = WindowContainer.GetAbsoltutePlacement();
  var winLeft = Win32Calc.PointsToPixels(rect.Left, Win32Calc.Dimension.Width);
  var winTop = Win32Calc.PointsToPixels(rect.Top, Win32Calc.Dimension.Height);
  var winWidth = Win32Calc.PointsToPixels(rect.Width, Win32Calc.Dimension.Width);
  var winHeight = Win32Calc.PointsToPixels(this.ActualHeight - 20, Win32Calc.Dimension.Height);

  Win32Api.MoveWindow(Host.GuestHwnd, (int)winLeft, (int)winTop, (int)winWidth + 1, (int)winHeight, true);
}

而且Win32Api.MoveWindow很老了:

[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);