添加项目文件。

This commit is contained in:
Administrator
2026-08-06 09:23:30 +08:00
parent 771e23e00a
commit 4660ceee70
604 changed files with 138380 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+65
View File
@@ -0,0 +1,65 @@
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
namespace JinYuan.ControlLib.UCHelper
{
/// <summary>
/// 缩放控件基类
/// </summary>
[Description("缩放控件基类")]
[ToolboxItem(true)]
public abstract class DpiControl : Control, IDpiControl
{
#region 新增属性
private float scaleDpi = 1.0f;
/// <summary>
/// 控件当前缩放Dpi
/// </summary>
[Description("控件当前缩放Dpi")]
[Browsable(false)]
[Localizable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual float ScaleDpi
{
get { return this.scaleDpi; }
set
{
if (value <= 0)
return;
this.scaleDpi = value;
this.OnScaleDpiChangedInitialize();
}
}
#endregion
public DpiControl()
{
}
#region 重写
protected override void CreateHandle()
{
base.CreateHandle();
this.ScaleDpi = DpiHelper.GetControlDpi(this);
}
#endregion
#region 要实现
/// <summary>
/// 控件DPI更改后重新初始化控件Rectangle信息
/// </summary>
protected abstract void OnScaleDpiChangedInitialize();
#endregion
}
}
+53
View File
@@ -0,0 +1,53 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace JinYuan.ControlLib.UCHelper
{
/// <summary>
/// 系统缩放比例
/// </summary>
public class DpiHelper
{
#region 公开方法
/// <summary>
/// 获取控件对应的系统缩放比例
/// </summary>
/// <param name="control"></param>
/// <returns></returns>
public static float GetControlDpi(Control control)
{
IntPtr hDC = IntPtr.Zero;
Graphics g = null;
ControlHelper.GetWindowClientGraphics(control.Handle, out g, out hDC);
float dpi = g.DpiX / 96f;
g.Dispose();
NativeMethods.ReleaseDC(control.Handle, hDC);
return dpi;
}
/// <summary>
/// 获取控件对应的系统缩放比例
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
public static float GetControlDpi(IntPtr hWnd)
{
IntPtr hDC = IntPtr.Zero;
Graphics g = null;
ControlHelper.GetWindowClientGraphics(hWnd, out g, out hDC);
float dpi = g.DpiX / 96f;
g.Dispose();
NativeMethods.ReleaseDC(hWnd, hDC);
return dpi;
}
#endregion
}
}
+474
View File
@@ -0,0 +1,474 @@
// ***********************************************************************
// Assembly : JinYuan.ControlLib
// Created : 08-08-2019
//
// ***********************************************************************
// <copyright file="Ext.cs">
// Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com
// </copyright>
//
// Blog: https://www.cnblogs.com/bfyx
// GitHub:https://github.com/kwwwvagaa/NetWinformControl
// gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
//
// If you use this code, please keep this note.
// ***********************************************************************
using System;
using System.Reflection;
using System.Text;
namespace JinYuan.ControlLib.UCHelper
{
/// <summary>
/// Class Ext.
/// </summary>
public static partial class Ext
{
/// <summary>
/// Clones the model.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="classObject">The class object.</param>
/// <returns>T.</returns>
public static T CloneModel<T>(this T classObject) where T : class
{
T result;
if (classObject == null)
{
result = default(T);
}
else
{
object obj = Activator.CreateInstance(typeof(T));
PropertyInfo[] properties = typeof(T).GetProperties();
PropertyInfo[] array = properties;
for (int i = 0; i < array.Length; i++)
{
PropertyInfo propertyInfo = array[i];
if (propertyInfo.CanWrite)
propertyInfo.SetValue(obj, propertyInfo.GetValue(classObject, null), null);
}
result = (obj as T);
}
return result;
}
/// <summary>
/// ASCII编码的数组转换为英文字符串
/// </summary>
/// <param name="s">字符串</param>
/// <returns>结果</returns>
public static string ToEnString(this byte[] s)
{
return ToEncodeString(s, Encoding.ASCII).Trim('\0').Trim();
}
/// <summary>
/// 数组按指定编码转换为字符串
/// </summary>
/// <param name="dealBytes">数组</param>
/// <param name="encode">编码</param>
/// <returns>结果</returns>
public static string ToEncodeString(this byte[] dealBytes, Encoding encode)
{
return encode.GetString(dealBytes);
}
#region 转换为base64字符串
/// <summary>
/// 功能描述:转换为base64字符串
/// 作  者:HZH
/// 创建日期:2019-03-29 10:12:38
/// 任务编号:POS
/// </summary>
/// <param name="data">data</param>
/// <returns>返回值</returns>
public static string ToBase64Str(this string data)
{
if (data.IsEmpty())
return string.Empty;
byte[] buffer = Encoding.Default.GetBytes(data);
return Convert.ToBase64String(buffer);
}
#endregion
/// <summary>
/// 转换为坐标
/// </summary>
/// <param name="data">The data.</param>
/// <returns>System.Drawing.Point.</returns>
public static System.Drawing.Point ToPoint(this string data)
{
if (!System.Text.RegularExpressions.Regex.IsMatch(data, @"^\s*\d+(\.\d+)?\s*\,\s*\d+(\.\d+)?\s*$"))
{
return System.Drawing.Point.Empty;
}
else
{
string[] strs = data.Split(',');
return new System.Drawing.Point(strs[0].ToInt(), strs[1].ToInt());
}
}
#region 数值转换
/// <summary>
/// 转换为整型
/// </summary>
/// <param name="data">数据</param>
/// <returns>System.Int32.</returns>
public static int ToInt(this object data)
{
if (data == null)
return 0;
if (data is bool)
{
return (bool)data ? 1 : 0;
}
int result;
var success = int.TryParse(data.ToString(), out result);
if (success)
return result;
try
{
return Convert.ToInt32(ToDouble(data, 0));
}
catch (Exception)
{
return 0;
}
}
/// <summary>
/// 转换为可空整型
/// </summary>
/// <param name="data">数据</param>
/// <returns>System.Nullable&lt;System.Int32&gt;.</returns>
public static int? ToIntOrNull(this object data)
{
if (data == null)
return null;
int result;
bool isValid = int.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
/// <summary>
/// 转换为双精度浮点数
/// </summary>
/// <param name="data">数据</param>
/// <returns>System.Double.</returns>
public static double ToDouble(this object data)
{
if (data == null)
return 0;
double result;
return double.TryParse(data.ToString(), out result) ? result : 0;
}
/// <summary>
/// 转换为双精度浮点数,并按指定的小数位4舍5入
/// </summary>
/// <param name="data">数据</param>
/// <param name="digits">小数位数</param>
/// <returns>System.Double.</returns>
public static double ToDouble(this object data, int digits)
{
return Math.Round(ToDouble(data), digits, System.MidpointRounding.AwayFromZero);
}
/// <summary>
/// 转换为可空双精度浮点数
/// </summary>
/// <param name="data">数据</param>
/// <returns>System.Nullable&lt;System.Double&gt;.</returns>
public static double? ToDoubleOrNull(this object data)
{
if (data == null)
return null;
double result;
bool isValid = double.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
/// <summary>
/// 转换为高精度浮点数
/// </summary>
/// <param name="data">数据</param>
/// <returns>System.Decimal.</returns>
public static decimal ToDecimal(this object data)
{
if (data == null)
return 0;
decimal result;
return decimal.TryParse(data.ToString(), out result) ? result : 0;
}
/// <summary>
/// 转换为高精度浮点数,并按指定的小数位4舍5入
/// </summary>
/// <param name="data">数据</param>
/// <param name="digits">小数位数</param>
/// <returns>System.Decimal.</returns>
public static decimal ToDecimal(this object data, int digits)
{
return Math.Round(ToDecimal(data), digits, System.MidpointRounding.AwayFromZero);
}
/// <summary>
/// 转换为可空高精度浮点数
/// </summary>
/// <param name="data">数据</param>
/// <returns>System.Nullable&lt;System.Decimal&gt;.</returns>
public static decimal? ToDecimalOrNull(this object data)
{
if (data == null)
return null;
decimal result;
bool isValid = decimal.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
/// <summary>
/// 转换为可空高精度浮点数,并按指定的小数位4舍5入
/// </summary>
/// <param name="data">数据</param>
/// <param name="digits">小数位数</param>
/// <returns>System.Nullable&lt;System.Decimal&gt;.</returns>
public static decimal? ToDecimalOrNull(this object data, int digits)
{
var result = ToDecimalOrNull(data);
if (result == null)
return null;
return Math.Round(result.Value, digits, System.MidpointRounding.AwayFromZero);
}
#endregion
#region 日期转换
/// <summary>
/// 转换为日期
/// </summary>
/// <param name="data">数据</param>
/// <returns>DateTime.</returns>
public static DateTime ToDate(this object data)
{
try
{
if (data == null)
return DateTime.MinValue;
if (System.Text.RegularExpressions.Regex.IsMatch(data.ToStringExt(), @"^\d{8}$"))
{
string strValue = data.ToStringExt();
return new DateTime(strValue.Substring(0, 4).ToInt(), strValue.Substring(4, 2).ToInt(), strValue.Substring(6, 2).ToInt());
}
DateTime result;
return DateTime.TryParse(data.ToString(), out result) ? result : DateTime.MinValue;
}
catch
{
return DateTime.MinValue;
}
}
/// <summary>
/// 转换为可空日期
/// </summary>
/// <param name="data">数据</param>
/// <returns>System.Nullable&lt;DateTime&gt;.</returns>
public static DateTime? ToDateOrNull(this object data)
{
try
{
if (data == null)
return null;
if (System.Text.RegularExpressions.Regex.IsMatch(data.ToStringExt(), @"^\d{8}$"))
{
string strValue = data.ToStringExt();
return new DateTime(strValue.Substring(0, 4).ToInt(), strValue.Substring(4, 2).ToInt(), strValue.Substring(6, 2).ToInt());
}
DateTime result;
bool isValid = DateTime.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
catch
{
return null;
}
}
#endregion
#region 布尔转换
/// <summary>
/// 转换为布尔值
/// </summary>
/// <param name="data">数据</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
public static bool ToBool(this object data)
{
if (data == null)
return false;
bool? value = GetBool(data);
if (value != null)
return value.Value;
bool result;
return bool.TryParse(data.ToString(), out result) && result;
}
/// <summary>
/// 获取布尔值
/// </summary>
/// <param name="data">The data.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
private static bool? GetBool(this object data)
{
switch (data.ToString().Trim().ToLower())
{
case "0":
return false;
case "1":
return true;
case "是":
return true;
case "否":
return false;
case "yes":
return true;
case "no":
return false;
default:
return null;
}
}
/// <summary>
/// 转换为可空布尔值
/// </summary>
/// <param name="data">数据</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
public static bool? ToBoolOrNull(this object data)
{
if (data == null)
return null;
bool? value = GetBool(data);
if (value != null)
return value.Value;
bool result;
bool isValid = bool.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
#endregion
#region 字符串转换
/// <summary>
/// 字符串转换为byte[]
/// </summary>
/// <param name="data">The data.</param>
/// <returns>System.Byte[].</returns>
public static byte[] ToBytes(this string data)
{
return System.Text.Encoding.GetEncoding("GBK").GetBytes(data);
}
/// <summary>
/// Converts to bytesdefault.
/// </summary>
/// <param name="data">The data.</param>
/// <returns>System.Byte[].</returns>
public static byte[] ToBytesDefault(this string data)
{
return System.Text.Encoding.Default.GetBytes(data);
}
/// <summary>
/// 转换为字符串
/// </summary>
/// <param name="data">数据</param>
/// <returns>System.String.</returns>
public static string ToStringExt(this object data)
{
return data == null ? string.Empty : data.ToString();
}
#endregion
/// <summary>
/// 安全返回值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">可空值</param>
/// <returns>T.</returns>
public static T SafeValue<T>(this T? value) where T : struct
{
return value ?? default(T);
}
/// <summary>
/// 是否为空
/// </summary>
/// <param name="value">值</param>
/// <returns><c>true</c> if the specified value is empty; otherwise, <c>false</c>.</returns>
public static bool IsEmpty(this string value)
{
return string.IsNullOrWhiteSpace(value);
}
/// <summary>
/// 是否为空
/// </summary>
/// <param name="value">值</param>
/// <returns><c>true</c> if the specified value is empty; otherwise, <c>false</c>.</returns>
public static bool IsEmpty(this Guid? value)
{
if (value == null)
return true;
return IsEmpty(value.Value);
}
/// <summary>
/// 是否为空
/// </summary>
/// <param name="value">值</param>
/// <returns><c>true</c> if the specified value is empty; otherwise, <c>false</c>.</returns>
public static bool IsEmpty(this Guid value)
{
if (value == Guid.Empty)
return true;
return false;
}
/// <summary>
/// 是否为空
/// </summary>
/// <param name="value">值</param>
/// <returns><c>true</c> if the specified value is empty; otherwise, <c>false</c>.</returns>
public static bool IsEmpty(this object value)
{
if (value != null && !string.IsNullOrEmpty(value.ToString()))
{
return false;
}
else
{
return true;
}
}
#region 是否数字
/// <summary>
/// 功能描述:是否数字
/// 作  者:HZH
/// 创建日期:2019-03-06 09:03:05
/// 任务编号:POS
/// </summary>
/// <param name="value">value</param>
/// <returns>返回值</returns>
public static bool IsNum(this string value)
{
return System.Text.RegularExpressions.Regex.IsMatch(value, @"^\d+(\.\d*)?$");
}
#endregion
}
}
@@ -0,0 +1,13 @@
namespace JinYuan.ControlLib.UCHelper
{
/// <summary>
/// 缩放控件接口
/// </summary>
public interface IDpiControl
{
/// <summary>
/// Dpi
/// </summary>
float ScaleDpi { get; set; }
}
}
@@ -0,0 +1,159 @@
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
namespace JinYuan.ControlLib.UCHelper
{
/// <summary>
/// 主线程动画控件基类,不能时耗时操作,该定时器时UI线程计时器。耗时长对导致画面卡顿。
/// </summary>
[ToolboxItem(false)]
[Description("动画控件基类")]
public abstract class MainThreadAnimationControl : DpiControl
{
#region 字段
/// <summary>
/// 动画控件集合锁
/// </summary>
private static object animationcontrols_lock = new object();
/// <summary>
/// 动画控件集合
/// </summary>
private static List<MainThreadAnimationControl> animationcontrols = new List<MainThreadAnimationControl>();
/// <summary>
/// 动画定时器锁
/// </summary>
private static object timer_lock = new object();
/// <summary>
/// 定时器间隔
/// </summary>
private static Thread thread = null;
/// <summary>
/// 线程间隔
/// </summary>
private static int threadInterval = 100;
private static CancellationTokenSource cts = new CancellationTokenSource();
/// <summary>
/// 停止线程
/// </summary>
private static ManualResetEvent stopEvent = new ManualResetEvent(false);
//private static Timer timer = null;
#endregion
public MainThreadAnimationControl()
{
if (thread == null)
{
lock (timer_lock)
{
thread = new Thread(() => ThreadFunction());
thread.IsBackground = true;
thread.Start();
}
}
}
#region 虚方法
/// <summary>
/// 动画控件动画中要处理的内容(不能时耗时操作,该定时器为UI线程计时器。耗时长对导致画面卡顿)
/// </summary>
/// <param name="interval">动画定时器间隔时间</param>
protected virtual void Animationing(int interval)
{
}
#endregion
#region 私有方法
/// <summary>
/// 定时器事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
internal static void ThreadFunction()
{
ArrayList indexArr = new ArrayList();
while (true)
{
if (cts.Token.IsCancellationRequested)
{
return;
}
// stopEvent.WaitOne();
for (int i = 0; i < animationcontrols.Count; i++)
{
if (animationcontrols[i] != null)
{
animationcontrols[i].Animationing(threadInterval);
}
else
{
indexArr.Add(i);
}
}
if (indexArr.Count > 0)
{
for (int i = 0; i < indexArr.Count; i++)
{
animationcontrols.RemoveAt((int)indexArr[i] - i);
}
}
if (animationcontrols.Count < 1)
{
stopEvent.Set();
}
Thread.Sleep(threadInterval);
}
}
/// <summary>
/// 开始指定控件动画
/// </summary>
/// <param name="control"></param>
internal static void AnimationStart(MainThreadAnimationControl control)
{
if (control == null)
return;
lock (animationcontrols_lock)
{
if (animationcontrols.IndexOf(control) < 0)
{
animationcontrols.Add(control);
}
}
stopEvent.Reset();
}
/// <summary>
/// 停止指定控件动画
/// </summary>
/// <param name="control"></param>
internal static void AnimationStop(MainThreadAnimationControl control)
{
if (control == null)
return;
lock (animationcontrols_lock)
{
animationcontrols.Remove(control);
}
}
#endregion
}
}
+195
View File
@@ -0,0 +1,195 @@
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace JinYuan.ControlLib.UCHelper
{
/// <summary>
/// 鼠标全局钩子
/// </summary>
public static class MouseHook
{
/// <summary>
/// The wm mousemove
/// </summary>
private const int WM_MOUSEMOVE = 0x200;
/// <summary>
/// The wm lbuttondown
/// </summary>
private const int WM_LBUTTONDOWN = 0x201;
/// <summary>
/// The wm rbuttondown
/// </summary>
private const int WM_RBUTTONDOWN = 0x204;
/// <summary>
/// The wm mbuttondown
/// </summary>
private const int WM_MBUTTONDOWN = 0x207;
/// <summary>
/// The wm lbuttonup
/// </summary>
private const int WM_LBUTTONUP = 0x202;
/// <summary>
/// The wm rbuttonup
/// </summary>
private const int WM_RBUTTONUP = 0x205;
/// <summary>
/// The wm mbuttonup
/// </summary>
private const int WM_MBUTTONUP = 0x208;
/// <summary>
/// The wm lbuttondblclk
/// </summary>
private const int WM_LBUTTONDBLCLK = 0x203;
/// <summary>
/// The wm rbuttondblclk
/// </summary>
private const int WM_RBUTTONDBLCLK = 0x206;
/// <summary>
/// The wm mbuttondblclk
/// </summary>
private const int WM_MBUTTONDBLCLK = 0x209;
/// <summary>
/// 点
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public class POINT
{
/// <summary>
/// The x
/// </summary>
public int x;
/// <summary>
/// The y
/// </summary>
public int y;
}
/// <summary>
/// 钩子结构体
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{
/// <summary>
/// The pt
/// </summary>
public POINT pt;
/// <summary>
/// The h WND
/// </summary>
public int hWnd;
/// <summary>
/// The w hit test code
/// </summary>
public int wHitTestCode;
/// <summary>
/// The dw extra information
/// </summary>
public int dwExtraInfo;
}
// 全局的鼠标事件
/// <summary>
/// Occurs when [on mouse activity].
/// </summary>
public static event MouseEventHandler OnMouseActivity;
/// <summary>
/// The h mouse hook
/// </summary>
private static int _hMouseHook = 0; // 鼠标钩子句柄
/// <summary>
/// 启动全局钩子
/// </summary>
/// <exception cref="System.Exception">SetWindowsHookEx failed.</exception>
/// <exception cref="Exception">SetWindowsHookEx failed.</exception>
public static void Start()
{
// 安装鼠标钩子
if (_hMouseHook != 0)
{
Stop();
}
// 生成一个HookProc的实例.
WindowsHook.HookMsgChanged += WindowsHook_HookMsgChanged;
_hMouseHook = WindowsHook.StartHook(HookType.WH_MOUSE_LL);
//假设装置失败停止钩子
if (_hMouseHook == 0)
{
Stop();
}
}
static void WindowsHook_HookMsgChanged(string strHookName, int nCode, IntPtr msg, IntPtr lParam)
{
// 假设正常执行而且用户要监听鼠标的消息
if (nCode >= 0 && OnMouseActivity != null)
{
MouseButtons button = MouseButtons.None;
int clickCount = 0;
switch ((int)msg)
{
case WM_LBUTTONDOWN:
button = MouseButtons.Left;
clickCount = 1;
break;
case WM_LBUTTONUP:
button = MouseButtons.Left;
clickCount = 1;
break;
case WM_LBUTTONDBLCLK:
button = MouseButtons.Left;
clickCount = 2;
break;
case WM_RBUTTONDOWN:
button = MouseButtons.Right;
clickCount = 1;
break;
case WM_RBUTTONUP:
button = MouseButtons.Right;
clickCount = 1;
break;
case WM_RBUTTONDBLCLK:
button = MouseButtons.Right;
clickCount = 2;
break;
}
if (button != MouseButtons.None && clickCount > 0)
{
// 从回调函数中得到鼠标的信息
MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
MouseEventArgs e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0);
OnMouseActivity(null, e);
}
}
}
/// <summary>
/// 停止全局钩子
/// </summary>
/// <exception cref="System.Exception">UnhookWindowsHookEx failed.</exception>
/// <exception cref="Exception">UnhookWindowsHookEx failed.</exception>
public static void Stop()
{
bool retMouse = true;
if (_hMouseHook != 0)
{
retMouse = WindowsHook.StopHook(_hMouseHook);
_hMouseHook = 0;
}
// 假设卸下钩子失败
if (!(retMouse))
throw new Exception("UnhookWindowsHookEx failed.");
}
}
}
@@ -0,0 +1,312 @@
using System;
using System.Runtime.InteropServices;
namespace JinYuan.ControlLib.UCHelper
{
/// <summary>
/// Win32
/// </summary>
public static class NativeMethods
{
#region 消息
public const int WM_USER = 0x0400;//用户自定义消息
public const int WM_USER_DROPDROWLISTPLUS_MOUSEENTER = NativeMethods.WM_USER + 10;// DropDrowListPlus MouseEnter消息
public const int WM_USER_DROPDROWLISTPLUS_MOUSELEAVE = NativeMethods.WM_USER + 11;// DropDrowListPlus MouseLeave消息
public const int WM_USER_DROPDROWLISTPLUS_MOUSEDOWN = NativeMethods.WM_USER + 12;// DropDrowListPlus MouseDown消息
public const int WM_USER_DROPDROWLISTPLUS_MOUSEUP = NativeMethods.WM_USER + 13;// DropDrowListPlus MouseUp消息
public const int WM_USER_DROPDROWLISTPLUS_MOUSEMOVE = NativeMethods.WM_USER + 14;// DropDrowListPlus MouseMove消息
public const int WM_USER_DROPDROWLISTPLUS_CLOSED = NativeMethods.WM_USER + 15;// DropDrowListPlus 下拉面板Closed消息
public const int WM_USER_DROPDROWLISTPLUS_MOUSEWHEEL = NativeMethods.WM_USER + 16;// DropDrowListPlus 下拉面板MouseWheel消息
public const int WM_USER_DROPDROWLISTPLUS_PAINT = NativeMethods.WM_USER + 17;// DropDrowListPlus 下拉面板Paint消息
public const int LOGPIXELSX = 88;
public const int LOGPIXELSY = 90;
#endregion
#region 结构
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public RECT(int left, int top, int right, int bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public RECT(System.Drawing.Rectangle r)
{
this.left = r.Left;
this.top = r.Top;
this.right = r.Right;
this.bottom = r.Bottom;
}
public static RECT FromXYWH(int x, int y, int width, int height)
{
return new RECT(x, y, x + width, y + height);
}
public System.Drawing.Size Size
{
get
{
return new System.Drawing.Size(this.right - this.left, this.bottom - this.top);
}
}
}
[StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int x;
public int y;
public POINT()
{
}
public POINT(int x, int y)
{
this.x = x;
this.y = y;
}
}
#endregion
#region 扩展
[DllImport("User32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)]
public static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
[DllImport("User32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Auto)]
public static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);
public static IntPtr GetWindowLong(IntPtr hWnd, int nIndex)
{
if (IntPtr.Size == 4)
{
return GetWindowLong32(hWnd, nIndex);
}
return GetWindowLongPtr64(hWnd, nIndex);
}
[DllImport("User32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]
public static extern IntPtr SetWindowLongPtr32(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
[DllImport("User32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)]
public static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
public static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong)
{
if (IntPtr.Size == 4)
{
return SetWindowLongPtr32(hWnd, nIndex, dwNewLong);
}
return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
}
[DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, int lParam);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("User32.dll", ExactSpelling = true, SetLastError = true)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
/// <summary>
/// 检索指定窗口的边界矩形的尺寸。 尺寸以相对于屏幕左上角的屏幕坐标提供。
/// </summary>
/// <param name="hWnd">窗口的句柄</param>
/// <param name="rect">指向 RECT 结构的指针,用于接收窗口左上角和右下角的屏幕坐标</param>
/// <returns></returns>
[DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern bool GetWindowRect(IntPtr hWnd, [In, Out] ref RECT rect);
/// <summary>
/// 激活指定窗口
/// </summary>
/// <param name="hWnd">窗口的句柄</param>
/// <returns></returns>
[DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern IntPtr SetActiveWindow(IntPtr hWnd);
[DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern bool IsWindowVisible(IntPtr hWnd);
/// <summary>
/// 获得的设备环境覆盖了整个窗口(包括非客户区)
/// </summary>
/// <param name="hwnd"></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetWindowDC(IntPtr hwnd);
/// <summary>
/// 用于获得hWnd参数所指定窗口的客户区域的一个设备环境
/// </summary>
/// <param name="ptr"></param>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr ptr);
[DllImport("User32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hdc);
/// <summary>
/// DPI的缩放由程序自己处理
/// </summary>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern bool SetProcessDPIAware();
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
[DllImport("gdi32.dll")]
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
public static int MAKELONG(int low, int high)
{
return (high << 16) | (low & 0xffff);
}
public static IntPtr MAKELPARAM(int low, int high)
{
return (IntPtr)((high << 16) | (low & 0xffff));
}
/// <summary>
/// 高16位(无符号)
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
public static int HIWORD(IntPtr n)
{
return HIWORD(unchecked((int)(long)n));
}
/// <summary>
/// 高16位(无符号)
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
public static int HIWORD(int n)
{
return (n >> 16) & 0xffff;
}
/// <summary>
/// 低16位(无符号)
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
public static int LOWORD(IntPtr n)
{
return LOWORD(unchecked((int)(long)n));
}
/// <summary>
/// 低16位(无符号)
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
public static int LOWORD(int n)
{
return n & 0xffff;
}
/// <summary>
/// 高16位(有符号)
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
public static int SignedHIWORD(IntPtr n)
{
return SignedHIWORD(unchecked((int)(long)n));
}
/// <summary>
/// 高16位(有符号)
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
public static int SignedHIWORD(int n)
{
return (int)(short)((n >> 16) & 0xffff);
}
/// <summary>
/// 低16位(有符号)
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
public static int SignedLOWORD(IntPtr n)
{
return SignedLOWORD(unchecked((int)(long)n));
}
/// <summary>
/// 低16位(有符号)
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
public static int SignedLOWORD(int n)
{
return (int)(short)(n & 0xFFFF);
}
/// <summary>
/// 结构转指针
/// </summary>
/// <typeparam name="T">结构类型</typeparam>
/// <param name="info"></param>
/// <returns></returns>
public static IntPtr StructToIntPtr<T>(T info)
{
int size = Marshal.SizeOf(info);
IntPtr intPtr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(info, intPtr, true);
return intPtr;
}
/// <summary>
/// 指针转结构
/// </summary>
/// <typeparam name="T">结构类型</typeparam>
/// <param name="info"></param>
/// <returns></returns>
public static T IntPtrToStruct<T>(IntPtr info)
{
return (T)Marshal.PtrToStructure(info, typeof(T));
}
#endregion
}
}
@@ -0,0 +1,27 @@
using System;
namespace JinYuan.ControlLib.UCHelper
{
//
// 摘要:
// 属性排序(升序)
[AttributeUsage(AttributeTargets.Property)]
public class PropertyOrderAttribute : Attribute
{
private float order;
//
// 摘要:
// 序号
public float Order => order;
//
// 参数:
// order:
// 序号
public PropertyOrderAttribute(float order)
{
this.order = order;
}
}
}
@@ -0,0 +1,60 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Globalization;
namespace JinYuan.ControlLib.UCHelper
{
//
// 摘要:
// 对属性进行排序
public class PropertyOrderConverter : TypeConverter
{
//
// 摘要:
// 当该属性为展开属性选型时,属性编辑器删除该属性的描述
//
// 参数:
// context:
//
// culture:
//
// value:
//
// destinationType:
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
return string.Empty;
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value, attributes);
ArrayList arrayList = new ArrayList();
foreach (PropertyDescriptor item in properties)
{
Attribute attribute = item.Attributes[typeof(PropertyOrderAttribute)];
arrayList.Add(new PropertyOrderPair(item.Name, (attribute == null) ? 0f : ((PropertyOrderAttribute)attribute).Order));
}
arrayList.Sort();
ArrayList arrayList2 = new ArrayList();
foreach (PropertyOrderPair item2 in arrayList)
{
arrayList2.Add(item2.CategoryName);
}
return properties.Sort((string[])arrayList2.ToArray(typeof(string)));
}
}
}
@@ -0,0 +1,49 @@
using System;
namespace JinYuan.ControlLib.UCHelper
{
//
// 摘要:
// 属性排序 序号比较器
public class PropertyOrderPair : IComparable
{
private float order;
private string categoryName;
//
// 摘要:
// 类别名称
public string CategoryName => categoryName;
//
// 参数:
// categoryName:
// 类别名称
//
// order:
// 序号
public PropertyOrderPair(string categoryName, float order)
{
this.order = order;
this.categoryName = categoryName;
}
public int CompareTo(object obj)
{
PropertyOrderPair propertyOrderPair = (PropertyOrderPair)obj;
if (propertyOrderPair.order == order)
{
return string.Compare(categoryName, propertyOrderPair.categoryName);
}
if (propertyOrderPair.order > order)
{
return -1;
}
return 1;
}
}
}
+177
View File
@@ -0,0 +1,177 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
namespace JinYuan.ControlLib.UCHelper
{
/// <summary>
/// 钩子类型
/// </summary>
public enum HookType : int
{
/// <summary>
/// 安装一个钩子过程,该过程监视由于对话框,消息框,菜单或滚动条中的输入事件而生成的消息。
/// 有关更多信息,请参阅MessageProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644987(v=vs.85))挂接过程。
/// </summary>
WH_MSGFILTER = -1,
/// <summary>
/// 安装一个钩子过程,记录发布到系统消息队列的输入消息。 此挂钩对于录制宏非常有用。
/// 有关更多信息,请参阅JournalRecordProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644983(v=vs.85))挂钩过程。
/// </summary>
WH_JOURNALRECORD = 0,
/// <summary>
/// 安装一个挂钩过程,该过程发布先前由WH_JOURNALRECORD挂钩过程记录的消息。
/// 有关更多信息,请参阅JournalPlaybackProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644982(v=vs.85))挂钩过程。
/// </summary>
WH_JOURNALPLAYBACK = 1,
/// <summary>
/// 安装一个监视击键消息的钩子程序。
/// 有关更多信息,请参阅KeyboardProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644984(v=vs.85))挂钩过程。
/// </summary>
WH_KEYBOARD = 2,
/// <summary>
/// 安装一个钩子过程来监视发布到消息队列的消息。
/// 有关更多信息,请参阅GetMsgProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644981(v=vs.85))挂接过程。
/// </summary>
WH_GETMESSAGE = 3,
/// <summary>
/// 安装一个钩子过程,在系统将消息发送到目标窗口过程之前监视消息。
/// 有关更多信息,请参阅CallWndProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644975(v=vs.85))挂接过程。
/// </summary>
WH_CALLWNDPROC = 4,
/// <summary>
/// 安装一个钩子程序,接收对CBT应用程序有用的通知。
/// 有关更多信息,请参阅CBTProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644977(v=vs.85))挂钩过程。
/// </summary>
WH_CBT = 5,
/// <summary>
/// 安装一个钩子过程,该过程监视由于对话框,消息框,菜单或滚动条中的输入事件而生成的消息。
/// 钩子过程监视与调用线程在同一桌面中的所有应用程序的这些消息。
/// 有关更多信息,请参阅SysMsgProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644992(v=vs.85))挂接过程。
/// </summary>
WH_SYSMSGFILTER = 6,
/// <summary>
/// 安装监视鼠标消息的钩子过程。
/// 有关更多信息,请参阅MouseProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644988(v=vs.85))挂钩过程。
/// </summary>
WH_MOUSE = 7,
/// <summary>
/// 安装一个用于调试其他钩子过程的钩子过程。
/// 有关更多信息,请参阅DebugProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644978(v=vs.85))挂接过程。
/// </summary>
WH_DEBUG = 9,
/// <summary>
/// 安装一个钩子过程,接收对shell应用程序有用的通知。
/// 有关更多信息,请参阅ShellProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644991(v=vs.85))挂钩过程。
/// </summary>
WH_SHELL = 10,
/// <summary>
/// 安装一个钩子过程,当应用程序的前台线程即将变为空闲时将调用该过程。
/// 此挂钩对于在空闲时执行低优先级任务非常有用。
/// 有关更多信息,请参阅ForegroundIdleProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644980(v=vs.85))挂钩过程。
/// </summary>
WH_FOREGROUNDIDLE = 11,
/// <summary>
/// 安装一个钩子过程,该过程在目标窗口过程处理完消息后对其进行监视。
/// 有关更多信息,请参阅CallWndRetProc(https://docs.microsoft.com/windows/desktop/api/winuser/nc-winuser-hookproc)挂接过程。
/// </summary>
WH_CALLWNDPROCRET = 12,
/// <summary>
/// 安装一个监视低级键盘输入事件的钩子过程。 有关更多信息,
/// 请参阅LowLevelKeyboardProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644985(v=vs.85))挂接过程。
/// </summary>
WH_KEYBOARD_LL = 13,
/// <summary>
/// 安装一个监视低级鼠标输入事件的钩子过程。 有关更多信息,
/// 请参阅LowLevelMouseProc(https://docs.microsoft.com/previous-versions/windows/desktop/legacy/ms644986(v=vs.85))挂接过程。
/// </summary>
WH_MOUSE_LL = 14,
}
public class WindowsHook
{
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
// 装置钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, int hInstance, int threadId);
// 卸下钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
// 下一个钩挂的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
/// <summary>
/// Delegate HookMsgHandler
/// </summary>
/// <param name="strHookName">钩子名称</param>
/// <param name="msg">消息值</param>
public delegate void HookMsgHandler(string strHookName, int nCode, IntPtr msg, IntPtr lParam);
/// <summary>
/// 钩子消息事件
/// </summary>
public static event HookMsgHandler HookMsgChanged;
/// <summary>
/// 启动一个钩子
/// </summary>
/// <param name="hookType">钩子类型</param>
/// <param name="wParam">模块句柄,为空则为当前模块</param>
/// <param name="pid">进程句柄,默认为0则表示当前进程</param>
/// <param name="strHookName">钩子名称</param>
/// <returns>钩子句柄(消耗钩子时需要使用)</returns>
/// <exception cref="Exception">SetWindowsHookEx failed.</exception>
public static int StartHook(HookType hookType, int wParam = 0, int pid = 0, string strHookName = "")
{
int _hHook = 0;
// 生成一个HookProc的实例.
var _hookProcedure = new HookProc((nCode, msg, lParam) =>
{
if (HookMsgChanged != null)
{
try
{
HookMsgChanged(strHookName, nCode, msg, lParam);
}
catch { }
}
int inext = CallNextHookEx(_hHook, nCode, msg, lParam);
return inext;
});
if (pid == 0)
pid = Thread.CurrentThread.ManagedThreadId;
_hHook = SetWindowsHookEx((int)hookType, _hookProcedure, wParam, pid);
//假设装置失败停止钩子
if (_hHook == 0)
{
StopHook(_hHook);
}
return _hHook;
}
/// <summary>
/// 停止钩子
/// </summary>
/// <param name="_hHook">StartHook函数返回的钩子句柄</param>
/// <returns><c>true</c> if 停止成功, <c>false</c> 否则.</returns>
public static bool StopHook(int _hHook)
{
bool ret = true;
if (_hHook != 0)
{
ret = UnhookWindowsHookEx(_hHook);
}
// 假设卸下钩子失败
if (!ret)
return false;
return true;
}
}
}