我希望用户在右下角调整无边框窗口的大小,就像我可以调整组合框控件的自动完成窗口一样。
我无法找到以这种方式配置表单的属性。
也许有人可以帮我解决这个问题。
可在此处找到图片:
答案 0 :(得分:32)
这是与Franci的解释相对应的代码,我正在编写它,但他同时回答所以如果这个代码适合你的需要,那么就可以对他的解释进行投票。
protected override void WndProc(ref Message m) {
const int wmNcHitTest = 0x84;
const int htBottomLeft = 16;
const int htBottomRight = 17;
if (m.Msg == wmNcHitTest) {
int x = (int) (m.LParam.ToInt64() & 0xFFFF);
int y = (int) ((m.LParam.ToInt64() & 0xFFFF0000) >> 16);
Point pt = PointToClient(new Point(x, y));
Size clientSize = ClientSize;
if (pt.X >= clientSize.Width - 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16) {
m.Result = (IntPtr) (IsMirrored ? htBottomLeft : htBottomRight);
return;
}
}
base.WndProc(ref m);
}
编辑:要编写抓手,您可以初始化new VisualStyleRenderer(VisualStyleElement.Status.Gripper.Normal)
并使用其PaintBackground()
方法。
答案 1 :(得分:19)
非常感谢您发布这个精彩的样本和解释。我添加了一些其他人可能感兴趣的附加内容。这里的一些代码来自其他stackoverflow发布,但是能够在一个代码块中看到它可能对其他人有帮助。 我希望能够在所有边框上调整表单大小,而不仅仅是右下角。我也希望能够拖动表单。最后,我想要一个阴影。
//***********************************************************
//This gives us the ability to resize the borderless from any borders instead of just the lower right corner
protected override void WndProc(ref Message m)
{
const int wmNcHitTest = 0x84;
const int htLeft = 10;
const int htRight = 11;
const int htTop = 12;
const int htTopLeft = 13;
const int htTopRight = 14;
const int htBottom = 15;
const int htBottomLeft = 16;
const int htBottomRight = 17;
if (m.Msg == wmNcHitTest)
{
int x = (int)(m.LParam.ToInt64() & 0xFFFF);
int y = (int)((m.LParam.ToInt64() & 0xFFFF0000) >> 16);
Point pt = PointToClient(new Point(x, y));
Size clientSize = ClientSize;
///allow resize on the lower right corner
if (pt.X >= clientSize.Width - 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(IsMirrored ? htBottomLeft : htBottomRight);
return;
}
///allow resize on the lower left corner
if (pt.X <= 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(IsMirrored ? htBottomRight : htBottomLeft);
return;
}
///allow resize on the upper right corner
if (pt.X <= 16 && pt.Y <= 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(IsMirrored ? htTopRight : htTopLeft);
return;
}
///allow resize on the upper left corner
if (pt.X >= clientSize.Width - 16 && pt.Y <= 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(IsMirrored ? htTopLeft : htTopRight);
return;
}
///allow resize on the top border
if (pt.Y <= 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(htTop);
return;
}
///allow resize on the bottom border
if (pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(htBottom);
return;
}
///allow resize on the left border
if (pt.X <= 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(htLeft);
return;
}
///allow resize on the right border
if (pt.X >= clientSize.Width - 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(htRight);
return;
}
}
base.WndProc(ref m);
}
//***********************************************************
//***********************************************************
//This gives us the ability to drag the borderless form to a new location
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();
private void YOURCONTROL_MouseDown(object sender, MouseEventArgs e)
{
//ctrl-leftclick anywhere on the control to drag the form to a new location
if (e.Button == MouseButtons.Left && Control.ModifierKeys == Keys.Control)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
}
//***********************************************************
//***********************************************************
//This gives us the drop shadow behind the borderless form
private const int CS_DROPSHADOW = 0x20000;
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ClassStyle |= CS_DROPSHADOW;
return cp;
}
}
//***********************************************************
答案 2 :(得分:13)
实现此目的的正确方法是在表单中添加消息proc处理程序(例如通过覆盖Form.WndProc
)并处理WM_NCHITTEST
消息。 (您可以在PInvoke.net上找到该消息的C#定义)特别是,当您收到消息时,计算命中测试是否针对您指定用于调整大小的区域中的某个点,如果是,则返回HTBOTTOMRIGHT。默认窗口proc将为您完成剩下的工作,因为它会假设用户已经点击了窗口边框的右下角,即使您的窗口没有边框。
这个方法需要一小部分Win32互操作,但它会使你的调整大小看起来像任何其他窗口调整大小。
简单的方法是按照@benPearce的说法进行操作,并在角落放置一个面板,并使用Width / Height调整表单大小。它会起作用,但调整大小并不顺利,尤其是在Vista和Win7 Basic上,在标准移动和调整大小时禁用完全重绘,同时尝试重绘每一步。
更新:在这两种方法中,您还必须弄清楚如何绘制抓手。例如,您可以放置标准夹具的位图。虽然,鉴于您的表单没有标题和边框,因此您不一定会遇到标准的Windows视觉效果,您可能会选择使用更加时髦的东西。
更新2 :如果您有一个覆盖整个窗口的控件,它将使用表单鼠标消息。你必须以某种方式剪切你想要用来调整控件的大小。您有几种方法可以解决这个问题:
我建议选择最简单的选项1。选项3是最复杂的,需要有关鼠标输入如何在Windows中工作的详细信息,所以我不推荐它。选项2是选项1的一个很好的替代方案,但你必须尝试看看ListView控件如何对其被调整的区域做出反应。
答案 3 :(得分:2)
使用面板的MouseDown和MouseMove事件在角落放置面板或其他控件,适当调整表单大小。
在MouseDown中,我会记录坐标,然后在MouseMove中,您可以计算与原始位置的差异,以调整表格大小。