WPF Fake Full Screen - c#

I have a project that automates/controls other Window applications by simulating keystrokes. To simulate keystrokes, I need to bring the window of that application to the front. When this is in progress, you can see the whole process on the screen.
However, I want to have a fake full screen to cover that up. If this is possible, I would also like to display something on the fake full screen, such as the progress bar.
Any suggestion would be helpful. Thanks

What you want to achieve is to make your main form be displayed in "windowed full screen" mode that is right ?
So in order to do that, you need to set your window size to your screen size.
A way to do it would be the following, in your WPF class :
this.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
this.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
Or
this.WindowState = WindowState.Maximized;
To bring a window forward, you can also use :
myWindow.Activate();
or
this.TopMost = true;
I hope this will be helpful.

To prevent other windows overlaying your window when it is deactivated you can add the method, I'd use the solution at WPF Always On Top (I've it used before and it worked well for me), to the Deactivated event of the window:
private void Window_Deactivated(object sender, EventArgs e)
{
Window window = (Window)sender;
window.Topmost = true;
}
If you would like to show a progress bar in a fullscreen window when your operation is in progress, you could do something like:
private Window CreateFullScreenLoadingBar()
{
Window fullscreenWindow = new YourLoadingBarWindow();
fullscreenWindow.WindowStyle = WindowStyle.None;
fullscreenWindow.WindowState = WindowState.Maximized;
fullscreenWindow.ResizeMode = ResizeMode.NoResize;
fullscreenWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
fullscreenWindow.Deactivated += delegate (object sender, EventArgs e)
{
Window window = (Window)sender;
window.Topmost = true;
};
}
Usage:
...
Window loadingBar = CreateFullScreenLoadingBar();
fullscreenWindow.Show();
fullscreenWindow.Activate();
// Your code
loadingBar.Close();
...
Where YourLoadingBarWindow is a window containing a progress bar or whatever you want the user to see.

Related

Maximizing form on secondary screen with different resolution?

I am developping a simple windows application (in C#) and I want it to display a form that is maximized in my second monitor. To do so, I am doing the following on the "Load" event of the form:
private void FormTest_Load(object sender, EventArgs e)
{
Screen[] screens = Screen.AllScreens;
this.WindowState = FormWindowState.Normal;
this.Location = screens[1].WorkingArea.Location;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.WindowState = FormWindowState.Maximized;
}
The problem I have is that when I execute this, the form only takes part of the screen. My primary screen has a resolution of 1024x768 and my secondary screen has a resolution of 1920x1080, and it seems that the form is taking the size of the primary screen in my secondary screen.
Also, I have a button that runs the following code to maximize the screen or turn it back to normal:
private void ChangeSize() {
if (this.WindowState == System.Windows.Forms.FormWindowState.Maximized)
{
this.WindowState = System.Windows.Forms.FormWindowState.Normal;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable;
}
else
{
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
}
}
When I click on the button twice (first to de-maximize the form, and then to maximize it again) the form does cover the entire secondary screen perfectly, but if I try to just run that function in code twice (for the sake of testing) right after the code in "FormTest_Load", the screen will still not cover correctly the entire screen.
I am probably making a noob mistake here but I have struggled with this for some time, so I would really appreciate if anyone can shed some light on what is wrong with my code.
I've tried to get the same result as you describe (changing resolutions, etc), but all works fine in my computer and screens. May be... what is exactly the variable screens? I've assumed that is Screen.AllScreens, like this:
protected override void OnLoad(EventArgs e)
{
Screen[] screens = Screen.AllScreens;
int screenNumber = 1;
this.WindowState = FormWindowState.Normal;
this.Location = screens[screenNumber].WorkingArea.Location;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.WindowState = FormWindowState.Maximized;
}
As I said, it works fine for me.
Also, you can check the screen settings of your computer: is the size of text and apps set to 100% (recommended value)?

Minimize and Hide Winform on Form Load

I have a Windows Form in a C# program with the FormBorderStyle set to FixedToolWindow.
The window doesn't have the normal control box, but the user can still minimize it from a menu. There is also a setting for the window to start in a minimized state.
When the user clicks the minimize button it called the following function:
private void minimizeWindow()
{
timer1.Enabled = false;
this.WindowState = FormWindowState.Minimized;
this.Hide();
}
The window becomes a small box in the bottom left of the screen, then disappears (from the this.hide call).
When the same function is called from within the Form_Load method (when the setting is to start minimized) it minimizes but does not disappear.
My guess is that because I am hiding the form before reaching the end of Form_Load it is being shown again when it reaches the end of the method. Is there any way to ensure the form hides when it is loaded (it is maximised again from a system tray icon)?
Edit: Included all code from form load
private void Form1_Load(object sender, EventArgs e)
{
this.Left = windowXPos;
this.Top = windowYPos;
sysTrayIcon.MouseDoubleClick += new MouseEventHandler(sysTrayIcon_MouseDoubleClick);
sysTrayIcon.BalloonTipText = "Timers Running";
this.sysTrayIcon.Icon = this.Icon;
sysTrayIcon.Visible = true;
sysTrayIcon.ShowBalloonTip(500);
Start(); //sets up timers
if (startMinimized)
{
minimizeWindow();
}
}
It might be best to change your logic slightly, and instead of showing the form at all, create an instance of it (var foo = new MyForm()) but don't call .Show() so it will never be shown until triggered from your system tray icon.

Why Won't Form Get Focus?

I have a form that is launched modally like this:
private void find_street_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
Form findForm = new FindStreet();
findForm.ShowDialog();
this.WindowState = FormWindowState.Normal;
}
The form launches correctly, and the cursor is in the first text box, whose TabIndex is set to 1.
Along with the InitializeComponent(); call, these commands are present.
public FindStreet()
{
InitializeComponent();
this.TopMost = true;
this.BringToFront();
this.Focus();
}
I have looked at and tried a number of examples. The cursor appears in the correct control, but the form's window does not have the focus. The problem is that if a user starts typing, even though the newly launched form is visible, those keystrokes are not going into the text box.
Remove the code in public FindStreet() and in load event of FindStreet add:
this.TopMost = true; //i don't know why you need this.
this.Activate();
When you minimize your main form the next one in z-order get the cursor. this.Focus() doesn't do anything. You need to Activate the dialog.
A dialog requires an owner, that cannot be a minimized window. Now accidents start to happen, starting with your WindowState assignment. Your app doesn't have a window left that can receive the focus so Windows is forced to find another one, that will be one owned by another application. Same problem happens when you close the dialog.
You can still get the intended effect, you must hide your main window after the dialog is displayed, show it again before the dialog closes. That requires a bit of hackorama:
using (var dlg = FindStreet()) {
// Show main window when dialog is closing
dlg.FormClosing += new FormClosingEventHandler((s, cea) => {
if (!cea.Cancel) this.Show();
});
// Hide main window after dialog is shown
this.BeginInvoke(new Action(() => {
this.Hide();
}));
dlg.StartPosition = FormStartPosition.Manual;
dlg.Location = this.Location;
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
// etc...
}
}
And remove the hacks from the FindStreet constructor. Watch out for event order if you have a FormClosing event handler in FindStreet, be sure to override OnFormClosing() instead.
If you want to set a specific control as the current active control then try this:
this.ActiveControl = myTextBox;
This will place the cursor you want as the main focus, when the form loads. So try this out:
public FindStreet()
{
InitializeComponent();
this.TopMost = true;
this.BringToFront();
this.Focus();
this.ActiveControl = myTextBox;
}
Here is the link to Focus() which should explain why your focus call was not working.

C#.NET MDI bugs when programmatically hiding and showing again a maximized child form and when maximized, child form's icon cannot be changed

Basically I am having two problems with C#.NET MDI. You can download VS2010 solution which reproduces bugs here.
1) When programmatically hiding and showing again a maximized child form, it is not maximized properly again and becomes neither maximized or in normal state.
childForm = new Form();
childForm.Text = "Child Form";
childForm.MdiParent = this;
...
private void showButton_Click(object sender, EventArgs e)
{
childForm.Visible = true;
}
...
private void hideButton_Click(object sender, EventArgs e)
{
childForm.Visible = false;
}
When child form is maximized, then programicaly hidden and shown again, it becomes something like this (please notice the menu bar - child form's control box appears, but child form is not maximized):
At this stage, child form cannot be moved around. However, I found a workaround for that, simply by showing and hiding a dummy child form, which forces the actual child form to become properly maximized. But this makes MDI area to flicker. Tried Invalidate, Refresh, Update methods, but they don't help. Maybe there are other workarounds to overcome this bug and not to make MDI area flicker with dummy child form?
private void workaround1Button_Click(object sender, EventArgs e)
{
dummyForm.Visible = true;
dummyForm.Visible = false;
}
2) When child form is maximized, the icon of the child form is displayed on menu bar. However, if you have to change the icon while the child form is maximized, the icon on the menu bar is not being refreshed (see the image above). I found a workaround for that too, which basically hides and shows menu bar. Icon gets refreshed, but it makes everything below menu bar to flicker. Tried Invalidate, Refresh, Update methods, but they don't help. Is there any other way to make menu bar to refresh the child form's icon?
private void workaround2Button_Click(object sender, EventArgs e)
{
menuStrip.Visible = false;
menuStrip.Visible = true;
}
Also I noticed that when parent form is in normal window state mode (not maximized) and you change the width or height of the form by 1 pixel, child form becomes maximized as it should be and child form's icon on menu bar gets refreshed properly and you don't need other workaround I described above. If I change the size of the form programicaly, form flickers by 1 pixel and I cannot do that, when parent form is maximized. Is there any way how I could invoke the repaint/refresh functionality which is called when you resize a form and which makes child form become maximized properly and the icon on the menu bar refreshed?
There's a bug in the implementation of the internal MdiControlStrip class, the control that displays the icon and the min/max/restore glyphs in the parent window. I haven't characterized it as yet, the code isn't that easy. A classic side effect of the bug is that the glyphs get doubled up, you found some other side-effects. The fix is simple though, delay creating the child windows until after the constructor is completed. Like this:
public MainForm()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e) {
childForm = new Form();
childForm.Text = "Child Form";
childForm.MdiParent = this;
dummyForm = new Form();
dummyForm.MdiParent = this;
dummyForm.WindowState = FormWindowState.Maximized;
base.OnLoad(e);
}
Have you tired using Hide/Show instead of setting visible to true/false?
Try:
private void showButton_Click(object sender, EventArgs e)
{
childForm.Show();
}
private void hideButton_Click(object sender, EventArgs e)
{
childForm.Hide();
}
How about this workaround?
private void showButton_Click(object sender, EventArgs e)
{
childForm.Visible = true;
childForm.WindowState = (FormWindowState)childForm.Tag;
}
private void hideButton_Click(object sender, EventArgs e)
{
childForm.Visible = false;
childForm.Tag = childForm.WindowState;
childForm.WindowState = FormWindowState.Normal;
}
UPDATE
I just gave you the idea how you could do. A better solution using the same idea as above would be a new base form which saves the windows state. See below. Derive your forms from FixedForm instead of Form:
public partial class FixedForm : Form
{
private FormWindowState lastWindowState;
public FixedForm()
{
InitializeComponent();
}
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
if (Visible)
{
WindowState = lastWindowState;
}
else
{
lastWindowState = WindowState;
WindowState = FormWindowState.Normal;
}
}
}
Found a way how to come around those bugs.
First of all you need to suspend painting for a form and its children. I found a very helpful thread here, which describes how to do it.
After suspending painting, you need call UpdateBounds method of the control and increase ClientRectangle Width or Height by one and then decrease it back to the same value it was before. This invokes layout functionality which makes everything to update/repaint. Last step is to enable painting. Not very nice solution I guess, but it works.
StopDrawing();
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height + 1);
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height - 1);
StartDrawing();
I find suspending painting very helpful not only for working around those two bugs, but also in general to make GUI work more smoothly. I guess this can help to remove any kind of flickering. However, this solution requires P/Invokes, which should be avoided in general.
Why not just manually reset required icon in menuStrip items, after the creation of the window:
menuStripMain.Items[0].Image = null;

Combine NotifyIcon and ToolTip

I have been working with NotifyIcon in order to show an icon in the taskbar.
This program has no Windows Form. I perhaps could create one and make it invisible but I was hoping to avoid it. The ToolTip functions attached to NotifyIcon are somewhat lacking, and one of the gurus here suggested I look at the ToolTip functionality. It is possible to attach ToolTip to a form. Is is possible to attach it to just the NotifyIcon? I'm trying do this:
NotifyIcon CTicon = new NotifyIcon();
ToolTip toolTip = new ToolTip();
toolTip.SetToolTip(CTicon, "Test");
And I get the error "cannot convert from 'System.Windows.Forms.NotifyIcon' to 'System.Windows.Forms.Control'. Is there a way to convert? I also tried:
toolTip.SetToolTip(CTicon.Container, "Test");
but a container is apparently not a valid control either.
I apologize for my total lack of understanding of how this may or may not work.
Thanks in advance.
A belated answer, but maybe useful for others .
NotifyIcon.Text = "ToolTipText";
Tray icons don't support square tool tips, only balloons. Kinda makes sense, the icons are usually quite close together so it would be hard to see what icon produced the tip without the "stem" on the balloon. Use the NotifyIcon.BalloonTipText property.
NotifyIcon is used for the system tray icon that you see on the bottom right hand corner of the screen, usage of ToolTip is only for controls such as textboxes, checkboxes and so on...for example, let's assume there's a TextBox instance called 'textBox1', on the form than this would work:
toolTip1.SetToolTip(textBox1, "Hello World");
Now, when you mouse-over the textbox, a tooltip is shown...
I'm not sure you can set a tooltip directly on a notify icon. It's the same thing as setting the text property on the notify icon itself. There are some limitations to the notify icon text. It's limited to 128 chars and will only stay up for a short amount of time. If you want to display more info for a longer amount of time you should look at the balloon text property of the notify icon. I highly suggest reading the MSDN page it's quite helpful.
http://msdn.microsoft.com/en-us/library/system.windows.forms.notifyicon.aspx
You shouldn't.
NotifyIcon is used to show notifications, whereas ToolTip is used to show the information about the user's current activity, it should be used "in place".
Check the user interface guidelines:
Notifications
Balloons
All the tray icons on my computer have tooltips. You need to create your NotifyIcon using the constructor that accepts a Component as an argument. It displays the NotifyIcon.Text property.
I was able to create one using the example code here:
http://msdn.microsoft.com/en-us/library/1by05f8d.aspx
using System;
using System.Drawing;
using System.Windows.Forms;
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.NotifyIcon notifyIcon1;
private System.Windows.Forms.ContextMenu contextMenu1;
private System.Windows.Forms.MenuItem menuItem1;
private System.ComponentModel.IContainer components;
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
public Form1()
{
this.components = new System.ComponentModel.Container();
this.contextMenu1 = new System.Windows.Forms.ContextMenu();
this.menuItem1 = new System.Windows.Forms.MenuItem();
// Initialize contextMenu1
this.contextMenu1.MenuItems.AddRange(
new System.Windows.Forms.MenuItem[] {this.menuItem1});
// Initialize menuItem1
this.menuItem1.Index = 0;
this.menuItem1.Text = "E&xit";
this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
// Set up how the form should be displayed.
this.ClientSize = new System.Drawing.Size(292, 266);
this.Text = "Notify Icon Example";
// Create the NotifyIcon.
this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
// The Icon property sets the icon that will appear
// in the systray for this application.
notifyIcon1.Icon = new Icon("appicon.ico");
// The ContextMenu property sets the menu that will
// appear when the systray icon is right clicked.
notifyIcon1.ContextMenu = this.contextMenu1;
// The Text property sets the text that will be displayed,
// in a tooltip, when the mouse hovers over the systray icon.
notifyIcon1.Text = "Form1 (NotifyIcon example)";
notifyIcon1.Visible = true;
// Handle the DoubleClick event to activate the form.
notifyIcon1.DoubleClick += new System.EventHandler(this.notifyIcon1_DoubleClick);
}
protected override void Dispose( bool disposing )
{
// Clean up any components being used.
if( disposing )
if (components != null)
components.Dispose();
base.Dispose( disposing );
}
private void notifyIcon1_DoubleClick(object Sender, EventArgs e)
{
// Show the form when the user double clicks on the notify icon.
// Set the WindowState to normal if the form is minimized.
if (this.WindowState == FormWindowState.Minimized)
this.WindowState = FormWindowState.Normal;
// Activate the form.
this.Activate();
}
private void menuItem1_Click(object Sender, EventArgs e) {
// Close the form, which closes the application.
this.Close();
}
}

Categories