利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)

时间:2022-02-27 09:41:34

http://blog.csdn.net/lovefootball/article/details/1784882

在写Windows应用程序的时候,经常会碰到需要修改例如MessageBox或者FileDialog的外观
此时我们需要监视 WndProc的消息
当然也可以直接调用API实现,具体方法请参考
http://www.codeproject.com/csharp/GetSaveFileName.asp?df=100&forumid=96342&exp=0&select=1950454
主要代码如下

  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Windows.Forms;
  4. using System.Collections.Generic;
  5. namespace testApplication1
  6. {
  7. public delegate void HookWndProcHandler(ref Message m);
  8. public class HookWndProc
  9. {
  10. private Dictionary<Control, NativeWindow> nativeWindows = new Dictionary<Control, NativeWindow>();
  11. public event HookWndProcHandler WndProcEvent;
  12. public void BeginHookProc(Control control)
  13. {
  14. if(nativeWindows.ContainsKey(control))
  15. {
  16. return;
  17. }
  18. nativeWindows.Add(control, new HookNativeWindow(this, control));
  19. }
  20. public void EndHookProc(Control control)
  21. {
  22. if(!nativeWindows.ContainsKey(control))
  23. {
  24. return;
  25. }
  26. NativeWindow window = nativeWindows[control];
  27. nativeWindows.Remove(control);
  28. window.ReleaseHandle();
  29. window = null;
  30. }
  31. protected virtual void WndProc(ref Message m)
  32. {
  33. FireWndProcEvent(ref m);
  34. }
  35. protected void FireWndProcEvent(ref Message m)
  36. {
  37. if (WndProcEvent != null)
  38. {
  39. WndProcEvent(ref m);
  40. }
  41. }
  42. #region NativeWindow
  43. protected class HookNativeWindow : NativeWindow
  44. {
  45. private HookWndProc hookWndProc;
  46. public HookNativeWindow(HookWndProc hookWndProc, Control control)
  47. {
  48. this.hookWndProc = hookWndProc;
  49. if (control.IsHandleCreated)
  50. {
  51. AssignHandle(control.Handle);
  52. }
  53. else
  54. {
  55. control.HandleCreated += new EventHandler(OnControlHandleCreated);
  56. }
  57. control.HandleDestroyed += new EventHandler(OnControlHandleDestroyed);
  58. }
  59. private void OnControlHandleCreated(object sender, EventArgs e)
  60. {
  61. AssignHandle(((Control)sender).Handle);
  62. }
  63. private void OnControlHandleDestroyed(object sender, EventArgs e)
  64. {
  65. ReleaseHandle();
  66. }
  67. [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name ="FullTrust")]
  68. protected override void WndProc(ref Message m)
  69. {
  70. hookWndProc.WndProc(ref m);
  71. base.WndProc(ref m);
  72. }
  73. }
  74. #endregion
  75. }
  76. }
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Windows.Forms;
  4. using System.Collections.Generic;
  5. namespace testApplication1
  6. {
  7. public delegate void HookWndProcHandler(ref Message m);
  8. public class HookWndProc
  9. {
  10. private Dictionary<Control, NativeWindow> nativeWindows = new Dictionary<Control, NativeWindow>();
  11. public event HookWndProcHandler WndProcEvent;
  12. public void BeginHookProc(Control control)
  13. {
  14. if(nativeWindows.ContainsKey(control))
  15. {
  16. return;
  17. }
  18. nativeWindows.Add(control, new HookNativeWindow(this, control));
  19. }
  20. public void EndHookProc(Control control)
  21. {
  22. if(!nativeWindows.ContainsKey(control))
  23. {
  24. return;
  25. }
  26. NativeWindow window = nativeWindows[control];
  27. nativeWindows.Remove(control);
  28. window.ReleaseHandle();
  29. window = null;
  30. }
  31. protected virtual void WndProc(ref Message m)
  32. {
  33. FireWndProcEvent(ref m);
  34. }
  35. protected void FireWndProcEvent(ref Message m)
  36. {
  37. if (WndProcEvent != null)
  38. {
  39. WndProcEvent(ref m);
  40. }
  41. }
  42. #region NativeWindow
  43. protected class HookNativeWindow : NativeWindow
  44. {
  45. private HookWndProc hookWndProc;
  46. public HookNativeWindow(HookWndProc hookWndProc, Control control)
  47. {
  48. this.hookWndProc = hookWndProc;
  49. if (control.IsHandleCreated)
  50. {
  51. AssignHandle(control.Handle);
  52. }
  53. else
  54. {
  55. control.HandleCreated += new EventHandler(OnControlHandleCreated);
  56. }
  57. control.HandleDestroyed += new EventHandler(OnControlHandleDestroyed);
  58. }
  59. private void OnControlHandleCreated(object sender, EventArgs e)
  60. {
  61. AssignHandle(((Control)sender).Handle);
  62. }
  63. private void OnControlHandleDestroyed(object sender, EventArgs e)
  64. {
  65. ReleaseHandle();
  66. }
  67. [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
  68. protected override void WndProc(ref Message m)
  69. {
  70. hookWndProc.WndProc(ref m);
  71. base.WndProc(ref m);
  72. }
  73. }
  74. #endregion
  75. }
  76. }

调用方法,以更改MessageBox的OK按钮文本为例

利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)            HookWndProc hookWndProc = new HookWndProc();
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)            hookWndProc.WndProcEvent += new HookWndProcHandler(hookWndProc_WndProcEvent);
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)            hookWndProc.BeginHookProc(this);
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)            MessageBox.Show("MSG APP", "MessageBoxCaption", MessageBoxButtons.OKCancel);
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)            hookWndProc.EndHookProc(this);
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)private void hookWndProc_WndProcEvent(ref Message m)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        ...{
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)            IntPtr wnd = FindWindow(null, "MessageBoxCaption");
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)            if (wnd != IntPtr.Zero)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)            ...{
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)                SetDlgItemText(wnd, 1, "需要修改的文本");
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)            }
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        }
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        [DllImport("user32.dll")]
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        public static extern IntPtr SetDlgItemText(IntPtr hwnd, int id, string caption);

也就是说在WndProcEvent事件里面你可以写上你所需要做的事情

如果需要修改FileDialog的外观
则需要在WndProcEvent事件里面写上如下代码

利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)if (m.Msg == WM_ENTERIDLE)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)...{
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)    uint dialogHandle = (uint)m.LParam;
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)    uint listviewHandle = FindWindowEx(dialogHandle, 0, "SHELLDLL_DefView", "");
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)    if (listviewHandle != 0 && listviewHandle != lastListViewHandle)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)    ...{
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        SendMessage(listviewHandle, WM_COMMAND, (uint)View, 0);
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)}
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)lastListViewHandle = listviewHandle;
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)    /**//// <summary>
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)    /// FileListViewType
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)    /// </summary>
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)    public enum FileListView
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)    ...{
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        Icons = 0x7029,
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        SmallIcons = 0x702a,
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        List = 0x702b,
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        Details = 0x702c,
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        Thumbnails = 0x7031,
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        XpThumbnails = 0x702d
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)    }
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        /**//// <summary>
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        /// win message : command
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        /// </summary>
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        private const uint WM_COMMAND = 0x0111;
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        /**//// <summary>
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        /// win message : enter idle
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        /// </summary>
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        private const uint WM_ENTERIDLE = 0x0121;
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        /**//// <summary>
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        /// listview type
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        /// </summary>
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        private FileListView view = FileListView.Thumbnails;
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        /**//// <summary>
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        /// dialog handle
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        /// </summary>
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        private uint lastListViewHandle = 0;
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)DllImports
#region DllImports
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        [DllImport("user32.dll", EntryPoint="SendMessageA", CallingConvention=CallingConvention.StdCall,CharSet=CharSet.Ansi)] 
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        private static extern uint SendMessage(uint Hdc, uint Msg_Const, uint wParam, uint lParam);
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        [DllImport("user32.dll", EntryPoint="FindWindowExA", CallingConvention=CallingConvention.StdCall,CharSet=CharSet.Ansi)] 
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        private static extern uint FindWindowEx(uint hwndParent, uint hwndChildAfter, string lpszClass,string lpszWindow);
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)
利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)        #endregion

SetDlgItemText(wnd, 1, "需要修改的文本");

private const int IDOK = 1;
private const int IDCANCEL = 2;
private const int IDABORT = 3;
private const int IDRETRY = 4;
private const int IDIGNORE = 5;
private const int IDYES = 6;
private const int IDNO = 7;

欢迎转载,请注明出处~~

http://blog.csdn.net/jiangxinyu/article/details/8080409