Modal Window not overlapping taskbar in Windows 7 on laptop - c#

I have a modal window that works on desktops with multiple monitors however when I attempt to run the application on a laptop its not overlapping the task bar. Below is the code I'm using to launch it.
if (result != DialogResult.Yes) return;
try
{
using (var fullscreenForm = new fullscreenkForm(eventDetails))
{
fullscreenForm.ShowDialog(this);
}
}
finally
{
Application.Exit();
}
Inside the application I have:
WindowState = Maximized
StartPosition = CenterScreen
AutoSizeMode = GrowOnly
FormBorderStyle = None
TopMost = true
Any help thoughts or help is well appreciated

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;

Make ShowDialog() after Show - WPF

Is there any possibility to make an already shown Window in to a Model Dialog (Like what happens when we call ShowDialog())
Blocking or Non Blocking, Any solution is acceptable for me, but all the Windows in the background should be disabled.
Hiding the window and again showing the window using ShowDialog is not possible since i have to maintain the state.
This is the closest I could get to a solution.The only issue is I change the WindowStyle to remove the title bar because otherwise you can still move those Windows.
this.Topmost = true;
foreach (Window window in Application.Current.Windows)
{
if (window.Title != this.Title)
{
window.Focusable = false;
window.WindowStyle = WindowStyle.None;
window.ResizeMode = ResizeMode.NoResize;
window.IsEnabled = false;
}
}

Windows Form on top of specific process

There is a full screen Windows POS Application(Aloha), that contains button, which opens a Windows form. The Form is set to be TopMost=true, ShowIcon = false and ShowInTaskbar = false. Once the button pressed, POS stays open full screen on top of Taskbar with a form above it.
If the form is closed\out of focus, its process exits and everything stays the same. But if button pressed while the form is open, it kills another instances of itself and then Taskbar pops-up on top of POS(once other instances are killed).
KillRunningProcess Function
private void KillRunningProccess()
{
try
{
Process[] proc = System.Diagnostics.Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location));
Process currentProcess = Process.GetCurrentProcess();
if (proc != null)
{
foreach (Process currProc in proc)
{
if (currentProcess.Id != currProc.Id)
{
currProc.Kill();
}
}
}
}
catch
{ }
}
I've tried using different PINVOKE API functions on Shown\GotFocus events, without any success. Hiding the taskbar fully is out of the question.

WPF window force redraw window size

I know there are lots of article over Google related to this, and believe me I have tried almost everything.
So the problem is, I have a wpf application in which when user focuses on any input control like textbox I am showing external touch keyboard using TabTip.exe.
Following code:
public class KeyboardHelper
{
private const string PROCESS_NAME = "TabTip";
private const string PROCESS_PATH = "Common Files/Microsoft Shared/ink/TabTip.exe";
public static void ShowKeyboard()
{
Process keyboard = null;
Process[] pname = Process.GetProcessesByName(PROCESS_NAME);
if (pname.Length == 0)
{
keyboard = new Process();
}
else
{
keyboard = pname[0];
}
string processPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), PROCESS_PATH);
keyboard.StartInfo.FileName = processPath;
keyboard.Start();
}
public static void Closekeyboard()
{
Process[] pname = Process.GetProcessesByName(PROCESS_NAME);
if (pname.Length > 0)
{
pname[0].Kill();
}
}
}
Now problem starts here keyboard open but if it is in docked mode, it causes my app to resize almost half of the screen. And when I close the keyboard app remains same in size, I want to restore to full screen state again.
Controlling my size from cs because it comes from a DB
WindowState = maximized;
ResizeMode= NoResize;
WindowsStyle = None;
Any work around to solve the issue.
I have tried UpdateLayout, Dispatcher.BeginInvoke, Invalidate methods.
Thanks Jason, now I know the cause or can say case scenario of the problem. In my app I have to decide the startup page at runtime, So I am using code like this
private void Application_Startup(object sender, StartupEventArgs e)
{
//Set startup page for the application.
MainWindow window = new MainWindow();
window.ShowDialog();
}
And this is the problem. If I use normal default way than everything works fine.

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