I need my application to open Excel 2010 and place it in a specific area of my application. I also need Excel to be fatal, inalienable and eliminate all menu interactions (Close, Maximize, Minimize)
I found a solution for almost everything, APART, making it motionless. I tried using SetWindowPos and setting the SWP_NOMOVE flag and several other flags, but I did not get any success.
- Specifications: I am using WPF C # .NET 4.0 and MS Excel 2010.
- Below is the method with which I came. Everything works as expected, except SetWindowPos (it has no effect at all)
public static void StartExcel(string p_processArguments, int p_x, int p_y, int p_height, int p_width, bool p_startMin = true, bool p_setForeground = true, bool p_useShell = true, bool p_waitInput = true, bool p_setNewStyles = true, bool p_removeMenu = true) { //Make sure there is no excel opened (Kill them all - if any) CloseAllExcelProcesses(true); //Make the most basic validations and required info. if (!ValidateProcessArgument(p_processArguments)) throw new Exception("Process' argument is invalid or incorrectly setted. " + p_processArguments); ProcessStartInfo psiApp = new ProcessStartInfo("excel", p_processArguments); if (p_useShell) psiApp.UseShellExecute = true; else psiApp.UseShellExecute = false; if (p_startMin) psiApp.WindowStyle = ProcessWindowStyle.Minimized; Process pApp = Process.Start(psiApp); if (p_waitInput) pApp.WaitForInputIdle(); //Wait for the app to receive the window handle(ID) max limit of 3sec. for (int i = 0; i < 25; i++) { System.Threading.Thread.Sleep(100); } if (pApp.MainWindowHandle != (IntPtr)0) { if (p_startMin) //Now restore its state Win32Import.ShowWindow(pApp.MainWindowHandle, WindowShowStyle.ShowNormal); //Set Foreground if (p_setForeground) Win32Import.SetForegroundWindow(pApp.MainWindowHandle); if (p_setNewStyles) { //Make it an Overlapped Window (Which has no size border, title bar and etc). int style = Win32Import.GetWindowLong(pApp.MainWindowHandle, Win32Import.GWL_STYLE); Win32Import.SetWindowLong(pApp.MainWindowHandle, Win32Import.GWL_STYLE, (uint)(style & ~Win32.WindowStyles.WS_OVERLAPPEDWINDOW)); //NOT WORKING - Apply some flags, to make it unmovable. Win32Import.SetWindowPos(pApp.MainWindowHandle, (IntPtr)0, 0, 0, 0, 0, Win32.SWP.NOMOVE); Win32Import.UpdateWindow(pApp.MainWindowHandle); } if (p_removeMenu) { //Get the app original menu. IntPtr hMenu = Win32Import.GetSystemMenu(pApp.MainWindowHandle, false); //Get the amount of menu the app has. int count = Win32Import.GetMenuItemCount(hMenu); //Remove all existing main menus. for (uint i = 0; i < count; i++) Win32Import.RemoveMenu(hMenu, i, (Win32Import.MF_BYPOSITION | Win32Import.MF_REMOVE)); //Force a redraw. Win32Import.DrawMenuBar(pApp.MainWindowHandle); } //Move the window to the specified location and size (set new position). Win32Import.MoveWindow(pApp.MainWindowHandle, p_x, p_y, p_width, p_height, true); } else { throw new Exception("StartEmbeddedApp - Couldn't get the embedded app handle."); } }
I also came up with several different ideas, such as switching Excel WM_Message (possibly using HWNDSource). Any idea that is not too complicated to achieve this goal is welcome!
Thanks in advance, Luis.