初めて作る C# プログラム - MyClock
プログラム電卓のためのC#プログラミング
2017/01/31
大きく改訂 2017/02/22
更新 2022/10/04
▶ クイックマニュアルにヘルプ表示方法を追記。
初めて作る C# プログラム - MyClock
[2022/10/04 追記]
Visual Studio Community 2019 ver16.11.19 でリビルドしました。scClockも同様にしてリビルドして Ver 3.02にアップデートしました。システム安定性とセキュリティー向上が目的。
[2019/05/03 追記]
開発環境を Visual Studio Community 2019 に切り替えました。これまで作成していた VS Comunity 2015 のソースをそのまま修正無しでビルドできました (VS Community 2017 では修正が必要でした)。VS Community 2019 は起動が非常に速くなり、ビルドも速くなりお勧めです。
無償で入手できる開発環境 Visual Studio Community 2015 の C# を初めて触ってみながら、具体的なプログラムを作ってみます。
プログラミングの習得に効果的なのは、自分が欲しいプログラムを作ること、そして人に説明すること。私の持論です。最初は簡単に作れそうで、さらに機能追加すると自分が欲しいプログラムになるようなのが題材として良いですね。
▋はじめに
シンプルな時計から始めます。
というのも、10年以上前に、アクティブになっているウィンドウのタイトルバーに常に張り付く小さな時計 scClock を作り、10年以上愛用していました。番外編 - 小さな時計 - scClock をご参照。
ところが最近は、目が疲れてくると小さな時計のフォントの視認に困ることがあります。フォントを大きくするとタイトルバーには収まりそうにないので、半透明で大きなフォントの時計にすれば良いかも知れない...ということで、老眼が始まった世代のための邪魔にならないデジタル時計...というコンセプトでアプリを作ることにしました。
[2022/10/04 追記]
Visual Studio Community 2019 の最新版 ver16.11.19 でリビルド。
[2019/05/03 追記]
開発環境を Visual Studio Community 2019 に変更。Ver 1.19.1.1 で2重起動抑制ができなくなっていたのを修正。
[2019/01/25 追記]
古いPCにインストールした時に .NET Framework 3.5.1 がインストールできないことがあるのを修正、その他、細かいバグ修正
[2018/11/18 追記]
外観を変更した時やカタログ機能で外観を切替える時、時計の外観に反映するのが1秒間隔でした。これを0.2秒間隔に変更したので、実質上リアルタイムで反映するようになりました。Ver 1.19.1.0 以降で対応。
[2017/03/05 追記]
MyClock の外観がカスタマイズできるようになり、アクティブなキャプションバーに貼り付く機能も盛り込んだので、scClock 同一の外観と同一の機能を MClockのカスタマイズで適用できるようになりました。scClock は役割を終えたようです。10年以上ありがとう!
[2017/02/14 追記]
10年以上前に Active Basic (Windows XP) で作った 小さな時計 - scClock を作って常用してきました。今回作ったMyClock のフォントや外観を小さくすることで scClock として作り直し、アクティブなキャプションバーに貼り付く機能を追加しました。これを Win 7 以降 (対象のフレームワークは .NT Framework 3.5) に対応する scClock Ver 3.01 としました。
小さな時計 - キャプションバーに張り付く時計 (ソース付き)
scClock Ver 3.02
▋PC保護の警告について
自作プログラムや信頼できる入手先からダウンロードしたプログラムを実行しようとすると、Windows 8 以降ではPC保護の警告がでます。
最近は悪質なマルウェアやインターネットサイトがあるので細心の注意は必要ですが、汚染されていない自信があるクリーンなPCで自分で作ったプログラムでも、ほぼ確実にこの警告がでます。さらにセキュリティーソフトが追いうちをかけて、警告を出します。
対策については、こちらをご覧ください。
自作プログラムがPC保護警告に引っかかる
▋最新の MyClock
初めてC#で作るプログラムの最新の MyClock は C#学習を反映しています。ここに至る道筋を簡単に記事にします。さらに自分なりのプログラミングTipsも紹介する予定です。
==========
邪魔にならないデジタル時計 (アラーム機能付き)
MyClock Ver 1.19.1.3
最新版 (ソース付き) Ver 1.19.1.3 のダウンロード
- アラーム機能があります。
- 時計の外観をカスタマイズできます。
- ポータブルアプリです(フォルダにコピーするだけで使え、不要になればフォルダごと削除するだけです)。
- カタログ機能を追加。時計の外観を登録しておいて一発切替えできます。
- MyClock.exe
- Interop.IWshRuntimeLibrary.dll
- scClock.exe
<MyClock>フォルダにソースファイルが入っています。MyClock.sln を実行するとVisual Studio で読み込んで起動します。Visual Studio Community 2015 で作ったものです。
MyClock紹介ページ
MyClock Ver 1.18.4 以降で、[MyClockについて]画面のキャプションバーにある[?]ボタンクリックで、このMyClock紹介ページがブラウザで開くようになっています。
▋シンプルなものから最新までの道筋
▍多分最も簡単に作れる時計アプリ

手始めに、前面表示する半透明でフォントの大きなのデジタル時計を作りました。
タイマーコントロール、フォームのプロパティ設定だけでできます。とは言っても初めてC#で作ったので、主にIDEの使い方やC#が自動生成するコードについて調べてみました。
▍クライアント領域のマウス操作、プロセスの排他処理
キャプションバーと枠を取り去ったデジタル時計に改造しました。そのためには、クライアント領域のマウス操作が不可欠になります。そこで、C#でマウスのイベントハンドラを使ってみました。
こんな感じになりました。

アプリ用のアイコンリソースの使い方も試しました。さらに二重起動禁止にするため、mutex を使ったプロセスの排他処理を C#で試してみました。VC++の感覚で扱えることが分かりました。
[C#プログラミングTIPS] 2重起動禁止のいくつかの方法
▍キー入力の取得とモーダルダイアログ
[Esc]キーを取得してモーダルダイアログを表示させる処理を作ってみました。
[C#プログラミングTIPS] モーダルダイアログと[OK]での戻り値
アプリの機能としては、こんな感じのフォームでアラームの設定を行います。

私の Windows 10 環境だと標準のフォントサイズが 9pt になっていますが、そもそも大きな文字の時計を作るコンセプトなので、12pt を基本のフォントサイズにしました。
過去の VC++ でも使ったことの無い DateTimeコントロールを初めて使ってみました。他には、ボタン操作やチェックボックスなどの練習もできました。クリックすると [▶前面] ⇒ [▶最大化] ⇒ [▶前面中央] と3フェーズを循環するボタンを実装。[OK]ボタンは[Enter]キーと連動、[Cancel]ボタンは[Esc]キーと連動させるのは、フォームのプロパテティの設定で実装できることも試しました。
▍Win32 APIの利用
アラームが発動した時、目立つように点滅させます。そこで、キャプションバーとボーダーフレームを点滅させるWin32 API の利用を試しました(.NET Framework にはウィンドウ点滅の機能が準備されていないようです)。
[C#プログラミングTIPS] フォームを点滅させる Win32 APIの利用
こんな感じで、点滅します。
アラーム発動時に、ウィンドウの最大化やスクリーン中央への移動などのオプションを作りました。

▍ピクチャーボックとテキストボックス、アセンブリ情報の活用
ピクチャーボックスにアイコンを表示し、テキストボックスにクイックマニュアルを表示するのを試しました。
こんな感じのアプリ情報のダイアログを作り、[F1]キーを押して呼び出すようにしました。

ここでも 標準の9pt よりも大きなフォントで表示しています。
さらに、アプリに埋め込まれるバージョンとかアプリ名などのアセンブリ情報の取得も試みました。
アセンブリ情報を利用は初めてで、ここで表示している「アプリの説明」、「アプリ名 (MyClock)」、「バージョン」、「Copyright表示」は全てアセンブリ情報から取得して表示。バージョンアップ時にアセンブリ情報を変更するだけで良く、フォームの変更は不要です。
▍外部アプリを起動してみる
外部アプリとして、以前作った scClock (小さな時計) を起動する処理を作ってみました。Win32 APIを使わずに .NET Framework と C# だけで起動しているプロセスの列挙、プロセスの終了、例外処理ができました。
[C#プログラミングTIPS] 外部プログラムを起動する
▍モードレスダイアログとプロパティグリッド
時計の外観をカスタマイズする機能を追加しました。外観の設定をリアルタイムに反映させるために、モードレスダイアログとプロパティグリッドの組み合わせが良さそうです。
[C#プログラミングTIPS] モードレスダイアログを使う
プロパティグリッドは初めて使ってみましたが、非常に便利なものですね!
プロパティグリッドは、基本的な使い方が分かれば、細かなユーザーインターフェースをコーディングする必要がありません。
[C#プログラミングTIPS] PropertyGrid を使う
今回作った時計は、その外観に "通常の外観"と"アラーム設定時の外観"の2つで1セットです。そこで、プロパティグリッドに表示するプロパティもそれぞれに併せて2つ用意します。2つの外観と2つのプロパティセットを動的に連動させました。
[C#プログラミングTIPS] 別フォームのプロパティにアクセス (set / get) する
さらに、プロパティグリッドの上にある外観変更ボタン (下の図では [通常の外観]ボタン) で2つの外観を強制的に変更し、プロパティグリッドの表示をこれに連動させました。
このように、異なるクラスのフォーム間で互いのフォームの表示を双方向で制御するC#のコーディングが試せました。
通常の外観のカスタマイズは、こんな感じ...

アラーム設定時の外観のカスタマイズは、こんな感じ...

極端に小さくして scClock のような外観にもできます。

読者の方からのコメントでヒントを頂き、MyClock にキャプションバーに常に貼り付く機能を選べるようにしました。
外観の設定の画面に追加したボタンを押すことで、貼り付く / 貼り付かないを選択できます。
通常の外観をこんな感じにして、キャプションバーに貼り付いたところ...

アラーム設定時の外観は、こんな感じにしてみます。

作ってみたら、良い機能だと気がつきました( ^^;
▍アプリケーション構成ファイル (*.exe.config) の思い込み
当初からレジストリや特殊フォルダを使わずに、インストールフォルダの中だけで完結するポータブルアプリを作っているつもりでした。アプリーション構成ファイルを使うと楽なので ビルドして得られる MyClock.exe.config をインストールフォルダに置いておけばポータブルアプリになると思い込んでいましたが、大きな勘違いでした。MyClock.exe.config は初期設定に使われるだけで、アプリケションの設定内容は AppData 配下のフォルダに作られていました。それもかなりの量のファイルやフォルダが作られていました。
さらに、アプリケーション構成ファイルは1つ前のバージョンの設定はそのまま引き継げますが、それ以前のバージョンで保存された設定情報を読み込めないという問題があることも知りました。
そこで、昔ながらの INIファイルにアプリの設定情報を保存して使うように変更しました。XMLファイルを設定ファイルとして使う方法もありますが、コーディングが楽な INIファイルを採用しました。Win32 API を呼び出してコーディングしますが、他の Win32 APIと異なり、C#用のラッパーの作成に少し悩みました。int 変数の読み書きは使わず、string (文字列) 変数のみの読み書きとしました。
[C#プログラミングTIPS] INIファイルを使う
▍ArrayList とトラックバー(スライダー)
時計の外観のプロパティを無制限に複数登録し、そこから任意のプロパティを呼び出す機能(カタログ機能)を追加するため、ArrayList と トラックバーを使ってみました。
ArrayListの良いところは、2次元配列と異なり、動的な要素の追加と削除が簡単にできる点にあります。非常に多くの外観のプロパティをArrayListに追加した場合でも、そのプロパティの個数の影響を受けずに選択しやすいインターフェースとしてトラックバーはメリットがあると思いました。登録数が増えればトラックバーの刻みを細かくするだけで良いからです。リストボックスやコンボボックスの利用も頭をよぎりましたが、これはVC++で以前使ったことがあり、登録保存するプロパティに何らかの名前(文字列)が与えられることが利用の前提となるのは使う時に煩わしいと感じたので、コンボボックスは使わないことにしました。
[C#プログラミングTIPS] ArrayListに配列を格納して使う
列挙したものを選択するコントロールとしては、
- リストボックス
- コンボボックス
- イメージリスト
- ツリービュー
- ラジオボタン
- ボタンを並べる
そして、プロパティの登録作業用のクラスを作って、インデックスプロパティ、操作メンバなどをクラスにキャプシュレートして C#らしいコードに挑戦してみました。C#使いの方からみればダメダメなコードだと思いますが、約1ヶ月前にC#を始めたころから見れば進歩はしていると思います。ダメさ加減も含めてソースを公開しているのは、気を引き締めるためもあります。
さて出来上がったカタログ画面ですが、こんな感じでカスタマイズした外観を[追加]します。

操作するコントロールが少ないですが、それだけに柔軟です。登録数が多くなってトラックバーの刻みが細かくなりすぎる時を想定して、フォームを横に広げられるようにしました。
時計の実際の外観、[時計のカスタマイズ]画面の表示、そして[時計のカタログ]画面の3つの異なるフォームの表示内容は、常に同期して変化するようにしました。
外観のプロパティを6個登録して、そこから INDEX 1/6 を通常の外観に適用した例...

時計のカスタマイズ(外観の設定)画面はプロパティグリッドを使って、リアルタイムに外観をカスタマイズできるよう作っていて、さらにカタログ機能も同期しているため、トラックバーを動かすと、実際に時刻を刻んでいる時計の外観が動的に変更されます。
こんな小さな外観を登録しておき、アラーム設定時の外観に適用したところ...

こんな小さな外観だと、色々なフォームが上に被さって行方不明になりそうなので、これらのフォームは時計に重ならないように「時計のカスタマイズ」ダイアログと「時計のカタログ」ダイアログを自動的に(タイマーを使って定期的に)再配置するようにしました。
なお、異なる3つのフォームの表示内容を同期させるために必要な変数を Public static にして、全てのフォームからアクセスするようにしました(C#としてはお行儀が悪いとの恐れがあります)。
▍特殊フォルダへのアクセスと実行中に自分自身のショートカットを作成する
これまで自分で使う際には、ショートカットファイル MyClock.lnk を作って、それをスタートアップフォルダへコピーしてログイン時に自動起動するようにしていました。そこでこれをアプリから自動的に設定できるようにしました。具体的には、実行中の自分自身のショートカット作成とスタートアップフォルダへのコピーを行う「ログイン時に起動する」機能を追加しました。タスクマネージャーのスタートアップで確認できます。

[ログイン時に MyClock を起動する] にチェックを入れるとその場でスタートアップフォルダにショートカットを作成し、チェックを外すとその場でショートカットを削除します。
[C#プログラミングTIPS] スタートアップフォルダに実行中のアプリのショートカットを作る
初めてC#を使いだして1ヶ月程度の間に機能を追加してきたアプリですが、かなり満足できる仕上がりになってきたと思います。肝心のC#の学習はまだ始まったばかりで、まだまだ分からないことが多くヘボなソースだと思います。
以下では、最初から順にソースを見直して学習したことの整理と定着を図りたいと考えています。
C#学習の履歴を以下にまとめます。
▋フォームを作り時刻を表示させる (Ver 0.10)
仕 様
- フォントが大きい
- 半透明で常に前面表示
- Visual Studio IDE の使い方と基本的な機能
・タイトルバーの無い小さな(邪魔にならない)外観に変更
・クライアント領域を左ダブルクリックで終了可能にする
・クライアント領域をマウスで掴んで移動可能にする
・マウス右クリックで最小化できるようにする
試したこと
- イベントハンドラの作成と フォームデザイナーの挙動
▋モーダルダイアログで設定した各種変数を親ウィンドウに反映させる
更新履歴
- [Esc]キーでアラーム設定
- アラーム発動時マウスを左クリックで元に戻る
⇒ MyClock Ver 1.10 のページ
▋MyClock Ver 1.11 にアップデート
更新履歴
▋MyClock Ver 1.11 にアップデート
更新履歴
・アラーム設置柄画面を時計の周りに重ならずに表示
・アラーム設定画面で、現在時刻をがが取得可能にした
・最小化からのアラーム発動では半透明最大化させる
・最前面に表示しないことがあったのを修正
・Alarm.exe 単独起動のエラーの場合メッセージを表示して終了。
⇒ MyClock Ver 1.11 のページ
▋MyClock Ver 1.12 にアップデート
更新履歴
・以下を保存して再起動時に復元するようにした
- アラーム設定時刻
- アラーム解除設定状態
- 時計の表示位置
⇒ MyClock Ver 1.12 のページ
▋MyClock Ver 1.13 にアップデート
更新履歴
▋MyClock Ver 1.13 にアップデート
更新履歴
・終了時に補村して再起動時に復元する項目を追加
- 終了時の時計のサイズ(ノーマル/最小化)
⇒ MyClock Ver 1.13 のページ
▋MyClock Ver 1.14 にアップデート
更新履歴
・時計の表示状態ごとにアラーム発動時の外観を選択できます。
- 時計の表示状態:前面表示 / 最小化
- アラーム発動時の外観:前面表示 / 最大化
・アラーム発動時の外観設定を終了時に保存し再起動時に復元する。
・MyClock.exe から呼び出されず単独起動の場合の例外処理を追加。
⇒ MyClock Ver 1.14 のページ
▋MyClock Ver 1.15 にアップデート
更新履歴
2017/02/04 ・アラーム設定に「▶前面中央」を追加した。
・起動時に「MyClock の使い方」の表示ができるようにした。
- 起動時の表示をするかどうかを設定できる
⇒ MyClock Ver 1.13 のページ
▋MyClock Ver 1.14 にアップデート
更新履歴
・時計の表示状態ごとにアラーム発動時の外観を選択できます。
- 時計の表示状態:前面表示 / 最小化
- アラーム発動時の外観:前面表示 / 最大化
・アラーム発動時の外観設定を終了時に保存し再起動時に復元する。
・MyClock.exe から呼び出されず単独起動の場合の例外処理を追加。
⇒ MyClock Ver 1.14 のページ
▋MyClock Ver 1.15 にアップデート
更新履歴
2017/02/04 ・アラーム設定に「▶前面中央」を追加した。
・起動時に「MyClock の使い方」の表示ができるようにした。
- 起動時の表示をするかどうかを設定できる
応援クリックをお願いします。励みになるので...