前面幾篇介紹了關于公用類庫的使用詳細情況,好久沒更新這個系列了,一直忙于Winform開發框架、WCF開發框架的細節完善工作,終于有時間、有興趣繼續介紹這個公用類庫的使用了。
本文主要介紹公用類庫中Winform開發部分的內容,一個是接著詳細介紹類庫的使用供自己查看和他人了解,二個是將其逐步整理成相關的幫助文檔,三是精細化提煉已有的類庫,更上一層樓。
厚積薄發,豐富的公用類庫積累,助你高效進行系統開發(4)
**1、實現系統全局熱鍵注冊輔助類 RegisterHotKeyHelper **
**實現效果 **
1)本輔助類主要是用來方便實現系統全局熱鍵注冊,全局熱鍵不同于一般的快捷鍵,它在程序最小化的時候依舊能夠調用運行,常見的看到有QQ的熱鍵提取消息,輸入法熱鍵等。
2)該熱鍵輔助類,創建一個實例對象會綁定一個具體的事件處理,主程序退出的時候,熱鍵自動失效,使用非常方便。
3)結合托盤圖標最小化,我們可以通過該類創建一個老板鍵(輸入某組合鍵隱藏或顯示窗體)。
實現代碼
1)輔助類提供的方法接口如下所示:
/// <summary>
/// 主窗體句柄
/// </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彈出提示信息。
public partial class Form1 : Form
{
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)本輔助類主要是用來方便實現在多線程中處理中,對數據的綁定和賦值。
2)我們知道,微軟的.NET控件做了大量的工作,用起來還是不錯的,一般的數據綁定或者賦值比較簡單。如下所示
文本賦值: txtTest.Text = "abc";
控件禁用: txtTest.Enable = false;
復雜的控件,如DataGridView的數據綁定,也是比較簡單,只要數據源支持IListDataSource接口就可以了。
3)在一般的單線程程序中,我們的數據綁定和UI的線程是一起的,那么綁定很正常,很OK,但是在多線程里面,如果你需要綁定這些數據,那么就要費一點周章了。 一般在線程間處理界面控件的數據綁定的時候,處理是這樣的,下面通過一個文本控件的屬性操作進行演示:
this.Invoke(new MethodInvoker(delegate()
{
this.Text = message;
}));
this.Invoke(new MethodInvoker(delegate()
{
this.Enable= false;
}));
4)為了方便,封裝了一般控件的跨線程訪問的公共類,操作控件的代碼可以變化為另外一種情況(和上面不同的方式).
CallCtrlWithThreadSafety.SetText(this, "您要顯示的文本", this);
//禁用按鈕
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 qq = QQList[currentIndex];
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);
}
或者
try
{
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的使用例子代碼如下所示
private void btnAnimator_Click(object sender, EventArgs e)
{
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的使用例子代碼如下所示
private void btnFreezeWindow_Click(object sender, EventArgs e)
{
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的使用例子代碼如下所示
public partial class FrmAnimator : Form
{
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 dir = System.AppDomain.CurrentDomain.BaseDirectory;
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)輔助類提供的方法接口如下所示:
#region Static Public
/// <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的使用例子代碼如下所示'
private void btnSearch_Click(object sender, EventArgs e)
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++監控出來的信息。
CHM幫助文檔持續更新中,統一下載地址是:http://www.iqidi.com/download/commonshelp.rar