2011-01-20 2 views
1

У меня есть System.Windows.Form и действующий как HWND.Как я могу сделать форму и взаимное перестановку HWND?

Я хочу, чтобы каждый из них размещал другую на ходу. Я удивлен, что не мог найти что-либо в Интернете с «Hwnd get/set position C#» и многими вариантами, возможно, я не замечаю очевидных результатов.

Для данных примеров рассмотрим форму «окно А» и окно «обложка» Bwn. Давайте также скажем, что я хочу, чтобы позиция B была позицией А + 50 пикселей справа.

ответ

3

Update: Вы также можете проверить WinForms' NativeWindow class, который может быть использован, чтобы обернуть родную HWWND и слушать окно сообщений, отправленных в это окно.

Я полагаю, вам нужна функция MoveWindow API Win32, чтобы установить положение (и размеры) ваше окно В (HWND один). Вы можете вызвать эту функцию 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

Liking it much. Не могу протестировать прямо сейчас, но сегодня вечером и отметьте, как принято, если он будет работать без излишнего вмешательства. Благодаря! – Lazlo

2

Чем больше деталей заключается в том, чтобы заставить A двигаться, когда B движется. Для этого требуется класс, основанный на NativeWindow. Используйте AssignHandle для прикрепления дескриптора окна, который вы получили. В переопределении WndProc() вы можете обнаружить сообщение WM_MOVE, позволяющее перемещать A. И WM_DESTROY для очистки.

Это, однако, работает только в том случае, если окно принадлежит вашему процессу. Более типичным сценарием является то, что это окно, принадлежащее некоторому коду, который вы не контролируете, работая в другой программе. Вы совершенно ввернуты, если это так, подход NativeWindow не может работать. Вам нужно будет внедрить неуправляемую DLL в процесс с помощью SetWindowsHookEx(), чтобы вы могли контролировать WH_CALLWNDPROC. С каким-то механизмом IPC, чтобы получить это уведомление в вашем процессе. Очень сложно получить право, вы не можете написать DLL-код на C#.

+0

К счастью для меня, он принадлежит моему процессу. – Lazlo

+0

Хорошо, тогда вы хорошо с NativeWindow. –

Смежные вопросы