我有一个System.Windows.Form
和一个IntPtr
充当HWND。
我希望他们每个人都把另一个放在移动中。我很惊讶我在网上找不到“Hwnd get / set position c#”和许多变化,或许我忽略了明显的结果。
为了给出示例,请考虑表单“窗口A”和Hwnd“窗口B”。我们还要说我希望B的位置是A的位置+右侧50像素。
答案 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代码。