MessageBoxEx.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Windows.Forms;
  7. using System.Runtime.InteropServices;
  8. using System.Drawing;
  9. using System.Management;
  10. using System.Windows.Forms.VisualStyles;
  11. namespace PDF_Master.CustomControl
  12. {
  13. /// <summary>
  14. /// 自定义可以更改按钮文字的Messagebox
  15. /// </summary>
  16. public class MessageBoxEx
  17. {
  18. private static string[] okstring = new string[] { "Ok" };
  19. private static string[] ok = okstring;
  20. private static string[] okcancelstring = new string[] { "OK", "Cancel" };
  21. private static string[] okcancel = okcancelstring;
  22. private static string[] abortretryignorestring = new string[] { "About", "Retry", "Ignore" };
  23. private static string[] abortretryignore = abortretryignorestring;
  24. private static string[] yesnocancelstring = new string[] { "Yes", "No", "Cancel" };
  25. private static string[] yesnocancel = yesnocancelstring;
  26. private static string[] yesnostring = new string[] { "Yes", "No" };
  27. private static string[] yesno = yesnostring;
  28. private static string[] retrycancelstring = new string[] { "Retry", "Cancel" };
  29. private static string[] retrycancel = retrycancelstring;
  30. public static DialogResult Show(string text,string[] buttonTitles = null)
  31. {
  32. if(buttonTitles!=null&&buttonTitles.Length==1)
  33. {
  34. ok = buttonTitles;
  35. }
  36. else
  37. {
  38. ok = okstring;
  39. }
  40. myProc = new HookProc(OK);
  41. SetHook();
  42. //默认标题为产品名
  43. DialogResult result = MessageBox.Show(text, Application.ProductName);
  44. UnHook();
  45. return result;
  46. }
  47. public static DialogResult Show(string text,string title,string[] buttonTitles = null)
  48. {
  49. if (buttonTitles != null && buttonTitles.Length == 1)
  50. {
  51. ok = buttonTitles;
  52. }
  53. else
  54. {
  55. ok = okstring;
  56. }
  57. myProc = new HookProc(OK);
  58. SetHook();
  59. DialogResult result = MessageBox.Show(text,title);
  60. UnHook();
  61. return result;
  62. }
  63. public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, string[] buttonTitles=null)
  64. {
  65. switch (buttons)
  66. {
  67. case MessageBoxButtons.OK:
  68. if (buttonTitles != null && buttonTitles.Length == 1)
  69. {
  70. ok = buttonTitles;
  71. }
  72. else
  73. {
  74. ok = okstring;
  75. }
  76. myProc = new HookProc(OK);
  77. break;
  78. case MessageBoxButtons.OKCancel:
  79. if (buttonTitles != null && buttonTitles.Length == 2)
  80. {
  81. okcancel = buttonTitles;
  82. }
  83. else
  84. {
  85. okcancel = okcancelstring;
  86. }
  87. myProc = new HookProc(OKCancel);
  88. break;
  89. case MessageBoxButtons.AbortRetryIgnore:
  90. if (buttonTitles != null && buttonTitles.Length == 3)
  91. {
  92. abortretryignore = buttonTitles;
  93. }
  94. else
  95. {
  96. abortretryignore = abortretryignorestring;
  97. }
  98. myProc = new HookProc(AbortRetryIgnore);
  99. break;
  100. case MessageBoxButtons.YesNoCancel:
  101. if (buttonTitles != null && buttonTitles.Length == 3)
  102. {
  103. yesnocancel = buttonTitles;
  104. }
  105. else
  106. {
  107. yesnocancel = yesnocancelstring;
  108. }
  109. myProc = new HookProc(YesNoCancel);
  110. break;
  111. case MessageBoxButtons.YesNo:
  112. if (buttonTitles != null && buttonTitles.Length == 2)
  113. {
  114. yesno = buttonTitles;
  115. }
  116. else
  117. {
  118. yesno = yesnostring;
  119. }
  120. myProc = new HookProc(YesNo);
  121. break;
  122. case MessageBoxButtons.RetryCancel:
  123. if (buttonTitles != null && buttonTitles.Length == 2)
  124. {
  125. retrycancel = buttonTitles;
  126. }
  127. else
  128. {
  129. retrycancel = retrycancelstring;
  130. }
  131. myProc = new HookProc(RetryCancel);
  132. break;
  133. default:
  134. break;
  135. }
  136. SetHook();
  137. DialogResult result = MessageBox.Show(text, string.IsNullOrEmpty(caption)?Application.ProductName:caption, buttons);
  138. UnHook();
  139. return result;
  140. }
  141. public static DialogResult Show(string text, string caption, MessageBoxButtons buttons,MessageBoxIcon icons,string[] buttonTitles = null)
  142. {
  143. switch (buttons)
  144. {
  145. case MessageBoxButtons.OK:
  146. if (buttonTitles != null && buttonTitles.Length == 1)
  147. {
  148. ok = buttonTitles;
  149. }
  150. else
  151. {
  152. ok = okstring;
  153. }
  154. myProc = new HookProc(OK);
  155. break;
  156. case MessageBoxButtons.OKCancel:
  157. if (buttonTitles != null && buttonTitles.Length == 2)
  158. {
  159. okcancel = buttonTitles;
  160. }
  161. else
  162. {
  163. okcancel = okcancelstring;
  164. }
  165. myProc = new HookProc(OKCancel);
  166. break;
  167. case MessageBoxButtons.AbortRetryIgnore:
  168. if (buttonTitles != null && buttonTitles.Length == 3)
  169. {
  170. abortretryignore = buttonTitles;
  171. }
  172. else
  173. {
  174. abortretryignore = abortretryignorestring;
  175. }
  176. myProc = new HookProc(AbortRetryIgnore);
  177. break;
  178. case MessageBoxButtons.YesNoCancel:
  179. if (buttonTitles != null && buttonTitles.Length == 3)
  180. {
  181. yesnocancel = buttonTitles;
  182. }
  183. else
  184. {
  185. yesnocancel = yesnocancelstring;
  186. }
  187. myProc = new HookProc(YesNoCancel);
  188. break;
  189. case MessageBoxButtons.YesNo:
  190. if (buttonTitles != null && buttonTitles.Length == 2)
  191. {
  192. yesno = buttonTitles;
  193. }
  194. else
  195. {
  196. yesno = yesnostring;
  197. }
  198. myProc = new HookProc(YesNo);
  199. break;
  200. case MessageBoxButtons.RetryCancel:
  201. if (buttonTitles != null && buttonTitles.Length == 2)
  202. {
  203. retrycancel = buttonTitles;
  204. }
  205. else
  206. {
  207. retrycancel = retrycancelstring;
  208. }
  209. myProc = new HookProc(RetryCancel);
  210. break;
  211. default:
  212. break;
  213. }
  214. SetHook();
  215. DialogResult result = MessageBox.Show(text, string.IsNullOrEmpty(caption) ? Application.ProductName : caption, buttons, icons);
  216. UnHook();
  217. return result;
  218. }
  219. public static DialogResult Show(string text, string caption, MessageBoxButtons buttons,
  220. MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, string[] buttonTitles=null)
  221. {
  222. switch (buttons)
  223. {
  224. case MessageBoxButtons.OK:
  225. if (buttonTitles != null && buttonTitles.Length == 1)
  226. {
  227. ok = buttonTitles;
  228. }
  229. else
  230. {
  231. ok = okstring;
  232. }
  233. myProc = new HookProc(OK);
  234. break;
  235. case MessageBoxButtons.OKCancel:
  236. if (buttonTitles != null && buttonTitles.Length == 2)
  237. {
  238. okcancel = buttonTitles;
  239. }
  240. else
  241. {
  242. okcancel = okcancelstring;
  243. }
  244. myProc = new HookProc(OKCancel);
  245. break;
  246. case MessageBoxButtons.AbortRetryIgnore:
  247. if (buttonTitles != null && buttonTitles.Length == 3)
  248. {
  249. abortretryignore = buttonTitles;
  250. }
  251. else
  252. {
  253. abortretryignore = abortretryignorestring;
  254. }
  255. myProc = new HookProc(AbortRetryIgnore);
  256. break;
  257. case MessageBoxButtons.YesNoCancel:
  258. if (buttonTitles != null && buttonTitles.Length == 3)
  259. {
  260. yesnocancel = buttonTitles;
  261. }
  262. else
  263. {
  264. yesnocancel = yesnocancelstring;
  265. }
  266. myProc = new HookProc(YesNoCancel);
  267. break;
  268. case MessageBoxButtons.YesNo:
  269. if (buttonTitles != null && buttonTitles.Length == 2)
  270. {
  271. yesno = buttonTitles;
  272. }
  273. else
  274. {
  275. yesno = yesnostring;
  276. }
  277. myProc = new HookProc(YesNo);
  278. break;
  279. case MessageBoxButtons.RetryCancel:
  280. if (buttonTitles != null && buttonTitles.Length == 2)
  281. {
  282. retrycancel = buttonTitles;
  283. }
  284. else
  285. {
  286. retrycancel = retrycancelstring;
  287. }
  288. myProc = new HookProc(RetryCancel);
  289. break;
  290. default:
  291. break;
  292. }
  293. DialogResult result = MessageBox.Show(text, string.IsNullOrEmpty(caption) ? Application.ProductName : caption, buttons, icon, defaultButton);
  294. return result;
  295. }
  296. //用钩子的方式 更改文本
  297. public enum HookType
  298. {
  299. Keyboard = 2,//键盘操作
  300. CBT = 5,//窗口操作
  301. Mouse = 7, //鼠标操作
  302. };
  303. [DllImport("kernel32.dll")]
  304. static extern int GetCurrentThreadId();//得到当前的线程ID
  305. [DllImport("user32.dll")]
  306. static extern int GetDlgItem(IntPtr hDlg, int nIDDlgItem);//得到Dialog窗口的子项
  307. [DllImport("user32", EntryPoint = "SetDlgItemText")]
  308. static extern int SetDlgItemTextA(IntPtr hDlg, int nIDDlgItem, string lpString);//设置Dialog窗口子项的文本
  309. [DllImport("user32.dll", EntryPoint = "SetWindowTextW", CharSet = CharSet.Unicode)]
  310. private static extern bool SetWindowText(IntPtr hWnd, string lpString);
  311. [DllImport("user32.dll")]
  312. static extern void UnhookWindowsHookEx(IntPtr handle);//解掉挂钩
  313. [DllImport("user32.dll")]
  314. static extern IntPtr SetWindowsHookEx(int idHook, [MarshalAs(UnmanagedType.FunctionPtr)] HookProc lpfn, IntPtr
  315. hInstance, int threadID);//设置挂钩
  316. [DllImport("user32.dll")]
  317. static extern IntPtr CallNextHookEx(IntPtr handle, int code, IntPtr wparam, IntPtr lparam);//进行下一个挂钩,如果有的话
  318. static IntPtr _nextHookPtr;
  319. ////must be global, or it will be Collected by GC, then no callback func can be used for the Hook
  320. static HookProc myProc = new HookProc(MyHookProc);
  321. private delegate IntPtr HookProc(int code, IntPtr wparam, IntPtr lparam);
  322. private static IntPtr OK(int code, IntPtr wparam, IntPtr lparam)
  323. {
  324. IntPtr hChildWnd;
  325. if (code == 5)//HCBT_ACTIVATE = 5
  326. {
  327. hChildWnd = wparam;
  328. var index = (IntPtr)GetDlgItem(hChildWnd,1);
  329. if (index != IntPtr.Zero)
  330. {
  331. SetWindowText(index, ok[0]);
  332. }
  333. }
  334. else
  335. CallNextHookEx(_nextHookPtr, code, wparam, lparam);
  336. return IntPtr.Zero;
  337. }
  338. private static IntPtr OKCancel(int code, IntPtr wparam, IntPtr lparam)
  339. {
  340. IntPtr hChildWnd;
  341. bool result = false;
  342. if (code == 5)//HCBT_ACTIVATE = 5
  343. {
  344. hChildWnd = wparam;
  345. IntPtr index = (IntPtr)GetDlgItem(hChildWnd, 1);
  346. if (index != IntPtr.Zero)
  347. {
  348. result = SetWindowText(index, okcancel[0]);
  349. }
  350. index = (IntPtr)GetDlgItem(hChildWnd, 2);
  351. if (index != IntPtr.Zero)
  352. {
  353. result = SetWindowText(index, okcancel[1]);
  354. }
  355. }
  356. else
  357. CallNextHookEx(_nextHookPtr, code, wparam, lparam);
  358. return IntPtr.Zero;
  359. }
  360. private static IntPtr RetryCancel(int code, IntPtr wparam, IntPtr lparam)
  361. {
  362. IntPtr hChildWnd;
  363. if (code == 5)//HCBT_ACTIVATE = 5
  364. {
  365. hChildWnd = wparam;
  366. var index = (IntPtr)GetDlgItem(hChildWnd,4);
  367. if (index!=IntPtr.Zero)
  368. {
  369. SetWindowText(index, retrycancel[0]);
  370. }
  371. index = (IntPtr)GetDlgItem(hChildWnd, 2);
  372. if (GetDlgItem(hChildWnd, 2) != 0)
  373. {
  374. SetWindowText(index, retrycancel[1]);
  375. }
  376. }
  377. else
  378. CallNextHookEx(_nextHookPtr, code, wparam, lparam);
  379. return IntPtr.Zero;
  380. }
  381. private static IntPtr YesNo(int code, IntPtr wparam, IntPtr lparam)
  382. {
  383. IntPtr hChildWnd;
  384. if (code == 5)//HCBT_ACTIVATE = 5
  385. {
  386. hChildWnd = wparam;
  387. var index = (IntPtr)GetDlgItem(hChildWnd, 6);
  388. if (index!=IntPtr.Zero)
  389. {
  390. SetWindowText(index, yesno[0]);
  391. }
  392. index = (IntPtr)GetDlgItem(hChildWnd, 7);
  393. if (index != IntPtr.Zero)
  394. {
  395. SetWindowText(index, yesno[1]);
  396. }
  397. }
  398. else
  399. CallNextHookEx(_nextHookPtr, code, wparam, lparam);
  400. return IntPtr.Zero;
  401. }
  402. private static IntPtr YesNoCancel(int code, IntPtr wparam, IntPtr lparam)
  403. {
  404. IntPtr hChildWnd;
  405. if (code == 5)//HCBT_ACTIVATE = 5
  406. {
  407. hChildWnd = wparam;
  408. var index = (IntPtr)GetDlgItem(hChildWnd, 6);
  409. if (index != IntPtr.Zero)
  410. {
  411. SetWindowText(index,yesnocancel[0]);
  412. }
  413. index = (IntPtr)GetDlgItem(hChildWnd, 7);
  414. if (index != IntPtr.Zero)
  415. {
  416. SetWindowText(index, yesnocancel[1]);
  417. }
  418. index = (IntPtr)GetDlgItem(hChildWnd, 2);
  419. if (index != IntPtr.Zero)
  420. {
  421. SetWindowText(index, yesnocancel[2]);
  422. }
  423. }
  424. else
  425. CallNextHookEx(_nextHookPtr, code, wparam, lparam);
  426. return IntPtr.Zero;
  427. }
  428. private static IntPtr AbortRetryIgnore(int code, IntPtr wparam, IntPtr lparam)
  429. {
  430. IntPtr hChildWnd;
  431. if (code == 5)//HCBT_ACTIVATE = 5
  432. {
  433. hChildWnd = wparam;
  434. var index = (IntPtr)GetDlgItem(hChildWnd, 3);
  435. if (index != IntPtr.Zero)
  436. {
  437. SetWindowText(index, abortretryignore[0]);
  438. }
  439. index = (IntPtr)GetDlgItem(hChildWnd, 4);
  440. if (index != IntPtr.Zero)
  441. {
  442. SetWindowText(index, abortretryignore[1]);
  443. }
  444. index = (IntPtr)GetDlgItem(hChildWnd, 5);
  445. if (index != IntPtr.Zero)
  446. {
  447. SetWindowText(index, abortretryignore[2]);
  448. }
  449. }
  450. else
  451. CallNextHookEx(_nextHookPtr, code, wparam, lparam);
  452. return IntPtr.Zero;
  453. }
  454. private static IntPtr MyHookProc(int code, IntPtr wparam, IntPtr lparam)
  455. {
  456. IntPtr hChildWnd;// msgbox is "child"
  457. // notification that a window is about to be activated
  458. // window handle is wParam
  459. if (code == 5)//HCBT_ACTIVATE = 5
  460. {
  461. // set window handles of messagebox
  462. hChildWnd = wparam;
  463. //to get the text of yes button
  464. for(int i=0;i<21;i++)
  465. {
  466. if (GetDlgItem(hChildWnd, i) != 0)
  467. SetDlgItemTextA(hChildWnd,i,string.Format("Item {0}",i));
  468. }
  469. }
  470. else
  471. {
  472. CallNextHookEx(_nextHookPtr, code, wparam, lparam);// otherwise, continue with any possible chained hooks
  473. }
  474. //return (IntPtr)1; //直接返回了,该消息就处理结束了
  475. return IntPtr.Zero;//返回,让后面的程序处理该消息
  476. }
  477. public static void SetHook()
  478. {
  479. if (_nextHookPtr != IntPtr.Zero)//Hooked already
  480. {
  481. return;
  482. }
  483. _nextHookPtr = SetWindowsHookEx((int)HookType.CBT, myProc, IntPtr.Zero, GetCurrentThreadId());
  484. }
  485. public static void UnHook()
  486. {
  487. if (_nextHookPtr != IntPtr.Zero)
  488. {
  489. UnhookWindowsHookEx(_nextHookPtr);
  490. _nextHookPtr = IntPtr.Zero;
  491. }
  492. }
  493. }
  494. }