アプリで 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 を使用する) など、いくつかの異なるアイデアも思いつきました。これを達成するのに複雑すぎないアイデアは大歓迎です!
前もって感謝します、ルイス。