Windowsのメモ帳を目指しました。
ソース
using System.Diagnostics;
using System;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Collections.Generic;
/*
コンパイル
mcs Form1.cs -r:System.Windows.Forms.dll -r:System.Drawing.dll -out:MyNotepad.exe
コンパイル(デバッグあり)
mcs Form1.cs -d:DEBUG -r:System.Windows.Forms.dll -r:System.Drawing.dll -out:MyNotepad.exe
実行
mono MyNotepad.exe
*/
namespace MyNotepad
{
class Form1 : Form
{
// コンストラクタ
public Form1()
{
// 定数の定義
const string APPLICATION_NAME = "私のメモ帳";
const string DEFAULT_TITLE = "タイトルなし";
const string OPEN_FILE_DIALOG_FILTER = "TextFile(*.txt)|*.txt|AllFile(*.*)|*.*";
bool monoFlag = (RuntimeInformation.FrameworkDescription).Substring(0, 4).ToUpper() == "MONO";
// フィールドの初期化
string _text = "";
string _fileName = "";
// タイトルバーの初期化
this.Text = String.Format("{0} - {1}", DEFAULT_TITLE, APPLICATION_NAME);
// ステータスバーの初期化
var statusbar = new StatusStrip();
this.Controls.Add(statusbar);
// テキストボックスの初期化
var textbox = new TextBox
{
Dock = DockStyle.Fill,
Multiline = true, // 複数行
AcceptsReturn = true, // エンターキーで改行
ScrollBars = ScrollBars.Both, // 垂直水平
};
this.Controls.Add(textbox);
// メニューの初期化
var menubar = new MenuStrip{ Name = "MENU", Height = 48, };
var menuFile = new ToolStripMenuItem { Name = "MENU_FILE", Text = "ファイル(&F)", };
menubar.Items.Add(menuFile);
var menuEdit = new ToolStripMenuItem { Name = "MENU_EDIT", Text = " 編集 (&E)", };
menubar.Items.Add(menuEdit);
var menuHelp = new ToolStripMenuItem { Name = "MENU_HELP", Text = "ヘルプ(&H)", };
menubar.Items.Add(menuHelp);
this.Controls.Add(menubar);
var menuNew = new ToolStripMenuItem
{
Name = "MENU_NEW", Text = "新規作成",
ShortcutKeys = Keys.Control | Keys.N,
ShowShortcutKeys = true,
};
menuFile.DropDownItems.Add(menuNew);
var menuOpen = new ToolStripMenuItem
{
Name = "MENU_OPEN", Text = "開く",
ShortcutKeys = Keys.Control | Keys.O,
ShowShortcutKeys = true,
};
menuFile.DropDownItems.Add(menuOpen);
var menuSave = new ToolStripMenuItem
{
Name = "MENU_SAVE", Text = "保存",
ShortcutKeys = Keys.Control | Keys.S,
ShowShortcutKeys = true,
};
menuFile.DropDownItems.Add(menuSave);
var menuSaveAs = new ToolStripMenuItem
{
Name = "MENU_SAVEAS", Text = "名前をつけて保存",
ShortcutKeys = Keys.Control | Keys.Shift | Keys.S,
ShowShortcutKeys = true,
};
menuFile.DropDownItems.Add(menuSaveAs);
var menuClose = new ToolStripMenuItem
{
Name = "MENU_CLOSE", Text = "終了",
ShortcutKeys = Keys.Control | Keys.Q,
ShowShortcutKeys = true,
};
menuFile.DropDownItems.Add(menuClose);
var menuSearchFor = new ToolStripMenuItem
{
Name = "MENU_SEARCHFOR", Text = "検索する",
ShortcutKeys = Keys.Control | Keys.F,
ShowShortcutKeys = true,
};
menuEdit.DropDownItems.Add(menuSearchFor);
// ステータスバー
var statusCursorPosition = new ToolStripStatusLabel{ Text = "行1,列1", };
statusbar.Items.Add(statusCursorPosition);
// ウィンドウ初期サイズ
this.Size = new Size(800, 600);
// タイトルバーをセット
Action setTitle = () =>
{
this.Text = String.Format("{0}{1} - {2}",
textbox.Modified ? "*" : "",
_fileName == "" ? DEFAULT_TITLE : System.IO.Path.GetFileName(_fileName),
APPLICATION_NAME);
};
// フォームを閉じる
Action closeForm1 = () =>
{
this.Close();
};
menuClose.Click += (sender, e) => closeForm1();
// テキストファイル保存
Action<string, string> saveText = (string fileName, string text) =>
{
using(var sw = new StreamWriter(fileName, false, Encoding.UTF8))
{
sw.Write(text);
};
};
// 名前をつけて保存
Action saveAsText = () =>
{
var dialog = new SaveFileDialog { Filter = OPEN_FILE_DIALOG_FILTER, };
if (dialog.ShowDialog() != DialogResult.OK) return;
_fileName = dialog.FileName;
saveText(_fileName, textbox.Text);
textbox.Modified = false;
_text = textbox.Text;
setTitle();
};
menuSaveAs.Click +=(sender, e) => saveAsText();
// テキストファイル読み込み
Func<string, string> loadText = (string fileName) =>
{
string text = "";
using(var sr = new StreamReader(fileName, Encoding.UTF8))
{
text = sr.ReadToEnd();
};
return text;
};
// 保存
Action overWriteText = () =>
{
if (_fileName == "")
{
saveAsText();
return;
}
saveText(_fileName, textbox.Text);
textbox.Modified = false;
_text = textbox.Text;
setTitle();
};
menuSave.Click += (sender, e) => overWriteText();
// 保存確認
Func<bool> SaveConfirmation = () =>
{
if (textbox.Modified)
{
var result = (int)MessageBox.Show("保存しますか?", "確認", (System.Windows.Forms.MessageBoxButtons)1);
if (result == 1)
{
overWriteText();
}
else
{
return false;
}
}
return true;
};
// テキストファイルを開く
Action openTextWithDialog = async () =>
{
SaveConfirmation();
var dialog = new OpenFileDialog { Filter = OPEN_FILE_DIALOG_FILTER, };
if (dialog.ShowDialog() != DialogResult.OK) return;
_fileName = dialog.FileName;
_text = await Task.Run<string>(()=> { return loadText(_fileName); });
textbox.Text = _text;
textbox.Modified = false;
};
Action<string> openText = async (string fileName) =>
{
SaveConfirmation();
_fileName = fileName;
_text = await Task.Run<string>(()=> { return loadText(_fileName); });
textbox.Text = _text;
textbox.Modified = false;
};
menuOpen.Click +=(sender, e) => openTextWithDialog();
// 新規作成
Action newText = () =>
{
SaveConfirmation();
_text = "";
_fileName = "";
setTitle();
textbox.Clear();
textbox.Modified = false;
};
menuNew.Click += (sender, e) => newText();
// ドラック&ドロップを受け入れる
this.AllowDrop = true;
// ドラック&ドロップの効果
this.DragEnter += (sender, e) =>
{
e.Effect = DragDropEffects.All;
};
// ドラック&ドロップイベント
this.DragDrop += (sender, e) =>
{
// ドロップされたデータを文字配列に取得
string[] fileNames =
(string[]) e.Data.GetData(DataFormats.FileDrop, false);
if (fileNames.Length > 0)
{
openText(fileNames[0]);
}
};
// フォームのロード
this.Load += (sender, e) =>
{
string[] args = Environment.GetCommandLineArgs();
if (args.Length > 1)
{
openText(args[1]);
}
};
// フォームのクローズ
this.Closing += (sender, e) =>
{
e.Cancel = !(SaveConfirmation());
};
// 変更
textbox.TextChanged += (sender, e) =>
{
textbox.Modified = _text != textbox.Text;
setTitle();
};
// カーソル位置を表示
Action showCursorPosition = () =>
{
int line = textbox.GetLineFromCharIndex(textbox.SelectionStart);
int column = textbox.SelectionStart - textbox.GetFirstCharIndexOfCurrentLine();
int n = monoFlag ? 0 : 1; // Monoと.Net Frameworkで行が異なるので調整。原因は未調査。
statusCursorPosition.Text = String.Format("行{0}、列{1}", line+n, column+1);
};
// 検索
Func<string, bool> searchText = (string word) =>
{
bool result = false;
string str = textbox.Text;
int startPos = textbox.SelectionStart;
int pos = str.IndexOf(word, startPos);
if (pos >= 0)
{
textbox.SelectionStart = pos;
textbox.SelectionLength = word.Length;
result = true;
}
return result;
};
// 検索する
Action searchFor = () =>
{
var dialog = new Form{ Size = new Size(640, 400), Text = "検索する", };
var searchWord = new TextBox{ Size = new Size(260, 64), Location = new Point(10, 10) };
var searchButton = new Button{ Size = new Size(120, 64), Location = new Point(10, 80), Text = " 検索 ", };
dialog.Controls.Add(searchWord);
dialog.Controls.Add(searchButton);
searchButton.Click += (o2, e2) =>
{
if (searchText(searchWord.Text) == false)
{
MessageBox.Show("該当無し");
}
dialog.Close();
};
searchWord.KeyDown += (o3, e3) =>
{
if (e3.KeyCode == Keys.Enter)
{
if (searchText(searchWord.Text) == false)
{
MessageBox.Show("該当無し");
}
dialog.Close();
}
};
dialog.ShowDialog();
};
menuSearchFor.Click += (o, e) => searchFor();
// カーソル位置
textbox.Click += (o, e) => showCursorPosition();
textbox.KeyUp += (o, e) => showCursorPosition();
}
// エントリーポイント
[STAThread]
static void Main()
{
var dl = (DefaultTraceListener)Debug.Listeners["Default"];
dl.LogFileName = @"E:\csharp\mono\MyNotepad\Debug.log";
Application.Run(new Form1());
}
}//class
}//ns
コメント