簡易テキストエディタを作ろうその2

前回までで、最低限のエディタっぽい外見が完成したので 今度はメニューをつけます。 早速つけてみましょう。
メニューの追加
open System;;
open System.Windows.Forms;;

//Editorクラス
type Editor = class inherit Form as base
	val edit : RichTextBox;
	//コンストラクタ
	new () as this ={edit=new RichTextBox()}
		then
		this.edit.Dock <- DockStyle.Fill;
		this.Controls.Add(this.edit);
		let mainmenu = this.Menu <- new MainMenu() in
		let menu_file = this.Menu.MenuItems.Add("ファイル(&amp;F)") in
		let mitem_open = menu_file.MenuItems.Add("ファイルを開く(&amp;O)") in
		let mitem_end = menu_file.MenuItems.Add("終了(&amp;x)") in
		mitem_end.Click.Add(fun _ -> this.Close())
end;;
[<STAThread>]
do System.Windows.Forms.Application.Run(new Editor());;
メニューの構造は次のようになっています。 MainMenuクラス MenuItemクラス(ファイル) MenuItemクラス(ファイルを開く) MenuItemクラス(終了) プログラムの通り、親クラスのAddメソッドで子メニューを追加していけば メニューが完成します。 クリックした際の動作は、Click.Addメソッドに 1引数の関数を渡すことでプログラムすることが出来ます。 ここでは簡略化のため、終了を選んだ際の動作だけを記述しています。 また、メニューアイテムの名前の最後に(&アルファベット)とすれば ショートカットキーとして反応するようになります。 このプログラムを起動して、Alt+F、xと打つと プログラムが終了することを確かめてみてください。 それでは、ファイルを開くほうの動作も作成してみましょう。
ファイルを開く機能を追加
open System;;
open System.IO;;
open System.Windows.Forms;;

//Editorクラス
type Editor = class inherit Form as base
	val edit : RichTextBox;
	//コンストラクタ
	new () as this ={edit=new RichTextBox()}
		then
		this.edit.Dock <- DockStyle.Fill;
		this.Controls.Add(this.edit);
		let mainmenu = this.Menu <- new MainMenu() in
		let menu_file = this.Menu.MenuItems.Add("ファイル(&amp;F)") in
		let mitem_open = menu_file.MenuItems.Add("ファイルを開く(&amp;O)") in
		let mitem_end = menu_file.MenuItems.Add("終了(&amp;x)") in
		mitem_end.Click.Add(fun _ -> this.Close());
		mitem_open.Click.Add(this.openfile)
	member this.openfile _ =
		let ofd = new OpenFileDialog() in 
		ofd.Filter <- "text files *.txt|*.txt|All files *.*|*.*";
		ofd.FilterIndex <- 1;
		if ofd.ShowDialog() = DialogResult.OK then
        let str  = new StreamReader(ofd.FileName) in
        let text = str.ReadToEnd () in
        this.edit.Text <- text
end;;
[<STAThread>]
do System.Windows.Forms.Application.Run(new Editor());;
若干作業量が多くなるため ファイルを開く機能は、メンバ関数として別途定義しています。 openfile関数でやっていることは 1.OpenFileDialog(ファイルを開くダイアログボックス)の生成 2.ダイアログボックスのフィルタの設定 3.デフォルトで選択されるフィルタを決定(拡張子.txtを持つものが表示される) 4.ダイアログの表示 5.ファイルを読み込み、テキストボックスに設定 となります。 そのままなので、さほど難しくは無いことと思います。 このように、ダイアログボックスなどは .Netライブラリの機能がそのまま使えるので 非常にプログラミングが楽です。 最後に、ファイルの保存機能をつけます。 完成版が以下のプログラムです。
簡易エディタ完成版
module editor

open System;;
open System.IO;;
open System.Text;;
open System.Windows.Forms;;

//Editorクラス
type Editor = class inherit Form as base
	val edit : RichTextBox;
	//コンストラクタ
	new () as this ={edit=new RichTextBox()}
		then
		this.edit.Dock <- DockStyle.Fill;
		this.Controls.Add(this.edit);
		let mainmenu = this.Menu <- new MainMenu() in
		let menu_file = this.Menu.MenuItems.Add("ファイル(&amp;F)") in
		let mitem_open = menu_file.MenuItems.Add("ファイルを開く(&amp;O)") in
		let mitem_save = menu_file.MenuItems.Add("ファイルを保存(&amp;S)") in
		let mitem_end = menu_file.MenuItems.Add("終了(&amp;x)") in
		mitem_end.Click.Add(fun _ -> this.Close());
		mitem_open.Click.Add(this.openfile);
		mitem_save.Click.Add(this.savefile);
	//ファイルを開く
	member this.openfile _ =
		let ofd = new OpenFileDialog() in 
		ofd.Filter <- "text files *.txt|*.txt|All files *.*|*.*";
		ofd.FilterIndex <- 1;
		if ofd.ShowDialog() = DialogResult.OK then
			let str  = new StreamReader(ofd.FileName,Encoding.GetEncoding("Shift_JIS")) in
			let text = str.ReadToEnd () in
			this.edit.Text <- text;
			str.Close()
	//ファイルの保存
    member this.savefile _ =
		let sfd = new SaveFileDialog() in
		sfd.FileName <- "新規テキスト.txt";
		sfd.InitialDirectory <- ".";
		sfd.Filter <- "text files *.txt|*.txt|All files *.*|*.*";
		sfd.FilterIndex <- 1;
		if sfd.ShowDialog() = DialogResult.OK then
			let sw = new StreamWriter(sfd.FileName,false,Encoding.GetEncoding("Shift_JIS")) in
			sw.WriteLine(this.edit.Text);
			sw.Close()
end;;
[<STAThread>]
do System.Windows.Forms.Application.Run(new Editor());;
ファイルを開く処理と同様にして ファイルを保存する処理を追加しています。 これで、Shift_JISのみに対応した ファイルのオープンと保存が可能なエディタができあがりました。