我想用Python为我的项目做一个简单的C#(VS)弹出窗口,由于美观,我想使用VS。
(请记住我是C#新手)
我做了什么
所以我创建了这个项目,将主窗体的Border
属性设置为None
,并添加了我称为titleBarPanel
的Panel对象。我已经启用了通过窗体的底部和侧面调整窗体大小,并启用了通过titleBarPanel
拖动窗体。
我想要的
我想简单地使窗体能够通过顶部面板对象调整大小。
我尝试了什么
我已经搜索过stackoverflow asd以及在youtube上,但我找不到任何东西。我也试着问ChatGPT,但他不是那么聪明,在这种情况下,无法解决我的问题。
代码由于代码量小,我将给予整个代码。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace UI_Variables_Prompt
{
public partial class Form1 : Form
{
private const int WM_NCHITTEST = 0x84;
private const int HTCLIENT = 0x1;
private const int HTCAPTION = 0x2;
private const int HTBOTTOMLEFT = 0x10;
private const int HTBOTTOMRIGHT = 0x11;
private const int HTLEFT = 0xa;
private const int HTRIGHT = 0xb;
private const int HTBOTTOM = 0xf;
private const int HTTOP = 0xc;
private const int HTTOPLEFT = 0xd;
private const int HTTOPRIGHT = 0xe;
private bool isDragging = false;
private Point dragStart;
private bool isResizing = false;
private int resizeDir = 0;
public Form1()
{
InitializeComponent();
titleBarPanel.MouseDown += new MouseEventHandler(titleBarPanel_MouseDown);
titleBarPanel.MouseMove += new MouseEventHandler(titleBarPanel_MouseMove);
titleBarPanel.MouseUp += new MouseEventHandler(titleBarPanel_MouseUp);
this.MouseDown += new MouseEventHandler(Form1_MouseDown);
this.MouseMove += new MouseEventHandler(Form1_MouseMove);
this.MouseUp += new MouseEventHandler(Form1_MouseUp);
}
protected override void WndProc(ref Message m)
{
const int WM_NCHITTEST = 0x0084;
const int HTCLIENT = 1;
const int HTCAPTION = 2;
const int HTTOP = 12;
const int HTLEFT = 10;
const int HTRIGHT = 11;
const int HTBOTTOM = 15;
const int HTTOPLEFT = 13;
const int HTTOPRIGHT = 14;
const int HTBOTTOMLEFT = 16;
const int HTBOTTOMRIGHT = 17;
if (m.Msg == WM_NCHITTEST)
{
base.WndProc(ref m);
if (m.Result == (IntPtr)HTCLIENT)
{
Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
pos = this.PointToClient(pos);
if (pos.Y < 10)
{
if (pos.X < 10)
m.Result = (IntPtr)HTTOPLEFT;
else if (pos.X > this.ClientSize.Width - 10)
m.Result = (IntPtr)HTTOPRIGHT;
else
m.Result = (IntPtr)HTTOP;
}
else if (pos.Y > this.ClientSize.Height - 10)
{
if (pos.X < 10)
m.Result = (IntPtr)HTBOTTOMLEFT;
else if (pos.X > this.ClientSize.Width - 10)
m.Result = (IntPtr)HTBOTTOMRIGHT;
else
m.Result = (IntPtr)HTBOTTOM;
}
else if (pos.X < 10)
m.Result = (IntPtr)HTLEFT;
else if (pos.X > this.ClientSize.Width - 10)
m.Result = (IntPtr)HTRIGHT;
}
else if (m.Result == (IntPtr)HTCAPTION)
{
m.Result = (IntPtr)HTCLIENT;
}
}
else
{
base.WndProc(ref m);
}
}
private int ResizeDirection(Point cursorPos, Rectangle formBounds)
{
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 (cursorPos.Y < formBounds.Top + 10)
{
if (cursorPos.X < formBounds.Left + 10)
return HTTOPLEFT;
else if (cursorPos.X > formBounds.Right - 10)
return HTTOPRIGHT;
else
return HTTOP;
}
else if (cursorPos.Y > formBounds.Bottom - 10)
{
if (cursorPos.X < formBounds.Left + 10)
return HTBOTTOMLEFT;
else if (cursorPos.X > formBounds.Right - 10)
return HTBOTTOMRIGHT;
else
return HTBOTTOM;
}
else if (cursorPos.X < formBounds.Left + 10)
return HTLEFT;
else if (cursorPos.X > formBounds.Right - 10)
return HTRIGHT;
return 0;
}
private void titleBarPanel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDragging = true;
dragStart = new Point(e.X, e.Y);
}
}
private void titleBarPanel_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
Point p = PointToScreen(e.Location);
Location = new Point(p.X - this.dragStart.X, p.Y - this.dragStart.Y);
}
else if (isResizing)
{
switch (resizeDir)
{
case HTTOP:
this.Height = Math.Max(this.MinimumSize.Height, this.dragStart.Y - e.Y + this.Height);
break;
case HTTOPLEFT:
this.Width = Math.Max(this.MinimumSize.Width, this.dragStart.X - e.X + this.Width);
this.Height = Math.Max(this.MinimumSize.Height, this.dragStart.Y - e.Y + this.Height);
this.Left = Math.Min(this.Left + e.X - this.dragStart.X, this.Left + this.Width - this.MinimumSize.Width);
break;
case HTTOPRIGHT:
this.Width = Math.Max(this.MinimumSize.Width, e.X - this.dragStart.X + this.Width);
this.Height = Math.Max(this.MinimumSize.Height, this.dragStart.Y - e.Y + this.Height);
break;
case HTLEFT:
this.Width = Math.Max(this.MinimumSize.Width, this.dragStart.X - e.X + this.Width);
this.Left = Math.Min(this.Left + e.X - this.dragStart.X, this.Left + this.Width - this.MinimumSize.Width);
break;
case HTRIGHT:
this.Width = Math.Max(this.MinimumSize.Width, e.X - this.dragStart.X + this.Width);
break;
case HTBOTTOM:
this.Height = Math.Max(this.MinimumSize.Height, e.Y - this.dragStart.Y + this.Height);
break;
case HTBOTTOMLEFT:
this.Width = Math.Max(this.MinimumSize.Width, this.dragStart.X - e.X + this.Width);
this.Height = Math.Max(this.MinimumSize.Height, e.Y - this.dragStart.Y + this.Height);
this.Left = Math.Min(this.Left + e.X - this.dragStart.X, this.Left + this.Width - this.MinimumSize.Width);
break;
case HTBOTTOMRIGHT:
this.Width = Math.Max(this.MinimumSize.Width, e.X - this.dragStart.X + this.Width);
this.Height = Math.Max(this.MinimumSize.Height, e.Y - this.dragStart.Y + this.Height);
break;
}
}
}
private void titleBarPanel_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
isResizing = false;
resizeDir = 0;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
isResizing = false;
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && !isDragging)
{
this.dragStart = new Point(e.X, e.Y);
isResizing = true;
resizeDir = ResizeDirection(e.Location, this.Bounds);
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (isResizing)
{
int cursorType = 0;
switch (resizeDir)
{
case HTTOP:
case HTBOTTOM:
cursorType = Cursors.SizeNS.Handle.ToInt32();
break;
case HTLEFT:
case HTRIGHT:
cursorType = Cursors.SizeWE.Handle.ToInt32();
break;
case HTTOPLEFT:
case HTBOTTOMRIGHT:
cursorType = Cursors.SizeNWSE.Handle.ToInt32();
break;
case HTTOPRIGHT:
case HTBOTTOMLEFT:
cursorType = Cursors.SizeNESW.Handle.ToInt32();
break;
}
Cursor.Current = new Cursor(new IntPtr(cursorType));
}
else
{
Cursor.Current = Cursors.Default;
}
}
}
}
非常感谢你提前!
3条答案
按热度按时间b4lqfgs41#
标题栏
Panel
是这里的问题,它接收鼠标输入,而不是From
。因此,窗体的移动和调整大小例程在面板区域中不起作用,这使得您复制几乎相同的代码来单独处理面板的鼠标输入。好吧,你不需要这样做,一个简单的替代方法是子类化面板的本机窗口,使其对鼠标输入透明,并将它们传递给父控件进行处理。对面板的非点击子控件(如果有的话)也这样做(即显示图标的
PictureBox
和显示标题/标题的Label
...)。要子类化,将
Control
传递给NativeWindow
的派生类,分配其句柄并重写WndProc
方法以捕获WM_NCHITTEST
消息,并将HTTRANSPARENT
指针分配给Result
属性。这里的例子是一个无边框的
Form
,它包含一个停靠在顶部的Panel
。Panel
本身托管一个显示图像的PictureBox
和一个显示标题的Label
。备注
Form
的任务栏图标时最小化和还原该Form
,必须重写CreateParams
属性以添加WS_MINIMIZEBOX
样式。SetMaxSize
方法来设置窗体的MaximumSize
是为了在最大化窗体时不覆盖任务栏区域。Location
和Size
)来避免重新定位和调整Form
的大小。这样做会在您移动或调整Form
的大小时发送连续的重绘请求。最好使用本机方法,如图所示,或者通过p/invoke相关函数来“吞下”一些重绘调用者。tcomlyy62#
我测试了你的代码,应该是拖动和调整大小状态处理得不好,拖动太滞后了。
我重新写了代码,大家可以参考一下,之前需要将面板的dock属性调整为Top,拖动时请慢一点,否则无法分辨是移动还是调整大小,如果想修复这个bug,可以在panel1_MouseMove中将所有-10改为-20或更大,但这样做不会很美观。
bhmjp9jg3#
据我所知,您希望在
titleBarPanel
上拖动鼠标并调整窗体的大小(而不是正常的 * 移动 * 窗体的行为)。为了实现这一点,请考虑实现IMessageFilter来挂钩鼠标事件,而不管单击的焦点是哪个控件(例如titleBarPanel
)。现在您需要做的就是:titleBarPanel
矩形中Size
和Location
Size
。上面的代码片段地址:
我想实现的-我想简单地使窗体能够通过顶部面板对象调整大小。
我用来测试这个答案的完整代码是在标题栏上放置调整大小-移动图标。