advmessagebox_dll_visualstudio/AdvMessageBox/AdvMessageBox.cs
Hoeglinger Eugen 5e8f669cc7 Initialized
- 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
2022-05-19 16:36:54 +02:00

448 lines
15 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Drawing;
using System.Reflection;
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
{
#region Version and Copyright
// Version and Copyright
static readonly string dllName = Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyTitleAttribute>().Title); //Den Programmnamen auslesen
//static readonly string dllName = Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase); //Den Programmnamen auslesen
static readonly string dllVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
static readonly object[] attributes = System.Reflection.Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
static readonly string copyright = GenerateCopyright();
private static string CurrentYear()
{
DateTime dtn = DateTime.Now;
return dtn.Year.ToString();
}
private static string StartYear()
{
string startYear;
if (((AssemblyCopyrightAttribute)attributes[0]).Copyright.Contains("Copyright © "))
{
startYear = ((AssemblyCopyrightAttribute)attributes[0]).Copyright.Replace("Copyright © ", "");
while (startYear.StartsWith(" "))
{
startYear = startYear.Remove(0, 1);
}
startYear = startYear.Remove(startYear.IndexOf(" "));
return startYear;
}
else
{
DateTime dtn = DateTime.Now;
return dtn.Year.ToString();
}
}
private static string GenerateCopyright()
{
string startYear = StartYear();
string currentYear = CurrentYear();
if (startYear == currentYear)
{
return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
}
else
{
return ((AssemblyCopyrightAttribute)attributes[0]).Copyright.Replace(startYear, String.Concat(startYear, "-", currentYear));
}
}
#endregion
#region DLL-Info
/// <summary>
/// Contains the name of the dll file.
/// </summary>
public static string DllName { private set; get; }
/// <summary>
/// Contains the version of the dll file.
/// </summary>
public static string DllVersion { private set; get; }
/// <summary>
/// Contains the copyright notice.
/// </summary>
public static string Copyright { private set; get; }
/// <summary>
/// Contains the name-, version- and copyright-information of the dll file.
/// </summary>
public static string[] DllInfo { private set; get; }
private static void SetDllInfo()
{
//Set name, version and copyright
DllName = dllName;
DllVersion = dllVersion;
Copyright = copyright;
}
#endregion
// *****************************************************************
// Properties
protected LocalCbtHook m_cbt;
protected IntPtr m_handle = IntPtr.Zero;
protected bool m_alreadySetup = false;
// *****************************************************************
/// <summary>
/// Provide name, version and copyright of the DLL
/// </summary>
static MessageBox()
{
SetDllInfo(); // Set name, version and copyright of the DLL
}
// *****************************************************************
public MessageBox()
{
SetDllInfo(); // Set name, version and copyright of the DLL
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 to All-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
}
}