在写Windows应用程序的时候,经常会碰到需要修改例如MessageBox或者FileDialog的外观
此时我们需要监视 WndProc的消息
当然也可以直接调用API实现,具体方法请参考
http://www.codeproject.com/csharp/GetSaveFileName.asp?df=100&forumid=96342&exp=0&select=1950454
主要代码如下
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
欢迎转载,请注明出处~~