如何使表格和HWND相互重新定位?

时间:2011-01-20 01:01:24

标签: c# .net winforms winapi hwnd

我有一个System.Windows.Form和一个IntPtr充当HWND。

我希望他们每个人都把另一个放在移动中。我很惊讶我在网上找不到“Hwnd get / set position c#”和许多变化,或许我忽略了明显的结果。

为了给出示例,请考虑表单“窗口A”和Hwnd“窗口B”。我们还要说我希望B的位置是A的位置+右侧50像素。

2 个答案:

答案 0 :(得分:3)

  

更新:您可能还想查看WinForms'NativeWindow class,它可用于包装本机HWWND并侦听发送到的窗口消息那个窗口。

我想您需要使用Win32 API函数MoveWindow来设置窗口B(HWND)的位置(和尺寸)。您可以从.NET via P/Invoke调用此API函数。

为了检索窗口B的当前位置和大小,您可能还需要通过P / Invoke调用GetWindowRect


以下代码可能无法开箱即用,也许有更简单的解决方案,但它可能会为您提供一个起点,以及上述链接:

// the following P/Invoke signatures have been copied from pinvoke.net:

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

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(HandleRef hWnd, out RECT lpRect);

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int Left;        // x position of upper-left corner
    public int Top;         // y position of upper-left corner
    public int Right;       // x position of lower-right corner
    public int Bottom;      // y position of lower-right corner
}

...

System.Windows.Form a = ...;
IntPtr b = ...;

RECT bRect;
GetWindowRect(b, out bRect);

MoveWindow(b,
           a.Location.X + 50, b.Location.Y,
           bRect.Right - bRect.Left, bRect.Bottom - bRect.Top,
           true);

答案 1 :(得分:2)

更难的部分是当B移动时让A移动。这需要NativeWindow派生类。使用AssignHandle附加您获得的窗口句柄。在WndProc()覆盖中,您可以检测WM_MOVE消息,允许您移动A.和WM_DESTROY进行清理。

但是,只有当窗口归您的进程所有时才有效。更典型的情况是,这是一个窗口,属于您无法控制的某些代码,在另一个程序中运行。如果是这样的话你会非常紧张,NativeWindow方法无法工作。您需要使用SetWindowsHookEx()将非托管DLL注入进程,以便监视WH_CALLWNDPROC。使用某种IPC机制将通知发送到您的流程中。很难做到,你不能用C#编写DLL代码。