Problem with MessageBox - c#

I'm having a problem with a MessageBox intended to be modal.
Here is the situation,
A user select xx from the form
MessageBox appears
User opens the embebed software keyboard (the built-in one, from the device)
User closes the keyboard
The MessageBox loses focus (how? it's supossed to be modal!) and the main form is shown in the foreground
The app blocks, as the user cannot now close the MessageBox.
Here is the code snippet for the MessageBox.
MessageBox.Show("message", "caption", MessageBoxButtons.OK, MessageBoxIcon.Asterisk,
MessageBoxDefaultButton.Button1);
Any ideas on how to solve this?

This is actually somewhat expected behavior under Windows CE (I'm not saying it's right, just expected).
When you click on the SIP button down in the corner of the desktop, your entire app loses focus and focus is passed to the Task Bar. You can see similar "wierdness" by clicking on your application's Task Bar button - the MessageBox will lose focus, even though by all rights you should just be sending focus to the app that is already running.
You can see that it's not a CF bug by changing your MessageBox call like so:
private void button1_Click(object sender, EventArgs e)
{
//MessageBox.Show("message", "caption", MessageBoxButtons.OK,
// MessageBoxIcon.Asterisk,
// MessageBoxDefaultButton.Button1);
MessageBoxCE(this.Handle, "message", "caption", 0);
}
// renamed to not collide with the Windows.Forms MessageBox class
[DllImport("coredll", EntryPoint="MessageBox")]
private static extern int MessageBoxCE(IntPtr hWnd, string lpText,
string lpCaption, int Type);
And you get the exact same behavior.
The one thing that is not expected is that the parent Form is coming up above the MessageBox. I just tested on an ARM-based CE 5.0 device I have on my desktop and the MessageBox stays on top in both the CF and the P/Invoke versions.
Are you able to repro this behavior with a very basic app (i.e. just one form, one button)? If so then it sounds like a platform issue. One thing to remember about using CE is that since the OEM has a lot of control over how the OS is actually implemented, you can never rule out a platform bug for behaviors.

You need to include a reference to the parent form when calling the MessageBox.Show (the IWin32Window parameter, usually just pass in "this"). I believe this is the overload you want to use - see below:
MessageBox.Show Method (IWin32Window, String, String, MessageBoxButtons, MessageBoxIcon, MessageBoxDefaultButton)
Here is a link to the Microsoft documentation.
Enjoy!

MessageBox.Show("Please insert Correct Username and Password.", "Login Error",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
this.Focus();
Its a simple solution. no need to run any JavaScript or other C# Code.

Related

MessageBox modal to a single form

I want to display a MessageBox that is modal to just a single form, and allows other top level windows on the thread to remain active. WinForms disables all windows on the current thread, whether displaying a custom modal form or using the MessageBox class.
I've tried a number of different approaches to solving the problem, including re-enabling any other top level windows (using the Win32 EnableWindow function) and p/invoking the native MessageBox function. Both of these approaches work, but leave keyboard shortcuts inoperable, including tab to move between controls, escape to cancel an open menu and most importantly menu shortcut keys.
I can make menu shortcut keys work by installing a keyboard hook when I display the MessageBox and then directly calling ProcessCmdKey on the active form, but other keyboard shortcuts still don't work. I guess I could press on and add more hacks to make these other cases work, but I was wondering if there was a better way.
Note, this is not about being non-blocking, but about not disabling all windows on the current thread. It happens that the solution may be similar, however.
The basic problem you are battling here is that MessageBox.Show() pumps its own message loop to make itself modal. This message loop is built into Windows and is thoroughly unaware of what the Winforms message loop looks like. So anything special that Winforms does in its message loop just won't happen when you use MessageBox. Which is keyboard handling: detecting mnemonics, implementing navigation and calling methods like ProcessCmdKey() so that a form can implement its own shortcut keystrokes. Not normally a problem since it is supposed to be modal and ignore user input.
The only practical way to revive this is to display the message box on its own thread. This is formally allowed in the winapi, the owner of a window can be a window owned by another thread. But that's a rule that Microsoft did not implement when they added the code to .NET 2.0 that detects threading mistakes. Working around that code requires an IWin32Window as the message box owner that is not also a Control.
Add a new class to your project and paste this code:
using System;
using System.Threading;
using System.Windows.Forms;
public class NonModalMessageBox : IWin32Window {
public NonModalMessageBox(Form owner, Action<IWin32Window> display) {
this.handle = owner.Handle;
var t = new Thread(new ThreadStart(() => display(this)));
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
public IntPtr Handle {
get { return handle; }
}
private IntPtr handle;
}
And use it like this:
new NonModalMessageBox(this, (owner) => {
MessageBox.Show(owner, "Testing", "Non-modal");
});
Where this the Form object that should be disabled while the message box is displayed. There's little I can do to make you feel better about this hack, if the FUD is too overpowering then you really do need to re-implement MessageBox with your own Form class so you can use Show() instead of ShowDialog(). It has been done.
You could pass a reference to the Form, set Enabled property to false when you open the dialog, and set it back to true when the dialog closes.

C#: Is there a winforms way to make C# MessageBox Buttons (YesNo) larger?

It would be nice to have larger MessageBox Buttons since the target for this application is a tablet.
DialogResult dialogResult = MessageBox.Show(
message, caption,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
switch (dialogResult)
{
case DialogResult.Yes:
// ...
It is a system setting. Tablet PCs are normally already configured to make it easy to tap buttons like this so that it works well in any program, not just yours. To configure your tablet, in Win7, use Control Panel + Display, Personalization, Window Color. Click Advanced appearance settings, select "Message Box" in the Item combo. Increase the font size. Don't be fooled by the poor preview, the button will actually grow. There are additional settings in this dialog you might want to tweak to make it easier to manipulate the UI.
A messagebox is just a simple modal form. You can make one yourself and use ShowDialog()
I'm not sure if it's possible or not, but you could use a simple form instead of a dialog box then you can get the design exactly as you wish.
Winforms way? Do you mean, an "automagically via a property change" way? If so, none that I know of.
You can spin up your own custom dialog/form that is bigger and use it instead. While this is not as automagic as the one line MessageBox.Show(), it is not very difficult.
That's not possible with MessageBox which wraps the native system dialog.
You'll need to produce your own dialog or even better see if there is a way to configure the system to give your app (and all others) bigger buttons.
The downside of rolling your own is that you lose all the functionality that the native one provides.
Yeah, going along with what MattP said, you'll need to create a custom form and then use the ShowDialog() method to display the second form as a modal dialog.
private void button2_Click(object sender, System.EventArgs e) {
using (Form2 xForm = new Form2()) {
if (xForm.ShowDialog(this) == DialogResult.OK) {
// Take some action
}
}
}
You can make a 2nd form, then you can make the buttons as big as you want

how to force user to respond to message box in c# windows application

I want to show messagebox to the user, such that the user cannot refuse to confirm the message box. User should not be allowed to do anything else in the screen until he confirms the messagebox. This is a windows based c# application. The main thing is, even if i use windows message box. Some times it is hiding behind some screen. But for my case, i want message box to be on top most whenever it appears. I am using some other third party applications, which over rides my message box. I want to overcome this. How to do this...
Invoke messagebox inside the constructor of your form.
public Form1()
{
if (MessageBox.Show(this, "Confirm?", "Attention", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
{
}
else
{
}
InitializeComponent();
}
OR
Invoke another form instance using ShowDialog() method,
public Form1()
{
Form2 frm=new Form2();
frm.ShowDialog(this);
}
You might have to define a custom message box (a Form) and set its TopMost property to true.This will make it on top of ever other window, except other TopMost windows.
That's assuming you want it on top of other applications too, which I'm not sure it's what you're looking for...
The normal windows MessageBox() function should do exactly this unless I'm missing something in your question.
Always specify a owner when displaying a message box.

Show only one instance of messagebox.show in c#

I have a created a custom keyboard shortcut for my application,
when the user press combination keys of CTRL + ALT + Q, i show
a messagebox "Are you sure you want to log out ?" Then if clicked
YES, i log out of the application.
Problem :
I want to make sure that, only once instance of message box shows.
No matter how many times the user presses the shortcut.
currently it shows multiple message box, on pressing multiple
shortcuts.
How to overcome this ?
From MSDN
A message box is a modal dialog box,
which means no input (keyboard or
mouse click) can occur except to
objects on the modal form. The program
must hide or close a modal form
(typically in response to some user
action) before input to another form
can occur.
File a bug on connect.microsoft.com !
Taking ck's comment into consideration...If you are showing a custom dialog (form) then you need to invoke the form using Form.ShowDialog() and not Show().
A quick and dirty way would be to have a class level boolean variable that tracks when the user is trying to exit. If they are, it's set to true, and your routine to display the dialog box can check this flag, then return without doing anything.
Seems like Singleton Pattern is your option.
I think you can create your own form and use the mymessageboxform.show() method, and check its dialogue result.
You'll want to make your application single instance so it can only be started once.
Single Instance App

How do I create a MessageBox in C#?

I have just installed C# for the first time, and at first glance it appears to be very similar to VB6. I decided to start off by trying to make a 'Hello, World!' UI Edition.
I started in the Form Designer and made a button named "Click Me!" proceeded to double-click it and typed in
MessageBox("Hello, World!");
I received the following error:
MessageBox is a 'type' but used as a 'variable'
Fair enough, it seems in C# MessageBox is an Object. I tried the following
MessageBox a = new MessageBox("Hello, World!");
I received the following error:
MessageBox does not contain a constructor that takes '1' arguments
Now I am stumped. Please help.
MessageBox.Show also returns a DialogResult, which if you put some buttons on there, means you can have it returned what the user clicked. Most of the time I write something like
if (MessageBox.Show("Do you want to continue?", "Question", MessageBoxButtons.YesNo) == MessageBoxResult.Yes) {
//some interesting behaviour here
}
which I guess is a bit unwieldy but it gets the job done.
See https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.dialogresult for additional enum options you can use here.
Code summary:
using System.Windows.Forms;
...
MessageBox.Show( "hello world" );
Also (as per this other stack post): In Visual Studio expand the project in Solution Tree, right click on References, Add Reference, Select System.Windows.Forms on Framework tab. This will get the MessageBox working in conjunction with the using System.Windows.Forms reference from above.
It is a static function on the MessageBox class, the simple way to do this is using
MessageBox.Show("my message");
in the System.Windows.Forms class. You can find more on the msdn page for this here . Among other things you can control the message box text, title, default button, and icons. Since you didn't specify, if you are trying to do this in a webpage you should look at triggering the javascript alert("my message"); or confirm("my question"); functions.
Try below code:
MessageBox.Show("Test Information Message", "Caption", MessageBoxButtons.OK, MessageBoxIcon.Information);
Also you can use a MessageBox with OKCancel options, but it requires many codes.
The if block is for OK, the else block is for Cancel. Here is the code:
if (MessageBox.Show("Are you sure you want to do this?", "Question", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
{
MessageBox.Show("You pressed OK!");
}
else
{
MessageBox.Show("You pressed Cancel!");
}
You can also use a MessageBox with YesNo options:
if (MessageBox.Show("Are you sure want to doing this?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
MessageBox.Show("You are pressed Yes!");
}
else
{
MessageBox.Show("You are pressed No!");
}
In the System.Windows.Forms class, you can find more on the MSDN page for this here. Among other things you can control the message box text, title, default button, and icons. Since you didn't specify, if you are trying to do this in a webpage you should look at triggering the javascript alert("my message"); or confirm("my question"); functions.
This is some of the things you can put into a message box. Enjoy
MessageBox.Show("Enter the text for the message box",
"Enter the name of the message box",
(Enter the button names e.g. MessageBoxButtons.YesNo),
(Enter the icon e.g. MessageBoxIcon.Question),
(Enter the default button e.g. MessageBoxDefaultButton.Button1)
More information can be found here
I got the same error 'System.Windows.Forms.MessageBox' is a 'type' but is used like a 'variable', even if using:
MessageBox.Show("Hello, World!");
I guess my initial attempts with invalid syntax caused some kind of bug and I ended up fixing it by adding a space between "MessageBox.Show" and the brackets ():
MessageBox.Show ("Hello, World!");
Now using the original syntax without the extra space works again:
MessageBox.Show("Hello, World!");

Categories

Resources