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按钮文本为例


            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消息(好像是一个字典,没搞明白)的更多相关文章

  1. 利用Delphi监视注册表的变化

    转帖:利用Delphi监视注册表的变化 2009-12-23 11:53:51 分类: 利用Delphi监视注册表的变化       我们在编写软件的时候,常常需要把一些信息保存到系统的注册表中.如果 ...

  2. WPF 利用HwndSource拦截Windows消息

    WPF提供了一个HwndSource可以使你更快的实现处理Windows消息. 通过HwndSource.FromHwnd得到的HwndSource可以添加(AddHook)移除(Remove)Hoo ...

  3. php 利用activeMq+stomp实现消息队列

    php 利用activeMq+stomp实现消息队列 一.activeMq概述 ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ 是一个完全支持JMS1.1和J ...

  4. 如何利用wireshark对TCP消息进行分析

    原文:https://www.cnblogs.com/studyofadeerlet/p/7485298.html 如何利用wireshark对TCP消息进行分析   (1) 几个概念介绍 1 seq ...

  5. 利用cron监视后台进程状态

    利用cron监视后台进程状态 http://blog.csdn.net/dyx810601/article/details/72967758 1. 利用cron监视后台进程状态,如果进程死掉或服务器重 ...

  6. Java开发笔记(一百一十四)利用Socket传输文本消息

    前面介绍了HTTP协议的网络通信,包括接口调用.文件下载和文件上传,这些功能固然已经覆盖了常见的联网操作,可是HTTP协议拥有专门的通信规则,这些规则一方面有利于维持正常的数据交互,另一方面不可避免地 ...

  7. 利用SignalR创建即时消息

    1. 什么是SignalR? SignalR 是一个及时消息推送,它与.NET 的 WCF ,WebAPI类似 是客户端和服务器进行消息交换的一种工具 2.SignalR 的作用? 它可以实时同步在线 ...

  8. 一个input标签搞定含内外描边及阴影的按钮~

    自从怀孕以来,我就变得很是轻松,偶尔写一两个页面,或者偶尔调试一个两个bug,或者偶尔给做JS的同事打打下手,修改个bug什么......一个习惯于忙碌的工作的人,这一闲下来,感觉还真TM很不舒服-怎 ...

  9. 通过一个模拟程序让你明白WCF大致的执行流程

    原文http://www.cnblogs.com/artech/archive/2011/12/07/wcf-how-to-work.html 在<通过一个模拟程序让你明白ASP.NET MVC ...

随机推荐

  1. Unity3D NGUI制作进度条

    利用GUI可以制作进度条,但是NGUI更加方便 我是用的NGUI3.5.3, 先找到NGUI  Slider的预制体,利用自带的UISlider来制作. 主要是利用UISlider的Value来控制进 ...

  2. 怎样使用 iOS 7 的 AVSpeechSynthesizer 制作有声书(2)

    切分语句 软件project的一条定律是数据和代码分离.这样做会使代码更易于測试,即使输入的数据发生改变,你的代码也能够同意.甚至于,程序能在执行中实时下载新的数据.假设程序能在执行中下载新书岂不是更 ...

  3. Oracle sequence排序的使用

    最近公司的项目中好多用到了Seq排序的,所以网上找些记录一下吧. 通过以下直接查询出所有的seq列表: select * from user_sequences; 查询结果如下: 查询结果和创建的基本 ...

  4. java.util.Date和java.sql.Date

    java.util.Date是在除了SQL语句的情况下面使用的. java.sql.Date是针对SQL语句使用的,它只包含日期而没有时间部分 它们都有getTime方法返回毫秒数,自然就可以直接构建 ...

  5. NYOJ-520 最大素因子

    这个题基本上就两个知识点, 一个素数筛选法求素数,另一个是求最大公因子, 不过确定最大素数在素数表中的位置时,要用到二分的思想,不然会超时,下面是具体代码的实现; #include <stdio ...

  6. JavaScript调用后台的三种方法实例(包含两种Ajax)

    方法一:直接使用<%=%>调用(ASPX页面) 前台JS,代码如下: <script type="text/javascript"> var methodS ...

  7. 洛谷 1373 小a和uim之大逃离

    /* 很容易想到f[i][j][k][l][01] 表示到ij点 两个人得分为kl 01表示这一步谁走的 因为起点不同 路径不同 所以要枚举起点.. 时间复杂度 O(nmk*nmk) 空间复杂度 O( ...

  8. Java 数据类型转换(转换成字节型)

    package com.mystudypro.byteutil; import java.io.UnsupportedEncodingException; public class ConToByte ...

  9. VB php JAVA关于数据库连接数过多的解决方法

    这里讲解一个关于数据库连接多多的解决办法 一般都会在方法中进行数据库的开,利用和关 不过如果在一个循环里面使用的时候 这样数据库的连接数就会过多,如果是1万次的话,数据库服务器可能就会当机 PHP 中 ...

  10. 阿里云OSS存储开发(一)

    Step 1. 初始化一个OSSClient OSSClient是与OSS服务交互的客户端,SDK的OSS操作都是通过OSSClient完成的. 下面代码新建了一个OSSClient: using A ...