How to minimize all open windows except my program? - c#

I want my program to be the only program showing, is there a way to do that?
I suppose by running something like
WindowState = ALL.Minimized;
Update
I made a Script like this
Set shell = wscript.CreateObject("Shell.Application")
Shell.MinimizeAll
Named it Mini.vbs
Then i used this code in Visual Studio
{
InitializeComponent();
TopMost = true;
System.Diagnostics.Process.Start("c:/mini.vbs");
}
It works, but its not the best solution .

You could simply set the TopMost property to True on the creation of the form.
public Form1()
{
InitializeComponent();
this.TopMost = true;
}
Goodluck.

Related

Showing invisible window

I have a window with some process and visualization but I want this window to be hidden on startup but still performing it's work. I've managed to achieve this using simple code
SomeWindow.Show();
SomeWindow.Hide();
But the issue is this code causing startup flickering. I can't fight this neither in Windows Forms, nor in WPF. Is there more elegant way to show hidden/invisible window?
UPDATE
I want the window to show in TaskBar but only when it's visible. Window is performing task that relies on rendering that will be performing in time regardless of visibility and user should be able to see it's state like it was open all the time.
Try this:
SomeWindow.ShowInTaskbar = false; // not shown on taskbar set to true if you want to show form on taskbar
SomeWindow.WindowState = FormWindowState.Minimized; // set window state as minimized
SomeWindow.Show();
You don't even need to hide it.
This is winforms version I did not test it in WPF.
Update:
If Hide() is not done after Show() window is on opened windows list (Alt+Tab). To prevent this do:
SomeWindow.Hide();
Based on Logman's answer I've created extension method to show invisible window
For Windows Forms:
public static class FormHelper
{
public static void ShowInvisible(this Form form)
{
// saving original settings
bool needToShowInTaskbar = form.ShowInTaskbar;
FormWindowState initialWindowState = form.WindowState;
// making form invisible
form.ShowInTaskbar = false;
form.WindowState = FormWindowState.Minimized;
// showing and hiding form
form.Show();
form.Hide();
// restoring original settings
form.ShowInTaskbar = needToShowInTaskbar;
form.WindowState = initialWindowState;
}
}
or for WPF:
public static class WindowHelper
{
public static void ShowInvisible(this Window window)
{
// saving original settings
bool needToShowInTaskbar = window.ShowInTaskbar;
WindowState initialWindowState = window.WindowState;
// making window invisible
window.ShowInTaskbar = false;
window.WindowState = WindowState.Minimized;
// showing and hiding window
window.Show();
window.Hide();
// restoring original settings
window.ShowInTaskbar = needToShowInTaskbar;
window.WindowState = initialWindowState;
}
}
Vadim Ovchinnikov's answer for WPF was a great start, but didn't work for me eventually for two reasons: Show() and Hide() are synchronous methods which is a problem when you want to have that window precreated while no other window is open (for there is no Dispatcher executing these requests); furthermore restoring the original values had to be performed later, otherwise a quick flicker was still noticeable. Then again, I had to restore the value of ShowInTaskbar asynchronously; otherwise the taskbar entry was missing, but curiously only when running in the Visual Studio debugger.
The following helper class does the job for me:
public class InitiallyInvisibleWindow
{
private readonly Window _window;
private bool _origShowActivated;
private bool _origShowInTaskbar;
private WindowState _origWindowState;
public InitiallyInvisibleWindow(Window window)
{
_window = window;
}
public void ShowInvisible()
{
_origShowActivated = _window.ShowActivated;
_origShowInTaskbar = _window.ShowInTaskbar;
_origWindowState = _window.WindowState;
_window.ShowActivated = false;
_window.ShowInTaskbar = false;
_window.WindowState = WindowState.Minimized;
_window.Visibility = Visibility.Visible;
_window.Visibility = Visibility.Hidden;
}
public void RestoreVisible()
{
_window.ShowActivated = _origShowActivated;
_window.Visibility = Visibility.Visible;
Dispatcher.CurrentDispatcher.InvokeAsync(() =>
{
_window.ShowInTaskbar = _origShowInTaskbar;
_window.WindowState = _origWindowState;
});
}
}
Why use a window for this task? Why not just start up a class on another thread and have it do the work?
If a window is really needed just have the window when opened request data from that custom task.
var myClass = new MyClass();
Task.Run(()=>myClass.Start());
This works on my machine without "flicker". As Ed mentioned, the Taskbar button behaves as you would expect without addition settings or code.
//Assuming SomeWindow is System.Windows.Form object
SomeWindow.Opacity = 0.0;
SomeWindow.Show();
SomeWindow.Hide();
//Elsewhere in code when you want to display the window
SomeWindow.Opacity = 1.0;
SomeWindow.Visible = true;

How to re-order the thumbnails for an application that appear in the taskbar?

Assume you have multiple windows in an application, and all of them are set to display in the taskbar. Mousing over the application's icon results in a set of thumbnails, one for each window. If there are enough windows, Windows 7 switches this to a tall, scrollable list of the windows by name.
I want to re-order this "thumbnail" list programmatically, as there is a certain window I want to be 2nd from the top of the list. How can I do this?
Note that I cannot change the order of creation of the windows (which would be one solution, but unfortunately not one I can leverage).
Well, it turns out this is pretty simple, and I was wrong.
All you need to do is set ShowInTaskbar, for all the Window objects you wish to re-order, to false. Then set it back to true, in the exact order you wish the windows to appear.
No re-creation of the Window object is necessary.
In my case, during re-ordering, the windows blinked once. This might have something to do with my current GFX driver.
NOTE: Tested and working with Windows 7 and Windows 10.
Example:
using System.Windows;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Window winA = new Window();
Window winB = new Window();
Window winC = new Window();
public MainWindow()
{
InitializeComponent();
winA.Title = "A";
winB.Title = "B";
winC.Title = "C";
winB.Show();
winA.Show();
winC.Show();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
winB.ShowInTaskbar = false;
winA.ShowInTaskbar = false;
winC.ShowInTaskbar = false;
winA.ShowInTaskbar = true;
winB.ShowInTaskbar = true;
winC.ShowInTaskbar = true;
}
}
}

WPF UI resize after minimize and restore

I have a WPF Application. I need to minimize and restore the main window after instantiate it to obtain focus. I am using something like the following class but it is not making what I want because when the window is restored it has an invalid size. I've tried to modify the width and height but it is not working.
public class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ConfigureWindow();
}
public void Show()
{
base.Show();
UpdateWindowPositionAndSize();
base.WindowState = WindowState.Normal;
base.Show();
}
private void ConfigureWindow()
{
base.ShowActivated = true;
this.Focusable = true;
if (base.IsActive == false)
{
base.Activate();
}
if (base.IsFocused == false)
{
base.Focus();
}
base.WindowState = WindowState.Minimized;
}
private void UpdateWindowPositionAndSize()
{
this.Top = (SystemParameters.WorkArea.Height - this.Height) / 2;
this.Left = (SystemParameters.WorkArea.Width - this.Width) / 2;
}
}
What I am doing wrong? There is another way to obtain the focus? Sorry if the question is too newby.
UPDATED:
What is the specific need?
I need that my WPF Application appears on focus and active after launch it.
why?
Since it will be launched by a Windows (7, 8.1 and 10) User after explicitly click on a submenu from a file context menu (meaning a Shell Extension). This is 'why' my client wants that appears on front of the screen and focused.
when?
After instantiate the window.
how?
Well, I made some research and I found several ways to do this. One of the methods that I've tried is minimize the window and the restore it. There where others like using the functions SwitchToThisWindow or setforegroundwindow, but I would like to know if there are better options.
What happen when I've tried minimize and restore the window? (correct size)
Well, this way gives me focus on the main window, but it change the width and heigh. By default I define them on 300 (w) and 300 (h), but after changing the windows state to normal these values change to 400 (w) and 350 (h).
If I dont do anything, it has the focus right away?
... No ...
UPDATE2:
I choose the method used in the next link:
https://www.roelvanlisdonk.nl/2014/09/05/reliable-bring-external-process-window-to-foreground-without-c/
I am not quite sure what your problem is but maybe this can help.
1.) Remove StartupUri="MainWindow.xaml" from App.xaml;
2.) Add Startup="Application_Startup"
Your App.xaml.cs should look like this:
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
//Create new Instance of MainWindow
MainWindow mainWindow = new MainWindow();
//Set Properties of that Window
UpdateWindowPositionAndSize(mainWindow);
//Show it !
MainWindow = mainWindow; //This is the Application.MainWindow Property - not needed
mainWindow.ShowDialog();
}
private void UpdateWindowPositionAndSize(MainWindow mainWindow)
{
//Do your modifications here
mainWindow.Top = (SystemParameters.WorkArea.Height - mainWindow.Height) / 2;
mainWindow.Left = (SystemParameters.WorkArea.Width - mainWindow.Width) / 2;
}
}
So basically you just modify your Window until all is done.
There is no need to show it first, change its position and then bring it back on - if I got your "usecase" right.
Because to me it looks like you are hiding the window to do your "positioning".
But I think it's better to do it when Initializing.
Just a short comment on your code so far:
ConfigureWindow() is only doing minimize.
The rest of your code is useless cause obviously the window loses focus when it's minimized.
I would suggest not to create methods with names that already exist.
This will only lead to cusfusion.
If you got problems with WindowState = WindowState.Minimized; you can try Hide() and Activate().
By default when calling Window.Show(); the window will have focus. Check here for details.
Also after setting WindowState = WindowState.Minimized; you don't need to call base.Show(); again - the window is shown already. WindowState = WindowState.Normal; should do the job.

Deleting old winform and tray icon when I make a new winform

In my application I have two winforms. The first acts as my control panel and the second I use to take screen shots. However, when I go from Winform 2 back to Winform 1 I have a new winform created and a brand new tray icon. This is on top of the initial ones I create when the program first starts.
When I go from winform 1 to winform 2 I do the following:
this.Hide();
Form2 form2 = new Form2();
form2.InstanceRef = this;
form2.Show();
Then when I want to go back from Winform 2 to Winform 1 I do the following:
this.Close();
Winform1 form;
form = new Winform1 (capturedImageObj);
form.Show();
I know straight off the bat the issue falls on the fact I'm creating a new Winform1, but I need to do that so I can pass my capturedImageObj back into Winform 1.
I've tried calling this.close() and this.dispose() in the my first section of code but that only closes the program down. Is there a way I can dispose of Winform 1 but still use Winform 2 and pass the object I need to back into a new copy of Winform 1?
Here is the constructor for my Winform 1:
public ControlPanel(Image imjObj)
{
InitializeComponent();
_screenCap = new ScreenCapture();
_screenCap.OnUpdateStatus += _screen_CapOnUpdateStatus;
capturedImage = imjObj;
imagePreview.Image = capturedImage;
}
Change Winform1 to use properties like this:
public Image CapturedImage {
get { return imagePreview.Image; }
set { imagePreview.Image = value; }
}
Then change your constructor like this:
public ControlPanel(Image imjObj)
{
InitializeComponent();
_screenCap = new ScreenCapture();
_screenCap.OnUpdateStatus += _screen_CapOnUpdateStatus;
CapturedImage = imjObj;
}
And, finally, change your Winform2 to do this:
((Winform1)this.InstanceRef).CapturedImage = capturedImageObj;
this.InstanceRef.Show();
this.Close();
Based on the comment, it sounds like your InstanceRef property is of type Form. Change it to be of type Winform1. Or, I changed the code above to do some casting for you.

C# Close processes minimized to tray in a graceful way?

I have an application that has can display a window using a Form. The form is only shown if the application is run using a -debug flag, otherwise it is only shown in tray.
var form = new Form();
if(DebugMode)
form.Show();
The application listens to CloseMainWindow() when run in debug mode, as the form is shown.
How can I make the application also listen to CloseMainWindow() without showing it? I don't want the user to be able to interact with the form if not in debug mode.
I've tried several approaches, like displaying the window but setting the size to 0. This shows a small form, i.e. not hidden.
if (!DebugMode)
{
form.Show();
form.Size = new Size(0, 0);
}
Also showing it, and then hiding it does not work:
if (!DebugMode)
{
form.Show();
form.Hide();
}
Showing it, but started minimized and not shown in taskbar does not work either:
if (!DebugMode)
{
form.Show();
form.WindowState = FormWindowState.Minimized;
form.ShowInTaskbar = false;
}
Am I missing something really obvious here, or is it not possible to close processes minimized to tray in a graceful way?
If i've understood the problem correctly, you want to completely hide the form when not in debug mode (i.e. the window is not seen anywhere but in the task manager) and when someone kills the process via task manager, you want to execute some code for clean-up or just get notified.
Basing my solution on this assumption, the following code should work
public static bool DebugMode = false;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form1();
form.Load += (s, e) =>
{
if (!DebugMode)
{
form.Opacity = 0;
form.ShowInTaskbar = false;
}
};
form.FormClosing += (s, e) =>
{
// Breakpoint hits
};
Application.Run(form);
}
I'm not sure you can do it through Process.CloseMainWindow(). Processes with no visible main window, I seem to recall, have MainWindowHandle set to IntPtr.Zero.
You need some kind of workaround. My advice is to keep track manually of the MainWindow Handles yourself:
static void Main()
{
...
MainWindow mainWindow = new MainWindow();
[HandleRepository] = mainWindow.Handle;
Application.Run(mainWindow);
}
Then when you want to close the process, do it with a workaround:
public void EndProcess()
{
Form mainWindow= (MainWindow)Form.FromHandle([HandleRepository]);
mainWindow.Close();
}
Might not be the most elegant solution but it should work (haven't tested it)

Categories