WindowState and the Maximum/Minimize buttons Event are different - c#

Before starting the question, I apologize for not using English well.
I don't want to use Border and Minimized/Maximized/Closed buttons in the existing form.
FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
Then, I created Custom Minimized/Maximized/Closed Button.
//Closed
private void imgLblCloseProgram_Click(object sender, EventArgs e) {
this.Close();
}
//Maximized
private void imgLblMaximumProgram_Click(object sender, EventArgs e) {
if(this.WindowState == FormWindowState.Maximized) {
this.WindowState = FormWindowState.Normal;
} else if(this.WindowState == FormWindowState.Normal) {
//this.MaximizedBounds = Screen.FromHandle(this.Handle).WorkingArea; //★★★
this.WindowState = FormWindowState.Maximized; //
}
}
private void tbPnlTopBar_DoubleClick(object sender, EventArgs e) {
imgLblMaximumProgram_Click(imgLblMaximumProgram, e);
}
//Minimized
private void imgLblMinimumProgram_Click(object sender, EventArgs e) {
this.WindowState = FormWindowState.Minimized; //
}
When Clear the annotation, Maximizes without taking up space on the taskbar.
However, if more than one monitors are used, they do not work on screens other than the main screen.
In addition, for the Maximized/Minimized button, there seems to be a built-in animation provided by Windows.
When the Maximized/Minimized was changed via FormWindowState, I confirmed that the animation did not work.
The biggest reason why I want the Low-cost Maximized Button Event is that when I use more than one monitors, I have a issue.
Therefore, I need a way to maximize the form while displaying TaskBar on two or more monitors.
p.s. I want the animation of the maximized/minimized button as well, so the best way to run the maximized/minimized button's event is.

I solved this.
when I use more than one monitors, I have a issue(they do not work on screens other than the main screen).
If you still want to use FormWindowState.Maximized on more than one monitor, this is likely to be an appropriate solution.
this.MaximizedBounds = new Rectangle(new Point(Screen.PrimaryScreen.WorkingArea.X, Screen.PrimaryScreen.WorkingArea.Y), new Size(Screen.FromHandle(this.Handle).WorkingArea.Width, Screen.FromHandle(this.Handle).WorkingArea.Height));
However, there is an error on the screen with higher resolution than the main monitor.

Related

Where do I put custom code to handle a resize event C# windows form

I cannot work out where to put nor get the code to trigger when my main form windows are resized (ie minimize button clicked)
I am trying to trigger this code when ANY resize of the DigiDocketMain window is minimized etc, or also how I can specifically code the minimize button to do something - the ideal goal is to get the program - n minimize button click to hide the taskbar icon and show a tray icon.
I have tried placing this is the main code body and the designer code but nothing triggers it. any help would be appreciated.
private void DigiDocketMain_Resize(object sender, System.EventArgs e)
{
MessageBox.Show("You are in the Form.ResizeEnd event.");
if (this.WindowState == System.Windows.Forms.FormWindowState.Minimized)
{
this.Hide();
mainTrayIcon.Visible = true;
}
}
In your code behind add the following to the Form_Load Event
this.SizeChanged += Form1_SizeChanged;
Then implement the function, autocomplete may do this for you.
private void Form1_SizeChanged(object sender, EventArgs e)
{
// Add the code that will be called on resize events.
}
According to your description, when clicking the minimize button, you want to hide the
taskbar icon and display the tray icon.
I suggest that you set the Visible of notifyIcon1 to false in the property bar, and select a icon format image as the icon, then try the following code.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Deactivate(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
{
this.notifyIcon1.Visible = true;
this.Hide();
this.ShowInTaskbar = false;
}
}
private void notifyIcon1_Click(object sender, EventArgs e)
{
this.Visible = true;
this.WindowState = FormWindowState.Normal;
this.notifyIcon1.Visible = false;
this.ShowInTaskbar = true;
}
}

Proper way of activating my MainForm from a NotifyIcon if it wasn't focused already

I just want to replace the task bar button of my winforms application by a tray notification icon. That means, if the user left-clicks the icon, the form should be activated if it wasn't focused, otherwise minimized or hidden.
I read lots and lots of articles about properly using a NotifyIcon, and it seems I have to accept a hackish solution. So, what's the most proper way?
I got it mostly to run, but now I'm stuck at detecting if my form was active already - because when clicking the icon, the form looses focus, so I cannot check the Focused property.
The following code does not yet solve this, so if the form was just hidden by other windows, you have to click 2 times, because the first click minimizes.
How can it be improved?
private void FormMain_Resize(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
Hide();
}
private void notifyIcon_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
if (WindowState == FormWindowState.Minimized) {
WindowState = FormWindowState.Normal;
Show();
Activate();
}
else {
Hide();
WindowState = FormWindowState.Minimized;
}
}
(I also don't understand why the Click event fires on right-clicking, which already opens the context menu in my case...)
(And of course it would be nice to have a proper minimize animation, but there are other questions here, where this wasn't really solved)
(I know I said Focused, but if the form was already fully visible (but maybe not focused), and the user clicks the tray icon, he most likely wants to hide it)
#LarsTech suggested a hack using a timer, and this works, thanks, but I still hope for better solutions or improvements.
Maybe interesting: I also hack-solved part of the animation problem - when there is no taskbar button, the animation originates from where the minimized form is located. You can make it visible by calling Show() after minimizing. It sits in the lower left of the screen and it is not possible to move it by setting i.e. the Left property. So I used winapi directly and it works!
Unfortunately only for the restore animation, because I don't know how to set the minimized position before minimizing. Hide() disables the animation anyway, so I would have to delay it...
That all is so disappointing! Why is there no nice solution? I can never be sure if it will work in every scenario. For example on one machine it worked well with a 100ms timer, but on another I needed 200ms. So I suggest to have a least 500ms.
[DllImport("user32.dll", SetLastError = true)]
static extern bool MoveWindow(IntPtr hWnd,
int X, int Y, int nWidth, int nHeight, bool bRepaint);
private void FormMain_Resize(object sender, EventArgs e)
{
if (!ShowInTaskbar && WindowState == FormWindowState.Minimized) {
Hide();
//Move the invisible minimized window near the tray notification area
if (!MoveWindow(Handle, Screen.PrimaryScreen.WorkingArea.Left
+ Screen.PrimaryScreen.WorkingArea.Width - Width - 100,
Top, Width, Height, false))
throw new Win32Exception();
}
}
private void notifyIcon_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
if (WindowState == FormWindowState.Minimized || !timer.Enabled) {
Show();
WindowState = FormWindowState.Normal;
Activate();
}
else {
WindowState = FormWindowState.Minimized;
//FormMain_Resize will be called after this
}
}
private void FormMain_Deactivate(object sender, EventArgs e)
{
timer.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
timer.Stop();
}
//other free goodies not mentioned before...
private void taskbarToolStripMenuItem_Click(object sender, EventArgs e)
{
ShowInTaskbar = !ShowInTaskbar;
taskbarToolStripMenuItem.Checked = ShowInTaskbar;
}
private void priorityToolStripMenuItem_Click(object sender, EventArgs e)
{
//Set the process priority from ToolStripMenuItem.Tag
//Normal = 32, Idle = 64, High = 128, BelowNormal = 16384, AboveNormal = 32768
Process.GetCurrentProcess().PriorityClass
= (ProcessPriorityClass)int.Parse((sender as ToolStripMenuItem).Tag.ToString());
foreach (ToolStripMenuItem item in contextMenuStrip.Items)
if (item.Tag != null)
item.Checked = item.Equals(sender);
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}

Minimize to tray [duplicate]

This question already has answers here:
How do I minimize a WinForms application to the notification area?
(4 answers)
Closed 9 years ago.
my app is for chatting, and i think if someone needs to hide it quick, but doesn't want to close it, i came up with this:
private void button6_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
}
however, instead of going to the taskbar, i want it to appear (no popup) in the tray, just the apps icon, and when someone clicks it it needs to set this
this.WindowState = FormWindowState.Normal;
Is this possible, how?
Also by system tray i mean the one in the bottom right corner, next to the time
I still can't get this to work, nothing appears in the notification bar if I do what you guys said (btw: this is the full code to minimise)
private void button6_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
}
private void Form_Resize(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
this.Hide();
}
}
private void notifyIcon_Click(object sender, EventArgs e)
{
this.Show();
this.WindowState = FormWindowState.Normal;
}
Why isn't this working?
Handle the form’s Resize event. In this handler, you override the
basic functionality of the Resize event to make the form minimize to
the system tray and not to the taskbar. This can be done by doing the
following in your form’s Resize event handler:
Check whether the form’s WindowState property is set to FormWindowState.Minimized. If yes, hide your form, enable the NotifyIcon object, and show the balloon tip that shows some information.
Once the WindowState becomes FormWindowState.Normal, disable the NotifyIcon object by setting its Visible property to false.
Now, you want the window to reappear when you double click on the NotifyIcon object in the taskbar. For this, handle the NotifyIcon’s MouseDoubleClick event. Here, you show the form using the Show() method.
In the form resize event, do the check there and hide the form
private void Form_Resize(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
this.Hide();
}
}
Then when clicking on the taskbar icon just restore it.
private void notifyIcon_Click(object sender, EventArgs e)
{
this.Show();
this.WindowState = FormWindowState.Normal;
}
Refer:
How do I minimize a WinForms application to the notification area?
minimize app to system tray
Use following code:
if (WindowState == FormWindowState.Minimized)
{
this.Hide();
}
When you minimize the form, simply hide it.
You will have to implement above code in Form_Resize event.
Then on clicking taskbar icon just restore its state as follows:
private void notifyIcon_Click(object sender, EventArgs e)
{
this.Show();
this.WindowState = FormWindowState.Normal;
}
You will need to use notifyIcon_Click event for this purpose.
Hope its helpful.

Show window after notify icon click

I'm trying to show my form when the user clicks on my notifyicon after the form has been minimized to the system tray. However upon calling Show() the form reappears but is always minimized, i have to click the taskbar icon to un-minimize. Here is my code.
private void Form1_Resize(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
Hide();
}
}
private void notifyIcon1_Click(object sender, EventArgs e)
{
Show();
//BringToFront();
}
I've also tried adding BringToFront() but to no avail.
I need noifyIcon click to show the form, but for it not to be minimized afterward.
Set the WindowState property to Normal.
Set your window state back to not minimized. For example :
this.WindowState = FormWindowState.Maximized;
Try adding
this.WindowState = FormWindowState.Normal;

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;

Categories