【问题标题】:How to activate my application after I run another process - C#运行另一个进程后如何激活我的应用程序 - C#
【发布时间】:2013-07-03 04:30:11
【问题描述】:

当文本框获得焦点时,我正在运行虚拟键盘,但随后键盘应用程序获得焦点并且不会将键传输到文本框。 如果我点击文本框来激活它,一切都很好,但我希望我的应用程序在 vKeyboard 进程运行后被激活。 这是我迄今为止尝试过的:

        [DllImport("user32.dll")]
    static extern bool PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll")]
    static extern bool SetForegroundWindow(IntPtr hWnd);
    [DllImport("user32.dll")]
    internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

....

        vKeyboard = Process.Start(keyboardPath);
        SetFocusToApplication(handle);

....

        private static void SetFocusToApplication(IntPtr handle)
    {
        Process currentProcess = Process.GetCurrentProcess();
        IntPtr hWnd = currentProcess.MainWindowHandle;
        if (hWnd != IntPtr.Zero)
        {
            SetForegroundWindow(handle);
            ShowWindow(hWnd,3);
        }
    }

我也尝试将 Alt + Tab 发送到键盘进程,但它不起作用:

        private static void AltTab(IntPtr handle)
    {
             vKeyboard.WaitForInputIdle(); 

       int WM_SYSCOMMAND = 0x0112;
        int SC_PREVWINDOW = 0xF050;
        PostMessage(vKeyboard.MainWindowHandle, WM_SYSCOMMAND, (IntPtr)SC_PREVWINDOW, (IntPtr)0);
    }

PS:我确实有虚拟键盘的源代码,如果我可以从那里做任何事情来停用它自己,仍然可以。让我知道。 键盘最顶部的属性也设置为 true,不确定这是否有任何不同。

这是我正在尝试并在按钮单击中起作用的代码:

           Process vKeyboard;
      string keyboardPath = Application.StartupPath + "\\vKeyboard.exe";
        vKeyboard = Process.Start(keyboardPath);

【问题讨论】:

  • 您是否编写了虚拟键盘并可以访问源代码?
  • 是的,我可以访问虚拟键盘源代码。
  • 您为什么要编写自己的虚拟键盘,而不是使用所有版本的 Windows 中包含的屏幕键盘?它经过充分测试,完全不会引起关注。
  • 我想要一个没有 ESC 和 Win 键以及一些附加键的键盘。它适用于自助服务终端应用程序,因此必须手动制作。

标签: c# .net process activation


【解决方案1】:

更改屏幕键盘的源代码,使表单具有 WS_EX_NOACTIVATE 标志:

public partial class OnScreenKeyboard : Form
{

    private const int WS_EX_NOACTIVATE = 0x08000000;

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams p = base.CreateParams;
            p.ExStyle |= WS_EX_NOACTIVATE;
            return p;
        }
    }

}

这将阻止 OSK 获得焦点,从而允许键定位当前活动的应用程序。

有关详细信息,请参阅我在 this 上一个问题中的示例。

【讨论】:

    【解决方案2】:

    要将您的表单放在前面,请使用:

    this.Activate();
    

    我尝试了以下代码,一切都运行良好(我在Timer.Tick 事件中编写了这段代码):

    System.Diagnostics.Process[] proc = System.Diagnostics.Process.GetProcessesByName("osk");
    if (proc.Length > 0)
    {
        this.Activate();
        textBox1.Focus(); //i focused it so i can write in it using on-screen keyboard
    }
    

    【讨论】:

    • 这不是我失去焦点的表格,而是整个申请过程。我希望应用程序获得焦点。
    • 应用程序是一个进程。如果您激活它的一个线程(例如,多个表单中的单个表单)以便整个应用程序成为焦点,那么您可以在表单之间导航。试试这个,会有帮助的。
    • 我确实在键盘进程加载后调用了这个方法,但它仍然没有激活我的应用程序或主窗体。
    • 谢谢,这会以这种方式工作,但由于某种原因,当我将它放在按钮单击时(这是我的应用程序中键盘进程的启动方式),它不再工作了。有什么想法吗?
    • 我在单击按钮时启动计时器,并在计时器滴答运行一次时停止它。这将工作,谢谢。但如果我能在没有计时器的情况下做到这一点,那就太好了。
    【解决方案3】:
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);
    
    private void ActivateWindow()
    {
        SetForegroundWindow(this.Handle);
    }
    

    使用此代码,假设您位于应用程序主窗口。如果没有,则需要通过主窗口的句柄更改“this.Handle”。

    【讨论】:

      猜你喜欢
      • 2012-01-06
      • 2020-03-25
      • 1970-01-01
      • 2011-08-06
      • 2011-10-17
      • 1970-01-01
      • 2013-07-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多