L'Isola di Niente
L'Isola di Niente » .NET Tips » mono で MessageBox.Show() もどき

mono で MessageBox.Show() もどき

Gtk# で System.Windows.MessageBox.Show() を実装。
使いたかったので作ってみたけど GtkMessageDialog を素直に使ったほうがいい...

コードとビルド

using System;
using Gtk;

/*
 *  Gtk# による MessageBox.Show 関数もどき
 *  Windows 名前空間を参照で利用する人は使ってはいけません。
 */
namespace System.Windows
{
	public enum MessageBoxButton
	{
		Ok,
		OkCancel,
		YesNo,
		YesNoCancel
	};
	
	public enum MessageBoxImage
	{
		DialogAuthentication, //鍵アイコン、Gtk のみ
		Asterisk,             //About でまかなう
		Error,
		Exclamation,          //Warning と共通
		Hand,                 //VisualStudio もエラーアイコン?
		Infomation,
		None,
		Question,
		Stop,
		Warning
	};
	
	/// <summary>
	/// System.Windows.MessageBox のラップ
	/// </summary>
	public class MessageBox
	{
		public static ResponseType Show(string text, string caption, MessageBoxButton type, MessageBoxImage icon)
		{
			Dialog d = new Dialog();
			
			d.Title = caption;
			d.HasSeparator = false;
			d.BorderWidth = 6;
			d.Resizable = false;
			
			HBox h = new HBox();
			h.BorderWidth = 6;
			h.Spacing = 12;
			
			Gtk.Image i;
			switch (icon)
			{
			case MessageBoxImage.Asterisk:
				i = new Image();
				i.SetFromStock(Stock.About, IconSize.Dialog);
				i.SetAlignment(0.5f, 0);
				h.PackStart(i, false, false, 0);
				break;
			case MessageBoxImage.Hand:
			case MessageBoxImage.Error:
				i = new Image();
				i.SetFromStock(Stock.DialogError, IconSize.Dialog);
				i.SetAlignment(0.5f, 0);
				h.PackStart(i, false, false, 0);
				break;
			case MessageBoxImage.Infomation:
				i = new Image();
				i.SetFromStock(Stock.DialogInfo, IconSize.Dialog);
				i.SetAlignment(0.5f, 0);
				h.PackStart(i, false, false, 0);
				break;
			case MessageBoxImage.Question:
				i = new Image();
				i.SetFromStock(Stock.DialogQuestion, IconSize.Dialog);
				i.SetAlignment(0.5f, 0);
				h.PackStart(i, false, false, 0);
				break;
			case MessageBoxImage.Stop:
				i = new Image();
				i.SetFromStock(Stock.Stop, IconSize.Dialog);
				i.SetAlignment(0.5f, 0);
				h.PackStart(i, false, false, 0);
				break;
			case MessageBoxImage.Exclamation:
			case MessageBoxImage.Warning:
				i = new Image();
				i.SetFromStock(Stock.DialogWarning, IconSize.Dialog);
				i.SetAlignment(0.5f, 0);
				h.PackStart(i, false, false, 0);
				break;
			case MessageBoxImage.DialogAuthentication:
				i = new Image();
				i.SetFromStock(Stock.DialogAuthentication, IconSize.Dialog);
				i.SetAlignment(0.5f, 0);
				h.PackStart(i, false, false, 0);
				break;
			}
			
			Label l = new Label(text);
			l.LineWrap = true;
			h.PackEnd(l);
			
			h.ShowAll();
			d.VBox.Add(h);
			switch (type)
			{
			case MessageBoxButton.Ok:
				d.AddButton(Stock.Ok, ResponseType.Ok);
				break;
			case MessageBoxButton.OkCancel:
				d.AddButton(Stock.Cancel, ResponseType.Cancel);
				d.AddButton(Stock.Ok, ResponseType.Ok);
				break;
			case MessageBoxButton.YesNo:
				d.AddButton(Stock.Yes, ResponseType.Yes);
				d.AddButton(Stock.No, ResponseType.No);
				break;
			case MessageBoxButton.YesNoCancel:
				d.AddButton(Stock.Yes, ResponseType.Yes);
				d.AddButton(Stock.No, ResponseType.No);
				d.AddButton(Stock.Cancel, ResponseType.Cancel);
				break;
			}
			int result = d.Run();
			d.Destroy();
			return (ResponseType)result;
		}
		
		public static ResponseType Show(string text, string caption, MessageBoxButton type)
		{
			Dialog d = new Dialog();
			
			d.Title = caption;
			d.HasSeparator = false;
			d.BorderWidth = 6;
			d.Resizable = false;
			
			HBox h = new HBox();
			h.BorderWidth = 6;
			h.Spacing = 12;
			
			Label l = new Label(text);
			l.LineWrap = true;
			h.PackEnd(l);
			
			h.ShowAll();
			d.VBox.Add(h);
			switch (type)
			{
			case MessageBoxButton.Ok:
				d.AddButton(Stock.Ok, ResponseType.Ok);
				break;
			case MessageBoxButton.OkCancel:
				d.AddButton(Stock.Cancel, ResponseType.Cancel);
				d.AddButton(Stock.Ok, ResponseType.Ok);
				break;
			case MessageBoxButton.YesNo:
				d.AddButton(Stock.Yes, ResponseType.Yes);
				d.AddButton(Stock.No, ResponseType.No);
				break;
			}
			int result = d.Run();
			d.Destroy();
			return (ResponseType)result;
		}
		
		public static ResponseType Show(string text, string caption)
		{
			Dialog d = new Dialog();
			
			d.Title = caption;
			d.HasSeparator = false;
			d.BorderWidth = 6;
			d.Resizable = false;
			
			HBox h = new HBox();
			h.BorderWidth = 6;
			h.Spacing = 12;
			
			Label l = new Label(text);
			l.LineWrap = true;
			h.PackEnd(l);
			
			h.ShowAll();
			d.VBox.Add(h);

			d.AddButton(Stock.Ok, ResponseType.Ok);

			int result = d.Run();
			d.Destroy();
			return (ResponseType)result;
		}
		
		public static ResponseType Show(string message)
		{
			MessageDialog d = new MessageDialog(
	            null,//(Window)this,
	            Gtk.DialogFlags.Modal,
	            Gtk.MessageType.Other,
	            Gtk.ButtonsType.Ok,
	            message);
	        int result = d.Run();
			d.Destroy();
			return (ResponseType)result;
		}
	}
}

messagebox.cs という名前で保存したとします。
普通に *.cs 指定で利用してもいいけどココではライブラリとして使う方法を。
コレを -target:library にてビルド、-lib 位置は各自で確認。
#!/bin/sh
gmcs \
-lib:/usr/lib/mono/gac/gtk-sharp/2.12.0.0__35e10195dab3c99f \
-reference:gtk-sharp.dll \
-target:library \
messagebox.cs

動作確認

/* test.cs */

using System;
using Gtk;
using System.Windows;

class GtkSharpTest : Window
{
    private void Quit(object sender, EventArgs e)
    {
        Application.Quit();
    }
    private void Click(object sender, EventArgs e)
    {
        MessageBox.Show("メッセージ");
    }
    public GtkSharpTest(string title) : base(title)
    {
        var b = new Button("MessageBox Show");
        b.Clicked += Click;
        Add(b);
        DeleteEvent += Quit;
        ShowAll();
    }
}

class __init__
{
    public static void Main()
    {
        // GtkSharp 初期化
        Application.Init();
        new GtkSharpTest("タイトルバー");
        Application.Run();
    }
}
ビルドは -reference に作成した messagebox.dll を含める。
説明不要だろうけど Linux では -target:winexe にする必要は無い。
#!/bin/sh
gmcs \
-lib:/usr/lib/mono/gac/gtk-sharp/2.12.0.0__35e10195dab3c99f \
-reference:gtk-sharp.dll \
-reference:messagebox.dll \
-target:exe \
test.cs

んで。
mono test.exe

img/mbox.png

mbox.tar.xz

だから GtkMessageDialog のほうがいいよ。
Copyright(C) sasakima-nao All rights reserved 2002 --- 2017.