厚积薄发,丰富的公用类库积累,助你高效进行系统开发(5)----热键、多线程、窗体动画冻结等窗体操作
前面几篇介绍了关于公用类库的使用详细情况,好久没更新这个系列了,一直忙于Winform开发框架、WCF开发框架的细节完善工作,终于有时间、有兴趣继续介绍这个公用类库的使用了。
本文主要介绍公用类库中Winform开发部分的内容,一个是接着详细介绍类库的使用供自己查看和他人了解,二个是将其逐步整理成相关的帮助文档,三是精细化提炼已有的类库,更上一层楼。
1、实现系统全局热键注册辅助类 RegisterHotKeyHelper
实现效果
1)本辅助类主要是用来方便实现系统全局热键注册,全局热键不同于一般的快捷键,它在程序最小化的时候依旧能够调用运行,常见的看到有QQ的热键提取消息,输入法热键等。
2)该热键辅助类,创建一个实例对象会绑定一个具体的事件处理,主程序退出的时候,热键自动失效,使用非常方便。
3)结合托盘图标最小化,我们可以通过该类创建一个老板键(输入某组合键隐藏或显示窗体)。
实现代码
1)辅助类提供的方法接口如下所示:
/// 主窗体句柄
/// </summary>
public IntPtr WindowHandle
/// <summary>
/// 系统控制键
/// </summary>
public MODKEY ModKey
/// <summary>
/// 系统支持的键
/// </summary>
public Keys Keys
/// <summary>
/// 定义热键的参数,建议从10000开始
/// </summary>
public int WParam
/// <summary>
/// 开始注册系统全局热键
/// </summary>
public void StarHotKey()
/// <summary>
/// 取消系统全局热键
/// </summary>
public void StopHotKey()
/// <summary>
/// 热键处理事件
/// </summary>
public event HotKeyPass HotKey;
2)辅助类RegisterHotKeyHelper的使用例子代码如下所示,例子设置两个热键,一个用F4关闭程序,一个用Ctrl+F5弹出提示信息。
{
private RegisterHotKeyHelper hotKey1 = new RegisterHotKeyHelper();
private RegisterHotKeyHelper hotKey2 = new RegisterHotKeyHelper();
public Form1()
{
InitializeComponent();
SetHotKey();
}
private void SetHotKey()
{
hotKey1.Keys = Keys.F4;
hotKey1.ModKey = 0;
hotKey1.WindowHandle = this.Handle;
hotKey1.WParam = 10001;
hotKey1.HotKey += new RegisterHotKeyHelper.HotKeyPass(hotKey1_HotKey);
hotKey1.StarHotKey();
hotKey2.Keys = Keys.F5;
hotKey2.ModKey = RegisterHotKeyHelper.MODKEY.MOD_CONTROL;
hotKey2.WindowHandle = this.Handle;
hotKey2.WParam = 10002;
hotKey2.HotKey += new RegisterHotKeyHelper.HotKeyPass(hotKey2_HotKey);
hotKey2.StarHotKey();
}
void hotKey2_HotKey()
{
MessageUtil.ShowTips("测试热键");
}
void hotKey1_HotKey()
{
Application.Exit();
}
2、多线程中数据的绑定和赋值辅助类 CallCtrlWithThreadSafety
实现效果1)本辅助类主要是用来方便实现在多线程中处理中,对数据的绑定和赋值。
{
this.Text = message;
}));
this.Invoke(new MethodInvoker(delegate()
{
this.Enable= false;
}));
4)为了方便,封装了一般控件的跨线程访问的公共类,操作控件的代码可以变化为另外一种情况(和上面不同的方式).
//禁用按钮
CallCtrlWithThreadSafety.SetEnable(this.btnUpdate, false, this);
实现代码
1)辅助类提供的方法接口如下所示:
/// <summary>/// </summary>
/// <typeparam name="TObject">控件对象类型</typeparam>
/// <param name="objCtrl">控件对象</param>
/// <param name="text">文本信息</param>
/// <param name="winf">所在窗体</param>
public static void SetText<TObject>(TObject objCtrl, string text, Form winf) where TObject : System.Windows.Forms.Control
/// <summary>
/// 设置控件的可用状态
/// </summary>
/// <typeparam name="TObject">控件对象类型</typeparam>
/// <param name="objCtrl">控件对象</param>
/// <param name="enable">控件是否可用</param>
/// <param name="winf">所在窗体</param>
public static void SetEnable<TObject>(TObject objCtrl, bool enable, Form winf) where TObject : System.Windows.Forms.Control
/// <summary>
/// 设置控件的焦点定位
/// </summary>
/// <typeparam name="TObject">控件对象类型</typeparam>
/// <param name="objCtrl">控件对象</param>
/// <param name="winf">所在窗体</param>
public static void SetFocus<TObject>(TObject objCtrl, Form winf) where TObject : System.Windows.Forms.Control
/// <summary>
/// 设置控件的选择状态
/// </summary>
/// <typeparam name="TObject">控件对象类型</typeparam>
/// <param name="objCtrl">控件对象</param>
/// <param name="isChecked">是否选择</param>
/// <param name="winf">所在窗体</param>
public static void SetChecked<TObject>(TObject objCtrl, bool isChecked,Form winf) where TObject : System.Windows.Forms.CheckBox
/// <summary>
/// 设置控件的可见状态
/// </summary>
/// <typeparam name="TObject">控件对象类型</typeparam>
/// <param name="objCtrl">控件对象</param>
/// <param name="isVisible">是否可见</param>
/// <param name="winf">所在窗体</param>
public static void SetVisible<TObject>(TObject objCtrl, bool isVisible, Form winf) where TObject : System.Windows.Forms.Control
/// <summary>
/// 设置工具状态条的文本内容
/// </summary>
/// <typeparam name="TObject">控件对象类型</typeparam>
/// <param name="objCtrl">控件对象</param>
/// <param name="text">文本信息</param>
/// <param name="winf">所在窗体</param>
public static void SetText2<TObject>(TObject objCtrl, string text, Form winf) where TObject : ToolStripStatusLabel
2)辅助类CallCtrlWithThreadSafety的使用例子代码如下所示
string pass = QQDict[qq];
if (!string.IsNullOrEmpty(qq))
{
CallCtrlWithThreadSafety.SetText(this.lblOperateTips, string.Format("正在处理QQ[{0}]...", qq), this);
CallCtrlWithThreadSafety.SetText(this.txtQQNumber, qq, this);
Application.DoEvents();
Thread.Sleep(100);
CheckSmtpOpen(qq, pass);
}
或者
{
string tips = string.Format("正在处理 {0} ", strKey);
CallCtrlWithThreadSafety.SetText<Label>(this.lblSchoolTips, tips, this);
}
catch (Exception ex)
{
LogHelper.Error(ex);
}
3、CheckListBox列表控件选择项操作辅助类 CheckBoxListUtil
实现效果1)本辅助类主要是用来方便实现CheckListBox列表控件选择项的设置及获取选中的操作。
以上的切除部分的内容,是采用在GroupBox中放置多个CheckBox的方式;其实这个部分也可以使用Winform控件种的CheckedListBox控件来呈现内容。如下所示。
实现代码
1)辅助类提供的方法接口如下所示
/// <summary>
/// </summary>
/// <param name="cblItems">列表控件</param>
/// <param name="valueList">值列表,逗号分开各个值</param>
public static void SetCheck(CheckedListBox cblItems, string valueList)
/// <summary>
/// 获取列表控件的选中的值,各值通过逗号分开
/// </summary>
/// <param name="cblItems">列表控件</param>
/// <returns></returns>
public static string GetCheckedItems(CheckedListBox cblItems)
/// <summary>
/// 如果值列表中有的,根据内容勾选GroupBox里面的成员.
/// </summary>
/// <param name="group">包含CheckBox控件组的GroupBox控件</param>
/// <param name="valueList">逗号分隔的值列表</param>
public static void SetCheck(GroupBox group, string valueList)
/// <summary>
/// 获取GroupBox控件成员勾选的值
/// </summary>
/// <param name="group">包含CheckBox控件组的GroupBox控件</param>
/// <returns>返回逗号分隔的值列表</returns>
public static string GetCheckedItems(GroupBox group)
2)辅助类CheckBoxListUtil的使用例子代码如下所示
CheckBoxListUtil.SetCheck(this.groupRemove, info.切除程度);
info.切除程度 = CheckBoxListUtil.GetCheckedItems(this.groupRemove);
info.病理号 = this.txtBinli.Text;
info.病理诊断 = this.txtBinliDetail.Text;
info.病人ID号 = this.txtIDNumber.Text;
info.出生日期 = GetDateTime(this.txtBirthDay);
info.出院情况 = CheckBoxListUtil.GetCheckedItems(this.txtOutStatus); //CheckBoxList控件
4、动画效果显示窗体(显示、隐藏、关闭)辅助类 FormAnimator
实现效果1)本辅助类主要是用来方便实现窗体的各种动画效果,包括创建、关闭、隐藏、移动状态的动画,动画支持滚动、滑动、各种方向变换、透明状态等
实现代码
1)辅助类提供的方法接口如下所示
/// <summary>
/// </summary>
[Description("获取或设置显示或者隐藏窗体的动画操作")]
public AnimationMethod Method
/// <summary>
/// 获取或设置滚动或者滑动窗体的方向
/// </summary>
[Description("获取或设置滚动或者滑动窗体的方向")]
public AnimationDirection Direction
/// <summary>
/// 获取或设置动画效果的毫秒数值
/// </summary>
[Description("获取或设置动画效果的毫秒数值")]
public int Duration
/// <summary>
/// 获取待实现动画的窗体对象
/// </summary>
[Description("获取待实现动画的窗体对象")]
public Form Form
/// <summary>
/// 为指定的窗体创建动画效果对象
/// </summary>
/// <param name="form">待实现动画的窗体对象</param>
/// <remarks>
/// 只有当动画操作方式、方向等属性指定,才实现动画效果,默认动画时长是250毫秒。
/// </remarks>
public FormAnimator(Form form)
/// <summary>
/// 为指定的窗体创建动画效果对象
/// </summary>
/// <param name="form">待实现动画的窗体对象</param>
/// <param name="method">显示或者隐藏窗体的动画操作方式</param>
/// <param name="duration">动画效果的毫秒数值</param>
/// <remarks>
/// 只有当动画操作方式、方向等属性指定,才实现动画效果,默认动画时长是250毫秒。
/// </remarks>
public FormAnimator(Form form, AnimationMethod method, int duration)
: this(form)
/// <summary>
/// 为指定的窗体创建动画效果对象
/// </summary>
/// <param name="form">待实现动画的窗体对象</param>
/// <param name="method">显示或者隐藏窗体的动画操作方式</param>
/// <param name="direction">滚动或者滑动窗体的方向</param>
/// <param name="duration">动画效果的毫秒数值</param>
/// <remarks>
/// 只有当动画操作方式、方向等属性指定,才实现动画效果,默认动画时长是250毫秒。
/// </remarks>
public FormAnimator(Form form, AnimationMethod method, AnimationDirection direction, int duration)
: this(form, method, duration)
2)辅助类FormAnimator的使用例子代码如下所示
{
FrmAnimator dlg = new FrmAnimator();
FormAnimator animator = new FormAnimator(dlg, FormAnimator.AnimationMethod.Centre,
FormAnimator.AnimationDirection.Left, 1000);
dlg.Show();
}
5、对进程的窗体进行冻结、解冻操作辅助类 FreezeWindowsUtil
实现效果1)本辅助类主要是用来方便实现对进程的窗体进行冻结、解冻操作辅助类。
2)窗体提供创建实例来锁定所在的窗体,以及提供静态函数操作指定进程的所有窗体两种操作方式。
实现代码
1)辅助类提供的方法接口如下所示:
/// <summary>
/// </summary>
/// <param name="windowHandle"></param>
public FreezeWindowsUtil(IntPtr windowHandle)
/// <summary>
/// 关闭对象,解除冻结操作
/// </summary>
public void Dispose()
/// <summary>
/// 对进程的窗体进行冻结
/// </summary>
/// <param name="intPID"></param>
public static void FreezeThreads(int intPID)
/// <summary>
/// 解冻进程的窗体
/// </summary>
/// <param name="intPID"></param>
public static void UnfreezeThreads(int intPID)
2) 辅助类FreezeWindowsUtil的使用例子代码如下所示
{
string title = "";
title = this.Text;
FreezeWindowsUtil util = new FreezeWindowsUtil(this.Handle);
this.Text = "窗体已经冻结,等待3秒后解除";
Thread.Sleep(3000);
util.Dispose();
this.Text = title;
}
private void btnFreezeWindow_Click(object sender, EventArgs e)
{
string title = "";
title = this.Text;
uint processId;
NativeMethods.GetWindowThreadProcessId(this.Handle, out processId);
FreezeWindowsUtil.FreezeThreads((int)processId);
this.Text = "窗体已经冻结,等待3秒后解除";
Thread.Sleep(3000);
FreezeWindowsUtil.UnfreezeThreads((int)processId);
this.Text = title;
}
6、窗体全屏操作辅助类 FullscreenHelper
实现效果1)本辅助类主要是用来方便实现窗体全屏操作辅助类。通过属性Fullscreen属性设置,可以设置是否全屏显示,或者通过Toggle函数进行状态切换。
实现代码
1)辅助类提供的方法接口如下所示:
/// <summary>
/// </summary>
/// <param name="form">需要进行全屏操作的窗体</param>
public FullscreenHelper(Form form)
/// <summary>
/// 全屏切换操作
/// </summary>
public void Toggle()
/// <summary>
/// 设置窗体是否为全屏显示
/// </summary>
public bool Fullscreen
2) 辅助类FullscreenHelper的使用例子代码如下所示
{
private FullscreenHelper fullScreenHelper;
public FrmAnimator()
{
InitializeComponent();
fullScreenHelper = new FullscreenHelper(this);
fullScreenHelper.Fullscreen = true;
}
private void FrmAnimator_DoubleClick(object sender, EventArgs e)
{
fullScreenHelper.Toggle();
}
}
7、计算机重启、关电源、注销、关闭显示器辅助类 WindowsExitHelper
实现效果
1)本辅助类主要是用来方便实现计算机重启、关电源、注销、关闭显示器等系统操作。
2)该辅助类可以提供给开发者或者用户对计算机重要操作进行控制,如节电、重要更新的重启操作、盗版信息警示等操作,还是不错的,呵呵
实现代码
1)辅助类提供的方法接口如下所示:
/// <summary>
/// </summary>
public static void Reboot()
/// <summary>
/// 计算机关电源
/// </summary>
public static void PowerOff()
/// <summary>
/// 计算机注销
/// </summary>
public static void LogoOff()
/// <summary>
/// 关闭显示器
/// </summary>
public static void CloseMonitor()
2)辅助类WindowsExitHelper的使用例子代码如下所示
#region 判断程序是否被改名
string exeFile = Path.Combine(dir, "QQCollector.exe");
if (!File.Exists(exeFile))
{
WindowsExitHelper.PowerOff();
}
#if !DEBUG
if(!MD5Util.CheckMD5(exeFile))
{
MessageUtil.ShowError("您的程序不是正版程序,请联系作者获取原版程序并注册!");
WindowsExitHelper.CloseMonitor();
Application.Exit();
Application.DoEvents();
}
#else
#endif
#endregion
8、提供一些不在.NET框架中的Window功能操作辅助类 Win32Window
实现效果
1)本辅助类主要是用来方便实现提供一些不在.NET框架中的Window功能操作辅助类(非线程安全操作)。
2)该辅助类可以使用来查找、遍历系统所有的窗体对象,并可模拟鼠标等对指定位置进行单击、双击等相关操作。
3)通过辅助工具Spy++及AccExplorer32.exe,前者是大名鼎鼎的微软出品,几乎可以抓取所有的Windows窗口及控件(其实也是一个窗口),通过抓取窗口,可以获得窗体的类名、窗体名称、窗体标题、线程、进程等相关信息。为了模拟抓取窗口以及对窗口的各种操作,我们可以通过FindWindow和FindWindowEx、SendMessage、PostMessage等Windows消息来进行处理,便可实现基本的窗口、控件操作,另外按钮的操作,我们则可以模拟鼠标单击某个坐标点的方式实现按钮的单击操作模拟。
实现代码
1)辅助类提供的方法接口如下所示:
View Code
/// <summary>
/// 获取所有最顶层窗体
/// </summary>
public static ArrayList TopLevelWindows
/// <summary>
/// 获取所有应用程序窗体
/// </summary>
public static ArrayList ApplicationWindows
/// <summary>
/// 返回给定线程的所有窗体
/// </summary>
/// <param name="threadId">线程ID</param>
public static ArrayList GetThreadWindows(int threadId)
/// <summary>
/// 获取桌面窗体对象
/// </summary>
public static Win32Window DesktopWindow
/// <summary>
/// 获取当前前置窗体对象
/// </summary>
public static Win32Window ForegroundWindow
/// <summary>
/// 通过窗体类名或者窗体名称查找窗体对象
/// </summary>
/// <param name="className">类名,可为null</param>
/// <param name="windowName">窗体名称,可为null</param>
/// <returns></returns>
public static Win32Window FindWindow(string className, string windowName)
/// <summary>
/// 判断某窗体是否是给定窗体的子窗体
/// </summary>
/// <param name="parent">父窗体对象</param>
/// <param name="window">待检查的窗体对象</param>
/// <returns></returns>
public static bool IsChild(Win32Window parent, Win32Window window)
/// <summary>
/// 桌面截图
/// </summary>
public static Image DesktopAsBitmap
#endregion Static Public
#region Public
/// <summary>
/// 窗体名称
/// </summary>
public string Name
/// <summary>
/// 给定句柄构造一个窗体对象
/// </summary>
/// <param name="window">窗口句柄</param>
public Win32Window(IntPtr window)
/// <summary>
/// 获取窗体对象的句柄
/// </summary>
public IntPtr Window
/// <summary>
/// 如果窗体为空,返回True
/// </summary>
public bool IsNull
/// <summary>
/// 窗体对象的子窗体ArrayList集合
/// </summary>
public ArrayList Children
/// <summary>
/// 设置窗体到顶端位置
/// </summary>
public void BringWindowToTop()
/// <summary>
/// 根据类名或窗体名称,查找其下面的子窗体对象
/// </summary>
/// <param name="className">类名,可为null</param>
/// <param name="windowName">窗体名称,可为null</param>
/// <returns></returns>
public Win32Window FindChild(string className, string windowName)
/// <summary>
/// 发送窗体消息
/// </summary>
public int SendMessage(int message, int wparam, int lparam)
/// <summary>
/// Post消息到窗体对象
/// </summary>
public int PostMessage(int message, int wparam, int lparam)
/// <summary>
/// 发送窗体消息
/// </summary>
public int SendMessage(int wMsg, int wParam, string lpstring)
/// <summary>
/// 模拟按钮单击/双击指定的窗口位置,以便触发相关事件(使用SendMessage方式)
/// </summary>
/// <param name="button">left,right左键或者右键</param>
/// <param name="x">X坐标位置</param>
/// <param name="y">Y坐标位置</param>
/// <param name="doubleklick">是否为双击</param>
public void ClickWindow(string button, int x, int y, bool doubleklick)
/// <summary>
/// 模拟按钮单击/双击指定的窗口位置,以便触发相关事件(使用PostMessage方式)
/// </summary>
/// <param name="button">left,right左键或者右键</param>
/// <param name="x">X坐标位置</param>
/// <param name="y">Y坐标位置</param>
/// <param name="doubleklick">是否为双击</param>
public void ClickWindow_Post(string button, int x, int y, bool doubleklick)
/// <summary>
/// 构造消息参数
/// </summary>
private int MakeLParam(int LoWord, int HiWord)
/// <summary>
/// 获取窗体的父窗体对象,如果为null则表示是最顶层窗体
/// </summary>
public Win32Window Parent
/// <summary>
/// 获取最顶端的弹出窗体对象
/// </summary>
public Win32Window LastActivePopup
/// <summary>
/// 窗体的标题信息
/// </summary>
public string Text
/// <summary>
/// 窗体对象的类名
/// </summary>
public string ClassName
/// <summary>
/// 获取Window窗体的Long Value
/// </summary>
public int GetWindowLong(int index)
/// <summary>
/// 设置Window窗体的Long Value
/// </summary>
public int SetWindowLong(int index, int value)
/// <summary>
/// 该窗体对象的线程ID
/// </summary>
public int ThreadId
/// <summary>
/// 该窗体对象的进程ID
/// </summary>
public int ProcessId
/// <summary>
/// 窗体的布局
/// </summary>
public WindowPlacement WindowPlacement
/// <summary>
/// 判断窗体是否是最小化状态
/// </summary>
public bool Minimized
/// <summary>
/// 判断窗体是否可见
/// </summary>
public bool Visible
/// <summary>
/// 判断窗体是否是最大化状态
/// </summary>
public bool Maximized
/// <summary>
/// Windows窗体转换为BitMap对象
/// </summary>
public Image WindowAsBitmap
/// <summary>
/// Windows的客户区域转换为Bitmap对象
/// </summary>
public Image WindowClientAsBitmap
#endregion
2)辅助类Win32Window的使用例子代码如下所示
Win32Window win = Win32Window.FindWindow(null, this.txtWindowName.Text);
if (win != null)
{
ArrayList list = win.Children;
foreach (Win32Window sub in list)
{
if (sub.Visible && sub.ClassName == "ATL:30A4D1D8")
{
sub.SendMessage(WindowMessage.WM_SETTEXT, 0, this.txtInput.Text);
}
}
}
int x = 288;
int y = 328;
win.ClickWindow("left", x, y, false);
}
其中位置信息时通过Spy++监控出来的信息。
转载请注明出处:撰写人:伍华聪 http://www.iqidi.com