Reputation: 3
I'm running a virtual keyboard when a textbox gets focus, but then keyboard app is focused and will not transfer keys to textbox. If I click on textbox to activate it, everything is fine, but I want my application to get activated after vKeyboard process runs. This is what I've tried so far:
[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);
}
}
I also tried sending Alt + Tab to keyboard process, but it doesn't work:
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: I do have the source code for virtual keyboard if I can do anything from there to deactivate itself, still fine. let me know. Also keyboard top most property is set to true, not sure if that makes any different.
This is the code that I'm trying and doenst work in button click:
Process vKeyboard;
string keyboardPath = Application.StartupPath + "\\vKeyboard.exe";
vKeyboard = Process.Start(keyboardPath);
Upvotes: 0
Views: 4290
Reputation: 2464
For an easy, reliable option that doesn't require you to write P/Invoke code, you can call Microsoft.VisualBasic.Interaction.AppActivate(int processId) from C# code.
using System.Diagnostics;
using System.Linq;
using Microsoft.VisualBasic;
...
Process? process = Process.GetProcessesByName("TextBoxProcessName").FirstOrDefault();
if (process != null)
{
Interaction.AppActivate(process.Id);
}
In legacy .NET Framework .csproj files, you need <Reference Include="Microsoft.VisualBasic" />
.
In modern .NET SDK .csproj files, you need to enable the Desktop SDK and set <UseWindowsForms>true</UseWindowsForms>
.
Note: I discovered Interaction.AppActivate
from this related answer, which may give you other ideas.
Upvotes: 0
Reputation: 59
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
private void ActivateWindow()
{
SetForegroundWindow(this.Handle);
}
With this code, it is suposed you are at the main app window. If not, you will need to change "this.Handle
" by the Handle of the main window.
Upvotes: 0
Reputation: 39152
Change the source code for the onscreen keyboard so that the form has the WS_EX_NOACTIVATE flag:
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;
}
}
}
This will prevent the OSK from getting focus, thus allowing the keys to target the currently active application.
See my example in this previous question for more details.
Upvotes: 1
Reputation: 12459
To bring your form to front, use:
this.Activate();
I tried the following code and every things works perfectly (I wrote this code in the Timer.Tick
event):
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
}
Upvotes: 1