添加项目文件。
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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<System.Int32>.</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<System.Double>.</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<System.Decimal>.</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<System.Decimal>.</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<DateTime>.</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
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user