2011-01-20 6 views
1

私はSystem.Windows.FormIntPtrをHWNDとして持っています。フォームとHWNDを相互に再配置するにはどうすればよいですか?

私は彼らのそれぞれが動いて、もう一方を置くことを望みます。私は "Hwnd get/set position C#"と多くのバリエーションを使ってウェブ上で何も見つけられなかったことに驚きました。おそらく私は明らかな結果を見落としています。

フォーム "ウィンドウA"とHwnd "ウィンドウB"を考えてみましょう。また、Bの位置をAの位置+右の50ピクセルにしたいとしましょう。

答えて

3

更新:あなたはまた、ネイティブHWWNDをラップし、そのウィンドウに送信されたウィンドウメッセージを聞くために使用することができ、WinFormsのNativeWindow classをチェックアウトする場合があります。

は、私はあなたのウィンドウのBの位置(および寸法)(HWND 1)を設定するためのWin32 API関数MoveWindowが必要になりますと仮定します。このAPI関数は.NET via P/Invokeから呼び出すことができます。

ウィンドウBの現在の位置とサイズを取得するには、さらにGetWindowRectとP/Invokeを使用して呼び出す必要があります。


次のコードは、箱から出して動作しない場合があります、そしておそらく単純な解決策があるが、それは一緒に上記のリンクを、あなたの出発点を与えるかもしれない:

// 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); 
+0

+1よく似ています –

+0

これが大好きです。今はテストすることはできませんが、今晩はそれほど微妙な操作をしなければ動作しないと認められます。ありがとう! – Lazlo

2

難しい部分Bが動いたときにAを動かすことです。これには、NativeWindow派生クラスが必要です。 AssignHandleを使用して、取得したウィンドウハンドルをアタッチします。 WndProc()オーバーライドでは、WM_MOVEメッセージを検出することができます.Aを移動し、WM_DESTROYをクリーンアップできます。

ただし、そのプロセスがそのウィンドウを所有している場合にのみ機能します。より典型的なシナリオは、これはあなたが制御しない別のプログラムで動作するコードに属するウィンドウであるということです。 NativeWindowのアプローチは動作しません。 WH_CALLWNDPROCを監視できるように、SetWindowsHookEx()でプロセスにアンマネージDLLを注入する必要があります。あなたのプロセスにその通知を得るための何らかの種類のIPCメカニズム。非常に難しいですが、C#でDLLコードを書くことはできません。

+0

私にとっては幸いにも、それは私のプロセスによって所有されています。 – Lazlo

+0

さて、あなたはNativeWindowをよく使っています。 –

関連する問題