System.Windows.MessageBox vs System.Windows.Forms.MessageBox - c#

I am having trouble finding out what the key differences are between the two message boxes. What is the difference between System.Windows.MessageBox and System.Windows.Forms.MessageBox?

System.Windows.MessageBox was added with WPF, and exists within the WPF assemblies (PresentationFramework.dll).
System.Windows.Forms.MessageBox was added with Windows Forms, and exists within the Windows Forms assemblies.
If your program is a Windows Forms program, I would use the latter (System.Windows.Forms.MessageBox), as it won't pull in a dependency on WPF. On the other hand, if you are developing for WPF, I'd use System.Windows.MessageBox.

One additional point should be noted:
If you want to display a message box in an application that is neither a windows forms application or a forms application (such as a .NET console application), you should not drag in assembly references for either as seems to be the common mantra all over the internet.
Instead, you should use pinvoke and call into User32 as follows:
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern MessageBoxResult MessageBox(IntPtr hWnd, String text, String caption, int options);
/// <summary>
/// Flags that define appearance and behaviour of a standard message box displayed by a call to the MessageBox function.
/// </summary>
[Flags]
public enum MessageBoxOptions : uint
{
Ok = 0x000000,
OkCancel = 0x000001,
AbortRetryIgnore = 0x000002,
YesNoCancel = 0x000003,
YesNo = 0x000004,
RetryCancel = 0x000005,
CancelTryContinue = 0x000006,
IconHand = 0x000010,
IconQuestion = 0x000020,
IconExclamation = 0x000030,
IconAsterisk = 0x000040,
UserIcon = 0x000080,
IconWarning = IconExclamation,
IconError = IconHand,
IconInformation = IconAsterisk,
IconStop = IconHand,
DefButton1 = 0x000000,
DefButton2 = 0x000100,
DefButton3 = 0x000200,
DefButton4 = 0x000300,
ApplicationModal = 0x000000,
SystemModal = 0x001000,
TaskModal = 0x002000,
Help = 0x004000, //Help Button
NoFocus = 0x008000,
SetForeground = 0x010000,
DefaultDesktopOnly = 0x020000,
Topmost = 0x040000,
Right = 0x080000,
RTLReading = 0x100000,
}
/// <summary>
/// Represents possible values returned by the MessageBox function.
/// </summary>
public enum MessageBoxResult : uint
{
Ok = 1,
Cancel,
Abort,
Retry,
Ignore,
Yes,
No,
Close,
Help,
TryAgain,
Continue,
Timeout = 32000
}
var result = User32.MessageBox(IntPtr.Zero, "Debugging Break", "Your Console Application", (int)User32.MessageBoxOptions.Ok);

Both eventually call the same low level windows API as far as I know...

The both basically do the same thing, except system.windows.messagebox is WPF and system.windows.forms.messagebox is Windows Forms. If you're using WPF use the former, for WinForms use the latter.

Related

How to maximize Access Application window using C#?

I'm using Microsoft.Office.Interop.Access to open access db using code like this :
Access.Application AccApp = new Access.Application();
AccApp.Visible = true;
AccApp.OpenCurrentDatabase(databasePathAndFileName, false, databasePassword);
The point is when access opens the window's size is small I need to maximize the access window after opening it .
Thanks
The VBA command for this is
DoCmd.RunCommand acCmdAppMaximize
which should be callable from C# interop as follows:
const int acCmdAppMaximize = 10;
AccApp.DoCmd.RunCommand(acCmdAppMaximize);
Obviously, you can (and should) skip the redeclaration of the acCmdAppMaximize constant if it is already provided by the interop library.
Thanks to #Heinzi who pointed me to the right direction , This worked for me :
Microsoft.Office.Interop.Access.Application AccApp = new Microsoft.Office.Interop.Access.Application();
AccApp.Visible = true;
AccApp.OpenCurrentDatabase("D:\\Settings.accdb", false, "017014A");
AccApp.RunCommand(AcCommand.acCmdAppMaximize);

Enable a disabled screen using ChangeDisplaySettingsEx

I'm using WinAPI ChangeDisplaySettingsEx to switch my windows 10 screens config.
There are more than two screens, so ScreenSwitch.exe is not enough for me.
I referenced this:
https://www.codeproject.com/Articles/178027/How-to-create-a-display-switcher-for-Windows-XP?msg=3850767#xx3850767xx
and successed disable a screen in these code:
string displayName = #"\\.\DISPLAY3";
DEVMODE devMode= new DEVMODE();
devMode.dmPosition.x = 0;
devMode.dmPosition.y = 0;
devMode.dmPelsWidth = 0;
devMode.dmPelsHeight = 0;
devMode.dmFields = DEVMODE_Flags.DM_PELSHEIGHT | DEVMODE_Flags.DM_PELSWIDTH | DEVMODE_Flags.DM_POSITION;
devMode.dmSize = (ushort)Marshal.SizeOf(devMode);
ChangeDisplaySettingsEx(displayName, ref devMode, IntPtr.Zero, (int)(DeviceFlags.CDS_RESET | DeviceFlags.CDS_UPDATEREGISTRY), IntPtr.Zero);
But I can't enable screen:
...
devMode.dmPosition.x = -3840;
devMode.dmPosition.y = -1059;
devMode.dmPelsWidth = 3840;
devMode.dmPelsHeight = 2160;
...
ChangeDisplaySettingsEx got -1 result means CHANGE_FAILED
I guess that screen has disabled, so enable it need more information?
I tried save DEVMODE when the screen enabled, and send it to ChangeDisplaySettingsEx when screen disabled. Not works.
Thanks for any suggest
Thanks Strive Sun's answer.
It work.
I can't enable my "\.\DISPLAY3" directly,
My "Screen2" will be active first, although the argument is "Screen3".
But it can workaround easily, like this:
enableScreen(2);
enableScreen(3);
disableScreen(2);
I also tried use EnumDisplayDevices to get the deviceName of my monitor.
I got "\.\DISPLAY3\Monitor0".
But it will fail in ChangeDisplaySettingsEx, got -5 result (means BAD_PARAM).

Using Hidden Security Icons in Taskdialog

I am trying to display a Security Success Icon (with the blue background) in TaskDialog message box. This is not one of the enum values of TaskDialogStandardIcon. Reference: http://dotnet.dzone.com/articles/using-new-taskdialog-winapi.
How do I assign these non standard values to ((TaskDialog)sender).Icon ? Is it even possible in C#? C#
Any pointers would be really helpful.
Regards,
Ashwin
I think you will need to import TaskDialog function from comctl32.dll yourself:
static class TaskDialogWrapper
{
[DllImport("comctl32.dll", CharSet = CharSet.Unicode, EntryPoint = "TaskDialog")]
static extern int TaskDialog(IntPtr hWnd, IntPtr hInstance, string pszWindowTitle, string pszMainInstruction, string pszContent, TaskDialogCommonButton dwCommonButtons, IntPtr pszIcon, out IntPtr pnButton);
public static TaskDialogCommonButton Show(IntPtr handle, IntPtr instance, string title, string instructionText, string content, TaskDialogCommonButton commonButtons, TaskDialogCommonIcon commonIcon)
{
IntPtr resultButton;
if (TaskDialog(handle, instance, title, instructionText, content, commonButtons, new IntPtr((int)commonIcon), out resultButton) != 0)
throw new InvalidOperationException();
return (TaskDialogCommonButton)resultButton;
}
}
[Flags()]
enum TaskDialogCommonButton
{
Ok = 0x1,
Yes = 0x2,
No = 0x4,
Cancel = 0x8,
Retry = 0x10,
Close = 0x20
}
enum TaskDialogCommonIcon
{
ShieldGrey = 65527,
ShieldOk = 65528,
ShieldError = 65529,
ShieldWarning = 65530,
ShieldBlue = 65531,
Shield = 65532,
Information = 65533,
Error = 65534,
Warning = 65535,
}
To use your own icon from a file, you will need to import TaskDialogIndirect.
(Btw., I found many other interesting icon styles for TaskDialogCommonIcon. You could add e.g.:
enum TaskDialogCommonIcon
{
None = 0,
Sheet = 2,
ExplorerFolderOpen = 3,
ExplorerFolderFlat = 5,
ExplorerFolderLeft = 6,
Search = 8,
ExplorerFolderClosed = 10,
ExplorerGames = 14,
Application = 15,
TransparentSpace = 17,
ExplorerSearch = 18,
TextFile = 19,
Letter = 20,
Picture = 21,
Diashow = 103,
// ...
}
I know that this is an old question, but I was looking for something similar, so I thought I'd pass along what I've found. Using the information posted by #KnorxThieus, I found a way to use the "hidden" security icons in the TaskDialog without going through the DLLImport process outlined above. Using the actual values he provided for the TaskDialogCommonIcon enumeration, I found that you can simply cast them to the appropriate type (i.e., the TaskDialogCommonIcon), and your application should display them properly.
Please note, I'm using the WindowsAPICodePack version 1.1.2 from Nuget (nuget.org/packages/WindowsAPICodePack-Core), and the code below has been converted from Visual Basic using the Telerik Code Converter (http://converter.telerik.com/), so it's possible that you may have to do some fine-tuning in C#:
if (TaskDialog.IsPlatformSupported) {
using (TaskDialog dialog = new TaskDialog()) {
dialog.Caption = "TESTING";
dialog.InstructionText = "THIS IS A TEST";
dialog.Text = "This is a test of casting a value to the desired Icon type for a TaskDialog.";
// Produces the green shield with green background
dialog.Icon = (TaskDialogStandardIcon)65528;
dialog.OwnerWindowHandle = this.Handle;
dialog.Show();
}
}
In my testing, this seems to work for all of the enumerations #KnorxThieus listed, as well as several others. I'm trying to figure out if there's a similar method for setting the Icon property to another (non-standard) image file, but I've been unsuccessful with that so far. I hope this helps anyone that stumbles across this in the future.
Take a look at the Ookii.Dialogs. It implements the TaskDialog and others dialogs as well, and have versions targeting WPF and Windows Forms.

How do you bring Outlook into focus and send it keystrokes in C#?

In my application I am trying to bring Outlook 2010 into focus and send it a CTRL-N (new email).
I have tried many different iterations of ShowWindow, FindWindow, SetFocus, SetForegroundWindow and SendMessage and can't seem to get any of them to work.
It works fine for Notepad, but not for Outlook... My code is:
using System.Runtime.InteropServices;
using System.Diagnostics;
const int kKeyDown = 0x0100;
const int kKeyUp = 0x0101;
const int kCtrl = 0x11;
const int kN = 0x4e;
Process[] prcOutlook = System.Diagnostics.Process.GetProcesses();
foreach (System.Diagnostics.Process prcTempProc in prcOutlook)
{
if (prcTempProc.ProcessName == "OUTLOOK")
{
IntPtr windowToFind = prcTempProc.MainWindowHandle;
if (ShowWindow(windowToFind, 1))
{
SetFocus(wHndle);
int result = SendMessage(windowToFind, kKeyDown, kCtrl, 0);
result = SendMessage(windowToFind, kKeyDown, kN, 0);
result = SendMessage(windowToFind, kKeyUp, kCtrl, 0);
result = SendMessage(windowToFind, kKeyUp, kN, 0);
}
}
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
The code runs fine, it just never brings Outlook to focus to get the keystrokes...
Where am I going wrong?
Regards,
Dean
Have a look at this question for a different approach to achieving the same result. You should also familiarize yourself with the Outlook PIA.
Don't try to control Outlook (or any other external application) by sending it keystrokes as if you are simulating a real user.
For Outlook you can use COM interop.
A quick guide:
Start a new project, a console application for instance.
Open the Add Reference dialog and select the COM tab
Search for the Microsoft Outlook X Object Library (where X is the version)
Add a reference to it.
Add the namespace "Microsoft.Office.Interop.Outlook" to your using clauses.
You can then execute the following code:
var application = new Application();
var mail = (_MailItem) application.CreateItem(OlItemType.olMailItem);
mail.To = "anonymous#somedomain.com";
// ... other mail properties ...
mail.Display(true);
First you start a new Outlook application. Then you create a new mail item (_MailItem). Use this object to configure the e-mail you want to send (to, from, subject...etc.) and then call its Display(...) method to show the Outlook new mail editor window.
If you want to retrieve the e-mails from your inbox then execute the following code:
var ns = application.GetNamespace("MAPI");
MAPIFolder inbox = ns.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
for (int i = 1; i <= inbox.Items.Count; i++)
{
var item = (MailItem) inbox.Items[i];
Console.WriteLine("Subject: {0}", item.Subject);
//...
}
Let's take the first mail we find in the inbox:
var mailItem = (MailItem) inbox.Items[1];
You can then reply to the sender as follows:
var reply = mailItem.Reply();
reply.Display(true);
As you can see this is very similar to creating a new e-mail.
A reply all is equally simple:
var replyAll = mailItem.ReplyAll();
replyAll.Display(true);
Try using SendKeys.Send(^N) after you bring you window on top

How to get current Windows theme name?

I am trying to get the current Windows theme name in C# but it has turned out to be a little tougher than expected. I have a code sample from MSDN:
public void Test()
{
StringBuilder themeFileName = new StringBuilder(0x200);
GetCurrentThemeName(themeFileName, themeFileName.Capacity, null, 0, null, 0);
string fileName = Path.GetFileName(VisualStyleInformation.ThemeFilename);
if (string.Equals("aero.msstyles", fileName, StringComparison.OrdinalIgnoreCase))
{
// user is using aero theme
}
}
[DllImport("uxtheme.dll", CharSet = CharSet.Auto)]
public static extern int GetCurrentThemeName(StringBuilder pszThemeFileName, int
dwMaxNameChars, StringBuilder pszColorBuff, int dwMaxColorChars,
StringBuilder pszSizeBuff, int cchMaxSizeChars);
GetCurrentTheme() does not modify the StringBuilder. I also tried looking at the
System.Windows.Forms.VisualStyles.VisualStyleInformation class, but it is full of empty values. Anyone know how to do this? I must be missing something easy, but I haven't found anything yet that works.
That article on CodeProject describes how to get "the current visual style information" (search for that string in the article).
It contains sample code how to do that.
You are not passing the string builder by reference.

Categories