【问题标题】:How To Give Back Focus From Console Window in C#?如何在 C# 中从控制台窗口返回焦点?
【发布时间】:2014-05-11 21:03:14
【问题描述】:

我有一个使用黑色 Windows 控制台打开的 C# 控制台应用程序 (A)。有时在启动时它会从另一个需要焦点的程序 (B) 中窃取焦点。

问题:如何将焦点从A.exe 重新分配给B.exe

A -> Focus -> B


详情:
  • 程序 B 不是我的,我对此无能为力。它有一个 GUI、多个窗口,其中 1 个需要焦点(它可能是一个模态对话框窗口)。
  • 程序 A 不需要任何焦点,也不会以任何方式与程序 B 交互。
  • 程序 A 通过启动快捷方式启动并基本上在后台运行(它已发布但仍在开发中,这就是控制台窗口的原因)
  • 我有几分钟/最多几分钟的时间来检查并重新集中注意力。

【问题讨论】:

  • 一个程序如果不集中注意力就不能正常运行是……坏的。不是你的错,我知道。最简单的解决方案:在另一个完成之前不要运行你的应用,或者根本不给你的应用提供任何界面。
  • 你的控制台程序如何知道你什么时候想要专注于它?如果您有需要检查的内容,则无需关注控制台应用程序。
  • @Tarec 我记得可以通过 .NET Framework、WinApi 或两者兼而有之地以各种方式操作控制台窗口。

标签: c# winapi user-interface console focus


【解决方案1】:
// this should do the trick....

[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(HandleRef hWnd, int nCmdShow);
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr WindowHandle);

public const int SW_RESTORE = 9;

private void FocusProcess(string procName)
{
    Process[] objProcesses = System.Diagnostics.Process.GetProcessesByName(procName);
    if (objProcesses.Length > 0)
    {
        IntPtr hWnd = IntPtr.Zero;
        hWnd = objProcesses[0].MainWindowHandle;
        ShowWindowAsync(new HandleRef(null,hWnd), SW_RESTORE);
        SetForegroundWindow(objProcesses[0].MainWindowHandle);
    }
}

【讨论】:

  • 好,这行得通!我需要等待下一次启动以检查它是否解决了 my 问题。但它回答了这个问题。谢谢!
  • 这可能会回答问题,但它忽略了真正的问题。如果您不想要焦点,请不要一开始就偷窃。很容易做到。
  • 没问题,我曾经遇到过需要控制窗口焦点的情况,这在很多场合都证明对我非常有用。很高兴为您提供帮助!
  • @DavidHeffernan:如何避免窃取焦点?见stackoverflow.com/questions/41272078/…
  • 似乎在 W10 中,它仅在窗口最小化时才有效。如果窗口可见但没有“聚焦”,则任务栏中的应用程序会“闪烁”。
【解决方案2】:

要为您当前正在运行的 C# 控制台应用程序执行此操作...

[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(HandleRef hWnd, int nCmdShow);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr zeroOnly, string lpWindowName);
public const int SW_RESTORE = 9;
static void FocusMe()
{
    string originalTitle = Console.Title;
    string uniqueTitle = Guid.NewGuid().ToString();
    Console.Title = uniqueTitle;
    Thread.Sleep(50);
    IntPtr handle = FindWindowByCaption(IntPtr.Zero, uniqueTitle);

    Console.Title = originalTitle;

    ShowWindowAsync(new HandleRef(null, handle), SW_RESTORE);
    SetForegroundWindow(handle);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    • 2014-04-11
    • 2010-10-10
    相关资源
    最近更新 更多