Как я могу сделать взаимную репозицию формы и HWND? - PullRequest
1 голос
/ 20 января 2011

У меня есть System.Windows.Form и IntPtr, выступающие в роли HWND.

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

Ради приведенных примеров рассмотрим Форму "окно А" и Hwnd "Окно B". Скажем также, что я хочу, чтобы позиция B была позицией A + 50 пикселей справа.

Ответы [ 2 ]

3 голосов
/ 20 января 2011

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

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

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

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

...