I try to get a window active to send keyboard inputs using
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
private void button1_Click(object sender, EventArgs e)
{
IntPtr calcWindow = FindWindow(null, "Calculator");
if (SetForegroundWindow(calcWindow))
SendKeys.Send("10{+}10=");
}
I am new to c# and i saw i need to put the exact name that apears on the taskbar, but i try to sent keyboard events to DOSBox which the name of the window i want to select has a weird name that i tried to write multiple times but i didnt get the right thing, do you know how i can browse the windows already opened and select this one or how can i get the exact name
You can use System.Diagnostics.Process to find the process. You can find the process by its ProcessName and then get its MainWindowHandle.
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
private void button1_Click(object sender, EventArgs e)
{
// find the process by its name, this is the process name and is not the window name
System.Diagnostics.Process process = System.Diagnostics.Process.GetProcesses()
.FirstOrDefault(p => p.ProcessName.Equals("DOSBox"));
if(process != null)
{
IntPtr calcWindow = process.MainWindowHandle;
SetForegroundWindow(calcWindow);
if (SetForegroundWindow(calcWindow))
SendKeys.SendWait("10{+}10=");
}
}
Related
I have a simple WinForm app with a button, and on-click I am trying to populate search keyword on Google Chrome already running (on chrome window). When I execute this program and click the button, Chrome window get presented (restored from minimized) but the focus still remains on my WinForm app and SendKeys does not work.
Is there a better way to do this?
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
[DllImport("User32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName,
string lpWindowName);
[DllImport("User32.DLL")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
IntPtr chromeHandle = FindWindow("Chrome_WidgetWin_1", null);
if(chromeHandle == IntPtr.Zero)
{
MessageBox.Show("Chrome is not running");
return;
}
SetForegroundWindow(chromeHandle);
SendKeys.SendWait("search term");
}
}
}
My code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private const int WM_SYSCOMMAND = 274; private const int SC_MAXIMIZE = 61488;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
private void button1_Click(object sender, EventArgs e)
{
Process proc;
proc = Process.Start("Notepad++.exe");
proc.WaitForInputIdle();
SetParent(proc.MainWindowHandle,panel1.Handle);
//SendMessage(proc.MainWindowHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
}
}
When I execute notepad.exe instead of notepad++.exe, it works fine. Normal notepad comes inside the panel in the Windows Form. But when I use notepad++.exe, it is not seen inside the panel instead, is opened outside as a different window. I don't want this. My preference is notepad++ to be embedded inside panel my Windows Form, through which, I want to control the notepad++.
Add Sleep after setParent it will work.
SetParent(proc.MainWindowHandle,panel1.Handle);
Thread.Sleep(500)
I'm new to WindowsForms building a small sample application.
I'm trying to build an application that types text into a Notepad window and I'm getting the error FindWindow does not exist in current context when it's being imported from the dll.
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void MenuAbout_Click(object sender, System.EventArgs e)
{
Form1 frm = new Form1();
frm.ShowDialog();
}
private void Launch_Click(object sender, System.EventArgs e)
{
// find window handle of Notepad
IntPtr handle = FindWindow("Notepad", "Untitled - Notepad");
if (!handle.Equals(IntPtr.Zero))
{
// activate Notepad window
if (SetForegroundWindow(handle))
{
// send "Hello World!"
SendKeys.Send("Hello World!");
// send key "Tab"
SendKeys.Send("{TAB}");
// send key "Enter"
SendKeys.Send("{ENTER}");
}
}
//Process.Start(#"D:\\32-Bit Programs\\StarCraft II\\Support\\SC2Switcher.exe");
}
[DllImport("user32.dll", EntryPoint = "FindWindow")]
private extern IntPtr FindWindow(string lp1, string lp2);
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private extern bool SetForegroundWindow(IntPtr hWnd);
}
}
Your imported methods must also be static:
[DllImport("user32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lp1, string lp2);
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
I am attempting to use this code sample to control the Windows XP On-Screen Keyboard (OSK.exe) from a C# (.NET 3.5) Winforms application:
[DllImport("User32.dll")]public static extern Int32 SetForegroundWindow(int hWnd);
[DllImport("user32.dll")]public static extern int FindWindow(string lpClassName, string lpWindowName);
private void BringToFront(string className,string CaptionName)
{
SetForegroundWindow(FindWindow(className,CaptionName));
}
private void Form1_Load(object sender, EventArgs e)
{
BringToFront("Notepad", "Untitled - Notepad");
}
How do I determine the accurate className? I assume that the CaptionName is 'On-Screen Keyboard'.
Looks like the classname is: "OSKMainClass"
Here is the code I used to find this. It's just a simple C# Forms App
[DllImport("User32.dll")]
public static extern Int32 SetForegroundWindow(int hWnd);
[DllImport("user32.dll")]
public static extern int FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern int GetClassName(int hWnd, StringBuilder lpClassName, int nMaxCount);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int hWnd = FindWindow(null, "On-Screen Keyboard");
StringBuilder buffer = new StringBuilder(128);
GetClassName(hWnd, buffer, buffer.Capacity);
MessageBox.Show(buffer.ToString());
}
Got this from the following sources Activate Any Window With API
and MSDN GetClassName function
How can I bring a console application window to front in C# (especially when running the Visual Studio debugger)?
It's hacky, it's horrible, but it works for me (thanks, pinvoke.net!):
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
public class Test
{
[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 static void Main()
{
string originalTitle = Console.Title;
string uniqueTitle = Guid.NewGuid().ToString();
Console.Title = uniqueTitle;
Thread.Sleep(50);
IntPtr handle = FindWindowByCaption(IntPtr.Zero, uniqueTitle);
if (handle == IntPtr.Zero)
{
Console.WriteLine("Oops, cant find main window.");
return;
}
Console.Title = originalTitle;
while (true)
{
Thread.Sleep(3000);
Console.WriteLine(SetForegroundWindow(handle));
}
}
}
This is what I would do.
[DllImport("kernel32.dll", ExactSpelling = true)]
public static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
public void BringConsoleToFront()
{
SetForegroundWindow(GetConsoleWindow());
}
Get two monitors (at least) and open VisualStudio in the secondary monitor. When you run your app from within VisualStudio it will start up by default on the primary monitor. Since it's the last app to be opened, it starts on top and changing over to VisualStudio doesn't affect it. Works for me anyway.
If you don't already have a second monitor, IMHO, you should.