2011-01-20 2 views
1

나는 System.Windows.FormIntPtr을 HWND로 사용합니다.Form과 HWND를 어떻게 재배치 할 수 있습니까?

각자 다른 사람을 이동 시키길 원합니다. 나는 "Hwnd get/set position C#"및 많은 변형을 통해 웹에서 아무 것도 찾을 수 없다는 것에 놀랐습니다. 아마도 명백한 결과를 간과 할 것입니다.

주어진 예제를 위해 양식 "창 A"와 Hwnd "창 B"를 고려하십시오. 또한 B의 위치가 A의 위치 + 오른쪽의 50 픽셀이되도록하고 싶다고합시다.

답변

3

업데이트 : 또한 체크 아웃 할 수 있습니다 윈폼 'NativeWindow class, 기본 HWWND을 포장하고 해당 창에 전송 윈도우 메시지에 들어하는 데 사용 될 수있다.

나는 당신이 당신의 창 B의 위치 (및 크기)합니다 (HWND 일)을 설정하려면 Win32 API 함수 MoveWindow 필요합니다 가정합니다. .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); 
+0

+1 많이 좋아합니다. –

+0

많이 좋아합니다. 지금 당장은 테스트 할 수 없지만, 오늘 밤에는 너무 많이 땜질하지 않고 작동한다면 받아 들일 수 있습니다. 감사! – Lazlo

2

열심히 부분 B가 움직일 때 A가 움직 이도록하는 것입니다. 이를 위해서는 NativeWindow 파생 클래스가 필요합니다. AssignHandle을 사용하여 가지고있는 창 핸들을 첨부하십시오. WndProc() 무시에서 WM_MOVE 메시지를 감지하여 A를 이동하고 WM_DESTROY를 정리할 수 있습니다.

그러나 프로세스가 해당 창을 소유 한 경우에만 작동합니다. 보다 일반적인 시나리오는 다른 프로그램에서 실행중인 제어 할 수없는 일부 코드에 속하는 창입니다. NativeWindow 접근 방식은 작동하지 않을 수 있습니다. SetWindowsHookEx()를 사용하여 WH_CALLWNDPROC를 모니터링 할 수 있도록 관리되지 않는 DLL을 프로세스에 삽입해야합니다. IPC 메커니즘을 사용하여 프로세스에 통지합니다. 매우 어렵 기 때문에 C#으로 DLL 코드를 작성할 수 없습니다.

+0

다행스럽게도 내 프로세스가 소유하고 있습니다. – Lazlo

+0

그래, 네가 NativeWindow를 잘 했어. –

관련 문제