zoukankan      html  css  js  c++  java
  • 利用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

  • 相关阅读:
    前端PC人脸识别登录
    html2canvas 轮播保存每个图片内容
    基于Element的下拉框,多选框的封装
    聊聊 HTTPS
    从 rails 窥探 web 全栈开发(零)
    理解 Angular 服务
    Vue3 与依赖注入
    一次 HTTP 请求就需要一次 TCP 连接吗?
    GO 语言入门(一)
    读 Angular 代码风格指南
  • 原文地址:https://www.cnblogs.com/findumars/p/5811429.html
Copyright © 2011-2022 走看看