4

我需要我的应用程序来打开 Excel 2010 并将其放置在我的应用程序的特定区域中。我还需要 Excel 不可调整大小、不可移动并消除所有菜单交互(关闭、最大化、最小化)

我已经找到了几乎所有东西的解决方案,除了让它无法移动。我尝试使用 SetWindowPos 并设置 SWP_NOMOVE 标志和其他一些标志,但我根本没有成功。

--规格:我使用的是 WPF C#.NET 4.0 和 MS Excel 2010。

--下面是我自带的方法。除了 SetWindowPos 之外,一切都按预期工作(它根本没有任何效果)

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.");
        }
    }

我还提出了一些不同的想法,例如拦截 Excel WM_Message(可能通过使用 HWNDSource)。欢迎任何不太复杂的想法来实现这一点!

在此先感谢,路易斯。

4

1 回答 1

0

I think you are mistaken about the SWP_NOMOVE parameter. That parameter does not mean that the window will not be movable, it just means that the x,y parameters will be ignored during that specific call to the method SetWindowPos. The goal of that flag is to use the function SetWindowPos for changing the size of the target window without changing its position.

From SetWindowPos in MSDN:

SWP_NOMOVE 0x0002 Retains the current position (ignores X and Y parameters).

Something that you could try is to create a custom window on your application that handles all messages related to size and position (examples:WM_SIZE, WM_SIZING, WM_WINDOWPOSCHANGED, WM_WINDOWPOSCHANGING, etc) to prevent modifications, then set your excel window as a child window of your custom window.

You could also try to just remove the title bar

于 2013-04-25T14:38:44.653 回答