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

Posted 朝闻道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)相关的知识,希望对你有一定的参考价值。

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
主要代码如下

 

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



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

 

 

 

技术分享
技术分享            HookWndProc hookWndProc = new HookWndProc();
技术分享            hookWndProc.WndProcEvent += new HookWndProcHandler(hookWndProc_WndProcEvent);
技术分享            hookWndProc.BeginHookProc(this);
技术分享            MessageBox.Show("MSG APP", "MessageBoxCaption", MessageBoxButtons.OKCancel);
技术分享            hookWndProc.EndHookProc(this);
技术分享
技术分享private void hookWndProc_WndProcEvent(ref Message m)
技术分享技术分享        ...{
技术分享            IntPtr wnd = FindWindow(null, "MessageBoxCaption");
技术分享
技术分享            if (wnd != IntPtr.Zero)
技术分享技术分享            ...{
技术分享                SetDlgItemText(wnd, 1, "需要修改的文本");
技术分享            }
技术分享        }
技术分享        [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
技术分享        private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
技术分享
技术分享        [DllImport("user32.dll")]
技术分享        public static extern IntPtr SetDlgItemText(IntPtr hwnd, int id, string caption);

 


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

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

技术分享if (m.Msg == WM_ENTERIDLE)
技术分享技术分享...{
技术分享    uint dialogHandle = (uint)m.LParam;
技术分享    uint listviewHandle = FindWindowEx(dialogHandle, 0, "SHELLDLL_DefView", "");
技术分享    if (listviewHandle != 0 && listviewHandle != lastListViewHandle)
技术分享技术分享    ...{
技术分享        SendMessage(listviewHandle, WM_COMMAND, (uint)View, 0);
技术分享}
技术分享lastListViewHandle = listviewHandle;
技术分享
技术分享
技术分享
技术分享技术分享    /**//// <summary>
技术分享    /// FileListViewType
技术分享    /// </summary>
技术分享    public enum FileListView
技术分享技术分享    ...{
技术分享        Icons = 0x7029,
技术分享        SmallIcons = 0x702a,
技术分享        List = 0x702b,
技术分享        Details = 0x702c,
技术分享        Thumbnails = 0x7031,
技术分享        XpThumbnails = 0x702d
技术分享    }
技术分享
技术分享
技术分享技术分享        /**//// <summary>
技术分享        /// win message : command
技术分享        /// </summary>
技术分享        private const uint WM_COMMAND = 0x0111;
技术分享
技术分享技术分享        /**//// <summary>
技术分享        /// win message : enter idle
技术分享        /// </summary>
技术分享        private const uint WM_ENTERIDLE = 0x0121;
技术分享
技术分享技术分享        /**//// <summary>
技术分享        /// listview type
技术分享        /// </summary>
技术分享        private FileListView view = FileListView.Thumbnails;
技术分享
技术分享技术分享        /**//// <summary>
技术分享        /// dialog handle
技术分享        /// </summary>
技术分享        private uint lastListViewHandle = 0;
技术分享
技术分享技术分享DllImports
#region DllImports
技术分享
技术分享        [DllImport("user32.dll", EntryPoint="SendMessageA", CallingConvention=CallingConvention.StdCall,CharSet=CharSet.Ansi)] 
技术分享        private static extern uint SendMessage(uint Hdc, uint Msg_Const, uint wParam, uint lParam);
技术分享
技术分享        [DllImport("user32.dll", EntryPoint="FindWindowExA", CallingConvention=CallingConvention.StdCall,CharSet=CharSet.Ansi)] 
技术分享        private static extern uint FindWindowEx(uint hwndParent, uint hwndChildAfter, string lpszClass,string lpszWindow);
技术分享
技术分享        #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

以上是关于利用NativeWindow监视WndProc消息(好像是一个字典,没搞明白)的主要内容,如果未能解决你的问题,请参考以下文章

在 wndproc 和 MSG 中处理窗口消息,有啥区别?

C# 重写WndProc 拦截 发送 系统消息 + windows消息常量值

WndProc和hook区别

如何在 WPF 中处理 WndProc 消息?

为控件创建MouseEnter和MouseLeave事件(覆盖WndProc,增加对消息的处理)——真简单!

TControl的消息覆盖函数大全(15个WM_函数和17个CM_函数,它的WndProc就处理鼠标与键盘消息)