我想把Outlook的主窗口从一个VSTO外接程序中带到前面。我尝试了这个问题的各种答案中描述的方法,但它似乎不起作用,至少对于Outlook2021来说是这样。
我得到了Outlook主窗口的句柄(我使用spy++验证了这个句柄,并且看起来是正确的),使用
Process.GetProcessesByName("outlook").FirstOrDefault().MainWindowHandle或
(Globals.ThisAddIn.Application.ActiveExplorer() as IOleWindow).GetWindow()(两者产生相同的结果)。
然后我试着把窗户带到前面(可能是一些多余的电话,我只是尽我所能让它发挥作用):
ShowWindow(proc.MainWindowHandle, SW_SHOWNORMAL);
ShowWindow(proc.MainWindowHandle, SW_RESTORE);
SetForegroundWindow(proc.MainWindowHandle);
SwitchToThisWindow(proc.MainWindowHandle, true);我做错了什么?
发布于 2022-09-22 18:46:55
结果发现,在调用模拟ALT点击 ()之前,缺少的部分是SetForegroundWindow(仅up部分就足够了)。不需要调用SwitchToThisWindow()。
作为奖励,设置ActiveExplorer().CurrentFolder() =.可靠地向上滚动&向下滚动到选定的文件夹(当outlook不在前台时,它不会这样做)。
发布于 2022-09-22 21:37:14
只有前台进程可以使用SetForegroundWindow设置活动窗口。若要欺骗Windows使其认为您的进程处于前台,请使用AttachThreadInput。以下是我所用的:
public static bool ForceForegroundWindow(IntPtr hWnd)
{
bool Result = false;
uint ForegroundThreadID = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
uint ThisThreadID = GetWindowThreadProcessId(hWnd, IntPtr.Zero);
if (AttachThreadInput(ThisThreadID, ForegroundThreadID, true))
{
BringWindowToTop(hWnd);
SetForegroundWindow(hWnd);
AttachThreadInput(ThisThreadID, ForegroundThreadID, false);
Result = (GetForegroundWindow() == hWnd);
}
if (!Result)
{
int timeout = 0;
SystemParametersInfo(SPI.SPI_GETFOREGROUNDLOCKTIMEOUT, 0, ref timeout, 0);
int newTimeout = 0;
SystemParametersInfo(SPI.SPI_SETFOREGROUNDLOCKTIMEOUT, 0, ref newTimeout, SPIF.SPIF_SENDCHANGE);
BringWindowToTop(hWnd);
SetForegroundWindow(hWnd);
SystemParametersInfo(SPI.SPI_SETFOREGROUNDLOCKTIMEOUT, 0, ref timeout, SPIF.SPIF_SENDCHANGE);
Result = (GetForegroundWindow() == hWnd);
}
return Result;
}发布于 2022-09-22 14:23:15
所有Outlook都实现了IOleWindow接口,该接口提供了允许应用程序获取参与就地激活的各种窗口的句柄的方法。因此,您可以使用检索到的窗口句柄来调用Windows函数,例如SetForegroundWindow方法,它将创建指定窗口的线程带入前台并激活窗口。此外,键盘输入被定向到窗口,并为用户更改各种视觉提示。
此外,您还可以考虑调用激活资源管理器或检查器窗口的Explorer.Activate或Inspector.Activate方法,方法是将其带到前台并设置键盘焦点。
https://stackoverflow.com/questions/73807571
复制相似问题