RaUI/Source/MyDb/SysFuns/SuperForm.cs

163 lines
6.2 KiB
C#
Raw Normal View History

2020-11-28 07:03:28 +00:00
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using WinAPI;
2020-11-28 07:03:28 +00:00
namespace ryCommon
{
/// <summary>
/// 窗体操作类
/// </summary>
public class SuperForm
{
private Form form;
private IntPtr handle = IntPtr.Zero;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="_form"></param>
public SuperForm(Form _form)
{
form = _form;
handle = form.Handle;
wndProcDelegate = new WndProcDelegate(WndProc);
oldWndFunc = SetWindowLong(handle, MyDb.RyWin32.GWL_WNDPROC, wndProcDelegate);
}
/// <summary>
/// 析构
/// </summary>
~SuperForm()
{
User32.SetWindowLong(handle, MyDb.RyWin32.GWL_WNDPROC, oldWndFunc);
2020-11-28 07:03:28 +00:00
}
private bool isMouseDown = false;
private Point FormLocation; //form的location
private Point mouseOffset; //鼠标的按下位置
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 = 0x10;
const int HTBOTTOMRIGHT = 17;
private readonly IntPtr oldWndFunc;
private delegate IntPtr WndProcDelegate(IntPtr hwnd, int Msg, IntPtr wParam, IntPtr lParam);
private readonly WndProcDelegate wndProcDelegate;
[DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, WndProcDelegate wndProcDelegate);
/// <summary>
/// 设置让窗体支持移动
/// </summary>
public void SetFormMove(Control ctl)
{
ctl.MouseMove += new MouseEventHandler((object o, MouseEventArgs e) =>
{
try
{
int _x = 0;
int _y = 0;
if (isMouseDown)
{
Point pt = Control.MousePosition;
_x = mouseOffset.X - pt.X;
_y = mouseOffset.Y - pt.Y;
form.Location = new Point(FormLocation.X - _x, FormLocation.Y - _y);
}
}
catch (Exception) { }
});
ctl.MouseDown+=new MouseEventHandler((object o, MouseEventArgs e) =>
{
try
{
if (e.Button == MouseButtons.Left)
{
isMouseDown = true;
FormLocation = form.Location;
mouseOffset = Control.MousePosition;
}
}
catch (Exception) { }
});
ctl.MouseUp+=new MouseEventHandler((object o, MouseEventArgs e) =>
{
isMouseDown = false;
});
}
/// <summary>
/// 是否允许可调节大小
/// </summary>
public bool Resizable { get; set; }
/// <summary>
/// 可调节窗体大小的宽度
/// </summary>
public int ResizeBorderWidth { get; set; } = 5;
/// <summary>
///
/// </summary>
/// <param name="m"></param>
protected virtual void WndProc(ref Message m)
{
m.Result = User32.CallWindowProc(oldWndFunc, m.HWnd, m.Msg, m.WParam, m.LParam);
2020-11-28 07:03:28 +00:00
switch (m.Msg)
{
case 0x0084:
//base.WndProc(ref m);
if (!Resizable) { return; }
Point vPoint = new Point((int)m.LParam & 0xFFFF,
(int)m.LParam >> 16 & 0xFFFF);
vPoint =form.PointToClient(vPoint);
if (vPoint.X <= ResizeBorderWidth)
if (vPoint.Y <= ResizeBorderWidth)
m.Result = (IntPtr)HTTOPLEFT;
else if (vPoint.Y >= form.ClientSize.Height - ResizeBorderWidth)
m.Result = (IntPtr)HTBOTTOMLEFT;
else m.Result = (IntPtr)HTLEFT;
else if (vPoint.X >= form.ClientSize.Width - ResizeBorderWidth)
if (vPoint.Y <= ResizeBorderWidth)
m.Result = (IntPtr)HTTOPRIGHT;
else if (vPoint.Y >= form.ClientSize.Height - ResizeBorderWidth)
m.Result = (IntPtr)HTBOTTOMRIGHT;
else m.Result = (IntPtr)HTRIGHT;
else if (vPoint.Y <= ResizeBorderWidth)
m.Result = (IntPtr)HTTOP;
else if (vPoint.Y >= form.ClientSize.Height - ResizeBorderWidth)
m.Result = (IntPtr)HTBOTTOM;
break;
case 0x0201://鼠标左键按下的消息
//m.Msg = 0x00A1;//更改消息为非客户区按下鼠标
//m.LParam = IntPtr.Zero;//默认值
//m.WParam = new IntPtr(2);//鼠标放在标题栏内
//以下做了一些修正,确保放大缩小按钮区域可以正常使用
Point point = Control.MousePosition;
point = form.PointToClient(point);
if (point.X < form.Width - 100 && point.Y < 30)
{
m.Msg = 0x00A1;//更改消息为非客户区按下鼠标
m.LParam = IntPtr.Zero;//默认值
m.WParam = new IntPtr(2);//鼠标放在标题栏内
}
//base.WndProc(ref m);
break;
default:
//base.WndProc(ref m);
break;
}
}
private IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
{
System.Windows.Forms.Message m = System.Windows.Forms.Message.Create(hWnd, msg, wParam, lParam);
WndProc(ref m);
return m.Result;
}
}
}