blah blah blah is here! blah blah » Close

up0down
link

Hi all,

I have this control, derived from Panel, called SizablePanel. I've created some properties to allow me to modify whether or not the user will be able to resize the top, bottom, left or right edge. The code for this looks like this:

public class SizablePanel : Panel
{
...
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_SIZING)
{
int wmsz = m.WParam.ToInt32();
RECT rect = new RECT();
Marshal.PtrToStructure(m.LParam, rect);
switch (wmsz)
{
case WMSZ_BOTTOMLEFT:
if (!UserCanResizeLeft)
rect.Left = rect.Right - this.Width;
if (!UserCanResizeBottom)
rect.Bottom = rect.Top + this.Height;
if (MinHeight > (rect.Bottom - rect.Top))
rect.Bottom = rect.Top + MinHeight;
if (MinWidth > (rect.Right - rect.Left))
rect.Left = rect.Right - this.Width;
break;
case WMSZ_BOTTOMRIGHT:
if (!UserCanResizeRight)
rect.Right = rect.Left + this.Width;
if (!UserCanResizeBottom)
rect.Bottom = rect.Top + this.Height;
if (MinHeight > (rect.Bottom - rect.Top))
rect.Bottom = rect.Top + MinHeight;
if (MinWidth > (rect.Right - rect.Left))
rect.Right = rect.Left + this.Width;
break;
case WMSZ_LEFT:
if (!UserCanResizeLeft)
rect.Left = rect.Right - this.Width;
if (MinWidth > (rect.Right - rect.Left))
rect.Left = rect.Right - this.Width;
break;
case WMSZ_RIGHT:
if (!UserCanResizeRight)
rect.Right = rect.Left + this.Width;
if (MinWidth > (rect.Right - rect.Left))
rect.Right = rect.Left + this.Width;
break;
case WMSZ_TOPLEFT:
if (!UserCanResizeLeft)
rect.Left = rect.Right - this.Width;
if (!UserCanResizeTop)
rect.Top = rect.Bottom - this.Height;
if (MinHeight > (rect.Bottom - rect.Top))
rect.Top = rect.Bottom - MinHeight;
if (MinWidth > (rect.Right - rect.Left))
rect.Left = rect.Right - this.Width;
break;
case WMSZ_TOPRIGHT:
if (!UserCanResizeRight)
rect.Right = rect.Left + this.Width;
if (!UserCanResizeTop)
rect.Top = rect.Bottom - this.Height;
if (MinHeight > (rect.Bottom - rect.Top))
rect.Top = rect.Bottom - MinHeight;
if (MinWidth > (rect.Right - rect.Left))
rect.Right = rect.Left + this.Width;
break;
case WMSZ_BOTTOM:
if (!UserCanResizeBottom)
rect.Bottom = rect.Top + this.Height;
if (MinHeight > (rect.Bottom - rect.Top))
rect.Bottom = rect.Top + MinHeight;
break;
case WMSZ_TOP:
if (!UserCanResizeTop)
rect.Top = rect.Bottom - this.Height;
if (MinHeight > (rect.Bottom - rect.Top))
rect.Top = rect.Bottom - MinHeight;
break;
}
if (this.Height < min_Height)
this.Height = min_Height;
Marshal.StructureToPtr(rect, m.LParam, true);
}
base.WndProc(ref m);
}

}


This works most of the time, but if I change the Anchor property at design time, I can't resize this thing in runtime. Does anyone have any insight as to what might be causing this?

last answered one year ago

1 answers

up0down
link

As you're calling base.WndProc(), I'd guess that WM_SIZING is bubbling up to the code which underlies the Anchor property (in the Control class) and the latter is resetting the Left,Top etc properties if the Anchor property contains anything other than the default setting.

If you omit base.WndProc(), then the Anchor property probably won't work at all. So I think that you'll need to override the Anchor property in your SizablePanel class if you can figure out what adjustments you'll need for its various settings.

EDIT - see comments below

I'd try something simple such as the following:

public class SizablePanel : Panel
{
...
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_SIZING)
{
int wmsz = m.WParam.ToInt32();
RECT rect = new RECT();
Marshal.PtrToStructure(m.LParam, rect);
switch (wmsz)
{
case WMSZ_BOTTOMLEFT:
if (!UserCanResizeLeft)
rect.Left = rect.Right - this.Width;
if (!UserCanResizeBottom)
rect.Bottom = rect.Top + this.Height;
if (MinHeight > (rect.Bottom - rect.Top))
rect.Bottom = rect.Top + MinHeight;
if (MinWidth > (rect.Right - rect.Left))
rect.Left = rect.Right - this.Width;
break;
case WMSZ_BOTTOMRIGHT:
if (!UserCanResizeRight)
rect.Right = rect.Left + this.Width;
if (!UserCanResizeBottom)
rect.Bottom = rect.Top + this.Height;
if (MinHeight > (rect.Bottom - rect.Top))
rect.Bottom = rect.Top + MinHeight;
if (MinWidth > (rect.Right - rect.Left))
rect.Right = rect.Left + this.Width;
break;
case WMSZ_LEFT:
if (!UserCanResizeLeft)
rect.Left = rect.Right - this.Width;
if (MinWidth > (rect.Right - rect.Left))
rect.Left = rect.Right - this.Width;
break;
case WMSZ_RIGHT:
if (!UserCanResizeRight)
rect.Right = rect.Left + this.Width;
if (MinWidth > (rect.Right - rect.Left))
rect.Right = rect.Left + this.Width;
break;
case WMSZ_TOPLEFT:
if (!UserCanResizeLeft)
rect.Left = rect.Right - this.Width;
if (!UserCanResizeTop)
rect.Top = rect.Bottom - this.Height;
if (MinHeight > (rect.Bottom - rect.Top))
rect.Top = rect.Bottom - MinHeight;
if (MinWidth > (rect.Right - rect.Left))
rect.Left = rect.Right - this.Width;
break;
case WMSZ_TOPRIGHT:
if (!UserCanResizeRight)
rect.Right = rect.Left + this.Width;
if (!UserCanResizeTop)
rect.Top = rect.Bottom - this.Height;
if (MinHeight > (rect.Bottom - rect.Top))
rect.Top = rect.Bottom - MinHeight;
if (MinWidth > (rect.Right - rect.Left))
rect.Right = rect.Left + this.Width;
break;
case WMSZ_BOTTOM:
if (!UserCanResizeBottom)
rect.Bottom = rect.Top + this.Height;
if (MinHeight > (rect.Bottom - rect.Top))
rect.Bottom = rect.Top + MinHeight;
break;
case WMSZ_TOP:
if (!UserCanResizeTop)
rect.Top = rect.Bottom - this.Height;
if (MinHeight > (rect.Bottom - rect.Top))
rect.Top = rect.Bottom - MinHeight;
break;
}
if (this.Height < min_Height)
this.Height = min_Height;
Marshal.StructureToPtr(rect, m.LParam, true);
base.WndProc(ref m);
if (this.Width < min_Width) this.Width = min_Width;
if (this.Height < min_Height) this.Height = min_Height;
}
else
{
base.WndProc(ref m);
}
}
}

foamy
2499

I had a feeling you'd say something like that :-P Really all I need is for the MinimumWidth and -Height to be kept, event when Anchor is used. So it should "override" the other properties for user resizing. Any pointers to achieving this?

vulpes
17279

I can't find any examples of overriding the Anchor property though, unlike the Height and Width properties, it is virtual and so can be overridden. However, if you just want to ensure that the minimum width and height are maintained, then a better idea may be to reset them if necessary following the call to base.WndProc. Please see my edit.

Feedback