Window for positioning problems when using SetParent ()

I am trying to set childFormas a child of the Excel main window using the SetParent API via PInvoke:

Form childForm = new MyForm();
IntPtr excelHandle = (IntPtr) excelApplication.Hwnd;
SetParent(childForm.Handle, excelHandle);
childForm.StartPosition = FormStartPosition.Manual;
childForm.Left = 0;
childForm.Top = 0;

As you can see above, I intend to also position the child in the upper left corner of the Excel window. However, for some reason it childFormalways ends in some strange place.

What am I doing wrong?

+3
source share
5 answers

Although all the answers here offer completely logical approaches, none of them worked for me. Then I tried MoveWindow. For some reason I don’t understand, he did the job.

:

[DllImport("user32.dll", SetLastError = true)]
internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

...

Form childForm = new MyForm();
IntPtr excelHandle = (IntPtr) excelApplication.Hwnd;
SetParent(childForm.Handle, excelHandle);
MoveWindow(childForm.Handle, 0, 0, childForm.Width, childForm.Height, true);
+7

SetParent , ( , set), WS_CHILD WS_POPUP. (. "" MSDN.) Windows , WS_CHILD. , left top / , , . , SetWindowLong SetParent, :

//Remove WS_POPUP style and add WS_CHILD style
const UInt32 WS_POPUP = 0x80000000;
const UInt32 WS_CHILD = 0x40000000;
int style = GetWindowLong(this.Handle, GWL_STYLE);
style = (style & ~(WS_POPUP)) | WS_CHILD;
SetWindowLong(this.Handle, GWL_STYLE, style);
+5

ShowDialog, . ShowDialog , reset.

-, IWin32Window HWND, . ShowDialog childForm.

excel GetWindowPos, childForm.

+1

, :

  • Top, do Left Top ?
  • SetParent .
  • , Left Top , BeginInvoke .
  • , . ShowDialog . , .
0

, , hwnds , z-, pInvoke:

    public stati class WindowsApi 
    {
     [DllImport("user32.dll")]
    public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
        int X, int Y, int cx, int cy, uint uFlags);
    }



    public class WindowZOrderPositioner 
    {
         public void SetZOrder(IntPtr targetHwnd, IntPtr insertAfter)
         {
             IntPtr nextHwnd = IntPtr.Zero;

             WindowsAPI.SetWindowPos(targetHwnd, insertAfter, 0, 0, 0, 0, SetWindowPosFlags.NoMove | SetWindowPosFlags.NoSize | SetWindowPosFlags.NoActivate);
     }
0

Source: https://habr.com/ru/post/1773611/


All Articles