When I use Process.Start(Path); Sometimes the program does not appear in the foreground, but it does appear in the taskbar To solve this problem, I must use the "AutoItX" reference to show the program in the foreground using GetForegroundWindow(), But how can I get GetForegroundWindow using Path? ("C:/Users/.../name_program/")
Update
my question is how can I get GetForegroundWindow From Path.
I appreciate any help, thank you
I can't test it, but it should work:
private const int ALT = 0xA4;
private const int EXTENDEDKEY = 0x1;
private const int KEYUP = 0x2;
private const int SHOW_MAXIMIZED = 3;
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
public static void ActivateWindow(IntPtr mainWindowHandle)
{
// Guard: check if window already has focus.
if (mainWindowHandle == GetForegroundWindow()) return;
// Show window maximized.
ShowWindow(mainWindowHandle, SHOW_MAXIMIZED);
// Simulate an "ALT" key press.
keybd_event((byte)ALT, 0x45, EXTENDEDKEY | 0, 0);
// Simulate an "ALT" key release.
keybd_event((byte)ALT, 0x45, EXTENDEDKEY | KEYUP, 0);
// Show window in forground.
SetForegroundWindow(mainWindowHandle);
}
With this you can create the process and then activate it:
var proc = Process.Start(path);
proc.WaitForInputIdle();
ActivateWindow(proc.MainWindowHandle);
Related
I have the following code that opens notepad within a tabControl panel, this works when I start the form maximized.
this.WindowState = FormWindowState.Maximized
Tab Opening:
TabPage tp = new TabPage("notepad");
Panel tb = new Panel();
tb.Dock = DockStyle.Fill;
tp.Controls.Add(tb);
myTab.TabPages.Add(tp);
The problem is when I launch the form not maximized, opens Notepad then resize the form, the following happens (see picture link) --- notepad doesn't stretch out.
After Opening Notepad within Panel the form is maximized
Any suggestions? Thanks!
[DllImport("user32.dll", SetLastError = true)]
private static extern uint SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("USER32.DLL")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("USER32.DLL")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
private const int GWL_STYLE = (-16);
public static int WS_BORDER = 0x00800000;
public static int WS_CAPTION = WS_BORDER;
public static void loadProcess()
{
Process p = Process.Start("Notepad");
p.WaitForInputIdle();
p.Refresh();
int WS_VISIBLE = GetWindowLong(p.MainWindowHandle, GWL_STYLE);
SetWindowLong(p.MainWindowHandle, GWL_STYLE, (WS_VISIBLE & ~WS_CAPTION));
SetParent(p.MainWindowHandle, panel1.Handle);
ShowWindow(p, SW_SHOWMAXIMIZED);
}
[DllImport("user32.dll")]
private static extern
bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
private const int SW_SHOWMAXIMIZED = 3;
private static bool ShowWindow(Process _Process, int nCmdShow)
{
return ShowWindowAsync(_Process.MainWindowHandle, nCmdShow);
}
After few trials, I was able to resize it automatically.
On my loadProcess method, I have stored the process in a hashtable for reference later.
Process p = Process.Start("Notepad");
p.WaitForInputIdle();
sessions.Add(tabName, p);
on tabControl1_Selecting event:
String name = myProcess.SelectedTab.Name;
Process pHandle = (Process) sessions[name];
SetForegroundWindow(pHandle.MainWindowHandle);
SetFocus(pHandle.MainWindowHandle);
MoveWindow(pHandle.MainWindowHandle, 0, 0, this.Width, this.Height, true);
I've added a Form1_Resize event so it will resize accordingly.
String name = myProcess.SelectedTab.Name;
Process pHandle = (Process) sessions[name];
MoveWindow(pHandle.MainWindowHandle, 0, 0, this.Width, this.Height, true);
Recently I tried to create a bot for an MMO-Game (called Florensia).
It should click on several positions in the game.
My problem is that it only sets the cursour to the position but the click doesn't work out. If I try it at my desktop or some other programs, it clicks correctly.
The game of course is in windowed mode and I already tried to set delays between the Mouseup and Mousedown.
Also to set the game to foreground window before the click didn't work.
Looking forward to any answers! :)
Try to use WinApi functions like in this example.
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
static void Main(string[] args)
{
const int WM_LBUTTONDOWN = 0x0201;
const int WM_LBUTTONUP = 0x0202;
const int MK_LBUTTON = 0x0001;
uint x = 100;
uint y = 100;
IntPtr handle = new IntPtr(0x00090996); //Your window handle
SetForegroundWindow(handle);
Thread.Sleep(300);
SendMessage(handle, WM_LBUTTONDOWN, new IntPtr(MK_LBUTTON), new IntPtr(y << 16 | x));
Thread.Sleep(300);
SendMessage(handle, WM_LBUTTONUP, new IntPtr(0), new IntPtr(y << 16 | x));
}
How can I get the Window Title that the user currently have focus on?
I'm making a program that runs with another Window, and if the user does not have focus on that window I find no reason for my program to keep updating.
So how can I determine what window the user have focus on?
I did try to look into
[DllImport("user32.dll")]
static extern IntPtr GetActiveWindow();
but I seems I can only use that if the Window is part of my application which is it not.
Check this code:
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
private string GetActiveWindowTitle()
{
const int nChars = 256;
StringBuilder Buff = new StringBuilder(nChars);
IntPtr handle = GetForegroundWindow();
if (GetWindowText(handle, Buff, nChars) > 0)
{
return Buff.ToString();
}
return null;
}
Use GetForegroundWindow to retrieve the handle of the focused window and GetWindowText to get the window title.
[ DllImport("user32.dll") ]
static extern int GetForegroundWindow();
[ DllImport("user32.dll") ]
static extern int GetWindowText(int hWnd, StringBuilder text, int count);
static void Main() {
StringBuilder builder = new StringBuilder(255) ;
GetWindowText(GetForegroundWindow(), builder, 255) ;
Console.WriteLine(builder) ;
}
ok, I have found many posts on finding a window by name, etc. What I have not found is how to find and switch the window application focus to last active window. The code I am showing below will give me the list of active applications in the task manager that are active.
What I can not figure out how to do is figure out what application was the last active application, and then switch to it. for example...
I have my custom winform application open.
I click a button
My application switches to the last active window / application.
Here is the working code I have so far. (this is the action on a button, and it expects that the application has a textbox named textbox1. you will also need to add using System.Diagnostics;
private void button1_Click(object sender, EventArgs e)
{
Process[] procs = Process.GetProcesses();
IntPtr hWnd;
foreach (Process proc in procs)
{
if ((hWnd = proc.MainWindowHandle) != IntPtr.Zero)
{
textBox1.Text += (proc.ProcessName.ToString());
textBox1.Text += "\t";
textBox1.Text += (hWnd.ToString());
textBox1.Text += "\r\n";
}
}
}
Check this article out: http://www.whitebyte.info/programming/how-to-get-main-window-handle-of-the-last-active-window
Specifically, this code:
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
enum GetWindow_Cmd : uint
{
GW_HWNDFIRST = 0,
GW_HWNDLAST = 1,
GW_HWNDNEXT = 2,
GW_HWNDPREV = 3,
GW_OWNER = 4,
GW_CHILD = 5,
GW_ENABLEDPOPUP = 6
}
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
[...]
IntPtr targetHwnd = GetWindow(Process.GetCurrentProcess().MainWindowHandle, (uint)GetWindow_Cmd.GW_HWNDNEXT);
while (true)
{
IntPtr temp = GetParent(targetHwnd);
if (temp.Equals(IntPtr.Zero)) break;
targetHwnd = temp;
}
SetForegroundWindow(targetHwnd);
Since my comments didn't help you, here's a little resume (didn't test it though):
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll")]
static extern IntPtr GetLastActivePopup(IntPtr hWnd);
[DllImport("user32.dll", ExactSpelling = true)]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
const uint GA_PARENT = 1;
const uint GA_ROOT = 2;
const uint GA_ROOTOWNER = 3;
public IntPtr GetPreviousWindow()
{
IntPtr activeAppWindow = GetForegroundWindow();
if ( activeAppWindow == IntPtr.Zero )
return IntPtr.Zero;
IntPtr prevAppWindow = GetLastActivePopup(activeAppWindow);
return IsWindowVisible(prevAppWindow) ? prevAppWindow : IntPtr.Zero;
}
public void FocusToPreviousWindow()
{
IntPtr prevWindow = GetPreviousWindow();
if ( prevWindow != IntPtr.Zero )
SetForegroundWindow(prevWindow);
}
Its possible remove a window console title bar using c# and windows api, if yes howto? Please.
This simple app hides and shows the title bar of the console that it's in. It changes the console title to a guid momentarily to find the window handle. Afterwards it uses ToggleTitleBar to show or hide using the found handle.
public class Program
{
public static void ToggleTitleBar(long hwnd, bool showTitle)
{
long style = GetWindowLong(hwnd, -16L);
if (showTitle)
style |= 0xc00000L;
else
style &= -12582913L;
SetWindowLong(hwnd, -16L, style);
SetWindowPos(hwnd, 0L, 0L, 0L, 0L, 0L, 0x27L);
}
public static void Main()
{
Guid guid = Guid.NewGuid();
string oldTitle = Console.Title;
Console.Title = guid.ToString();
int hwnd = FindWindow("ConsoleWindowClass", guid.ToString());
Console.Title = oldTitle;
Console.WriteLine("Press enter to hide title");
Console.ReadLine();
ToggleTitleBar(hwnd, false);
Console.WriteLine("Press enter to show title");
Console.ReadLine();
ToggleTitleBar(hwnd, true);
Console.WriteLine("Press enter to exit");
Console.ReadLine();
}
[DllImport("user32", EntryPoint = "GetWindowLongA")]
public static extern long GetWindowLong(long hwnd, long nIndex);
[DllImport("user32", EntryPoint = "SetWindowLongA")]
public static extern long SetWindowLong(long hwnd, long nIndex, long dwNewLong);
[DllImport("user32")]
public static extern long SetWindowPos(long hwnd, long hWndInsertAfter, long x, long y, long cx, long cy,
long wFlags);
[DllImport("User32.dll")]
public static extern int FindWindow(string lpClassName, string lpWindowName);
}
Edit: Sorry, I see that you're looking for a solution for a console application. No, there is no way I know of to do what you're trying to do. It is also not simple to host a console in a WinForms application.
However, if you ARE using a WinForms application or WPF, consider the following.
this.ControlBox = false;
this.Text = string.Empty;
Otherwise, you could set FormBorderStyle to None.
You can also hide the program from the task bar if you need to.
this.ShowInTaskBar = false;
This will probably not work. In theory you could use something like this:
HWND handle = FindWindow(L"ConsoleWindowClass", NULL);
LONG style = GetWindowLong(handle, GWL_STYLE);
style = style & ~WS_CAPTION;
SetWindowLong(handle, GWL_STYLE, style);
This will work for every window except console windows. SetWindowLong returns 0, and GetLastError returns 5 (Access denied), even if you run the application as administrator.
I have some (very) old code I think somehow related; I'd to display Microsoft Excel inside a winform application:
[DllImport("user32.dll")]
public static extern int FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern int SetParent(int hWndChild, int hWndNewParent);
[DllImport("user32.dll")]
public static extern int MoveWindow(
int hWnd, int x, int y,
int nWidth, int nHeight, int bRepaint);
//
private static int hwnExcel = 0;
private System.Windows.Forms.PictureBox picContainer;
// ...
private void Principal_Resize(object sender, EventArgs e)
{
picContainer.Width = this.Width - 8;
picContainer.Height = this.Height - 45;
User32.SetParent(hwnExcel, 0);
User32.MoveWindow(
hwnExcel, 0, 0,
picContainer.Width, picContainer.Height, 1);
}
use FindWindow to get the handle of the console window then SetWindowLong to modify his properties