Wrong size when restoring form that has no WS_DLGFRAME style flag set

M

Martin.Hallerdal

Hello,
I have a form that I don't want to display the title bar for. The way
I've implemented this is to to remove the WS_DLGFRAME style flag.
However, when this form is minimized and then restored, it is restored
to the wrong size. The height of the form increases 19 pixels (height
of a title bar on my computer) with every minimize/restore.

Can someone shead any light on this?

I've attached an example program. To reproduce, just create a standard
windows forms project, paste the code, and add a button to the form
whose click handler you connect to the button1_Click method.

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

// Attach this to a button click event for a button on the form
private void button1_Click(object sender, EventArgs e)
{
if (IsStyleFlagSet(this.Handle, WS_DLGFRAME))
{
// Remove caption bar
SetStyleFlag(this.Handle, WS_DLGFRAME , false);
// Repaint NC area
SetWindowPos(this.Handle, IntPtr.Zero, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER);
}

// Get my current client size
Size prevSize = this.ClientSize;

// Minimize and restore me
this.WindowState = FormWindowState.Minimized;
this.WindowState = FormWindowState.Normal;

// Get my client size now
Size currSize = this.ClientSize;

if (currSize == prevSize)
MessageBox.Show("Size was equal! :) ");
else
MessageBox.Show(string.Format("Size was not equal! :-(. Before:
{0}, After: {1}", prevSize, currSize));

}


// Style constants
internal const int GWL_STYLE = (-16);

internal const int WS_DLGFRAME = 0x00400000;
internal const int WS_BORDER = 0x00800000;
internal const int WS_CAPTION = WS_BORDER | WS_DLGFRAME;

// SetWindowPos Flags
internal const int SWP_NOSIZE = 0x0001;
internal const int SWP_NOMOVE = 0x0002;
internal const int SWP_NOZORDER = 0x0004;
internal const int SWP_NOACTIVATE = 0x0010;
internal const int SWP_FRAMECHANGED = 0x0020;
internal const int SWP_NOOWNERZORDER = 0x0200;

[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int
dwNewLong);

[DllImport("user32.dll", SetLastError = true)]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32")]
internal static extern int SetWindowPos(IntPtr hWnd, IntPtr
hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

internal static bool IsStyleFlagSet(IntPtr handle, int styleFlag)
{
return (GetWindowLong(handle, GWL_STYLE) & styleFlag) == styleFlag;
}

internal static void SetStyleFlag(IntPtr handle, int dwNewLong, bool
set)
{
int style = GetWindowLong(handle, GWL_STYLE);

if (set)
style |= dwNewLong;
else
style &= ~dwNewLong;

SetWindowLong(handle, GWL_STYLE, style);
}
}
 
N

Nick Hounsome

This is a .NET newsgroup.
Why are you using all this stuff that instead of .NET and then posting here
when it doesn't work?

Use the FormBorderStyle property to remove the frame and remove the
SetWindowPos as well and it will work fine.

Hello,
I have a form that I don't want to display the title bar for. The way
I've implemented this is to to remove the WS_DLGFRAME style flag.
However, when this form is minimized and then restored, it is restored
to the wrong size. The height of the form increases 19 pixels (height
of a title bar on my computer) with every minimize/restore.

Can someone shead any light on this?

I've attached an example program. To reproduce, just create a standard
windows forms project, paste the code, and add a button to the form
whose click handler you connect to the button1_Click method.

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

// Attach this to a button click event for a button on the form
private void button1_Click(object sender, EventArgs e)
{
if (IsStyleFlagSet(this.Handle, WS_DLGFRAME))
{
// Remove caption bar
SetStyleFlag(this.Handle, WS_DLGFRAME , false);
// Repaint NC area
SetWindowPos(this.Handle, IntPtr.Zero, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER);
}

// Get my current client size
Size prevSize = this.ClientSize;

// Minimize and restore me
this.WindowState = FormWindowState.Minimized;
this.WindowState = FormWindowState.Normal;

// Get my client size now
Size currSize = this.ClientSize;

if (currSize == prevSize)
MessageBox.Show("Size was equal! :) ");
else
MessageBox.Show(string.Format("Size was not equal! :-(. Before:
{0}, After: {1}", prevSize, currSize));

}


// Style constants
internal const int GWL_STYLE = (-16);

internal const int WS_DLGFRAME = 0x00400000;
internal const int WS_BORDER = 0x00800000;
internal const int WS_CAPTION = WS_BORDER | WS_DLGFRAME;

// SetWindowPos Flags
internal const int SWP_NOSIZE = 0x0001;
internal const int SWP_NOMOVE = 0x0002;
internal const int SWP_NOZORDER = 0x0004;
internal const int SWP_NOACTIVATE = 0x0010;
internal const int SWP_FRAMECHANGED = 0x0020;
internal const int SWP_NOOWNERZORDER = 0x0200;

[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int
dwNewLong);

[DllImport("user32.dll", SetLastError = true)]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32")]
internal static extern int SetWindowPos(IntPtr hWnd, IntPtr
hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

internal static bool IsStyleFlagSet(IntPtr handle, int styleFlag)
{
return (GetWindowLong(handle, GWL_STYLE) & styleFlag) == styleFlag;
}

internal static void SetStyleFlag(IntPtr handle, int dwNewLong, bool
set)
{
int style = GetWindowLong(handle, GWL_STYLE);

if (set)
style |= dwNewLong;
else
style &= ~dwNewLong;

SetWindowLong(handle, GWL_STYLE, style);
}
}
 
M

Martin

Nick,
although I can remove the title bar and the border with a
FormBorderStyle.None, I still want to keep my border. Going with
borderstyle None removes it, so that won't fly.

As to your first remark, I'm happy to hear any suggestions on how this
may be done in pure .Net, without Win23 interop. And the place where
I'm most likely to get these suggestions is in this newsgroup.
 
N

Nick Hounsome

Martin said:
Nick,
although I can remove the title bar and the border with a
FormBorderStyle.None, I still want to keep my border. Going with
borderstyle None removes it, so that won't fly.

So you want a border like a normal window but with the top like the bottom -
without text and boxes?

I just discovered that turning off all the boxes and setting the Text to ""
will get rid of the title part although strangely the border is in the form
background color and also you don't get any window menu so I doubt that that
will do the job.

What exactly do you need the border for?
 
M

Martin

Yes, that was my previous approach, setting text to "" and ControlBox
to false. However, that had a, for me, bad side effect. It removes the
form from the Application.OpenForms collection (search for "Strange
behaviour in Application.OpenForms" in Google Groups)

I need the border because the window looks ugly without one, I may have
to end up drawing it myself though if I can't find a solution to this.

Thanks for your time.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top