After launching an application using the Process class I'd like to make that window topmost. Currently, my app is the topmost window so when i launch the other app it doesn't display. One thing that came to mind is that I could set topmost = false for my application before launching the process, the problem with this is I want to give the process ample time to load up before displaying it to the user, so I'd like more control over when I switch the other application to the topmost.
You need to use P/Invoke with SetWindowPos to accopmlish this:
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
const UInt32 SWP_NOSIZE = 0x0001;
const UInt32 SWP_NOMOVE = 0x0002;
const UInt32 SWP_SHOWWINDOW = 0x0040;
// Call this way:
SetWindowPos(theWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
Related
I have the following code that opens a remote desktop window. Everything seems to be running as expected, except the last call to SetWindowPos. It seems to be setting the TopMost property correctly, but for some reason, when I launch to code, I am able to resize and move the window. I indicated SWP_NOSIZE and SWP_NOMOVE, but I can resize and move the window. I don't want it to be movable nor resized.
m_proc = new Process {
StartInfo = {
FileName = "mstsc.exe",
Arguments = #"C:\projects\...\RemoteDesktop\IPS\Workstation1.rdp"
}
};
m_proc.Start();
//Wait until process is started and main rdp window is created.
while (m_proc.MainWindowHandle == IntPtr.Zero)
{
Thread.Sleep(2000);
}
// Restore the window in the working screen so we can
// manipulate its size programmatically.
PostMessage(m_proc.MainWindowHandle, WM_SYSCOMMAND, SC_RESTORE, IntPtr.Zero);
// Move the restored window by X and Y, to the top left of the virtual screen.
// Note the width and height parameters don't work in this call, so
// width and height must be provided in the .rdp file in the winposstr parameter.
MoveWindow(m_proc.MainWindowHandle,
SystemInformation.VirtualScreen.Left,
SystemInformation.VirtualScreen.Top,
SystemInformation.VirtualScreen.Width,
SystemInformation.VirtualScreen.Height, true);
// This sets the RDP window as TopMost.
UnsafeNativeMethods.SetWindowPos(m_proc.MainWindowHandle,
UnsafeNativeMethods.HWND_TOPMOST, 0, 0, 0, 0,
UnsafeNativeMethods.SWP_NOMOVE | UnsafeNativeMethods.SWP_NOSIZE);
I have the following definitions in my UnsafeNativeMethods static class:
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd,
IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
public const UInt32 SWP_NOSIZE = 0x0001;
public const UInt32 SWP_NOMOVE = 0x0002;
public const UInt32 SWP_SHOWWINDOW = 0x0040;
What am I doing wrong?
How can I ensure my C# console application is always in front?
e.i. if a person clicks away from the console, how can I detect that the console has lost the focus an bring it back to front?
I have this C# console application that is waiting for users to scan bar codes, if for some reason someone clicks away from the console window then the barcode data will be "lost".
I took a look at this code posted on another thread;however, I can not seem to get this to work for me:
bring a console window to front in c#
This code thanks to #ILan keeps the console ontop of all windows, but it does not set the "focus" to keep capturing the incoming data.
class Program
{
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd,
IntPtr hWndInsertAfter,
int X,
int Y,
int cx,
int cy,
uint uFlags);
static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
const uint SWP_NOSIZE = 0x0001, SWP_NOMOVE = 0x0002, SWP_SHOWWINDOW = 0x0040;
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
static void Main()
{
IntPtr handle = GetConsoleWindow();
SetWindowPos(handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
Console.WriteLine($"Hello handle: {handle}");
Console.ReadLine();
}
}
The following will do the job if the application is the one that attached to the console.
For a complete answer how to get the handle in case that your application is not the one that attached to the console, see https://stackoverflow.com/a/28616832/2370138.
class Program
{
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd,
IntPtr hWndInsertAfter,
int X,
int Y,
int cx,
int cy,
uint uFlags);
static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
const uint SWP_NOSIZE = 0x0001, SWP_NOMOVE = 0x0002, SWP_SHOWWINDOW = 0x0040;
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
static void Main()
{
IntPtr handle = GetConsoleWindow();
SetWindowPos(handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
Console.WriteLine($"Hello handle: {handle}");
Console.ReadLine();
}
}
SetForegroundWindow has been limited since then (see Remarks in https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setforegroundwindow). It will not allow you to arbitrarily put windows in the foreground anymore, exactly to prevent you from doing what you're trying to do.
If you need other applications running on the system, you're out of luck. You'll just need to tell your users they need to have the window focused when scanning a barcode.
I have a security program for my schools. What i need,
I keep my Windows form up until I'm allowed to.
I can partially do with the following codes..
<code>
private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
private const UInt32 SWP_NOSIZE = 0x0001;
private const UInt32 SWP_NOMOVE = 0x0002;
private const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);</code>
But
the above code.
Does not work in task view(windows 10)
preview
I have a window in an application, and the Resize mode is set to NoResize, but if you click the top-left of the window, the menu items of "Maximize", "Minimize", and "Size" are still enabled. This only happens to my windows that has no icon but still has the close button. Meaning this problem isn't happening to my windows that do have an icon.
This is the code that is removing the icon but still keeps the red close button:
protected override void OnSourceInitialized(EventArgs e) {
IconHelper.RemoveIcon(this);
}
public static class IconHelper {
[DllImport("user32.dll")]
static extern int GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags);
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam);
const int GWL_EXSTYLE = -20;
const int WS_EX_DLGMODALFRAME = 0x0001;
const int SWP_NOSIZE = 0x0001;
const int SWP_NOMOVE = 0x0002;
const int SWP_NOZORDER = 0x0004;
const int SWP_FRAMECHANGED = 0x0020;
const uint WM_SETICON = 0x0080;
public static void RemoveIcon(Window window) {
IntPtr hwnd = new WindowInteropHelper(window).Handle;
int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_DLGMODALFRAME);
SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
}
}
I would like to know why this is happening and would appreciate it if some one can fix this problem. I am using WPF and C#.
I'm opening up a new Outlook email from code in my windows application. Is there a way to give focus to the new window (instead of blinking orange behind)?
Thank you!
Try using the PInvoke:
public class MoveToForeground
{
[DllImportAttribute("User32.dll")]
private static extern int FindWindow(string ClassName, string WindowName);
[DllImport("user32.dll", EntryPoint="SetWindowPos")]
public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);
const int SWP_NOMOVE = 0x0002;
const int SWP_NOSIZE = 0x0001;
const int SWP_SHOWWINDOW = 0x0040;
const int SWP_NOACTIVATE = 0x0010;
public static void DoOnProcess(string processName)
{
var process = Process.GetProcessesByName(processName);
if (process.Length > 0)
{
int hWnd = FindWindow(null, process[0].MainWindowTitle.ToString());
SetWindowPos(new IntPtr(hWnd), 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
}
}
}
MoveToForeground.DoOnProcess("OUTLOOK.EXE");