I have a form that that minimizes on deactivate but now the task bar button does not minimize the form. It goes away for an instance then comes back. There seems to be a race with the task bar function and the deactivate event where when I click the icon the form minimizes, then the task bar function sees that it is minimized and the form restores. I have the following code:
public Form1()
{
InitializeComponent();
Text = string.Empty;
ControlBox = false;
FormBorderStyle = FormBorderStyle.SizableToolWindow;
Deactivate += lostFocus;
}
private void lostFocus(object o, EventArgs e)
{
WindowState = FormWindowState.Minimized;
}
protected override void WndProc(ref Message message)
{
const int WM_NCHITTEST = 0x0084;
if (message.Msg == WM_NCHITTEST) return;
base.WndProc(ref message);
}
(Note that the form has no controls)
I was able to get it to kind of work with the following bandade:
private void focusTimerEvent(object o, EventArgs e)
{
WindowState = FormWindowState.Minimized;
focusTimer.Stop();
}
private void lostFocus(object o, EventArgs e)
{
focusTimer.Start();
}
and setting the timer to 1000 in Form1() method
focusTimer = new Timer();
focusTimer.Interval = 1000;
focusTimer.Tick += focusTimerEvent;
any suggestions would be appreciated
Related
I'm lookin for examples how hide form when I minimize, but this.Hide() doesn't work. I don't understand what's wrong. At the moment I just want to hide Form1.
private void Form1_Resize(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
this.Hide();
}
}
When I click in minimize button, form goes to taskbar but form doesn't hide.
I found a solution. After InitializeComponent():
public Form1()
{
InitializeComponent();
this.Resize += SetMinimizeState;
}
Then:
private void SetMinimizeState(object sender, EventArgs e)
{
bool isMinimized = this.WindowState == FormWindowState.Minimized;
this.ShowInTaskbar = !isMinimized;
if (isMinimized)
{
// optional
notifyIcon1.ShowBalloonTip(500, "Title", "Message.", ToolTipIcon.Info);
}
}
It works!
I am new to windows app development. I am developing a Windows Form Application where the layout is as follows:
There is one textbox and i have created the keyboard inside the application using SendKeys event.
Problem is that all other application on the system are able to detect the keys but the textbox inside the application is not able to detect the keys.
Basically app is having complete keyboard this is just one button press code
What I have tried:
public partial class Form1 : Form
{
Control focusedC;
protected override CreateParams CreateParams
{
get
{
CreateParams param = base.CreateParams;
param.ExStyle |= 0x08000000;
return param;
}
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
FormBorderStyle = FormBorderStyle.None;
WindowState = FormWindowState.Maximized;
TopMost = true;
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape) {
FormBorderStyle = FormBorderStyle.Sizable;
WindowState = FormWindowState.Normal;
TopMost = false;
}
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
//checkbox is for CapsLock Key
}
private void button14_Click(object sender, EventArgs e)
{
if (checkBox1.Checked && focusedC != null)
{
focusedC.Focus();
SendKeys.Send("Q");
}
else if(focusedC != null)
{
focusedC.Focus();
SendKeys.Send("q");
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
focusedC = sender as TextBox;
}
}
Of cource it doesn't work on your window. You set the WS_EX_NOACTIVATE style! It works on other windows but not yours, obviously. If you want it to work on your textbox remove or comment this line
param.ExStyle |= 0x08000000;
and it will work fine in your app window not others:
private void button14_Click(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
textBox1.Focus();
SendKeys.Send("Q");
}
else
{
textBox1.Focus();
SendKeys.Send("q");
}
}
For WPF applications, you have to use SendKeys.SendWait() method.
SendKeys.SendWait("Q")
SendKeys.Send() will work for WinForm Applications.
Another option is to use WinAPI instead of SendKeys. More information here
Edit 1
Control focusedC;
//Enter event handler for your TextBox
private void textBox1_TextChanged(object sender, EventArgs e)
{
focusedC = sender as TextBox;
}
//Click event handler
private void button14_Click(object sender, EventArgs e)
{
if (focusedC != null)
{
focusedC.Focus();
SendKeys.Send("Q");
}
}
Edit 2: Using WinAPI
[DllImport("user32.dll")]
static extern void SendInput(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
public static void PressKey(byte keyCode)
{
const int KEYEVENTF_EXTENDEDKEY = 0x1;
const int KEYEVENTF_KEYUP = 0x2;
SendInput((byte)keyCode, 0x45, KEYEVENTF_EXTENDEDKEY, 0);
SendInput((byte)keyCode, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
}
Use by calling the PressKey function and Keycodes can be found here
In one of our apps we want to want to limit the user from opening other menu items when an existing menu item is already open. We are currently doing this:
private void menuItem1_Click(object sender, EventArgs e)
{
Myform f = new MyForm();
f.ShowDialog(this);
}
However in doing this, we lose the ability to interact at all with the parent window because internally, the parent.enabled property was set to false. Using the code above, if the user has menu item open and wants to move the parent window to see something on their desktop, they first must close the menu item, move the parent, and reopen the menu item.
I have come up with the follow method of doing the UI in a backgroundworker
public class BaseForm : Form
{
private bool _HasChildOpen;
protected BackgroundWorker bgThead;
public BaseForm()
{
_HasChildOpen = false;
bgThead = new BackgroundWorker();
bgThead.DoWork += new DoWorkEventHandler(OpenChildWindow);
bgThead.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.ClearChildWindows);
}
protected void ClearChildWindows(object sender, RunWorkerCompletedEventArgs e)
{
_HasChildOpen = false;
}
public void OpenChildWindow(object sender, DoWorkEventArgs e)
{
if (!_HasChildOpen)
{
Form f = (Form)e.Argument;
f.StartPosition = FormStartPosition.CenterScreen;
f.ShowDialog();
}
}
}
and then each menu item has the following code
private void menuItem1_Click(object sender, EventArgs e)
{
if (!bgThead.IsBusy)
{
bgThead.RunWorkerAsync(new Myform());
}
}
but this approach is a big no no. However, using invoke seems to get me back where I started:
private void doUIWork(MethodInvoker d)
{
if (this.InvokeRequired)
{
this.Invoke(d);
}
else
{
d();
}
}
public void OpenChildWindow(object sender, DoWorkEventArgs e)
{
if (!_HasChildOpen)
{
doUIWork(delegate() {
Form f = (Form)e.Argument;
f.StartPosition = FormStartPosition.CenterScreen;
f.ShowDialog();
});
//Form f = (Form)e.Argument;
//f.StartPosition = FormStartPosition.CenterScreen;
//f.ShowDialog();
}
}
How do I properly limit the user to just one menu item open, but at the same time leave the parent enabled such that it can be moved resized etc?
You will need to programmatically disable menu strip behavior once one of the forms is open. So if you have Form1 and Form2, (with a menuStrip on Form1 and toolStripMenuItem1, toolStripMenuItem2 on the menuStrip):
private void menuItem1_Click(object sender, EventArgs e)
{
var f2 = new Form2();
f2.FormClosing += f2_FormClosing;
f2.Show();
this.menuStrip1.Enabled = false;
}
private void menuItem2_Click(object sender, EventArgs e)
{
var f2 = new Form2();
f2.FormClosing += f2_FormClosing;
f2.Show();
this.menuStrip1.Enabled = false;
}
void f2_FormClosing(object sender, FormClosingEventArgs e)
{
this.menuStrip1.Enabled = true;
}
using the Show() method instead of ShowDialog() enables interaction with the parent control, though you will need to manually disable/enable behavior depending on when the child control is shown or not.
I have a main form window which will pop up a new form window. I want to lock the location of the popup form so that the window cannot be moved and it will move at the same time as the main form.
(so if a user drags the main form the popup moves with it)
Did a search on the site and some did it like this:
this.FormBorderStyle=System.Windows.Forms.FormBorderStyle.None
and I have the Locked attribute set to True but that doesn't work.
But I want to keep the borders. What's the proper way of locking a form?
public class Form1
{
private Form2 Form2 = new Form2();
private Point form2Location;
private Point form1Location;
private void Button1_Click(System.Object sender, System.EventArgs e)
{
form1Location = this.Location;
Form2.Show();
form2Location = Form2.Location;
}
private void Form1_Move(System.Object sender, System.EventArgs e)
{
Form2.IsMoving = true;
Point form2OffSetLocation = new Point(this.Location.X - form2Location.X, this.Location.Y - form2Location.Y);
Form2.Location = form2OffSetLocation;
Form2.IsMoving = false;
}
}
public class Form2
{
public bool IsMoving;
private void Form2_Move(System.Object sender, System.EventArgs e)
{
if (IsMoving) return;
if (staticLocation.X != 0 & staticLocation.Y != 0) this.Location = staticLocation;
}
private Point staticLocation;
private void Form2_Load(System.Object sender, System.EventArgs e)
{
staticLocation = this.Location;
}
}
I agree with Hans on this one and I think once you see how dodgy it looks you'll probably agree too.
You could do something like this (taken from here):
protected override void WndProc(ref Message message)
{
const int WM_SYSCOMMAND = 0x0112;
const int SC_MOVE = 0xF010;
switch(message.Msg)
{
case WM_SYSCOMMAND:
int command = message.WParam.ToInt32() & 0xfff0;
if (command == SC_MOVE)
return;
break;
}
base.WndProc(ref message);
}
I'm trying to have the owner-form minimize when the modal-form is minimized. But when I minimize the modal-form – it disappears completely. (- I can click on the owner-form.)
How do I solve this?
I have:
public partial class Form1 : Form
{
Form2 frm2 = new Form2();
public Form1()
{
InitializeComponent();
frm2.Owner = this;
}
private void button1_Click(object sender, EventArgs e)
{
frm2.ShowDialog();
}
}
And:
class Form2 : Form
{
Form1 frm1;
FormWindowState ws = new FormWindowState();
public Form2()
{
SizeChanged += new EventHandler(Form2_SizeChanged);
}
void Form2_SizeChanged(object sender, EventArgs e)
{
frm1 = (Form1)Owner;
if (WindowState == FormWindowState.Minimized)
{
ws = frm1.WindowState;
frm1.WindowState = FormWindowState.Minimized;
}
else frm1.WindowState = ws;
}
}
(While trying this, I also ran into this: Modal form doesn't appear in tray until minimized and owner-form is clicked once. How do I make it appear? )
This is by design. As part of the modality contract, showing a dialog disables all the other windows in the application. When the user minimizes the dialog window, there are no windows left that the user can access. Making the app unusable. Winforms ensures this cannot happen by automatically closing the dialog when it gets minimized.
Clearly you'll want to prevent this from happening at all. Set the MinimizeBox property to false. The MaximizeBox property ought to be set to false as well, making both buttons disappear from the window caption. Leaving room for the HelpButton btw.
I don't recall every needing this much code to get modal Windows to work. I'm concerned by your comment 'I can click on the owner form', which leads me to believe that the form is nt being correctly set up as modal. By defintion, modal forms must be dealt with before user control can return to the owner form. Minimizinfg the modal form does not constitute properly 'dealing' with the modal form.
Here is some code that I have used in the past. Notes: passing the owner as parameter in ShowDialog establishes the ownership relationship. While I suspect your code works, I've not used it that way.
Also, when I have done this, I have not put any special code in the modal form, and have also disabled all the button in the upper right corner of the form; thereby insuring that the user cannot close, minimize, or maximize the modal form outside of any buttons I have provided.
public partial class Form1 : Form
{
Form2 frm2 = new Form2();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
frm2.ShowDialog(this);
}
}
I hope this helps.
Forms have a property ShowInTaskbar. If it is set to false then the form will never appear on the task bar, even when minimized.
Add a:
Show();
At the end of Form2's event-handler.
I also had the requirement where when minimizing a dialog form it should minimize the application and when restoring the application it should show the dialog again. Here's what I did:
MainForm.cs
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2.Show(this, "Testing 123");
}
}
Form2.cs
public partial class Form2 : Form
{
bool isMinimized;
private Form2()
{
InitializeComponent();
ShowInTaskbar = false;
}
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
if (Owner != null)
{
Owner.Enabled = true;
}
}
private void Form2_Load(object sender, EventArgs e)
{
MinimizeBox = Owner != null;
if (Owner != null)
{
Owner.Enabled = false;
}
}
private void Form2_SizeChanged(object sender, EventArgs e)
{
if (Owner != null)
{
if (WindowState == FormWindowState.Minimized && Owner.WindowState != FormWindowState.Minimized)
{
Owner.Enabled = true;
Owner.WindowState = FormWindowState.Minimized;
isMinimized = true;
}
else if (isMinimized && Owner.WindowState != FormWindowState.Minimized)
{
Owner.Enabled = false;
}
}
}
public static void Show(Form owner, string message)
{
var form2 = new Form2();
form2.label1.Text = message;
if (owner != null)
form2.Show(owner);
else
form2.ShowDialog();
}
}