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