簡易テキストエディタを作ろうその2
前回までで、最低限のエディタっぽい外見が完成したので
今度はメニューをつけます。
早速つけてみましょう。
メニューの追加
open System;;
open System.Windows.Forms;;
//Editorクラス
type Editor() as this = class
inherit Form()
let edit = new RichTextBox()
do
edit.Dock <- DockStyle.Fill;
this.Controls.Add(edit);
let ms = new MenuStrip() in
let mi = new ToolStripMenuItem("ファイル(&F)") in
let mis = new ToolStripMenuItem("ファイルを開く(&o)") in
let mie = new ToolStripMenuItem("終了(&x)") in
mi.DropDownItems.Add(mis) |> ignore;
mi.DropDownItems.Add(mie) |> ignore;
mie.Click.Add(fun _ -> this.Close());
ms.MdiWindowListItem <- mi;
ms.Items.Add(mi) |> ignore;
this.MainMenuStrip <- ms;
this.Controls.Add(ms);
end;;
[<STAThread>]
do Application.Run(new Editor());;
メニューの追加(軽量構文)
open System;;
open System.Windows.Forms;;
//Editorクラス
type Editor() as this =
inherit Form()
let edit = new RichTextBox()
do
edit.Dock <- DockStyle.Fill;
this.Controls.Add(edit);
let ms = new MenuStrip()
let mi = new ToolStripMenuItem("ファイル(&F)")
let mis = new ToolStripMenuItem("ファイルを開く(&o)")
let mie = new ToolStripMenuItem("終了(&x)")
mi.DropDownItems.Add(mis) |> ignore
mi.DropDownItems.Add(mie) |> ignore
mie.Click.Add(fun _ -> this.Close())
ms.MdiWindowListItem <- mi
ms.Items.Add(mi) |> ignore
this.MainMenuStrip <- ms
this.Controls.Add(ms)
[<STAThread>]
do Application.Run(new Editor())
これはファイルを開くと終了をメニューにもつプログラムです。
終了だけ実装してあってファイルを開くは次で実装します。
以前は次のような構造になっていましたが、MainMenuクラスは
.Net Core3.1から使用できなくなりました
MainMenuクラス
MenuItemクラス(ファイル)
MenuItemクラス(ファイルを開く)
MenuItemクラス(終了)
上のサイトの言う通りMainMenuの代わりにMenuStripクラスを使用します。
ここではメニューは次のような構造になっています
MenuStripクラス
ToolStripMenuItemクラス(ファイル)
ToolStripMenuItemクラス(ファイルを開く)
ToolStripMenuItemクラス(終了)
プログラムの通り、親クラスのAddメソッドで子メニューを追加していけば
メニューが完成します。
クリックした際の動作は、Click.Addメソッドに
1引数の関数を渡すことでプログラムすることが出来ます。
ここでは簡略化のため、終了を選んだ際の動作だけを記述しています。
また、メニューアイテムの名前の最後に(&アルファベット)とすれば
ショートカットキーとして反応するようになります。
このプログラムを起動して、Alt+F、xと打つと
プログラムが終了することを確かめてみてください。
それでは、ファイルを開くほうの動作も作成してみましょう。
ファイルを開く機能を追加
open System;
open System.IO;
open System.Windows.Forms;;
//Editorクラス
type Editor() as this = class
inherit Form()
let edit = new RichTextBox();
do
edit.Dock <- DockStyle.Fill;
this.Controls.Add(edit);
let ms = new MenuStrip() in
let mi = new ToolStripMenuItem("ファイル(&F)") in
let mio = new ToolStripMenuItem("ファイルを開く(&o)") in
let mie = new ToolStripMenuItem("終了(&x)") in
mi.DropDownItems.Add(mio) |> ignore;
mi.DropDownItems.Add(mie) |> ignore;
mie.Click.Add(fun _ -> this.Close());
mio.Click.Add(this.openfile);
ms.MdiWindowListItem <- mi;
ms.Items.Add(mi) |> ignore;
this.MainMenuStrip <- ms;
this.Controls.Add(ms);
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
edit.Text <- text;
str.Close();
end;;
[<STAThread>]
do Application.Run(new Editor());;
ファイルを開く機能を追加(軽量構文)
open System
open System.IO
open System.Windows.Forms
//Editorクラス
type Editor() as this =
inherit Form()
let edit = new RichTextBox()
do
edit.Dock <- DockStyle.Fill
this.Controls.Add(edit)
let ms = new MenuStrip()
let mi = new ToolStripMenuItem("ファイル(&F)")
let mio = new ToolStripMenuItem("ファイルを開く(&o)")
let mie = new ToolStripMenuItem("終了(&x)")
mi.DropDownItems.Add(mio) |> ignore
mi.DropDownItems.Add(mie) |> ignore
mie.Click.Add(fun _ -> this.Close())
mio.Click.Add(this.openfile)
ms.MdiWindowListItem <- mi
ms.Items.Add(mi) |> ignore
this.MainMenuStrip <- ms
this.Controls.Add(ms)
member this.openfile _ =
let ofd = new OpenFileDialog()
ofd.Filter <- "text files *.txt|*.txt|All files *.*|*.*"
ofd.FilterIndex <- 1
if ofd.ShowDialog() = DialogResult.OK then
let str = new StreamReader(ofd.FileName)
let text = str.ReadToEnd ()
edit.Text <- text
str.Close()
[<STAThread>]
do Application.Run(new Editor())
若干作業量が多くなるため
ファイルを開く機能は、メソッドとして別途定義しています。
追加した部分はファイルを開くためのメソッドとmis.Click.Add(this.openfile)の二箇所です。
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() as this = class
inherit Form()
let edit = new RichTextBox()
do
edit.Dock <- DockStyle.Fill;
this.Controls.Add(edit);
let ms = new MenuStrip() in
let mi = new ToolStripMenuItem("ファイル(&F)") in
let mio = new ToolStripMenuItem("ファイルを開く(&o)") in
let mis = new ToolStripMenuItem("ファイルを保存(&s)") in
let mie = new ToolStripMenuItem("終了(&x)") in
mi.DropDownItems.Add(mio) |> ignore;
mi.DropDownItems.Add(mis) |> ignore;
mi.DropDownItems.Add(mie) |> ignore;
mio.Click.Add(this.openfile);
mis.Click.Add(this.savefile);
mie.Click.Add(fun _ -> this.Close());
ms.MdiWindowListItem <- mi;
ms.Items.Add(mi) |> ignore;
this.MainMenuStrip <- ms;
this.Controls.Add(ms);
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
edit.Text <- text;
str.Close();
member this.savefile _ =
let sfd = new SaveFileDialog() in
sfd.Filter <- "text files *.txt|*.txt|All files *.*|*.*";
sfd.FilterIndex <- 1;
sfd.FileName <- "新規テキスト.txt";
sfd.InitialDirectory <- ".";
if sfd.ShowDialog() = DialogResult.OK then
let sw = new StreamWriter(sfd.FileName,false,Encoding.GetEncoding(65001)) in //65001はutf-8のID
sw.Write(edit.Text)
sw.Close()
end;;
[<STAThread>]
do Application.Run(new Editor());;
簡易エディタ完成版(軽量構文)
module editor
open System
open System.IO
open System.Text
open System.Windows.Forms
//Editorクラス
type Editor() as this =
inherit Form()
let edit = new RichTextBox()
do
edit.Dock <- DockStyle.Fill
this.Controls.Add(edit)
let ms = new MenuStrip()
let mi = new ToolStripMenuItem("ファイル(&F)")
let mio = new ToolStripMenuItem("ファイルを開く(&o)")
let mis = new ToolStripMenuItem("ファイルを保存(&s)")
let mie = new ToolStripMenuItem("終了(&x)")
mi.DropDownItems.Add(mio) |> ignore
mi.DropDownItems.Add(mis) |> ignore
mi.DropDownItems.Add(mie) |> ignore
mio.Click.Add(this.openfile)
mis.Click.Add(this.savefile)
mie.Click.Add(fun _ -> this.Close())
ms.MdiWindowListItem <- mi
ms.Items.Add(mi) |> ignore
this.MainMenuStrip <- ms
this.Controls.Add(ms)
member this.openfile _ =
let ofd = new OpenFileDialog()
ofd.Filter <- "text files *.txt|*.txt|All files *.*|*.*"
ofd.FilterIndex <- 1
if ofd.ShowDialog() = DialogResult.OK then
let str = new StreamReader(ofd.FileName)
let text = str.ReadToEnd ()
edit.Text <- text
str.Close()
member this.savefile _ =
let sfd = new SaveFileDialog()
sfd.Filter <- "text files *.txt|*.txt|All files *.*|*.*";
sfd.FilterIndex <- 1;
sfd.FileName <- "新規テキスト.txt";
sfd.InitialDirectory <- ".";
if sfd.ShowDialog() = DialogResult.OK then
let sw = new StreamWriter(sfd.FileName,false,Encoding.GetEncoding(65001)) //65001はutf-8のID
sw.Write(edit.Text)
sw.Close()
[<STAThread>]
do Application.Run(new Editor())
ファイルを開く処理と同様にして
ファイルを保存する処理(savefile)を追加しています。
また、ファイルを保存するためのToolStripMenuItemを追加して
クリック時のメソッドにsavefileを指定しました。
これで、UTF-8のみに対応した
ファイルのオープンと保存が可能なエディタができあがりました。