利用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

posted @ 2016-08-26 18:19  findumars  Views(745)  Comments(0Edit  收藏  举报