I am developing a Windows Forms application in C# in which I have a form which must start in a maximized state and not allow users to restore or resize it. I have already configured the form to start in maximized mode, disable the restore and maximize button and locked the borders of the form but when the title bar is double clicked, the form restores to a smaller size which is unexpected. The following are the properties I set to achieve the required behaviour:
FormBorderStyle = FixedSingle
MaximizeBox = False
WindowState = Maximized
Can someone please help me solve this problem and explain me the solution?
Thanks in advance.
You have to remember that your form starts with some default size values and double click is just toggling between 2 states.
Within your normal state the form will retrieve it's last ( in your case default ) size which you can override :
Width = Screen.PrimaryScreen.Bounds.Width;
Height = Screen.PrimaryScreen.Bounds.Height;
Another thing is that your application has something called start position which ( from what I remember ) defaults to the center of the screen and you can change it using :
Form.StartPosition = new Point(0, 0); // top-left corner
Now all you have to do in your applicaiton is to check for the toggle between window states. Easiest way would be to use WndProc and wait for messages listed in this msdn page :
protected override void WndProc(ref Message m)
{
const int WM_SYSCOMMAND = 0x0112;
const int SC_MAXIMIZE = 0xF030;
const int SC_RESTORE = 0xF120;
if (m.Msg == WM_SYSCOMMAND)
{
switch((int)m.WParam)
{
case SC_RESTORE:
// your window was restored ( double clicked on the command bar )
// set it's window state back to maximize or do whatever
break;
case SC_MAXIMIZE:
// your window was maximized .. no actions needed, just for debugging purpose
break;
}
}
base.WndProc(ref m);
}
This can be accomplished by catching the event and overriding it:
private void Form_Load(object sender, EventArgs e)
{
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.WindowState = FormWindowState.Maximized;
this.MaximizeBox = false;
this.MinimumSize = Screen.GetWorkingArea(this.Location).Size;
}
private const int WM_NCLBUTTONDBLCLK = 0x00A3;
//double click on a title bar
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_NCLBUTTONDBLCLK)
{
m.Result = IntPtr.Zero;
return;
}
base.WndProc(ref m);
}
Related
I am using this code to check if the form is minimized:
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_SYSCOMMAND:
int command = m.WParam.ToInt32() & 0xfff0;
if (command == SC_MINIMIZE)
MessageBox.Show("Minimized");
Variaveis.telaMinimizada = true;
else
Variaveis.telaMinimizada = false;
MessageBox.Show("Maximized");
break;
}
base.WndProc(ref m);
}
This code works like a charm. When I click on minimize button, appear the message "minimized", and when I reopen the application, appear the message "maximized"
But there is a problem. Not always people minimize the form by clicking on minimize button. I mean, if I click on screen OUT the form, the form will also minimize, and when this happens, the code I have do not detect that the form got minimized.
How can I check if the form is minimized (or is invisible on screen) when the form gets minimized after clicking OUT the form?
Ideas? Thanks!
Edit: I already tried doing what is recommended on this post, but do not work:
How to detect when a windows form is being minimized?
this might work for you
//we create a variable to store our window's last state
FormWindowState lastState;
public Form2()
{
InitializeComponent();
//then we create an event for form size changed
//i did use lambda for creating event but you can use ordinary way.
this.SizeChanged += (s, e) =>
{
//when window size changed we check if current state
//is not the same with the previous
if (WindowState != lastState)
{
//i did use switch to show all
//but you can use if to get only minimized status
switch (WindowState)
{
case FormWindowState.Normal:
MessageBox.Show("normal");
break;
case FormWindowState.Minimized:
MessageBox.Show("min");
break;
case FormWindowState.Maximized:
MessageBox.Show("max");
break;
default:
break;
}
//and at the and of the event we store last window state in our
//variable so we get single message when state changed.
lastState = WindowState;
}
};
}
Edit:
and to check if form is not on top anymore you can override OnLostFocus like so
protected override void OnLostFocus(EventArgs e)
{
MessageBox.Show("form not on top anymore");
base.OnLostFocus(e);
this.Focus();
}
I set the MaximumSize of a form to a value so that when the user presses the maximize button, the form is still displayed as a window, not full-screen. This works, but there are two side effects of this which I do not want to have:
The window is automatically moved to the top left corner of the
screen;
When I move the window with the mouse it is automatically
resized to the size before I pressed the maximize button.
How can I avoid these side effects?
Edit: Is there a way to center the form horizontally upon pressing the maximize button?
You could override WndProc to capture MaximumSize event
like this
private const int SC_MAXIMIZE = 0xF030;
private const int WM_SYSCOMMAND = 0x0112;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_SYSCOMMAND)
{
if (m.WParam == new IntPtr(SC_MAXIMIZE))
{
this.Size = this.MaximumSize;
return;
}
}
base.WndProc(ref m);
}
this should solve your problem,
however, it is not advisable to go against the design of the operating system. This will cause problems with docking and it goes against the expectations of the users
Question:
How do I display a MDI child form in a ShowDialog() format?
What I've tried:
private void Add()
{
ModuleAddPopUp map = new ModuleAddPopUp();
map.StartPosition = FormStartPosition.CenterScreen;
map.ShowDialog();
}
Doing the above, the form displays center screen as a pop-up, however I can drag the form outside the MDI when the MDI isn't maximized.
private void Add()
{
ModuleAddPopUp map = new ModuleAddPopUp();
FormFunctions.OpenMdiDataForm(App.Program.GetMainMdiParent(), map);
}
Doing the above, the form displays center screen, doesn't allow for the form to be dragged outside the MDI, but acts as a map.Show() , rather than a map.ShowDialog();
Add this code to your ModuleAddPopup class:
protected override void WndProc(ref Message message)
{
const int WM_SYSCOMMAND = 0x0112;
const int SC_MOVE = 0xF010;
//SC_SIZE = 0XF000 if you also want to prevent them from resizing the form.
//Add it to the 'if' condition.
switch (message.Msg)
{
case WM_SYSCOMMAND:
int command = message.WParam.ToInt32() & 0xfff0;
if (command == SC_MOVE)
return;
break;
}
base.WndProc(ref message);
}
This is native code wrapped in C# code, as seen in here.
This, however, will prevent the user from moving the dialog form anywhere.
Then, in your main form:
private void Add()
{
ModuleAddPopUp map = new ModuleAddPopUp();
map.StartPosition = FormStartPosition.CenterParent;
map.ShowDialog();
}
I have a windows form that I want to make it non movable when the user clicks a button and make it movable again when the user clicks again the button.
I found this solution here: How do you prevent a windows from being moved?
But its an override so I think that is for making the form non movable for ever.
Any clue?
Thanks
Just have a flag:
private bool _preventMove = false;
protected override void WndProc(ref Message message)
{
const int WM_SYSCOMMAND = 0×0112;
const int SC_MOVE = 0xF010;
if(_preventMove)
{
switch(message.Msg)
{
case WM_SYSCOMMAND:
int command = message.WParam.ToInt32() & 0xfff0;
if (command == SC_MOVE)
return;
break;
}
}
base.WndProc(ref message);
}
Set the flag to true/false to disable/enable movement
I made a custom window for my app and I wrote some code if a user clicks my custom maximize button:
private void MaxThis(object sender, System.Windows.RoutedEventArgs e)
{ if (WindowState == WindowState.Maximized){
WindowState = WindowState.Normal;}
else {
this.Top = 0;
this.Left = 0;
this.MaxWidth = System.Windows.SystemParameters.WorkArea.Width;
this.MaxHeight = System.Windows.SystemParameters.WorkArea.Height;
this.WindowState = WindowState.Maximized;
}
}
The restoring to the normal state works fine. However when I want to maximize, it maximizes the window with a small margin on the right and bottom of the screen. Clicking maximize again fixes this somehow. How do I fix this to maximize at the first click...?
Take away the Height and Width properties you have set in XAML for your window
Try to use just
this.WindowState = WindowState.Maximized;
Perhaps code, goes before messing Windows API action.
Sorry, my mistake.
Then you should use Windows API to raise Maximize event.
Try this code:
[DllImport("user32.dll")]
public static extern int SendMessage(
int hWnd, // handle to destination window
uint Msg, // message
long wParam, // first message parameter
long lParam // second message parameter
);
public const int WM_SIZE = 0x0005;
public const int SIZE_MAXIMIZED = 2;
And in your click event:
SendMessage(this.Handle, WM_SIZE, SIZE_MAXIMIZED, 0);