none
Problem with SetParent API in Excel 2013 RRS feed

  • Question

  • Hi,

    Our application extensively uses Excel for manipulating/loading data. we embed excel workbook with in a form (using SetParent win API) and show it to the user. Everything works fine till Excel 2010 but with the recent update to Excel 2013 when ever the code hits the SetParent() function Excel crashes. Is there any way i can get the SetParent function work with Excel 2013 ? or any other approach to embed Excel into a Win Form. 

    Any help is highly appreciated. 

    Thanks 


    Rajesh Yesurajan

    • Moved by Stanly Fan Wednesday, January 3, 2018 7:14 AM Excel 2013 related
    Tuesday, January 2, 2018 12:14 PM

All replies

  • On Windows 10/Office 2016, it doesn't seem to crash when I use a container lile "AtlAxWin" window class (and if I call 

    SetParent(hWndExcel, IntPtr.Zero);
    on FormClosing, otherwise it crashes when I close the main window...)

    Tuesday, January 2, 2018 1:30 PM
  • Thanks for your reply.

    My issue is after the setParent() method the excel application class object becoming null.

    Ex:  excelApp.ActiveWindow.DisplayHorizontalScrollBar = true;

    Here ,

    "excelApp.ActiveWindow" is becoming null.

    Note:In excel version 2010 its working


    Rajesh Yesurajan

    Tuesday, January 2, 2018 1:35 PM
  • The test I did with "AtlAxWin" and a test file "E:\\Employees2.xls", which doesn't crash on my configuration =>

    public partial class Form1 : Form
    {
        [DllImport("User32.dll", SetLastError = true)]
        public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
    
        [DllImport("Atl.dll", SetLastError = true)]
        public static extern bool AtlAxWinInit();
    
        [DllImport("Atl.dll", SetLastError = true)]
        public static extern int AtlAxGetControl(IntPtr h, [MarshalAs(UnmanagedType.IUnknown)] out object pp);
    
        public const int WS_OVERLAPPED = 0x0;
        public const int WS_BORDER = 0x00800000;
        public const int WS_POPUP = unchecked((int)0x80000000L);
        public const int WS_CHILD = 0x40000000;
        public const int WS_MINIMIZE = 0x20000000;
        public const int WS_VISIBLE = 0x10000000;
        public const int WS_DISABLED = 0x8000000;
    
        [DllImport("User32.dll", SetLastError = true)]
        public static extern IntPtr CreateWindowEx(int dwExStyle, string lpClassName, string lpWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
    
        [DllImport("User32.dll", SetLastError = true)]
        public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndParent);
    
        [DllImport("User32.dll")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
        private IntPtr hWndContainer = IntPtr.Zero;
        private IntPtr hWndExcel = IntPtr.Zero;
        private Excel.Application oExcel = null;
    
        public Form1()
        {
            //InitializeComponent();
            Load += Form1_Load;
            SizeChanged += Form1_SizeChanged;
            FormClosing += Form1_FormClosing;
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
            this.ClientSize = new System.Drawing.Size(980, 460);
            CenterToScreen();
            if (AtlAxWinInit())
            {
                hWndContainer = CreateWindowEx(0, "AtlAxWin", "Excel.Application", WS_VISIBLE | WS_CHILD | WS_BORDER, 0, 0, Width, Height, this.Handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
                object pp;
                int hr = AtlAxGetControl(hWndContainer, out pp);
                oExcel = (Excel.Application)pp;
                object oBook = oExcel.Workbooks.Open("E:\\Employees2.xls");
                oExcel.Visible = true;
    
                // the title should be added instead of null in case another instance exists
                hWndExcel = FindWindow("XLMAIN", null);
                SetParent(hWndExcel, hWndContainer);
            
                MoveWindow(hWndContainer, 0, 0, Width - 20, Height - 42, true);
                MoveWindow(hWndExcel, 0, 0, Width - 20, Height - 42, true);
            }
        }
        private void Form1_SizeChanged(object sender, EventArgs eventArgs)
        {
            MoveWindow(hWndContainer, 0, 0, Width - 20, Height - 42, true);
            MoveWindow(hWndExcel, 0, 0, Width - 20, Height - 42, true);
        }
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (oExcel != null)
            {
                oExcel.Visible = false;
                SetParent(hWndExcel, IntPtr.Zero);
                oExcel.Quit();
            }
        }
    }


    • Edited by Castorix31 Tuesday, January 2, 2018 2:19 PM
    • Proposed as answer by Terry Xu - MSFT Thursday, January 4, 2018 9:20 AM
    Tuesday, January 2, 2018 2:17 PM
  • I have tried your code its loading good inside the window form.

    I need to activate a range after that but its throwing error.


    Rajesh Yesurajan

    Tuesday, January 2, 2018 2:53 PM
  • I tested your sample with Range

    and it only works if SetParent() is called after (otherwise the keyboard/mouse focus is even lost on my 2016 version)


    • Edited by Castorix31 Tuesday, January 2, 2018 3:39 PM
    Tuesday, January 2, 2018 3:35 PM
  • Oh okay thanks..

    Do you have any idea how to overcome this issue.

    Any solution will be highly appreciated!!


    Rajesh Yesurajan

    Wednesday, January 3, 2018 5:19 AM
  • Hi Rajesh,

    Since your issue is more related to Excel 2013, I will move this thread to corresponding forum: Excel for Developers Forum for dedicated information.

    Thank you for your understanding.

    Regards,

    Stanly


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, January 3, 2018 7:13 AM
  • Oh okay thanks..

    Do you have any idea how to overcome this issue.

    Any solution will be highly appreciated!!


    Rajesh Yesurajan

    It doesn't crash by embedding Excel with the WebBrowser control (How to use the WebBrowser control to open Office documents in Visual C# 2005 or in Visual C# .NET (or "Shell.Explorer" or xls file with "AtlAxWin"))
    (but some flags need to be changed in registry

    http://www.axelr.com/demos/reprodoc/open.htm

    A new application window opens when you try to view an Office 2010 or Office 2007 document in Internet Explorer 7 or in Internet Explorer 8

    )



    • Edited by Castorix31 Wednesday, January 3, 2018 10:03 AM
    Wednesday, January 3, 2018 9:35 AM
  • Since the introduction of SDI with 2013 you you may need to do quite a lot more. All explained here -

    http://www.jkp-ads.com/Articles/keepuserformontop.asp

    Thursday, January 4, 2018 8:17 AM
    Moderator
  • Hello Rajesh Yesurejan,

    It seems that your original issue using SetParent API to embed Excel 2013 has been resolved by Castorix31, I would suggest you mark useful reply to close this thread.

    For the issue avtivating the range A5:A10, I note that you have post a thread for it in the forum. We will continue this issue in your new post thread.

    Thanks for understanding.

    Best Regards,

    Terry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, January 4, 2018 9:35 AM