- AdvMessageBox dient zum Erzeugen einer eigenen MessageBox. Der MessageBox kann ein eigenes Icon übergeben werden. Die Anzahl der Buttons kann zwischen 1 und 4 geändert werden. Die Standard-Buttons lassen sich benutzerdefiniert beschriften
355 lines
12 KiB
C#
355 lines
12 KiB
C#
using System;
|
|
using System.Text;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace MsdnMag
|
|
{
|
|
// *****************************************************************
|
|
// Buttons combination
|
|
public enum MyMessageBoxButtons
|
|
{
|
|
OK = 0,
|
|
OKCancel = 1,
|
|
AbortRetryIgnore = 2,
|
|
YesNoCancel = 3,
|
|
YesNo = 4,
|
|
RetryCancel = 5,
|
|
YesNoAllCancel = 6 // NEW
|
|
}
|
|
// *****************************************************************
|
|
|
|
public class MessageBox
|
|
{
|
|
// *****************************************************************
|
|
// Properties
|
|
protected LocalCbtHook m_cbt;
|
|
protected IntPtr m_handle = IntPtr.Zero;
|
|
protected bool m_alreadySetup = false;
|
|
// *****************************************************************
|
|
|
|
// *****************************************************************
|
|
public MessageBox()
|
|
{
|
|
m_cbt = new LocalCbtHook();
|
|
m_cbt.WindowCreated += new LocalCbtHook.CbtEventHandler(WndCreated);
|
|
m_cbt.WindowDestroyed += new LocalCbtHook.CbtEventHandler(WndDestroyed);
|
|
m_cbt.WindowActivated += new LocalCbtHook.CbtEventHandler(WndActivated);
|
|
}
|
|
// *****************************************************************
|
|
|
|
// *****************************************************************
|
|
// PROPERTY IconFile
|
|
private string m_iconFile = "";
|
|
public string IconFile
|
|
{
|
|
get {return m_iconFile;}
|
|
set {m_iconFile=value; m_iconIndex=0;}
|
|
}
|
|
// *****************************************************************
|
|
|
|
// *****************************************************************
|
|
// PROPERTY YesAllNoCancel
|
|
public bool YesAllNoCancel = false;
|
|
private const int IDALL = 9; // same as IDHELP in the Win32 API
|
|
private const int MB_HELP = 0x00004000;
|
|
// *****************************************************************
|
|
|
|
// *****************************************************************
|
|
// PROPERTY IconIndex
|
|
private int m_iconIndex = 0;
|
|
public int IconIndex
|
|
{
|
|
get {return m_iconIndex;}
|
|
set {m_iconIndex=value;}
|
|
}
|
|
// *****************************************************************
|
|
|
|
// *****************************************************************
|
|
// Show
|
|
public DialogResult Show(string text, string title, MessageBoxButtons buttons, MessageBoxIcon icon)
|
|
{
|
|
// If a custom icon is requested, ensure the window leaves room for
|
|
// the icon... Add a fake icon
|
|
if (IconFile.Length > 0 && icon == MessageBoxIcon.None)
|
|
icon = MessageBoxIcon.Information;
|
|
else
|
|
IconFile = "";
|
|
|
|
|
|
// Apply the changes needed if 4 buttons are required
|
|
if (YesAllNoCancel)
|
|
{
|
|
m_cbt.Install();
|
|
buttons = MessageBoxButtons.YesNoCancel;
|
|
// Must use MessageBox API because of the 4th button
|
|
int res = _MessageBox(GetActiveWindow(), text, title,
|
|
(int) (buttons + (int) icon + MB_HELP));
|
|
m_cbt.Uninstall();
|
|
return (DialogResult) res;
|
|
}
|
|
|
|
// Go the default way
|
|
m_cbt.Install();
|
|
DialogResult dr = System.Windows.Forms.MessageBox.Show(text, title, buttons, icon);
|
|
m_cbt.Uninstall();
|
|
return dr;
|
|
}
|
|
public DialogResult Show(string text, string title, MessageBoxButtons buttons)
|
|
{
|
|
return Show(text, title, buttons, MessageBoxIcon.None);
|
|
}
|
|
public DialogResult Show(string text, string title)
|
|
{
|
|
return Show(text, title, MessageBoxButtons.OK, MessageBoxIcon.None);
|
|
}
|
|
public DialogResult Show(string text)
|
|
{
|
|
return Show(text, "", MessageBoxButtons.OK, MessageBoxIcon.None);
|
|
}
|
|
// *****************************************************************
|
|
|
|
// *****************************************************************
|
|
// WndCreated event handler
|
|
private void WndCreated(object sender, CbtEventArgs e)
|
|
{
|
|
if (e.IsDialogWindow)
|
|
{
|
|
m_alreadySetup = false;
|
|
Console.WriteLine("MessageBox created");
|
|
m_handle = e.Handle;
|
|
}
|
|
}
|
|
// *****************************************************************
|
|
|
|
// *****************************************************************
|
|
// WndDestroyed event handler
|
|
private void WndDestroyed(object sender, CbtEventArgs e)
|
|
{
|
|
if (e.Handle == m_handle)
|
|
{
|
|
m_alreadySetup = false;
|
|
m_handle = IntPtr.Zero;
|
|
}
|
|
}
|
|
// *****************************************************************
|
|
|
|
// *****************************************************************
|
|
// WndActivated event handler
|
|
private void WndActivated(object sender, CbtEventArgs e)
|
|
{
|
|
if (m_handle != e.Handle)
|
|
return;
|
|
|
|
// Not the first time
|
|
if (m_alreadySetup)
|
|
{
|
|
Console.WriteLine("(Already configured. Not the first time it is activated!)");
|
|
return;
|
|
}
|
|
else
|
|
m_alreadySetup = true;
|
|
|
|
|
|
//
|
|
// Modify the MessageBox window
|
|
//
|
|
Console.WriteLine("MessageBox activated");
|
|
|
|
|
|
// Replace the icon (0x0014 is the ID of the icon window)
|
|
if (m_iconFile.Length >0)
|
|
{
|
|
IntPtr hwndIcon = GetDlgItem(m_handle, 0x0014);
|
|
IntPtr hIcon = ExtractIcon(IntPtr.Zero, m_iconFile, m_iconIndex);
|
|
SendMessage(hwndIcon, STM_SETICON, hIcon, IntPtr.Zero);
|
|
}
|
|
|
|
// Get the static window with the text and the text
|
|
IntPtr hwndText = GetDlgItem(m_handle, 0xFFFF);
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.Capacity = 256;
|
|
GetWindowText(hwndText, sb, 256);
|
|
string text = sb.ToString();
|
|
|
|
// Get the window position
|
|
RECT rc = new RECT();
|
|
GetWindowRect(hwndText, rc);
|
|
POINT pt = new POINT();
|
|
pt.x = rc.left;
|
|
pt.y = rc.top;
|
|
ScreenToClient(m_handle, pt);
|
|
|
|
// Create the alternate EDIT window
|
|
IntPtr m_edit = CreateWindowEx(0, "edit", "", ES_READONLY|ES_MULTILINE|WS_CHILD|WS_VISIBLE,
|
|
pt.x, pt.y, rc.right-rc.left, rc.bottom-rc.top,
|
|
m_handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
|
|
|
|
// Set font and text
|
|
IntPtr hFont = SendMessage(hwndText, WM_GETFONT, IntPtr.Zero, IntPtr.Zero);
|
|
SendMessage(m_edit, WM_SETFONT, hFont, new IntPtr(1));
|
|
SetWindowText(m_edit, text);
|
|
|
|
// Copy the displayed text to the clipboard
|
|
Clipboard.SetDataObject(text);
|
|
|
|
// Finalizing...
|
|
DestroyWindow(hwndText);
|
|
|
|
|
|
|
|
// Yes-All-No-Cancel setup
|
|
// Map the YES-NO-CANCEL-HELP sequence to YES-OK-NO-CANCEL
|
|
// The mapping has two steps: button text and button ID
|
|
// No need to change the Yes button
|
|
|
|
// Map button text
|
|
SetWindowText(GetDlgItem(m_handle,(int) DialogResult.No), "OK to All");
|
|
SetWindowText(GetDlgItem(m_handle,(int) DialogResult.Cancel), DialogResult.No.ToString());
|
|
SetWindowText(GetDlgItem(m_handle,IDALL), DialogResult.Cancel.ToString());
|
|
|
|
// Map button IDs
|
|
SetWindowLong(GetDlgItem(m_handle,(int) DialogResult.No), GWL_ID, (int)DialogResult.OK);
|
|
SetWindowLong(GetDlgItem(m_handle,(int) DialogResult.Cancel), GWL_ID, (int) DialogResult.No);
|
|
SetWindowLong(GetDlgItem(m_handle,IDALL), GWL_ID, (int) DialogResult.Cancel);
|
|
}
|
|
// *****************************************************************
|
|
|
|
#region Win32 Imports
|
|
private const int ES_READONLY = 0x00000800;
|
|
private const int ES_MULTILINE = 0x00000004;
|
|
private const int WS_VISIBLE = 0x10000000;
|
|
private const int WS_CHILD = 0x40000000;
|
|
private const int WM_SETFONT = 0x00000030;
|
|
private const int WM_GETFONT = 0x00000031;
|
|
private const int STM_SETICON = 0x00000170;
|
|
|
|
// ************************************************************************
|
|
// Win32: GetClassName
|
|
[DllImport("user32.dll")]
|
|
protected static extern int GetClassName(IntPtr hwnd,
|
|
StringBuilder lpClassName, int nMaxCount);
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// Win32: GetDlgItem
|
|
[DllImport("user32.dll")]
|
|
protected static extern IntPtr GetDlgItem(IntPtr hwnd, int id);
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// Win32: GetWindowText
|
|
[DllImport("user32.dll")]
|
|
protected static extern int GetWindowText(IntPtr hwnd,
|
|
StringBuilder lpString, int nMaxCount);
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// Win32: SetWindowText
|
|
[DllImport("user32.dll")]
|
|
protected static extern bool SetWindowText(IntPtr hwnd, string text);
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// Win32: GetWindowRect
|
|
[DllImport("user32.dll")]
|
|
protected static extern int GetWindowRect(IntPtr hwnd, RECT rc);
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// Win32: ScreenToClient
|
|
[DllImport("user32.dll")]
|
|
protected static extern int ScreenToClient(IntPtr hwnd, POINT pt);
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// Win32: SetWindowLong
|
|
protected const int GWL_ID = -12;
|
|
[DllImport("user32.dll")]
|
|
protected static extern int SetWindowLong(IntPtr hwnd,
|
|
int index, int newValue);
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// Win32: ExtractIcon
|
|
[DllImport("shell32.dll")]
|
|
protected static extern IntPtr ExtractIcon(
|
|
IntPtr hInst, // instance handle
|
|
string lpszExeFileName, // file name
|
|
int nIconIndex // icon index
|
|
);
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// Win32: DestroyWindow
|
|
[DllImport("user32.dll")]
|
|
protected static extern void DestroyWindow(IntPtr hwnd);
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// Win32: MessageBox
|
|
[DllImport("user32.dll", EntryPoint="MessageBox")]
|
|
protected static extern int _MessageBox(IntPtr hwnd, string text, string caption,
|
|
int options);
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// Win32: SendMessage
|
|
[DllImport("user32.dll")]
|
|
protected static extern IntPtr SendMessage(IntPtr hwnd,
|
|
int msg, IntPtr wParam, IntPtr lParam);
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// Win32: GetActiveWindow
|
|
[DllImport("user32.dll")]
|
|
protected static extern IntPtr GetActiveWindow();
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// Win32: CreateWindowEx
|
|
[DllImport("user32.dll")]
|
|
protected static extern IntPtr CreateWindowEx(
|
|
int dwExStyle, // extended window style
|
|
string lpClassName, // registered class name
|
|
string lpWindowName, // window name
|
|
int dwStyle, // window style
|
|
int x, // horizontal position of window
|
|
int y, // vertical position of window
|
|
int nWidth, // window width
|
|
int nHeight, // window height
|
|
IntPtr hWndParent, // handle to parent or owner window
|
|
IntPtr hMenu, // menu handle or child identifier
|
|
IntPtr hInstance, // handle to application instance
|
|
IntPtr lpParam // window-creation data
|
|
);
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// POINT
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public class POINT
|
|
{
|
|
public int x;
|
|
public int y;
|
|
}
|
|
// ************************************************************************
|
|
|
|
// ************************************************************************
|
|
// RECT
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public class RECT
|
|
{
|
|
public int left;
|
|
public int top;
|
|
public int right;
|
|
public int bottom;
|
|
}
|
|
// ************************************************************************
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
|