none
Why do I get: ERROR_INVALID_WINDOW_HANDLE 1400 (0x578)? RRS feed

  • Question

  • Wishing to embed Excel in a Panel, I "stole" a few code fragments from the web and mixed and merged them, to get the scaffolding working.

    I can see that the code works up until the "SetParent".

    It seems that panel1.Handle is invalid. Any ideas?

    namespace embedProgram
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            [DllImport("user32.dll")]
            static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
    
            [DllImport("Kernel32.dll")]
            private static extern IntPtr GetLastError();
    
            private void Form1_Load(object sender, EventArgs e)
            {
                ProcessStartInfo psi = new ProcessStartInfo("powerpnt.exe");
                psi.WindowStyle = ProcessWindowStyle.Minimized;
                Process p = Process.Start(psi);
                Process[] pname = Process.GetProcessesByName("powerpnt");
                int waitCount = 0;
                while (pname.Length == 0)
                {
                    if (waitCount > 3000)
                    {
                        // Exit with a message
                        MessageBox.Show("Problem starting PowerPoint", "KKZIS");
                        System.Windows.Forms.Application.Exit();
                    }
                    Thread.Sleep(10);
                    waitCount += 1;
                }
    // Generates error code 1400
                SetParent(p.MainWindowHandle, panel1.Handle);
                // Show return code of the just created process
                uint rc = (uint)GetLastError();
                MessageBox.Show($"{rc}");
                CenterToScreen();
                psi.WindowStyle = ProcessWindowStyle.Normal;
            }
        }
    }
    

    Wednesday, March 27, 2019 4:34 PM

All replies

  • You cannot start a separate process and then "embed" it into another process. This isn't supported by Windows. A window (and all its children) must be defined within the same process because a handle is nothing more than a glorified pointer. Further all interaction with a window must occur on the thread that created it. Threads are per process so you cannot interact with it without marshaling the calls to the other process. You can interact with a window in another process but they are in no way embedded or related, even if you were to somehow overlap the windows.

    To properly embed an app like PowerPoint into your app you'll need to use COM and host the app as an ActiveX control inside your app. This will allow you to interact with the control like you would any normal control. 

    Refer to the various questions and responses others have provided on how you can go about "embedding" PP into your app including here.


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, March 27, 2019 5:04 PM
    Moderator
  • You don't set the right window : it must be "PPTFrameClass" class (on my ppt version (2016), could be different for other versions) (FindWindow in loop or EnumWindows)

    You must add SetLastError = true to SetParent declaration

    You must use Marshal.GetLastWin32Error() to get the last Win32 error

     + ShowWindow(hWnd, SW_SHOWNORMAL); at end

    I tested with these updates and it works.

    But it is not the recommended method by MS (WebBrowser)


    • Edited by Castorix31 Wednesday, March 27, 2019 5:38 PM
    Wednesday, March 27, 2019 5:34 PM