需要用到hook,具體hook類在附件裏,此hook類也是網上扒來的,忘了地址了。。。。否則作爲尊重應該貼上原文地址的。。。
原hook類寫了有鍵鼠hook,MessageBox 是我後添加的,如果有其他hook也可以參照我的方式自己添加。
詳解自定義hook:(以下都是hook類裏有的,不需要再複製添加)
具體調用方式在末尾的第二個代碼段內有,複製過去就可以用
首先定義一個事件,在寫對應的鉤子回調函數,在函數類觸發事件即可,至於事件的具體執行什麼動作則在外部定義hook時設置,和註冊控件的事件一樣的。
下面就是一個自定義hook所需要添加的完整代碼
Hook.cs:
/// <summary>
/// 彈窗鉤子
/// </summary>
private int msboxHook = 0;
/// <summary>
/// 彈窗鉤子回調函數
/// </summary>
private HookProc mboxHook;
/// <summary>
/// 定義一個自定義的事件
/// </summary>
public event EventHandler<MessageBoxEventArgs> OnMessageBoxShow;
public class MessageBoxEventArgs
{
public MessageBoxEventArgs() { }
public MessageBoxEventArgs(IntPtr _hChildWnd)
{
hChildWnd = _hChildWnd;
}
public IntPtr hChildWnd;
}
/// <summary>
/// 安裝彈窗鉤子
/// </summary>
/// <param name="type"></param>
public void InstallMessageBoxHook()
{
InstallMessageBoxHook(HookType.WH_CBT);
}
/// <summary>
/// 安裝彈窗鉤子
/// </summary>
/// <param name="type"></param>
public void InstallMessageBoxHook(HookType type)
{
if (msboxHook == 0)
{
mboxHook = new HookProc(DefaultMessageBoxHookProc);
msboxHook = Win32Api_Hook.SetWindowsHookEx(
type,
mboxHook,
Win32Api_Hook.GetModuleHandle(
Process.GetCurrentProcess().MainModule.ModuleName
),
Win32Api_Hook.GetCurrentThreadId()//自身線程,如果是0則表示全局
);
if (msboxHook == 0)
UninstallMessageBoxHook();
}
}
/// <summary>
/// 卸載彈窗鉤子
/// </summary>
public void UninstallMessageBoxHook()
{
UninstallHook(ref msboxHook);
}
/// <summary>
/// 這是一個鉤子回調函數,參數都是統一的
/// </summary>
private int DefaultMessageBoxHookProc(int nCode, int wParam, IntPtr lParam)
{
IntPtr hChildWnd;// msgbox is "child"
// notification that a window is about to be activated
// window handle is wParam
if (nCode == 5)//HCBT_ACTIVATE = 5
{
// set window handles of messagebox
hChildWnd = (IntPtr)wParam;
//to get the text of yes button
//自定義事件,在外部調用時通過註冊事件執行對應邏輯即可
OnMessageBoxShow.Invoke(this, new MessageBoxEventArgs(hChildWnd));
//return (IntPtr)1; //直接返回了,該消息就處理結束了
return Win32Api_Hook.CallNextHookEx(msboxHook, nCode, wParam, lParam);// otherwise, continue with any possible chained hooks; //返回,讓後面的程序處理該消息
}
具體調用方式
private void checkBox_pause_CheckedChanged(object sender, EventArgs e)
{
BeginInvoke(new Action(() =>
{
if (!checkBox_pause.Checked)
{
Properties.Settings.Default.pause = false;
Properties.Settings.Default.pauseWorker = false;
Logger.Log("已取消暫停,恢復運行");
return;
}
Action<DialogResult> handle = (dialogResult) => {
if (dialogResult == DialogResult.Yes)
{
Properties.Settings.Default.pause = true;
Logger.Warn("已暫停,將暫停開啓新線程和已開啓的工作線程");
}
else if (dialogResult == DialogResult.No)
{
Properties.Settings.Default.pauseWorker = true;
Logger.Warn("已暫停開啓新線程,已開啓線程將繼續運行直到完成");
}
};
HookMessageBoxShow($"(Y)暫停整個程序\r\n(N)暫停開啓新線程,已開啓線程會繼續執行", "暫停", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information,
"暫停(Y)", "暫停開新(N)", "", handle);
}));
}
/// <summary>
/// 帶返回值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="text"></param>
/// <param name="caption"></param>
/// <param name="buttons"></param>
/// <param name="icon"></param>
/// <param name="yesText"></param>
/// <param name="noText"></param>
/// <param name="cancelText"></param>
/// <param name="handleResult"></param>
/// <returns></returns>
public T HookMessageBoxShow<T>(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon = MessageBoxIcon.Information,
string yesText = "",string noText = "",string cancelText = "",Func<DialogResult,T> handleResult = null)
{
//hook 修改彈出窗按鈕 文本
var hook = new HookINCS.Hook();
hook.OnMessageBoxShow += (s, mbe) =>
{
IntPtr hChildWnd = mbe.hChildWnd;
int result;
if (!string.IsNullOrEmpty(yesText) && HookINCS.Win32Api_Hook.GetDlgItem(hChildWnd, 6) != 0)//IDYES = 6
{
result = HookINCS.Win32Api_Hook.SetDlgItemTextA(hChildWnd, 6, $"{yesText}");//在Project.Resources裏自定義文本
}
if (!string.IsNullOrEmpty(noText) && HookINCS.Win32Api_Hook.GetDlgItem(hChildWnd, 7) != 0)//IDNO = 7
{
result = HookINCS.Win32Api_Hook.SetDlgItemTextA(hChildWnd, 7, $"{noText}");
}
if (!string.IsNullOrEmpty(cancelText) && HookINCS.Win32Api_Hook.GetDlgItem(hChildWnd, 2) != 0)//IDCANCEL = 2
{
result = HookINCS.Win32Api_Hook.SetDlgItemTextA(hChildWnd, 7, $"{cancelText}");
}
};
hook.InstallMessageBoxHook();
DialogResult dialogResult = MessageBox.Show(text, caption, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);
if (handleResult == null)
{
//卸載鉤子
hook.UninstallMessageBoxHook();
return default;
}
//卸載鉤子
hook.UninstallMessageBoxHook();
return handleResult(dialogResult);
}
/// <summary>
/// 不帶返回值
/// </summary>
/// <param name="text"></param>
/// <param name="caption"></param>
/// <param name="buttons"></param>
/// <param name="icon"></param>
/// <param name="yesText"></param>
/// <param name="noText"></param>
/// <param name="cancelText"></param>
/// <param name="handleResult"></param>
public void HookMessageBoxShow(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon = MessageBoxIcon.Information,
string yesText = "", string noText = "", string cancelText = "", Action<DialogResult> handleResult = null)
{
//hook 修改彈出窗按鈕 文本
var hook = new HookINCS.Hook();
hook.OnMessageBoxShow += (s, mbe) =>
{
IntPtr hChildWnd = mbe.hChildWnd;
int result;
if (!string.IsNullOrEmpty(yesText) && HookINCS.Win32Api_Hook.GetDlgItem(hChildWnd, 6) != 0)//IDYES = 6
{
result = HookINCS.Win32Api_Hook.SetDlgItemTextA(hChildWnd, 6, $"{yesText}");//在Project.Resources裏自定義文本
}
if (!string.IsNullOrEmpty(noText) && HookINCS.Win32Api_Hook.GetDlgItem(hChildWnd, 7) != 0)//IDNO = 7
{
result = HookINCS.Win32Api_Hook.SetDlgItemTextA(hChildWnd, 7, $"{noText}");
}
if (!string.IsNullOrEmpty(cancelText) && HookINCS.Win32Api_Hook.GetDlgItem(hChildWnd, 2) != 0)//IDCANCEL = 2
{
result = HookINCS.Win32Api_Hook.SetDlgItemTextA(hChildWnd, 7, $"{cancelText}");
}
};
hook.InstallMessageBoxHook();
DialogResult dialogResult = MessageBox.Show(text, caption, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);
if (handleResult != null)
handleResult(dialogResult);
//卸載鉤子
hook.UninstallMessageBoxHook();
}
fouz