【发布时间】:2023-12-16 01:26:01
【问题描述】:
我想问你一个关于在 Windows 10 中将计算器窗口置于前面的问题。我已经测试了很多代码,但没有一个真正有效。我认为主要问题是,计算器是“ApplicationFrameHost”的一部分。 在我的应用程序(C# WinForm)中,如果系统计算器没有运行,我想启动它。如果它正在运行,即使它是否已最小化,也要将窗口置于前面。
public static class WindowHelper
{
[DllImport("user32.dll")]
private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int ALT = 0xA4;
private const int EXTENDEDKEY = 0x01;
private const int KEYUP = 0x02;
private const int SW_MINIMIZE = 0x06;
private const int SW_RESTORE = 0x09;
public static void BringProcessToFront(IntPtr mainWindowHandle)
{
// check if window has focus already
//if (mainWindowHandle == GetForegroundWindow()) return;
ShowWindow(mainWindowHandle, SW_RESTORE);
// simulate ALT key down
keybd_event((byte)ALT, 0x45, EXTENDEDKEY | 0, 0);
// simulate ALT key up
keybd_event((byte)ALT, 0x45, EXTENDEDKEY | KEYUP, 0);
// bring window into foreground
SetForegroundWindow(mainWindowHandle);
}
}
private void btnCalc_Click(object sender, EventArgs e)
{
// get all processes
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcesses();
// get ApplicationFrameHost for win10
System.Diagnostics.Process[] appFH = System.Diagnostics.Process.GetProcessesByName("ApplicationFrameHost");
IntPtr mWHandle = IntPtr.Zero;
foreach (System.Diagnostics.Process proc in processes)
{
if (proc.ProcessName == "calc" || proc.ProcessName == "Calculator" || proc.ProcessName == "win32calc")
{
// non-ApplicationFrameHost case
mWHandle = proc.MainWindowHandle;
if (appFH.Length > 0)
{
// if ApplicationFrameHost is running, find calculator MainWindowHandle
foreach (System.Diagnostics.Process app in appFH)
{
if ((app.MainWindowTitle == proc.MainWindowTitle) || (proc.MainWindowTitle.Length == 0))
mWHandle = app.MainWindowHandle;
}
}
// bring window to front
WindowHelper.BringProcessToFront(mWHandle);
return;
}
}
// calculator was not found, starts new one
System.Diagnostics.Process.Start("calc");
}
此代码也适用于 Windows 7,但不适用于没有英语本地化的 10。有个问题,计算器最小化后无法恢复。
正如我所说,我尝试了很多代码,例如:
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
private static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
// this was working to bring focus on already displayed window
WindowHelper.FindWindowEx(app.MainWindowHandle, IntPtr.Zero, "Windows.UI.Core.CoreWindow", null);
主要问题是,我没有找到解决方案,这可能会使非英语本地化窗口上的窗口最小化。
你有一些例子,如何处理? 谢谢。
编辑: 经过一些测试,我已经确定,为什么不能把这个窗口放在前面。带有 en 的 Win7 和 Win10(可能与语言环境无关)即使已最小化或未最小化,仍然激活计算器。另一方面,第二个 Win10 在最小化时会暂停进程(参见图片附件)。 所以现在的问题是,如何取消挂起它。然后希望窗口可以被带到前面。
【问题讨论】:
-
该帖子强调它在“非英语本地化 Windows”上存在问题 - 您能否澄清它是否适用于“en-US Windows”?
-
是的,这就是我发现的。我的朋友有“斯洛伐克本地化”并报告说,那是行不通的。所以我设置了相同的设置,他有什么(在虚拟机中)。它也不适用于我。使用 EN 本地化,没有问题。
-
在这种情况下,在 VM 上进行调试将是您尽快获得答案的最佳选择(如果您不想在其上安装任何大的东西,远程调试甚至可以打印每一步)。 .. 在您发布的代码中没有明显的字符串可以本地化 - 因此有人知道答案的可能性相对较低。
标签: c# windows-10 calculator