Come posso fare una forma e un HWND reciprocamente riposizionamento?
Domanda
Ho un System.Windows.Form
e IntPtr
in qualità di HWND.
voglio ciascuno di loro di mettere l'altro in movimento. Sono sorpreso, non ho trovato nulla sul web con "Hwnd get / set posizione C #" e molte varianti, forse sto affaccia risultati evidenti.
Per il bene degli esempi riportati, la forma "a finestra" e la Hwnd "finestra B". Diciamo che anche io voglio la posizione di B per essere la posizione di un + 50 pixel a destra.
Soluzione
Aggiornamento: Si potrebbe anche voler controllare WinForms' class
NativeWindow
, che può essere usato per avvolgere unHWWND
nativa e ascoltare i messaggi di finestra inviati a quella finestra.
Credo che sarà necessario la funzione API Win32 MoveWindow
per impostare la posizione (e dimensioni) della finestra B (la HWND
uno). È possibile chiamare questa funzione API da .NET tramite P / Invoke .
Al fine di recuperare la posizione e la dimensione della finestra B corrente, può inoltre essere necessario chiamare GetWindowRect
, anche tramite P / Invoke.
Il codice seguente potrebbe non funzionare out of the box, e forse ci sono soluzioni più semplici, ma potrebbe dare un punto di partenza, insieme ai link di cui sopra:
// 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);
Altri suggerimenti
La parte più difficile è quello di ottenere da A a muoversi quando si muove B. Ciò richiede una classe NativeWindow derivata. Utilizzare AssignHandle per fissare la maniglia della finestra che hai. Nel WndProc () ignorare è possibile rilevare il messaggio WM_MOVE, che consente di spostare A. E WM_DESTROY per ripulire.
Questo funziona però solo se la finestra è di proprietà di processo. Lo scenario più tipico è che questa è una finestra appartenente a qualche codice che non si controlla, in esecuzione in un altro programma. Lei ha perfettamente avvitato se questo è il caso, l'approccio NativeWindow non può funzionare. Avresti bisogno di iniettare una DLL non gestita nel processo con SetWindowsHookEx () in modo da poter monitorare WH_CALLWNDPROC. Con qualche tipo di meccanismo IPC per ottenere che la notifica nel vostro processo. Molto difficile da ottenere di destra, non si può scrivere il codice DLL in C #.