怎么办呢?
自己做一个FORM来Show?办法太笨且重用性不高。
直接Show个MessageBox,加些提示内容,告诉用户哪个按钮代表什么意思?太不以人为本了!!!
看来还是得动用WIN32 API这把宝刀。用SPY++研究了一下Show出来的MessageBox,看来不复杂,把窗口中子控件的类名为“Button”的文字给替换为想要的内容就OK了。
说干就干,卷起裤管,拿上锄头,三下五除二封装了一个“MessageBoxEx”的类,在MessageBox.Show的参数基础上加了一个“buttonTitles”的字符串数组参数,是想修改的内容数组。具体实现就不描述了,见所附代码。
其中获取对话框窗体句柄的方法是参考了一个关于扩展OpenFileDialog窗体的代码,具体出处不记得了。其实有了这个基础,可以在Show出来的窗体上做很多事情,如加一个图片、按钮或是*****,这就要看具体的需求了。抛砖引玉,希望能引出点啥。
代码:
class MessageBoxEx
{
//测试样例
static void test()
{
Show("提示消息", "提示标题", MessageBoxButtons.YesNoCancel, new string[] { "按钮一(&O)", "按钮二(&T)", "按钮三(&H)" });
}
public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, string[] buttonTitles)
{
DummyForm frm = new DummyForm(buttons, buttonTitles);
frm.Show();
frm.WatchForActivate = true;
DialogResult result = MessageBox.Show(frm, text, caption, buttons);
frm.Close();
return result;
}
class DummyForm : Form
{
IntPtr _handle;
MessageBoxButtons _buttons;
string[] _buttOnTitles= null;
bool _watchForActivate = false;
public bool WatchForActivate
{
get { return _watchForActivate; }
set { _watchForActivate = value; }
}
public DummyForm(MessageBoxButtons buttons, string[] buttonTitles)
{
_buttOns= buttons;
_buttOnTitles= buttonTitles;
//让自己在界面上看不到
this.Text = "";
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(-32000, -32000);
this.ShowInTaskbar = false;
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
//把自己藏起来,在任务列表里也看不到
NativeWin32API.SetWindowPos(this.Handle, IntPtr.Zero, 0, 0, 0, 0, 659);
}
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (_watchForActivate && m.Msg == 0x0006)
{
_watchForActivate = false;
_handle = m.LParam;
CheckMsgbox();
}
base.WndProc(ref m);
}
private void CheckMsgbox()
{
if (_buttOnTitles== null || _buttonTitles.Length == 0)
return;
//按钮标题的索引
int buttOnTitleIndex= 0;
//获取子控件的句柄
IntPtr h = NativeWin32API.GetWindow(_handle, OCCommon.Message.GW_CHILD);
while (h != IntPtr.Zero)
{
//按顺序把按钮标题赋上
if (NativeWin32API.GetWindowClassName(h).Equals("Button"))
{
if (_buttonTitles.Length > buttonTitleIndex)
{
NativeWin32API.SetWindowText(h, _buttonTitles[buttonTitleIndex]);
buttonTitleIndex++;
}
}
h = NativeWin32API.GetWindow(h, OCCommon.Message.GW_HWNDNEXT);
}
}
}
}
用到的消息:
public const int GW_CHILD = 5;
public const int GW_HWNDNEXT = 2;
用到的WIN32 API:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int Width, int Height, int flags);
[DllImport("user32.dll")]
public static extern IntPtr GetWindow(IntPtr hWnd, long wCmd);
[DllImport("user32.dll")]
public static extern bool SetWindowText(IntPtr hWnd, string lpString);
[DllImport("user32.dll")]
public static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);
public static string GetWindowClassName(IntPtr handle)
{
StringBuilder sb = new StringBuilder(256);
GetClassNameW(handle, sb, sb.Capacity); //得到窗口类名并保存在strClass中
return sb.ToString();
}
怎么办呢?
自己做一个FORM来Show?办法太笨且重用性不高。
直接Show个MessageBox,加些提示内容,告诉用户哪个按钮代表什么意思?太不以人为本了!!!
看来还是得动用WIN32 API这把宝刀。用SPY++研究了一下Show出来的MessageBox,看来不复杂,把窗口中子控件的类名为“Button”的文字给替换为想要的内容就OK了。
说干就干,卷起裤管,拿上锄头,三下五除二封装了一个“MessageBoxEx”的类,在MessageBox.Show的参数基础上加了一个“buttonTitles”的字符串数组参数,是想修改的内容数组。具体实现就不描述了,见所附代码。
其中获取对话框窗体句柄的方法是参考了一个关于扩展OpenFileDialog窗体的代码,具体出处不记得了。其实有了这个基础,可以在Show出来的窗体上做很多事情,如加一个图片、按钮或是*****,这就要看具体的需求了。抛砖引玉,希望能引出点啥。
代码:
class MessageBoxEx
{
//测试样例
static void test()
{
Show("提示消息", "提示标题", MessageBoxButtons.YesNoCancel, new string[] { "按钮一(&O)", "按钮二(&T)", "按钮三(&H)" });
}
public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, string[] buttonTitles)
{
DummyForm frm = new DummyForm(buttons, buttonTitles);
frm.Show();
frm.WatchForActivate = true;
DialogResult result = MessageBox.Show(frm, text, caption, buttons);
frm.Close();
return result;
}
class DummyForm : Form
{
IntPtr _handle;
MessageBoxButtons _buttons;
string[] _buttOnTitles= null;
bool _watchForActivate = false;
public bool WatchForActivate
{
get { return _watchForActivate; }
set { _watchForActivate = value; }
}
public DummyForm(MessageBoxButtons buttons, string[] buttonTitles)
{
_buttOns= buttons;
_buttOnTitles= buttonTitles;
//让自己在界面上看不到
this.Text = "";
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(-32000, -32000);
this.ShowInTaskbar = false;
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
//把自己藏起来,在任务列表里也看不到
NativeWin32API.SetWindowPos(this.Handle, IntPtr.Zero, 0, 0, 0, 0, 659);
}
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (_watchForActivate && m.Msg == 0x0006)
{
_watchForActivate = false;
_handle = m.LParam;
CheckMsgbox();
}
base.WndProc(ref m);
}
private void CheckMsgbox()
{
if (_buttOnTitles== null || _buttonTitles.Length == 0)
return;
//按钮标题的索引
int buttOnTitleIndex= 0;
//获取子控件的句柄
IntPtr h = NativeWin32API.GetWindow(_handle, OCCommon.Message.GW_CHILD);
while (h != IntPtr.Zero)
{
//按顺序把按钮标题赋上
if (NativeWin32API.GetWindowClassName(h).Equals("Button"))
{
if (_buttonTitles.Length > buttonTitleIndex)
{
NativeWin32API.SetWindowText(h, _buttonTitles[buttonTitleIndex]);
buttonTitleIndex++;
}
}
h = NativeWin32API.GetWindow(h, OCCommon.Message.GW_HWNDNEXT);
}
}
}
}
用到的消息:
public const int GW_CHILD = 5;
public const int GW_HWNDNEXT = 2;
用到的WIN32 API:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int Width, int Height, int flags);
[DllImport("user32.dll")]
public static extern IntPtr GetWindow(IntPtr hWnd, long wCmd);
[DllImport("user32.dll")]
public static extern bool SetWindowText(IntPtr hWnd, string lpString);
[DllImport("user32.dll")]
public static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);
public static string GetWindowClassName(IntPtr handle)
{
StringBuilder sb = new StringBuilder(256);
GetClassNameW(handle, sb, sb.Capacity); //得到窗口类名并保存在strClass中
return sb.ToString();
}