2015年11月30日月曜日

P007-自作ライブラリを使ってみる

今日の目標→

プログラムコードを使い回せたら楽じゃね? そんなプログラマの永遠の夢を実現するのがライブラリだ。今回はライブラリ自作の基礎を説明する。

●プロジェクトの準備

まずは「TextWork4」という名前で、新規プロジェクトを作る。

●前回作ったクラスを現プロジェクトに組み込んでみる

  1. メニューバーから「プロジェクト」→「既存の項目の追加」で、ファイルダイアログを開く
  2. 前回の"TextWork3"プロジェクトのフォルダを探す
  3. ファイル"RichReporter.cs"を選択する
  4. 「追加」ボタンの右にある「▼」記号をクリックし、「リンクとして追加」を選択する

これで前回のRichReporterのソースコードにリンクが張られ、このプロジェクトから利用できるようになった。なお、「リンクとして追加」じゃなく、ただの「追加」でも良いのだが、その場合はファイルがまるっとコピーされる。

●RichReporerクラスを利用するコードを書く

  1. Form1.csを開く
  2. 次のコードを入力する

こうやって前回書いたコードを読み込んで使えると、コピペとか駆使するよりずっと楽ですね。

さてここで、Print()やColorPrint()などメソッドの呼び出し方は前と同じだが、RichRepoterクラスのクラス名を、

TextWork3.RichRepoter

と長い名前で指定しているのに注目してほしい。

なぜならば、今回のプログラムは「namespace TextWork4」の中で作られているのに対し、前回のプログラムは「namespace TextWork3」で作られていたからだ。このように所属が異なるクラスを指定するには、相手のnamespaceを含む長い名前、すなわち「完全修飾名」を使わなくてはならない。

もし、いちいち完全修飾名を書くのが面倒なら、ファイル先頭で次のように宣言してもよい。

using TextWork3;

このusing宣言があれば、以後クラス名の頭の「TextWork3.」は省略できる。

●なんでnamespaceなんかがあるの

namespaceがあるのは、名前の衝突をできるだけ回避するためだ。コンパイラ内部では常に完全修飾名でクラスが区別されるので、短いクラス名が同じでもnamespaceが違えば異なるクラス名となり、名前がぶつからない。

だから実はnamespaceには、「世界の誰とも一致しない独自の単語」を採用するのが理想だったりする。デフォルトはプロジェクト名と同じnamespaceがついているが、自作ライブラリを作る場合などは、独自のかっこいいnamespaceに書き換えたうえでコードを記述していくとよい。

あ、せっかくだからこれは次回のネタに回します。

●次回の予告

ライブラリの作り方後編。自作クラスをDLL化して、それを呼び出します。

2015年11月29日日曜日

P006-色付き表示をライブラリ化

今日の目標→

前回は、「色付き文字を出力するメソッド」を作った。使ってみたら結構便利なので、他のプログラムからでも利用できるように、これをライブラリ化してみる。

●プロジェクトの作成

とりあえず「TextWork3」という名前で、新規プロジェクトを作る

●色付き文字表示用クラスRichReporterの作成

  1. メニューバーから「プロジェクト」→「クラスの追加」を選ぶとクラス追加ウィンドウが開く
  2. 左のカテゴリで「コード」を選び、右のアイコンから「クラス」を選ぶ
  3. 名前を「RichReporter.cs」として「追加」を押すと、新しいコードウィンドウが開く
  4. 次のコードを入力する

メソッドの中身は、前回(TextWork2)のForm1.csとまったく変わらないので、ほとんどコピペでいけるはず。ただしPrint()とColorPrint()は公開メソッドにするので、private宣言をpublicに修正してちょ。

●フォームからRichReporterクラスを利用する

  1. Form1.csを開く
  2. 次のコードを入力する

RichReporterクラスの使い方は、まず

MyReporter = new RichReporter(MyTextBox);

のように、出力先を指定してRichReporterのオブジェクトを作る。そして、

MyReporter.ColorPrint(Color.Red, "ほげほげ");

みたいな形でメソッドを呼び出せば、指定した出力先にテキストが表示されるという寸法だ。ね、簡単でしょう?(反語表現)

●次回の予告

次回はこのRichRepoterライブラリを、ソースコードのままリンクして利用する方法と、DLL化して利用する方法について説明する。

2015年11月28日土曜日

P005-文字を色付きで表示

今日の目標→

文字に色を付けたり、行をスクロールさせるなど、RichTextBoxを使ったテキスト表示のテクニックを探る。

●プロジェクトの作成

  1. 「TextWork2」という名前で、新規プロジェクトを作る
  2. Form1.csのコードを開き、前回(TextWork)のForm1.csのコードをコピペする
  3. コードを次のように修正する。

これも「開始(S)」ボタンで表示が始まり、「停止(E)」ボタンで止まる。見どころは次の3つ。

  • 開始と停止メッセージに色がついている
  • 文字表示が最下部に達するとスクロールする
  • 行数が20行を超えると先頭行から順に消えていく

(実行画面が入る予定)

●文字に色

RichTextBoxで、文字に色を付ける方法は2つある。

(A) すでに表示されている文字の色を変えるには

  1. Select()メソッドで、色を変えたい文字範囲を選択
  2. SelectionColorプロパティで、その範囲の色を設定

(B) これから表示する文字の色を変えるには

  1. Select()メソッドで、テキスト末尾の「長さ0の範囲」を選択
  2. SelectionColorプロパティで、文字色を設定
  3. この状態でAppendText()メソッドを実行すると文字に色がつく

今回はAddText()の定義の中で(B)の方法を使っているので見てみてね。

●余分な行を削除

行の削除にはコツがある。というのも、RichTextBoxの操作は基本的にキャラクタ単位で行うため、行単位の操作は面倒なのだ。そこで次の2つのメソッドの出番となる。

  • GetLineFromCharIndex() -- 文字の位置から行番号を得る
  • GetFirstCharIndexFromLine() -- 行番号からその行の先頭の文字位置を返す

今回はCheckLines()の定義の中でこれらを使っている。

●最下行までスクロール

RichTextBoxにはScrollToCaret()メソッドというものがあって、キャレットが見える位置までウィンドウをスクロールできる。キャレットというのは、文字入力の位置でチカチカ点滅している線のことだ。文字カーソルともいう。

キャレットを移動するには、Select()メソッドで、任意の文字位置に「長さ0の範囲」を指定すればよい。

今回はScrollToEnd()の定義の中でこの方法を使っている。

以上、とても駆け足の説明でした。まあ、詳しいことはコードを読んでください。

●今日から投稿は丑三つ時に

今後の投稿ペースですが、できれば毎日1記事を目指します。 もちろん全部プログラムネタは無理っぽいので、ただの独り言の場合もあります。

投稿時刻はブログの設定で毎回午前2:00に統一しようと思います。あまりバラバラな投稿時刻だと、どんな生活リズムだと思われそうで恥ずかしいから…。

2015年11月27日金曜日

P004-テキスト表示プログラム

今日の目標→

ここまで画像表示ばっかり続いたので、テキスト表示にも挑戦する。

●プロジェクトの作成

  1. 「TextWork」という名前で、新規プロジェクトを作る
  2. Form1.csのコードを開き、次のプログラムを入力する

プログラムを実行し、「開始(S)」ボタンを押すと、現在時刻を1秒ごとに繰り返して表示する。「終了(E)」ボタンを押すと停止する。

●要点の解説

文字出力には各種の方法がある。たとえばConsole.Write()によるコンソール出力とか、Labelコントロールにテキストを表示するとか。しかしいろいろ試した結果、いちばん便利だと思ったのは、テキストボックスを1個配置して、そこにテキスト出力を垂れ流していく方法だ。

このときただのTextBoxクラスではなくRichTextBoxクラスを使えば、文字に色をつけたりできて面白い。次の記事からしばらくは、RichTextBoxを利用したテキスト出力や文字列処理についてみていきたい。

あと今回使ったタイマー(Windows.Forms.Timerクラス)についても、いつか説明したいところ。

(実行画面が入る予定)

2015年11月25日水曜日

P003-クリップボードから画像をペースト

今日の目標→

前回のプログラム(ImageView2)に手を加え、クリップボードから画像を貼り付けられるようにする。

●プロジェクトの作成

  1. 「ImageView3」という名前で、新規プロジェクトを作る
  2. Form1.csのコードを開き、ImageView2のForm1.csからコードをコピペする
  3. コードを次のように修正する。

コードを書き終えたらさっそく実行してみよう。他のソフト上で画像の「コピー」を実行し、このプログラムの「貼り付け」メニューを選択すると、ピクチャボックスに画像が表示されるはずだ。

●要点の解説

クリップボードとの画像データのやりとりは単純だ。次の2つのメソッドを使えばいい。

  • Clipboard.SetImage() → クリップボードに画像を保存する
  • Clipboard.GetImage() → クリップボードから画像を取得する

まあ実際は、このお手軽なメソッドにも弱点があって、透過GIFや透過PNGをクリップボード経由でやりとりすると透明色が消えてしまったりする。この問題は、昔なんかして解決した記憶があるので、あとで思い出したら解決法を書いてみる。

しかし今回の追加コードのほとんどがメニュー関連の処理になってしまった。ここでは標準のMenuStripクラスじゃなくて、古くからあるMainMenuクラスを使っている。古いプログラムから取ってきたコードだけど問題なく動いてよかった。

またメニューの設定データにXMLを利用している。こういうメニューみたいな階層構造のデータは、XMLで記述するのが楽である。XMLの使い方はそのうちちゃんと説明するので、しばらくお待ちくだされ。

(実行画面が入る予定)

2015年11月24日火曜日

P002-ファイルをドラッグ&ドロップで開く

今日の目標→

前回のプログラム(ImageView)に手を加え、ドラッグ&ドロップで画像ファイルを開けるようにする。

●プロジェクトの作成

  1. 「ImageView2」という名前で、新規プロジェクトを作る
  2. Form1.csのコードを開き、前回のForm1.csのコードをコピペする
  3. コードを次のように修正する。

しかしこれ<textarea>タグでコードを表示してるんだけど読みにくいな。別の表示法にしたほうがいいかな。まあ、おいおい考えよう。

●要点の解説

フォームに対してドラッグ&ドロップを行うには、少なくとも次の3つが必要だ。

  • DragEnterイベントの処理ルーチンを追加する
  • DragDropイベントの処理ルーチンを追加する
  • AllowDropフラグをtrueに設定する

イベント処理ルーチンの入力はVisual Studioが助けてくれるので楽ちんである。たとえばDragEnter処理を書く場合は次のようになる。

  1. まず「this.DragEnter +=」まで手で入力する
  2. TABキーを押すと、自動的にイベントハンドラの枠組みのコードが挿入される
  3. Enterキーを押すと確定する。Enterキーを押す前にハンドラ名の変更もできるが、まあ必要ないと思う
  4. イベントハンドラの枠組みができたら、あとは中身を自分でコーディングする

DragEnterハンドラとDragDropハンドラの中身は、定型の処理なので説明は省略する。わからない部分があればコメント欄ででも質問してください。できる範囲で答えます。

コードを書き終えたらさっそく実行してみよう。Windowsのフォルダから適当な画像ファイルをドラッグして、このプログラムのフォームにドロップすれば、画像が表示されるはずだ。

(実行画面が入る予定)

P001-画像表示プログラム

最近ではC#もいろいろ進化してるようだけど、まあその辺はいずれ学ぶとして、とりあえず昔の知識でできるところから始めよう。「画像をピクチャボックスに表示するプログラム」なんか簡単でいいかな。

●プロジェクトの作成

  1. メインメニューから[ファイル]→[新しいプロジェクト]を選ぶく
  2. 開いたウィンドウで、左上のツリーから[Visual C#]を選ぶ
  3. 右のテンプレート一覧から[Windowsフォームアプリケーション]を選ぶ
  4. 下の名前欄にプログラムの名前を入力(ここではImageViewとした)
  5. [OK]ボタンを押すと、プロジェクトが新規作成される

ここでツールバーの[開始]ボタンをクリックすると、プログラムがコンパイルされ、起動し、何もないウィンドウが表示された。よしよし昔と変わってないね。

(画像が入る予定)

●コードの入力

さてそれじゃコードを書いていくよ。ソリューションエクスプローラで、

Form1.csの名前を右クリック→[コードの表示]を選択

すると、コードウィンドウが開くから、次のようにコード入力する。

ボタン等の配置は、Visual Studioのデザイナー上でマウスで置くこともできるが、個人的には上記のようにぜんぶコードで書くほうが好きだ。そのほうが早いし。

コード入力が終わったら、ツールバーの[開始]ボタンを押すとプログラムが起動する。[ファイル参照]ボタンで適当な画像ファイルが読み込めることを確認すべし。

(画像が入る予定)