G
Guest
Hi,
I am wondering why the .NET Framework is quite different from Win32 API when
it comes to displaying system modal message boxes.
Consider the four following types of system modal message boxes (please see
associated source code below):
1) Win32 API with context ("btnWin32WithContext_Click")
2) .NET Framework with context ("btnFrameworkWithContext_Click")
3) Win32 API withOUT context ("btnWin32WithOUTContext_Click")
4) .NET Framework withOUT context ("btnFrameworkWithOUTContext_Click")
Message box (1) will display on the same screen as the caller.
Message box (2) will throw an exception.
Message box (3) will display on the same screen as the caller.
Message box (4) will NOT display on the same screen as the caller.
I would like to use the .NET Framework to display a system modal message box
on the same screen as the caller. Any ideas why this doesn't work in (2) or
(4)?
Thanks,
Nate
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace DifferentTypesOfSystemModalMessageBoxes
{
public partial class Form1 : Form
{
/// <summary>
/// Standard Windows point
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
/// <summary>
/// x
/// </summary>
public long x;
/// <summary>
/// y
/// </summary>
public long y;
};
/// <summary>
/// From winuser.h
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct HELPINFO
{
/// <summary>
///
/// </summary>
public uint cbSize;
/// <summary>
///
/// </summary>
public int iContextType;
/// <summary>
///
/// </summary>
public int iCtrlId;
/// <summary>
///
/// </summary>
public IntPtr hItemHandle;
/// <summary>
///
/// </summary>
public IntPtr dwContextId;
/// <summary>
///
/// </summary>
public POINT MousePos;
/// <summary>
/// Unmarshal the helpinfo out of the given intptr, which is
presumably the lParam received
/// in a WM_HELP message.
/// </summary>
/// <param name="lParam"></param>
/// <returns></returns>
public static HELPINFO UnmarshalFrom(IntPtr lParam)
{
return (HELPINFO)Marshal.PtrToStructure(lParam,
typeof(HELPINFO));
}
};
/// <summary>
/// Delegate declaration for a callback that gets called when the
help button is pushed.
/// </summary>
public delegate void MsgBoxCallback(HELPINFO lpHelpInfo);
/// <summary>
/// From winuser.h
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct MSGBOXPARAMS
{
/// <summary>
///
/// </summary>
public uint cbSize;
/// <summary>
///
/// </summary>
public IntPtr hwndOwner;
/// <summary>
///
/// </summary>
public IntPtr hInstance;
/// <summary>
///
/// </summary>
public String lpszText;
/// <summary>
///
/// </summary>
public String lpszCaption;
/// <summary>
///
/// </summary>
public uint dwStyle;
/// <summary>
///
/// </summary>
public IntPtr lpszIcon;
/// <summary>
///
/// </summary>
public IntPtr dwContextHelpId;
/// <summary>
///
/// </summary>
public MsgBoxCallback lpfnMsgBoxCallback;
/// <summary>
///
/// </summary>
public uint dwLanguageId;
};
/// <summary>
/// The actual MessageBoxIndirect API declaration.
/// </summary>
/// <param name="msgboxParams"></param>
/// <returns></returns>
[DllImport("user32", EntryPoint = "MessageBoxIndirect")]
private static extern int _MessageBoxIndirect(ref MSGBOXPARAMS
msgboxParams);
public Form1()
{
InitializeComponent();
}
private void btnWin32WithContext_Click(object sender, EventArgs e)
{
MSGBOXPARAMS parms = new MSGBOXPARAMS();
parms.dwStyle = 0x00000000 | 0x00001000; // MB_OK |
MB_SYSTEMMODAL
parms.lpszText = "testing";
parms.lpszCaption = "test caption";
parms.hwndOwner = this.Handle; // Window context
parms.hInstance = IntPtr.Zero;
parms.cbSize = (uint)Marshal.SizeOf(typeof(MSGBOXPARAMS));
parms.lpszIcon = IntPtr.Zero;
DialogResult dr = (DialogResult)_MessageBoxIndirect(ref parms);
}
private void btnFrameworkWithContext_Click(object sender, EventArgs e)
{
MessageBox.Show(
this,
"testing",
"test caption",
MessageBoxButtons.OK,
MessageBoxIcon.None,
MessageBoxDefaultButton.Button1,
MessageBoxOptions.DefaultDesktopOnly);
}
private void btnWin32WithOUTContext_Click(object sender, EventArgs e)
{
MSGBOXPARAMS parms = new MSGBOXPARAMS();
parms.dwStyle = 0x00000000 | 0x00001000; // MB_OK |
MB_SYSTEMMODAL
parms.lpszText = "testing";
parms.lpszCaption = "test caption";
parms.hwndOwner = IntPtr.Zero; // Window context
parms.hInstance = IntPtr.Zero;
parms.cbSize = (uint)Marshal.SizeOf(typeof(MSGBOXPARAMS));
parms.lpszIcon = IntPtr.Zero;
DialogResult dr = (DialogResult)_MessageBoxIndirect(ref parms);
}
private void btnFrameworkWithOUTContext_Click(object sender,
EventArgs e)
{
MessageBox.Show(
"testing",
"test caption",
MessageBoxButtons.OK,
MessageBoxIcon.None,
MessageBoxDefaultButton.Button1,
MessageBoxOptions.DefaultDesktopOnly);
}
}
}
I am wondering why the .NET Framework is quite different from Win32 API when
it comes to displaying system modal message boxes.
Consider the four following types of system modal message boxes (please see
associated source code below):
1) Win32 API with context ("btnWin32WithContext_Click")
2) .NET Framework with context ("btnFrameworkWithContext_Click")
3) Win32 API withOUT context ("btnWin32WithOUTContext_Click")
4) .NET Framework withOUT context ("btnFrameworkWithOUTContext_Click")
Message box (1) will display on the same screen as the caller.
Message box (2) will throw an exception.
Message box (3) will display on the same screen as the caller.
Message box (4) will NOT display on the same screen as the caller.
I would like to use the .NET Framework to display a system modal message box
on the same screen as the caller. Any ideas why this doesn't work in (2) or
(4)?
Thanks,
Nate
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace DifferentTypesOfSystemModalMessageBoxes
{
public partial class Form1 : Form
{
/// <summary>
/// Standard Windows point
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
/// <summary>
/// x
/// </summary>
public long x;
/// <summary>
/// y
/// </summary>
public long y;
};
/// <summary>
/// From winuser.h
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct HELPINFO
{
/// <summary>
///
/// </summary>
public uint cbSize;
/// <summary>
///
/// </summary>
public int iContextType;
/// <summary>
///
/// </summary>
public int iCtrlId;
/// <summary>
///
/// </summary>
public IntPtr hItemHandle;
/// <summary>
///
/// </summary>
public IntPtr dwContextId;
/// <summary>
///
/// </summary>
public POINT MousePos;
/// <summary>
/// Unmarshal the helpinfo out of the given intptr, which is
presumably the lParam received
/// in a WM_HELP message.
/// </summary>
/// <param name="lParam"></param>
/// <returns></returns>
public static HELPINFO UnmarshalFrom(IntPtr lParam)
{
return (HELPINFO)Marshal.PtrToStructure(lParam,
typeof(HELPINFO));
}
};
/// <summary>
/// Delegate declaration for a callback that gets called when the
help button is pushed.
/// </summary>
public delegate void MsgBoxCallback(HELPINFO lpHelpInfo);
/// <summary>
/// From winuser.h
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct MSGBOXPARAMS
{
/// <summary>
///
/// </summary>
public uint cbSize;
/// <summary>
///
/// </summary>
public IntPtr hwndOwner;
/// <summary>
///
/// </summary>
public IntPtr hInstance;
/// <summary>
///
/// </summary>
public String lpszText;
/// <summary>
///
/// </summary>
public String lpszCaption;
/// <summary>
///
/// </summary>
public uint dwStyle;
/// <summary>
///
/// </summary>
public IntPtr lpszIcon;
/// <summary>
///
/// </summary>
public IntPtr dwContextHelpId;
/// <summary>
///
/// </summary>
public MsgBoxCallback lpfnMsgBoxCallback;
/// <summary>
///
/// </summary>
public uint dwLanguageId;
};
/// <summary>
/// The actual MessageBoxIndirect API declaration.
/// </summary>
/// <param name="msgboxParams"></param>
/// <returns></returns>
[DllImport("user32", EntryPoint = "MessageBoxIndirect")]
private static extern int _MessageBoxIndirect(ref MSGBOXPARAMS
msgboxParams);
public Form1()
{
InitializeComponent();
}
private void btnWin32WithContext_Click(object sender, EventArgs e)
{
MSGBOXPARAMS parms = new MSGBOXPARAMS();
parms.dwStyle = 0x00000000 | 0x00001000; // MB_OK |
MB_SYSTEMMODAL
parms.lpszText = "testing";
parms.lpszCaption = "test caption";
parms.hwndOwner = this.Handle; // Window context
parms.hInstance = IntPtr.Zero;
parms.cbSize = (uint)Marshal.SizeOf(typeof(MSGBOXPARAMS));
parms.lpszIcon = IntPtr.Zero;
DialogResult dr = (DialogResult)_MessageBoxIndirect(ref parms);
}
private void btnFrameworkWithContext_Click(object sender, EventArgs e)
{
MessageBox.Show(
this,
"testing",
"test caption",
MessageBoxButtons.OK,
MessageBoxIcon.None,
MessageBoxDefaultButton.Button1,
MessageBoxOptions.DefaultDesktopOnly);
}
private void btnWin32WithOUTContext_Click(object sender, EventArgs e)
{
MSGBOXPARAMS parms = new MSGBOXPARAMS();
parms.dwStyle = 0x00000000 | 0x00001000; // MB_OK |
MB_SYSTEMMODAL
parms.lpszText = "testing";
parms.lpszCaption = "test caption";
parms.hwndOwner = IntPtr.Zero; // Window context
parms.hInstance = IntPtr.Zero;
parms.cbSize = (uint)Marshal.SizeOf(typeof(MSGBOXPARAMS));
parms.lpszIcon = IntPtr.Zero;
DialogResult dr = (DialogResult)_MessageBoxIndirect(ref parms);
}
private void btnFrameworkWithOUTContext_Click(object sender,
EventArgs e)
{
MessageBox.Show(
"testing",
"test caption",
MessageBoxButtons.OK,
MessageBoxIcon.None,
MessageBoxDefaultButton.Button1,
MessageBoxOptions.DefaultDesktopOnly);
}
}
}