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");
}
}
}
Related
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=");
}
}
I'm making a c# overlay for a game.
It appears on the game but it won't hide if the game is minimized so I'm wondering if there's any way to check if a window is minimized/out of focus. I searched about it on google but I couldn't find anything useful.
To check the state of a window (normal, maximized or minimized) when you have the windows caption name or the windows handle, you can use this code:
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsZoomed(IntPtr hWnd);
enum WinState
{
None,
Maximized,
Minimized,
Normal,
}
private static WinState GetWindowState(IntPtr hWnd)
{
WinState winState = WinState.None;
if (hWnd != IntPtr.Zero)
{
if (IsIconic(hWnd))
{
winState = WinState.Minimized;
}
else if (IsZoomed(hWnd))
{
winState = WinState.Maximized;
}
else
{
winState = WinState.Normal;
}
}
return winState;
}
private static WinState GetWindowState(string windowCaption)
{
return GetWindowState((IntPtr)FindWindow(null, windowCaption));
}
Usage:
string windowCaption = "New Tab - Google Chrome";
WinState winState = GetWindowState(windowCaption);
I'm trying to use the youtube embedded player ( axshockwaveflash) and make a nice program out of it.
Thing is i'm trying to implement a button that'll replay/next/previous the current video.
what I have atm is:
private void btReplay_Click(object sender, EventArgs e)
{
if (!youtubePlayer.Focus())
{
youtubePlayer.Focus();
SendKeys.Send("0");
}
else
{
SendKeys.Send("0");
}
this.BringToFront();
}
The '0' key press makes the video replay from the start. Only it also makes the form dissappear between other open windows.
As you see i've tried using bringtofront but it won't work.
Any thoughts?
Also if anyone has any experience with this, i also want to play how to enable auto play the next video when using the 'END' key. I know about the autoplay=1 function but it won't seem to work when pressing the END key.
EDIT: Using WinForms btw
You didn't specify whether you use winForms or WPF. This snippet is for winforms.
Here I am giving you a static method that forces any given Form to front:
public static void bringWindowToFront(System.Windows.Forms.Form form)
{
uint foreThread = GetWindowThreadProcessId(GetForegroundWindow(), System.IntPtr.Zero);
uint appThread = GetCurrentThreadId();
const uint SW_SHOW = 5;
if (foreThread != appThread)
{
AttachThreadInput(foreThread, appThread, true);
BringWindowToTop(form.Handle);
ShowWindow(form.Handle, SW_SHOW);
AttachThreadInput(foreThread, appThread, false);
}
else
{
BringWindowToTop(form.Handle);
ShowWindow(form.Handle, SW_SHOW);
}
form.Activate();
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
private static extern bool BringWindowToTop(System.IntPtr hWnd);
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
public static extern uint GetCurrentThreadId();
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern System.IntPtr GetForegroundWindow();
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(System.IntPtr hWnd, System.IntPtr ProcessId);
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool ShowWindow(System.IntPtr hWnd, uint nCmdShow);
this.BringToFront();
this.TopMost = true;
worked for me, silly i didnt think of this.
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);
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.