How to Get the Text of a Messagebox When It Has an Icon

How to get the text of a MessageBox when it has an icon?

It appears that when the MessageBox has an icon, FindWindowEx returns the text of the first child (which is the icon in this case) hence, the zero length. Now, with the help of this answer, I got the idea to iterate the children until finding one with a text. This should work:

IntPtr handle = FindWindowByCaption(IntPtr.Zero, "Caption");

if (handle == IntPtr.Zero)
return;

//Get the Text window handle
IntPtr txtHandle = IntPtr.Zero;
int len;
do
{
txtHandle = FindWindowEx(handle, txtHandle, "Static", null);
len = GetWindowTextLength(txtHandle);
} while (len == 0 && txtHandle != IntPtr.Zero);

//Get the text
StringBuilder sb = new StringBuilder(len + 1);
GetWindowText(txtHandle, sb, len + 1);

//close the messagebox
if (sb.ToString() == "Original message")
{
SendMessage(new HandleRef(null, handle), WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}

Obviously, you could adjust it to fit your particular situation (e.g., keep iterating until you find the actual text you're looking for) although I think the child with the text will probably always be the second one:

Messagebox in Spy++

Message Box Icon - Variable?

The icon is an enum, so you can do it like:

private void MB(string Text, String Title, MessageBoxIcon ICON)
{
MessageBox.Show(Text, Title,
MessageBoxButtons.OKCancel,
ICON);
}

and you can use it like:

MB("String 1", "String 2", MessageBoxIcon.Error);

SWT: custom MessageBox / more text / how to get the icons?

Unfortunately, MessageBox is fairly constrained in its functionality. You can get the system icon from the Display class and then set it in a label:

final Image warningImage = getShell().getDisplay().getSystemImage(SWT.ICON_WARNING);

final Label imageLabel = new Label(dialogArea, SWT.NONE);
imageLabel.setImage(image);

Display Messagebox Buttons / Icon as an integer

The only thing that comes to my mind is to have 2 arrays which you fill with the corresponding buttons/icons...

Something like this:

MessageBoxButtons[] mbs = new[] {
MessageBoxButtons.AbortRetryIgnore,
MessageBoxButtons.OK,
MessageBoxButtons.OKCancel,
MessageBoxButtons.RetryCancel,
MessageBoxButtons.YesNo,
MessageBoxButtons.YesNoCancel
};

MessageBoxIcon[] mbi = new[] {
MessageBoxIcon.Asterisk,
MessageBoxIcon.Error,
MessageBoxIcon.Exclamation,
MessageBoxIcon.Hand,
MessageBoxIcon.Information,
MessageBoxIcon.None,
MessageBoxIcon.Question,
MessageBoxIcon.Stop,
MessageBoxIcon.Warning
};

MessageBox.Show("Message Text", "Message Title", mbs[2], mbi[4]);

But as I can see there is a different set between vb6 and c# 4.0 I am using... so you have to figure out how you want to translate them

Intercepting VB Messageboxes with icons (vbCritical, vbInformation) in C#

I was able to get the content of the MessageBox using by referring to the second window with class name Static, using an index.

The following answer helped me -> https://stackoverflow.com/a/5685715/10468231

public void KillMbox()
{
IntPtr h = FindWindow("#32770", "Microsoft Word");

if (h != IntPtr.Zero)
{
IntPtr TextMesaj = FindWindowByIndex(h, 2);
int len = GetWindowTextLength(TextMesaj);
StringBuilder sb = new StringBuilder(len + 1);
GetWindowText(TextMesaj, sb, len + 1);
SendMessage(new HandleRef(null, h), 16, IntPtr.Zero, IntPtr.Zero);
MessageBox.Show(sb.ToString());
}
}

static IntPtr FindWindowByIndex(IntPtr hWndParent, int index)
{
if (index == 0)
return hWndParent;
else
{
int ct = 0;
IntPtr result = IntPtr.Zero;
do
{
result = FindWindowEx(hWndParent, result, "Static", null);
if (result != IntPtr.Zero)
++ct;
}
while (ct < index && result != IntPtr.Zero);
return result;
}
}

MessageBox.Show() Custom Icon?

I wrote one a little while ago, it works exactly like the regular messagebox class.

CustomMessageBox (Class): http://pastebin.com/m8evBmZi

using System;
using System.Drawing;
using System.Windows.Forms;

public static class CustomMessageBox
{
public static DialogResult Show(string Text, string Title, eDialogButtons Buttons, Image Image)
{
MessageForm message = new MessageForm();
message.Text = Title;

if (Image.Height < 0 || Image.Height > 64)
throw new Exception("Invalid image height. Valid height ranges from 0 to 64.");
else if (Image.Width < 0 || Image.Width > 64)
throw new Exception("Invalid image width. Valid width ranges from 0 to 64.");
else
{
message.picImage.Image = Image;
message.lblText.Text = Text;

switch (Buttons)
{
case eDialogButtons.OK:
message.btnYes.Visible = false;
message.btnNo.Visible = false;
message.btnCancel.Visible = false;
message.btnOK.Location = message.btnCancel.Location;
break;
case eDialogButtons.OKCancel:
message.btnYes.Visible = false;
message.btnNo.Visible = false;
break;
case eDialogButtons.YesNo:
message.btnOK.Visible = false;
message.btnCancel.Visible = false;
message.btnYes.Location = message.btnOK.Location;
message.btnNo.Location = message.btnCancel.Location;
break;
case eDialogButtons.YesNoCancel:
message.btnOK.Visible = false;
break;
}

if (message.lblText.Height > 64)
message.Height = (message.lblText.Top + message.lblText.Height) + 78;

return (message.ShowDialog());
}
}

public enum eDialogButtons { OK, OKCancel, YesNo, YesNoCancel }
}

MessageForm (Form): http://pastebin.com/jawHZDzY

using System;
using System.Windows.Forms;

internal partial class MessageForm : Form
{
internal MessageForm() => InitializeComponent();

private void btnYes_Click(object sender, EventArgs e) =>
DialogResult = DialogResult.Yes;

private void btnNo_Click(object sender, EventArgs e) =>
DialogResult = DialogResult.No;

private void btnCancel_Click(object sender, EventArgs e) =>
DialogResult = DialogResult.Cancel;

private void btnOK_Click(object sender, EventArgs e) =>
DialogResult = DialogResult.OK;
}

MessageForm (Designer Code): http://pastebin.com/CRXjeUFN

partial class MessageForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.picImage = new System.Windows.Forms.PictureBox();
this.lblText = new System.Windows.Forms.Label();
this.btnYes = new Dark.WinForms.Controls.dButton();
this.btnNo = new Dark.WinForms.Controls.dButton();
this.btnCancel = new Dark.WinForms.Controls.dButton();
this.btnOK = new Dark.WinForms.Controls.dButton();
((System.ComponentModel.ISupportInitialize)(this.picImage)).BeginInit();
this.SuspendLayout();
//
// picImage
//
this.picImage.ErrorImage = null;
this.picImage.InitialImage = null;
this.picImage.Location = new System.Drawing.Point(15, 15);
this.picImage.Name = "picImage";
this.picImage.Size = new System.Drawing.Size(64, 64);
this.picImage.TabIndex = 0;
this.picImage.TabStop = false;
//
// lblText
//
this.lblText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.lblText.AutoSize = true;
this.lblText.Location = new System.Drawing.Point(85, 15);
this.lblText.MaximumSize = new System.Drawing.Size(294, 0);
this.lblText.Name = "lblText";
this.lblText.Size = new System.Drawing.Size(28, 13);
this.lblText.TabIndex = 0;
this.lblText.Text = "Text";
//
// btnYes
//
this.btnYes.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnYes.FocusDuesEnabled = false;
this.btnYes.Location = new System.Drawing.Point(139, 88);
this.btnYes.Name = "btnYes";
this.btnYes.Size = new System.Drawing.Size(75, 23);
this.btnYes.TabIndex = 2;
this.btnYes.Text = "Yes";
this.btnYes.Tooltip = "";
this.btnYes.UseVisualStyleBackColor = true;
this.btnYes.Click += new System.EventHandler(this.btnYes_Click);
//
// btnNo
//
this.btnNo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnNo.FocusDuesEnabled = false;
this.btnNo.Location = new System.Drawing.Point(220, 88);
this.btnNo.Name = "btnNo";
this.btnNo.Size = new System.Drawing.Size(75, 23);
this.btnNo.TabIndex = 3;
this.btnNo.Text = "No";
this.btnNo.Tooltip = "";
this.btnNo.UseVisualStyleBackColor = true;
this.btnNo.Click += new System.EventHandler(this.btnNo_Click);
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.FocusDuesEnabled = false;
this.btnCancel.Location = new System.Drawing.Point(301, 88);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 1;
this.btnCancel.Text = "Cancel";
this.btnCancel.Tooltip = "";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// btnOK
//
this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnOK.FocusDuesEnabled = false;
this.btnOK.Location = new System.Drawing.Point(220, 88);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(75, 23);
this.btnOK.TabIndex = 4;
this.btnOK.Text = "OK";
this.btnOK.Tooltip = "";
this.btnOK.UseVisualStyleBackColor = true;
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// MessageForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(394, 129);
this.Controls.Add(this.btnYes);
this.Controls.Add(this.btnNo);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.picImage);
this.Controls.Add(this.lblText);
this.Controls.Add(this.btnOK);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "MessageForm";
this.Padding = new System.Windows.Forms.Padding(15);
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Title";
((System.ComponentModel.ISupportInitialize)(this.picImage)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();

}

#endregion

internal Dark.WinForms.Controls.dButton btnCancel;
internal Dark.WinForms.Controls.dButton btnNo;
internal Dark.WinForms.Controls.dButton btnYes;
internal Dark.WinForms.Controls.dButton btnOK;
internal System.Windows.Forms.PictureBox picImage;
internal System.Windows.Forms.Label lblText;
}

How do I get MessageBox icon using WinAPI

The icon that is displayed on the message box dialog is implemented using a STATIC control with SS_ICON style. You can obtain the icon handle by sending that control the STM_GETICON message.

In the code in your question, the variable named hlbl is actually the window handle of the STATIC control that contains the icon. I'd name it hIconWnd. With that name change, the code to obtain the icon would look like this:

HICON getIcon(HWND hwnd) { // handle of messagebox dialog
HWND hIconWnd = GetDlgItem(hwnd, 20);
if (hIconWnd != NULL) {
return (HICON)SendMessage(hIconWnd, STM_GETICON, 0, 0);
}
return NULL;
}

Adding a message box to a button icon

A button doesn't have a launch function, instead you need to use the handler function.

Like this:

{
text: 'Button Icon',
id: 'buttonIcon',
cls: 'x-btn-text-icon',
handler: function() {
Ext.MessageBox.show({
title: "",
msg: "Message Text",
icon: Ext.MessageBox.WARNING,
buttons: Ext.MessageBox.OKCANCEL,
fn: function(buttonIcon) {
if (buttonIcon === "ok") {
alert("Done!")
}
}
});
}
}

Ext.MessageBox title with font awesome icon

You have fallen into a documentation trap there.

The title config is available on the Ext.Panel class instantiation and therefore, technically, also on the Ext.MessageBox instantiation, but not on its show method, which you call on a singleton that has been pre-instantiated for you by Sencha.

The following would technically instantiate a Message Box with a custom title config:

Ext.create('Ext.MessageBox',{
title: {
text: 'Error Title',
iconCls: 'x-fa fa-exclamation'
}
});

However, to show the Ext.MessageBox, you have to call the show method, which has been overridden so as to overwrite every custom setting you add to the title config.



Related Topics



Leave a reply



Submit