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 plain copy print ?
- using System;
- using System.Runtime.InteropServices;
- using System.Windows.Forms;
- using System.Collections.Generic;
-
- namespace testApplication1
- {
- public delegate void HookWndProcHandler(ref Message m);
-
- public class HookWndProc
- {
- private Dictionary<Control, NativeWindow> nativeWindows = new Dictionary<Control, NativeWindow>();
-
- public event HookWndProcHandler WndProcEvent;
-
- public void BeginHookProc(Control control)
- {
- if(nativeWindows.ContainsKey(control))
- {
- return;
- }
-
- nativeWindows.Add(control, new HookNativeWindow(this, control));
- }
-
- public void EndHookProc(Control control)
- {
- if(!nativeWindows.ContainsKey(control))
- {
- return;
- }
-
- NativeWindow window = nativeWindows[control];
- nativeWindows.Remove(control);
- window.ReleaseHandle();
- window = null;
- }
-
- protected virtual void WndProc(ref Message m)
- {
- FireWndProcEvent(ref m);
- }
-
- protected void FireWndProcEvent(ref Message m)
- {
- if (WndProcEvent != null)
- {
- WndProcEvent(ref m);
- }
- }
- #region NativeWindow
-
- protected class HookNativeWindow : NativeWindow
- {
- private HookWndProc hookWndProc;
-
- public HookNativeWindow(HookWndProc hookWndProc, Control control)
- {
- this.hookWndProc = hookWndProc;
-
- if (control.IsHandleCreated)
- {
- AssignHandle(control.Handle);
- }
- else
- {
- control.HandleCreated += new EventHandler(OnControlHandleCreated);
- }
-
- control.HandleDestroyed += new EventHandler(OnControlHandleDestroyed);
- }
-
- private void OnControlHandleCreated(object sender, EventArgs e)
- {
- AssignHandle(((Control)sender).Handle);
- }
-
- private void OnControlHandleDestroyed(object sender, EventArgs e)
- {
- ReleaseHandle();
- }
-
- [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
- protected override void WndProc(ref Message m)
- {
- hookWndProc.WndProc(ref m);
- base.WndProc(ref m);
- }
- }
- #endregion
- }
- }
using System; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Collections.Generic; namespace testApplication1 { public delegate void HookWndProcHandler(ref Message m); public class HookWndProc { private Dictionary<Control, NativeWindow> nativeWindows = new Dictionary<Control, NativeWindow>(); public event HookWndProcHandler WndProcEvent; public void BeginHookProc(Control control) { if(nativeWindows.ContainsKey(control)) { return; } nativeWindows.Add(control, new HookNativeWindow(this, control)); } public void EndHookProc(Control control) { if(!nativeWindows.ContainsKey(control)) { return; } NativeWindow window = nativeWindows[control]; nativeWindows.Remove(control); window.ReleaseHandle(); window = null; } protected virtual void WndProc(ref Message m) { FireWndProcEvent(ref m); } protected void FireWndProcEvent(ref Message m) { if (WndProcEvent != null) { WndProcEvent(ref m); } } #region NativeWindow protected class HookNativeWindow : NativeWindow { private HookWndProc hookWndProc; public HookNativeWindow(HookWndProc hookWndProc, Control control) { this.hookWndProc = hookWndProc; if (control.IsHandleCreated) { AssignHandle(control.Handle); } else { control.HandleCreated += new EventHandler(OnControlHandleCreated); } control.HandleDestroyed += new EventHandler(OnControlHandleDestroyed); } private void OnControlHandleCreated(object sender, EventArgs e) { AssignHandle(((Control)sender).Handle); } private void OnControlHandleDestroyed(object sender, EventArgs e) { ReleaseHandle(); } [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] protected override void WndProc(ref Message m) { hookWndProc.WndProc(ref m); base.WndProc(ref m); } } #endregion } }
调用方法,以更改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;
欢迎转载,请注明出处~~