Post: [C#] Custom Message Box
02-23-2017, 03:36 AM #1
TehMerkMods
I’m too L33T
(adsbygoogle = window.adsbygoogle || []).push({}); So I've had this for a damn while and used it a while back in a personal project.
Add this to it's own class.
    #pragma warning disable 0618
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

[assembly: SecurityPermission(SecurityAction.RequestMinimum, UnmanagedCode = true)]
namespace System.Windows.Forms
{
public class MessageBoxManager
{
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private delegate bool EnumChildProc(IntPtr hWnd, IntPtr lParam);

private const int WH_CALLWNDPROCRET = 12;
private const int WM_DESTROY = 0x0002;
private const int WM_INITDIALOG = 0x0110;
private const int WM_TIMER = 0x0113;
private const int WM_USER = 0x400;
private const int DM_GETDEFID = WM_USER + 0;

private const int MBOK = 1;
private const int MBCancel = 2;
private const int MBAbort = 3;
private const int MBRetry = 4;
private const int MBIgnore = 5;
private const int MBYes = 6;
private const int MBNo = 7;


[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

[DllImport("user32.dll")]
private static extern int UnhookWindowsHookEx(IntPtr idHook);

[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll", EntryPoint = "GetWindowTextLengthW", CharSet = CharSet.Unicode)]
private static extern int GetWindowTextLength(IntPtr hWnd);

[DllImport("user32.dll", EntryPoint = "GetWindowTextW", CharSet = CharSet.Unicode)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int maxLength);

[DllImport("user32.dll")]
private static extern int EndDialog(IntPtr hDlg, IntPtr nResult);

[DllImport("user32.dll")]
private static extern bool EnumChildWindows(IntPtr hWndParent, EnumChildProc lpEnumFunc, IntPtr lParam);

[DllImport("user32.dll", EntryPoint = "GetClassNameW", CharSet = CharSet.Unicode)]
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

[DllImport("user32.dll")]
private static extern int GetDlgCtrlID(IntPtr hwndCtl);

[DllImport("user32.dll")]
private static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);

[DllImport("user32.dll", EntryPoint = "SetWindowTextW", CharSet = CharSet.Unicode)]
private static extern bool SetWindowText(IntPtr hWnd, string lpString);


[StructLayout(LayoutKind.Sequential)]
public struct CWPRETSTRUCT
{
public IntPtr lResult;
public IntPtr lParam;
public IntPtr wParam;
public uint message;
public IntPtr hwnd;
};

private static HookProc hookProc;
private static EnumChildProc enumProc;
[ThreadStatic]
private static IntPtr hHook;
[ThreadStatic]
private static int nButton;

/// <summary>
/// OK text
/// </summary>
public static string OK = "&OK";
/// <summary>
/// Cancel text
/// </summary>
public static string Cancel = "&Cancel";
/// <summary>
/// Abort text
/// </summary>
public static string Abort = "&Abort";
/// <summary>
/// Retry text
/// </summary>
public static string Retry = "&Retry";
/// <summary>
/// Ignore text
/// </summary>
public static string Ignore = "&Ignore";
/// <summary>
/// Yes text
/// </summary>
public static string Yes = "&Yes";
/// <summary>
/// No text
/// </summary>
public static string No = "&No";

static MessageBoxManager()
{
hookProc = new HookProc(MessageBoxHookProc);
enumProc = new EnumChildProc(MessageBoxEnumProc);
hHook = IntPtr.Zero;
}

/// <summary>
/// Enables MessageBoxManager functionality
/// </summary>
/// <remarks>
/// MessageBoxManager functionality is enabled on current thread only.
/// Each thread that needs MessageBoxManager functionality has to call this method.
/// </remarks>
public static void Register()
{
if (hHook != IntPtr.Zero)
throw new NotSupportedException("One hook per thread allowed.");
hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, hookProc, IntPtr.Zero, AppDomain.GetCurrentThreadId());
}

/// <summary>
/// Disables MessageBoxManager functionality
/// </summary>
/// <remarks>
/// Disables MessageBoxManager functionality on current thread only.
/// </remarks>
public static void Unregister()
{
if (hHook != IntPtr.Zero)
{
UnhookWindowsHookEx(hHook);
hHook = IntPtr.Zero;
}
}

private static IntPtr MessageBoxHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode < 0)
return CallNextHookEx(hHook, nCode, wParam, lParam);

CWPRETSTRUCT msg = (CWPRETSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPRETSTRUCT));
IntPtr hook = hHook;

if (msg.message == WM_INITDIALOG)
{
int nLength = GetWindowTextLength(msg.hwnd);
StringBuilder className = new StringBuilder(10);
GetClassName(msg.hwnd, className, className.Capacity);
if (className.ToString() == "#32770")
{
nButton = 0;
EnumChildWindows(msg.hwnd, enumProc, IntPtr.Zero);
if (nButton == 1)
{
IntPtr hButton = GetDlgItem(msg.hwnd, MBCancel);
if (hButton != IntPtr.Zero)
SetWindowText(hButton, OK);
}
}
}

return CallNextHookEx(hook, nCode, wParam, lParam);
}

private static bool MessageBoxEnumProc(IntPtr hWnd, IntPtr lParam)
{
StringBuilder className = new StringBuilder(10);
GetClassName(hWnd, className, className.Capacity);
if (className.ToString() == "Button")
{
int ctlId = GetDlgCtrlID(hWnd);
switch (ctlId)
{
case MBOK:
SetWindowText(hWnd, OK);
break;
case MBCancel:
SetWindowText(hWnd, Cancel);
break;
case MBAbort:
SetWindowText(hWnd, Abort);
break;
case MBRetry:
SetWindowText(hWnd, Retry);
break;
case MBIgnore:
SetWindowText(hWnd, Ignore);
break;
case MBYes:
SetWindowText(hWnd, Yes);
break;
case MBNo:
SetWindowText(hWnd, No);
break;

}
nButton++;
}

return true;
}


}
}


Here is how you use it.
    
MessageBoxManager.OK = "New Text For OK";
MessageBoxManager.Yes = "New Text For Yes";
MessageBoxManager.No = "New Text For No";
MessageBoxManager.Register();


Screenies:

You must login or register to view this content.
You must login or register to view this content.
You must login or register to view this content.


If You want a project source to go along side let me know.

The following user thanked TehMerkMods for this useful post:

MessinBound
02-26-2017, 08:31 PM #2
Default Avatar
Oneup
Guest
Originally posted by TehMerkMods View Post
So I've had this for a damn while and used it a while back in a personal project.
Add this to it's own class.
    #pragma warning disable 0618
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;

[assembly: SecurityPermission(SecurityAction.RequestMinimum, UnmanagedCode = true)]
namespace System.Windows.Forms
{
public class MessageBoxManager
{
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private delegate bool EnumChildProc(IntPtr hWnd, IntPtr lParam);

private const int WH_CALLWNDPROCRET = 12;
private const int WM_DESTROY = 0x0002;
private const int WM_INITDIALOG = 0x0110;
private const int WM_TIMER = 0x0113;
private const int WM_USER = 0x400;
private const int DM_GETDEFID = WM_USER + 0;

private const int MBOK = 1;
private const int MBCancel = 2;
private const int MBAbort = 3;
private const int MBRetry = 4;
private const int MBIgnore = 5;
private const int MBYes = 6;
private const int MBNo = 7;


[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

[DllImport("user32.dll")]
private static extern int UnhookWindowsHookEx(IntPtr idHook);

[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll", EntryPoint = "GetWindowTextLengthW", CharSet = CharSet.Unicode)]
private static extern int GetWindowTextLength(IntPtr hWnd);

[DllImport("user32.dll", EntryPoint = "GetWindowTextW", CharSet = CharSet.Unicode)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int maxLength);

[DllImport("user32.dll")]
private static extern int EndDialog(IntPtr hDlg, IntPtr nResult);

[DllImport("user32.dll")]
private static extern bool EnumChildWindows(IntPtr hWndParent, EnumChildProc lpEnumFunc, IntPtr lParam);

[DllImport("user32.dll", EntryPoint = "GetClassNameW", CharSet = CharSet.Unicode)]
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

[DllImport("user32.dll")]
private static extern int GetDlgCtrlID(IntPtr hwndCtl);

[DllImport("user32.dll")]
private static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);

[DllImport("user32.dll", EntryPoint = "SetWindowTextW", CharSet = CharSet.Unicode)]
private static extern bool SetWindowText(IntPtr hWnd, string lpString);


[StructLayout(LayoutKind.Sequential)]
public struct CWPRETSTRUCT
{
public IntPtr lResult;
public IntPtr lParam;
public IntPtr wParam;
public uint message;
public IntPtr hwnd;
};

private static HookProc hookProc;
private static EnumChildProc enumProc;
[ThreadStatic]
private static IntPtr hHook;
[ThreadStatic]
private static int nButton;

/// <summary>
/// OK text
/// </summary>
public static string OK = "&OK";
/// <summary>
/// Cancel text
/// </summary>
public static string Cancel = "&Cancel";
/// <summary>
/// Abort text
/// </summary>
public static string Abort = "&Abort";
/// <summary>
/// Retry text
/// </summary>
public static string Retry = "&Retry";
/// <summary>
/// Ignore text
/// </summary>
public static string Ignore = "&Ignore";
/// <summary>
/// Yes text
/// </summary>
public static string Yes = "&Yes";
/// <summary>
/// No text
/// </summary>
public static string No = "&No";

static MessageBoxManager()
{
hookProc = new HookProc(MessageBoxHookProc);
enumProc = new EnumChildProc(MessageBoxEnumProc);
hHook = IntPtr.Zero;
}

/// <summary>
/// Enables MessageBoxManager functionality
/// </summary>
/// <remarks>
/// MessageBoxManager functionality is enabled on current thread only.
/// Each thread that needs MessageBoxManager functionality has to call this method.
/// </remarks>
public static void Register()
{
if (hHook != IntPtr.Zero)
throw new NotSupportedException("One hook per thread allowed.");
hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, hookProc, IntPtr.Zero, AppDomain.GetCurrentThreadId());
}

/// <summary>
/// Disables MessageBoxManager functionality
/// </summary>
/// <remarks>
/// Disables MessageBoxManager functionality on current thread only.
/// </remarks>
public static void Unregister()
{
if (hHook != IntPtr.Zero)
{
UnhookWindowsHookEx(hHook);
hHook = IntPtr.Zero;
}
}

private static IntPtr MessageBoxHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode < 0)
return CallNextHookEx(hHook, nCode, wParam, lParam);

CWPRETSTRUCT msg = (CWPRETSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPRETSTRUCT));
IntPtr hook = hHook;

if (msg.message == WM_INITDIALOG)
{
int nLength = GetWindowTextLength(msg.hwnd);
StringBuilder className = new StringBuilder(10);
GetClassName(msg.hwnd, className, className.Capacity);
if (className.ToString() == "#32770")
{
nButton = 0;
EnumChildWindows(msg.hwnd, enumProc, IntPtr.Zero);
if (nButton == 1)
{
IntPtr hButton = GetDlgItem(msg.hwnd, MBCancel);
if (hButton != IntPtr.Zero)
SetWindowText(hButton, OK);
}
}
}

return CallNextHookEx(hook, nCode, wParam, lParam);
}

private static bool MessageBoxEnumProc(IntPtr hWnd, IntPtr lParam)
{
StringBuilder className = new StringBuilder(10);
GetClassName(hWnd, className, className.Capacity);
if (className.ToString() == "Button")
{
int ctlId = GetDlgCtrlID(hWnd);
switch (ctlId)
{
case MBOK:
SetWindowText(hWnd, OK);
break;
case MBCancel:
SetWindowText(hWnd, Cancel);
break;
case MBAbort:
SetWindowText(hWnd, Abort);
break;
case MBRetry:
SetWindowText(hWnd, Retry);
break;
case MBIgnore:
SetWindowText(hWnd, Ignore);
break;
case MBYes:
SetWindowText(hWnd, Yes);
break;
case MBNo:
SetWindowText(hWnd, No);
break;

}
nButton++;
}

return true;
}


}
}


Here is how you use it.
    
MessageBoxManager.OK = "New Text For OK";
MessageBoxManager.Yes = "New Text For Yes";
MessageBoxManager.No = "New Text For No";
MessageBoxManager.Register();


Screenies:

You must login or register to view this content.
You must login or register to view this content.
You must login or register to view this content.


If You want a project source to go along side let me know.

The alternative to this would be to just create a form that you populate your information with. Way less code and would function the same.
03-11-2017, 02:06 AM #3
TehMerkMods
I’m too L33T
Originally posted by Oneup View Post
The alternative to this would be to just create a form that you populate your information with. Way less code and would function the same.


Yeah that's true but I'd rather use this. No reason as to why as with a form you could have a nice looking setup. but idk I like this

Copyright © 2024, NextGenUpdate.
All Rights Reserved.

Gray NextGenUpdate Logo