初めて作る C# プログラム - MyClock

プログラム電卓のためのC#プログラミング
e-Gadget

<トップページへ>


2017/01/31
大きく改訂 2017/02/22
更新 2017/04/06

更新: 最新版 MyClock Ver 1.18.5.1 を公開(ソース付き)


初めて作る C# プログラム - MyClock


無償で入手できる開発環境 Visual Studio Community 2015 の C# を初めて触ってみながら、具体的なプログラムを作ってみます。

プログラミングの習得に効果的なのは、自分が欲しいプログラムを作ること、そして人に説明すること。私の持論です。最初は簡単に作れそうで、機能追加で欲しいプログラムになりそうなものが良いですね。


はじめに

シンプルな時計から始めます。

というのも、10年以上前に、アクティブになっているウィンドウのタイトルバーに常に張り付く小さな時計 scClock を作り、10年以上愛用していました。番外編 - 小さな時計 - scClock をご参照。

ところが最近は、目が疲れてくると小さな時計のフォントの視認に困ることがあります。フォントを大きくするとタイトルバーには収まりそうにないので、半透明で大きなフォントの時計にすれば良いかも知れない...ということで、老眼が始まった世代のための邪魔にならないデジタル時計...というコンセプトでアプリを作ることにしました。



[2017/02/14 追記]
10年以上前に Active Basic (Windows XP) で作った 小さな時計 - scClock を作って常用してきました。今回作ったMyClock のフォントや外観を小さくすることで scClock として作り直し、アクティブなキャプションバーに貼り付く機能を追加しました。これを Win 7 以降 (対象のフレームワークは .NT Framework 3.5) に対応する scClock Ver 3.01 としました。 

小さな時計 - キャプションバーに張り付く時計 (ソース付き)
scClock Ver 3.01


[2017/03/05 追記]
MyClock の外観がカスタマイズできるようになり、アクティブなキャプションバーに貼り付く機能も盛り込んだので、scClock として使えるようになりました。scClock は寿命を終えたようです。10年以上ご苦労様!


PC保護の警告について

自作プログラムや信頼できる入手先からダウンロードしたプログラムを実行しようとすると、Windows 8 以降ではPC保護の警告がでます。

最近は悪質なマルウェアやインターネットサイトがあるので細心の注意は必要ですが、汚染されていない自身のあるクリーンなPCで自分で作ったプログラムで、ほぼ確実にこの警告がでます。さらにセキュリティーソフトが追いうちをかけて、警告を出します。

対策については、こちらをご覧ください。

自作プログラムがPC保護警告に引っかかる



最新の MyClock

初めてC#で作るプログラムの最新の MyClock は C#学習を反映しています。ここに至る道筋を簡単に記事にします。さらに自分なりのプログラミングTipsも紹介する予定です。

==========

邪魔にならないデジタル時計 (アラーム機能付き)
MyClock Ver 1.18.5.1  [更新 2017/04/06]
最新版 (ソース付き) Ver 1.18.5.1 のダウンロード
  • アラーム機能があります。
  • 時計の外観をカスタマイズできます。
  • ポータブルアプリです(フォルダにコピーするだけで使え、不要になればフォルダごと削除するだけです)。
  • カタログ機能を追加。時計の外観を登録しておいて一発切替えできます。
動作に必要な最小限のファイル:
  • MyClock.exe
  • Interop.IWshRuntimeLibrary.dll
  • scClock.exe
一応 ReadMe.txt も入っています。

<MyClock>フォルダにソースファイルが入っています。MyClock.sln を実行するとVisual Studio で読み込んで起動します。Visual Studio Community 2015 で作ったものです。

MyClock紹介ページ
MyClock Ver 1.18.4 以降で、[MyClockについて]画面のキャプションバーにある[?]ボタンクリックで、このMyClock紹介ページがブラウザで開くようになっています。


シンプルなものから最新までの道筋

多分最も簡単に作れる時計アプリ

Ver1.00外観 

手始めに、前面表示する半透明でフォントの大きなのデジタル時計を作りました。
タイマーコントロール、フォームのプロパティ設定だけでできます。とは言っても初めて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]キーを押して呼び出すようにしました。

Aboutダイアログ_ボタンなし 

ここでも 標準の9pt よりも大きなフォントで表示しています。

さらに、アプリに埋め込まれるバージョンとかアプリ名などのアセンブリ情報の取得も試みました。
アセンブリ情報を利用は初めてで、ここで表示している「アプリの説明」、「アプリ名 (MyClock)」、「バージョン」、「Copyright表示」は全てアセンブリ情報から取得して表示。バージョンアップ時にアセンブリ情報を変更するだけで良く、フォームの変更は不要です。


外部アプリを起動してみる

外部アプリとして、以前作った scClock (小さな時計) を起動する処理を作ってみました。Win32 APIを使わずに .NET Framework と C# だけで起動しているプロセスの列挙、プロセスの終了、例外処理ができました。

[C#プログラミングTIPS] 外部プログラムを起動する


モードレスダイアログとプロパティグリッド

時計の外観をカスタマイズする機能を追加しました。外観の設定をリアルタイムに反映させるために、モードレスダイアログとプロパティグリッドの組み合わせが良さそうです。

[C#プログラミングTIPS] モードレスダイアログを使う

プロパティグリッドは初めて使ってみましたが、非常に便利なものですね!
プロパティグリッドは、基本的な使い方が分かれば、細かなユーザーインターフェースをコーディングする必要がありません。

[C#プログラミングTIPS] PropertyGrid を使う

今回作った時計は、その外観に "通常の外観"と"アラーム設定時の外観"の2セットあります。そこで、プロパティグリッドに表示するプロパティもそれぞれに併せて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に追加した外観プロパティを視覚的に無制限に表現するためにトラックバーはメリットがあると思いました。登録数が増えればトラックバーの刻みを細かくするだけで良いからです。

[C#プログラミングTIPS] ArrayListに配列を格納して使う

列挙したものを選択するコントロールとしては、
  • リストボックス
  • コンボボックス
  • イメージリスト
  • ツリービュー
  • ラジオボタン
  • ボタンを並べる
などが考えられますが、文字列を使わない(ユーザーがいちいち外観に名前を付ける手間が無い)、無制限に追加削除が簡単にできて決まった領域にコントロールを格納できる、といった要件を考え、さらにコーディングが楽そうだという理由でトラックバー (スライダー)を使ってみることにしました。

そして、プロパティの登録作業用のクラスを作って、インデックスプロパティ、操作メンバなどを行うような C#らしいコードに挑戦しました。C#使いの方からみればダメダメなコードだと思いますが、約1ヶ月前にC#を始めたころから見れば進歩はしていると思います。ダメさ加減も含めてソースを公開しているのは、気を引き締めるためもあります。

さて出来上がったカタログ画面ですが、こんな感じでカスタマイズした外観を[追加]します。
カタログ機能

操作するコントロールが少ないですが、それだけに柔軟です。登録数が多くなってトラックバーの刻みが細かくなりすぎる時を想定して、フォームを横に広げられるようにしています。

時計の実際の外観、[時計のカスタマイズ]画面の表示、そして[時計のカタログ]画面の3つの異なるフォームの表示内容は、常に同期して変化するようにしました。

外観のプロパティを6個登録して、そこから INDEX 1/6 を通常の外観に適用した例...
カタログ機能2

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

こんな小さな外観を登録しておき、アラーム設定時の外観に適用したところ...
カタログ機能3

こんな小さな外観だと、色々なフォームが上に被さって行方不明になりそうなので、これらのフォームは時計に重ならないように再配置するようにしています。

異なる3つのフォームの表示内容を同期させるため、Public static な変数を全てのフォームからアクセスするようにしています。


特殊フォルダへのアクセスと実行中に自分自身のショートカットを作成する

これまで自分で使う際には、ショートカットファイル MyClock.lnk を作って、それをスタートアップフォルダへコピーしてログイン時に自動起動するようにしていました。そこで、実行中の自分自身のショートカット作成とスタートアップフォルダへのコピーを行う「ログイン時に起動する」機能を追加しました。タスクマネージャーのスタートアップで確認できます。

スタートアップ設定 

[ログイン時に MyClock を起動する] にチェックを入れるとその場でスタートアップフォルダにショートカットを作成し、チェックを外すとその場でショートカットを削除します。

[C#プログラミングTIPS] スタートアップフォルダに実行中のアプリのショートカットを作る

初めてC#を使いだして1ヶ月程度の間に機能を追加してきたアプリですが、かなり満足できる仕上がりになってきたと思います。肝心のC#の学習はまだ始まったばかりで、まだまだ分からないことが多くヘボなソースだと思います。

以下では、最初から順にソースを見直して学習したことの整理と定着を図りたいと考えています。



C#学習の履歴を以下にまとめます。

フォームを作り時刻を表示させる (Ver 0.10)

仕 様
  • フォントが大きい
  • 半透明で常に前面表示
試したこと
  • Visual Studio IDE の使い方と基本的な機能
 MyClock Ver 0.10 のページ



クライアント領域のマウス操作でアプリの終了と移動を行う (Ver 1.00)

更新履歴

 ・タイトルバーの無い小さな(邪魔にならない)外観に変更
 ・クライアント領域を左ダブルクリックで終了可能にする
 ・クライアント領域をマウスで掴んで移動可能にする
 ・マウス右クリックで最小化できるようにする

試したこと
  • イベントハンドラの作成と フォームデザイナーの挙動

 MyClock Ver 1.00 のページ



モーダルダイアログで設定した各種変数を親ウィンドウに反映させる

更新履歴

 ・アラーム機能を追加
  - [Esc]キーでアラーム設定
  - アラーム発動時マウスを左クリックで元に戻る

 MyClock Ver 1.10 のページ



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.14 にアップデート

更新履歴
 ・時計の表示状態ごとにアラーム発動時の外観を選択できます。
  - 時計の表示状態:前面表示 / 最小化
  - アラーム発動時の外観:前面表示 / 最大化
 ・アラーム発動時の外観設定を終了時に保存し再起動時に復元する。
 ・MyClock.exe から呼び出されず単独起動の場合の例外処理を追加。

 MyClock Ver 1.14 のページ


MyClock Ver 1.15 にアップデート

更新履歴

  2017/02/04 ・アラーム設定に「▶前面中央」を追加した。
        ・起動時に「MyClock の使い方」の表示ができるようにした。
         - 起動時の表示をするかどうかを設定できる




応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ



  


keywords: プログラム関数電卓、Windowsプログラミング

リンク集 | ブログ内マップ

テーマ : プログラム関数電卓
ジャンル : コンピュータ

C# で MyClock Ver 0.10 を作る (2/2)

プログラム電卓のためのC#プログラミング
e-Gadget

<MyClock トップへ戻る>


2017/01/31

初めて作る C# プログラム - MyClock


MyClock Ver 0.10を作る (2/2)

MyClock が動作するようになりましたが、.NET Framework を必要とする C# アプリに関しては、.NET Framework のバージョンが気になります。


Windows 10 にインストールした Visual Studio Community 2015 の C# で MyClock の新規プロジェクトを作成する時に「対象のフレームワーク」を .NET Framework 4.6.1 に設定しています。



.NET Framework と Windows バージョンの関係



.NET Framework には新旧多くのバージョンがあります。開発と同じPCで使う場合は .NET Framework のバージョンを気にする必要がありませんが、別のPCで使う場合はWindowsのバージョンによってはアプリが正常動作しない可能性が考えられます。

そこで、Windows と .NET Framework のバージョンの関係を調べてみました。

 .NET Frameworkのバージョンを整理する (1/2)
 .NET Frameworkの一部バージョンのサポート終了が差し迫る! その対策は? (1/2)

Windows 7 のサポートは 2020年1月15日に終了し、プレインストールされている .NET Framewok 3.5.1 の同日までサポートされるようです。Windows 8.1 / 10 のサポートと、プレインストールされている .NET Framework 3.5.1 / 4.5.2 / 4.6.x は 2023年1月15日までサポートされるようです。

そこで、Windows 7 以降で使えるようにするには、.NET Framework 3.5.1 を対象にしてアプリを作れば2020年1月15日までは問題ないことが分かります。Windows 8.1 以降を対象にするなら、.NET Framework 4.6.2 (本日時点での最新版) を対象のフレームワークにしておけば 2023年1月15日まで問題ないことになります。

さすがに Windows XP をネットに繋いで使っているケースを考慮する必要は無いと割り切れますが、Window 7 は未だに人気が高いので、MyClock は .NET Framework 3.5.1 を前提にしようと思います。




対象の .NET Framework バージョンを変更

プロジェクトの「対象のフレームワーク」に設定する .NET Framework バージョンの確認や変更は、プロジェクトのプロパティで行えます。

ソリューションエクスプローラーで、プロジェクト MyClock を選び、

プロジェクトのプロパティの出し方 

右クリックでメニューが現れ、

プロジェクトのプロパティの出し方2 

[プロパティ(R)] を選ぶと、

 プロジェクトのプロパティ縮小  

プロジェクト MyClock のプロパティが現れます。対象のフレームワークが、デフォルトで .NET Framework 4.6.1 になっていることが確認できます。

これを .NET Framework 3.5 に変更 (3.5 Client Profile ではなくて 3.5) し、プロパティを保存します。変更を有効にするにはソリューションを一旦閉じてから再び開く必要があります。

そこで、全てのファイルを保存後、[ファイル(F)] - [ソリューションを閉じる(T)] を選ぶか、右上の[X] でソリューションを一旦閉じます。そして再びソリューションを開くと、「対象のフレームワーク」の変更が反映されます。

では、[F5] を押してビルド後デバッグモードで実行します。

するとエラーと警告が発生しました。

フレームワーク3.5でのエラー  

 マークがエラーで、これがあるとビルドできません。そこでこのエラー表示の上でダブルクリックしてみると、エラー箇所が表示され、カーソルが Display.cs と Program.cs の冒頭にある


using System.Threading.Tasks;

の Tasks の前にあり、Tasks の下に赤い波線がついています。

この機能が .NET Framework 3.5 ではサポートされていないので、上記2つのファイルでこの行をコメントアウトします。

//using System.Threading.Tasks;


コメントアウトすると、その場でエラー表示が消えます。[F5] を押してビルド&実行してみると、ビルドに成功して MyClock が正常動作しました。

なお、4つの警告がありますが、Microsoft.CSharp と System.Net.Http が見つからないことによります。.NET Framework 4.6.1 には用意されているので組み込まれたが、3.5.1 に変更したら見つからなくなったのが原因のようです。

以下のように、これら2つに警告マークがついています。

参照エラー 

今は、これらの機能を使わなくても MyClock は正常動作しているので、この警告を無視することにします。

対象フレームワークを変更したのに参照の対象を自動的に更新できていない、つまり 開発環境がそこまで万能では無いのだと思います。これらを削除することもできますが、将来の機能追加で対象フレームワークをより新しいものに変更した時に、削除したものを自動で追加してくれないかも知れず(動作が怪しい)そのときに苦労したくないので、そのままにしておきます。


これで、MyClock は、対象フレームワーク .NET Framework 3.5 (つまりWindows 7 以降) で動作するようになりました。






アセンブリ情報を変更

プロジェクトのプロパティを開き、

プロジェクトのプロパティ縮小 

 [アセンブリ情報(I)...]をクリックすると、デフォルトのアセンブリ情報が出てきます。

アセンブリ情報変更前 

ここで、タイトル、製品、著作権を変更してみます。

アセンブリ情報変更後 

[OK] で保存。

ここでの設定は、実行ファイル MyClock.exe を右クリックして表示されるプロパティで [詳細] ボタンを押して現れる情報に反映されます。

プロパティ情報が変更されたので、[F5] でビルドしデバッグモードで実行して動作確認します。

デバッグモードで作成された MyClock.exe は、作業フォルダの下にある bin\Debug フォルダにあります。このファイルを右クリックしてプロパティを表示すると、ここにアセンブリ情報が反映されていることが分かります。

プロパティ1 

プロパティ2 





アイコンを設定


今は既定のアイコンになっています。そこでアイコンを変更してみます。

以下のサイトから無償で使えるアイコンを選んで使うことにします。

FIND ICONS

こんなアイコンにしてみました。

アイコン 

このアイコンデータは、作業フォルダのどこかにコピーしておきます。今回は、作業フォルダに res フォルダ (リソースフォルダ) を作り、そこにアイコンファイルを入れることにします。

resを追加した作業ファイル  


さて、これをアプリに登録するには、プロジェクトのプロパティを開き、

アイコン登録1縮小 

アイコンとマニュフェスト(C) にチェックが入っていますが、この下にある(既定のアイコン) の右にある参照ボタンをクリックして、res フォルダ内にコピーした xclock.ico を選択します。

アイコン登録2縮小 


このように、アイコンが登録できました。

こうしておいてビルドすれば、アプリのアイコンが変わります。作業フォルダの下にある bin\Debug\ フォルダを開くと、MyClock.exe のアイコンが時計のアイコンになっています。

デバッグモードの実行ファイル 

表示を「中アイコン」に変えてみると、

新アイコンの実行ファイル2 

こんな感じで、それらしいアイコンになったことが分かります。

ところで、作業フォルダの下にある *cs ファイルがあるところに、アイコンファイルがあります。自動的にここにコピーされるようです。

新アイコンのもう一つの場所 


なお、フォーム Display のプロパティにある Icon がまだ既定のアイコンのままになっていますので、これも変更しておきます。今は FormBorderStyle が FixedToolWindow になっているので、フォームにアイコンは表示されませんが、これを仮に Sizable に変更してみると新しいアイコンになります。FixedToolWindow に戻しておきます。

Debug モードで「リビルド」しておきます。そして [F5] キーで実行して、問題ないことを確認します。



Releaseモードでビルド

さて、ビルドには Release モードもありますので、これを使ってみます。

リリースモードに変更 

このように「ソリューション構成」を Rlease に変更し、ビルドするとリリースモードで実行ファイルができます。

リリースモードの MyClock.exe は、作業ファイルの下の bin\Release\ の中にあります。
リリースモードの実行ファイル 
リリースモードで [F5] キーを押すとエラーになって実行できません。リリースモードでビルドするとデバッグ情報が無いのでエラーになります。従って、このフォルダにある実行ファイルを直接実行して動作確認をします。

リリースモードでビルドは、デフォルトで最適化が行われる設定になっています。しかし、デバッグモード、リリースモードいずれの実行ファイルもファイルサイズは 142KBと同じ、この程度の簡単なアプリでは実行速度の違いも分かりません。

一応 リリースモードの実行ファイルを完成形とします。これで、C#で初めて作るアプリ MyClock Ver 0.10 ができました。



ダウンロード

 MyClock Ver 0.10 (ソース付き)








応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ



    

keywords: プログラム関数電卓、Windowsプログラミング

リンク集 | ブログ内マップ

テーマ : プログラム関数電卓
ジャンル : コンピュータ

C# で MyClock Ver 0.10 を作る (1/2)

プログラム電卓のためのC#プログラミング
e-Gadget

<MyClock トップへ戻る>


2017/01/31

初めて作る C# プログラム - MyClock


MyClock Ver 0.10を作る (1/2)

仕 様
  • フォントが大きい
  • 時計は半透明で常に前画面表示


MyClock プロジェクトを作る

初めての C# なので、分かる範囲で手順とポイントを記録しておきます。

1. Visual Studio Community 2015 を起動

起動時に、管理者権限にするかそうでないかの選択肢があります。取り敢えず管理者権限で起動します。


2. 初めてのソリューションとプロジェクトの作成

 新しいプロジェクト作成の方法

新しいプロジェクト作成には複数の方法があります。
  • スタートページにある「新しいプロジェクト ...」のリンクをクリック
  • ツールバーの左から3詰めの"新しいプロジェクト"ボタンをクリック
  • メニューで、[ファイル] - [新規作成] - [プロジェクト] を選ぶ

ひな形プロジェクトを選ぶ

[テンプレート] - [Visual C#] - [Windows]  から「Windowsフォームアプリケーション」を選択

「名前(N):」と「ソリューション(M):」に MyClock と入力し、「場所(L):」に適切に入力します。
なお、「場所(L):」で設定したフォルダの下に、ソリューションに指定した名前のフォルダが自動的に作られ、その下に必要なファイルが自動生成されます。

バージョン管理を分かり易くするために、新規プロジェクトを作る前に MyClockフォルダを作っておき、さらにその下に例えば MyClock0100 とバージョンが分かるフォルダも作っておき、このフォルダを「場所(L):」に指定しています。

 <MyClock>
  <MyClock0100> ← [場所(L):」に入力したフォルダ

[OK] をクリックすると、ひな形のプロジェクトが作成されます。自動作成だけで合計 92KB のファイルが数多く生成されます。

 <MyClock>
  <MyClock0100> ← [場所(L):」に入力したフォルダ
   <MyClock>
    MyClock.sln
    <vs.>
    <MyClock>
     App.config
     MyClock.csproj
     Form1.cs
     Form1Designer.cs
     Program.cs
     <bin>
      <Debug>
       MyClock.exe.config
       MyClock.vshost.exe
       MyClock.vshost.exe.config
       MyClock.vshost.exe.manifest
      <obj>
       <Debug>
        MyClock.csproj.FileListAbsolute.txt
        DesignTimeResolveAssemblyReference.cache
        TemporaryGeneratedFile_xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx.cs
        TemporaryGeneratedFile_yyyyyyyy_yyyy_yyyy_yyyy_yyyyyyyyyyyy.cs
        TemporaryGeneratedFile_zzzzzzzz_zzzz_zzzz_zzzz_zzzzzzzzzzzz.cs
        <TempPE>
      <Properties>
       AssemblyIngo.cs
       Resource.Designer.cs
       Resource.resx
       Setttings.Designer.cs
       Settings.settings

そして、フォームデザイナーが開いて、デフォルトの (素の) フォームが現れます。

初めてのフォームデザイナー 


 初めてビルドしてみる

メニューバーの下に「Debug」「Any CPU」とあります。この状態で、メニューで、[ビルド(B)] - [ソリューションのビルド] を選び、ビルドを実行します。すると、出力ウィンドウで

1>------ ビルド開始: プロジェクト:MyClock, 構成:Debug Any CPU ------

と表示され、その後すぐに

1>------ ビルド開始: プロジェクト:MyCloxk, 構成:Debug Any CPU ------
1> MyClock -> C:\MyData\MySource\VS2015\Projects\C#\MyClock\MyClock0100\MyClock\MyClock\bin\Debug\MyClock.exe

と1行追加表示されます。デバッグモードでビルドした実行ファイル名とパスが表示されます。

ここで、
1> MyClock -> C:\MyData\MySource\VS2015\Projects\C#\MyClock\MyClock0100\
は「場所(L):」で設定したパスで、

その下の MyClock フォルダがソリューション MyClock のフォルダ、
さらにその下にある 同じ名前の MyClock フォルダが プロジェクト MyClock のフォルダです。

そして、実行ファイル MyClock.exe は プロジェクトフォルダの下の bin\Debug フォルダに作成されていることが分かります。リリースモードでビルドすると、bin\Release フォルダ内にファイルが出力されます。

ビルドが終わると、出力は以下のようになります。

1>------ ビルド開始: プロジェクト:MyCloxk, 構成:Debug Any CPU ------
1> MyClock -> C:\MyData\MySource\VS2015\Projects\C#\MyClock\MyClock0100\MyClock\MyClock\bin\Debug\MyCloxk.exe
========== ビルド: 1 正常終了、0 失敗、0 更新不要、0 スキップ ==========


1 正常終了 となっているのでビルドエラーが無かったことが分かります。


デバッグモードで実行してみる

方法は複数あります。
  • [F5]キーを押す
  • ツールバーの[ 開始]ボタンを押す
  • メニューで、[デバッグ] - [デバッグの開始] を選ぶ
ソースファイルが変更された状態でデバッグを始めると、先にビルドが行われてからデバッグが始まります。従って [F5] を覚えておけば、キーを押すだけでビルドとデバッグ開始になるので便利です。

素のMyClock 
素のウィンドウが既にできています。最小化ボタン、最大化ボタン、中止ボタン、システムメニューを出すアイコン、プログラムのタイトル Form1 が備わっていて、いっちょ前にウィンドウの陰までできています。これは Windows 10 で実行した時の画像です。Windows 7 や 8 ではその環境でのデフォルトのウィンドウになる筈です。

1行もコードを書かずに、取り敢えずここまでは自動的に作ってくれますが、昔の VC++ 6 でも変わりなく驚くことでもありません。実はVisual Studio 2015 での開発の段取りは、基本は以前の Visual Studio 6 と同じような感じですので、経験があれば必要なものは探して使えると思います。

ここで、MyClock ソリューションと、その中に含まれる MyClock プロジェクトが作成されたことになります。このソリューションの中に 新しいプロジェクトを作って含めることができます。


 namespace、class そして Form

私には Namespace (名前空間) は新しい概念で、クラスやメンバー は MFC (Microsoft Foundation Class) で馴染みがあり、Form は Visal Basic で出てきました。

C# は、これらが混じった感じですね。C++ で記述できる Visual Basic とでも言えそうな感じです。

画面右にあるソリューションエクスプローラで、Form1.cs を
右クリックして [コードの表示] を選んで、自動作成されたコードを眺めてみます。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MyClock // これがプロジェクトMyClock
{
  public partial class Form1 : Form // ここで Form1 ウィンドウに必要な処理を書く
  {
    public Form1() // Form1 の最初の処理として初期化している
    {
      InitializeComponent();
    }
  }
}

ここで、using は、VC++ の include のような感じで、予め準備されているライブラリからデフォルトで必要なものが列挙されていて、今後必要に応じて追加することになります。

public Form()
{

}

は、この先頭の位置に記述しておかないと、開発環境がエラーを出します(実際悩みました)。Form1 のインスタンス生成で最初の1回だけ行われる処理のようです。

さらに分かることとしては、

using System.Windows.Forms;

で、関連づけられた Forms に 基底クラスの Form の定義があって、それをサブクラス化して Form1 クラスが作られています。

仮に、以下のように class Form1 の中で、public な静的文字列変数 m_variable を宣言しておきます。

namespace MyClock
{
 public partial class Form1 : Form
 {
  public Form1() 
  {
   InitializeComponent();
  }

  public static string m_variable; // 静的文字列変数
 }
}

この変数へ、class Form1 の外の例えば class Form2 からアクセスするには、

Form2 の中では、

(namespace).(class).m_variable

つまり

Form1.Form1.m_variable

と記述する必要があります。スコープを考えると名前空間がクラスの上位にあるわけです。

そして、Form2 の中で、一例として

public string m_var = Form1.Form1.m_variable;

と橋渡しをしておけば、タイプ数の少ない m_var を使えて便利です。

なお、Visual Studio では正しく記述すれば、クラス名を Form1 と色分けして表示してくれるので、目安になって便利です。


Form名 = クラス名

今、名前空間とプロジェクト名が、MyClock になっています。フォーム名とクラス名は自動生成された Form1 のままです。

これを適切な名前に変更します。時間を表示させるので、Display としましょう。フォーム名とクラス名を変更するために、全て手で変更するのは大変なので、自動変更の機能を使います。但しプログラムが込み入ってくると自動生成も完璧ではないと心配される (どこまで信用して良いか分からない)ので、自動生成された直後に名称変更を自動で行わせることにします。

ちょっと脱線しますが、ここで自動作成された主なファイルは、以下です。
  • Form1.cs
  • Form1.Designer.cs
  • Program.cs
主にコーディングするのが Form1.cs です。

Form1.Designer.cs は開発環境の機能を使って自動でコードに落としてくれるものです。部品をフォームへドラッグ&ドロップで追加したり、フォームや部品のプロパティを変更したり、イベントハンドラのテンプレート作成などがコーディングせずに行えます。そして、その結果がこのファイルと Form1.cs の両方に反映されます。

Form1.Designer.cs は宣言や定義が書き込まれ、Form1.cs にはテンプレートが書き込まれます。このテンプレートの中に具体的にコーディングしてアプリを作ってゆきます。

一旦作成したイベントハンドラが不要になった場合は、Form1.cs と Form1.Designer.cs の両方で関連する部分だけを慎重に削除しないと、Visual Studio が混乱して面倒なことになります。

Program.cs には WinMain() 関数が書かれていてます。これはアプリが起動した時に最初に実行されるもので、終了時にもここへ戻ってきて必要な処理を行います。アプリが起動してからフォームのインスタンスを生成する前に必要な処理はここにコーディングします。

話を元に戻して、フォーム名とクラス名を実際に Display に変更します。

ソリューションエクスプローラで、Form1.cs で右クリックして[名前の変更] を選ぶと、Form1.cs が反転するので、そこで Display.cs となるように変更します。すると以下のメッセージボックスが現れます。

リファレンス 

ここで [はい]をクリックすると、自動で名称変更してくれます。他の関連ファイル名も変更され、主要ファイル名は以下のようになりました。
  • Display.cs
  • Display.Designer.cs
  • Program.cs
これら3つのファイル内に記述されている内容では、フォーム名とクラス名が Form1 から Display に変更されています。自動処理に任せるとフォーム名とクラス名が同じになります。どうしてもこれらを違う名前にする必要性が無い限り、この作法に従うことにします。

上記以外のファイル名も変更されているのは、ソリューションエクスプローラで確認できます。
Ver1.00ソリューションエクスプローラ 

Display.cs [デザイン] で表示されるフォームのタイトルバーは、まだ Form1 となっています。これはフォーム名やクラス名とも無関係で、単にフォームのテキスト (Display.Text) の設定が Form1 のままになっているためです。これは、フォームのプロパティで変更できます。プログラム中で変更するには Text プロパティを使って、

Display.Text = "変更する文字列";

とします。タイトルバーに表示するテキストをアプリの状況に応じて動的に変更したい時に使えます。

今回は、フォームのテキストを Form1 から MyClock に変更してみます。Display.cs[デザイン]を表示して、フォームをクリックすると、Displayフォームのプロパティ一覧が(右下に)表示されるので、そこで Text というキーを探して、Form1 から MyClock に変更します。この変更は Display.Designer.cs に自動的に反映されます。

全てのファイルが変更されたので、[F5] を押して、ビルドとデバッグモードでの実行を行います。
なお、ビルドする際に変更されたファイルは上書き保存されます。

Displayフォーム 
これで下準備終了です。


3. デジタル時計の部品を追加

時刻を表示するために、ラベルとタイマーの2つの部品を導入します。ラベルは 12:34:56 といった文字列を表示するための部品、タイマーは現在の時刻を取得するための部品です。

そして、タイマーで1秒ことに時刻と取得し、その結果をラベルに表示するように仕上げてゆきます。

ところで、Windows アプリは、四角い領域を視覚的に表示したウィンドウから構成されるのが基本です。タイトルバー付きのウィンドウ (C# や VB ではフォームという) であれ、ボタンであれ、文字列入力用のエディットボックス (C# や VB ではテキストボックスと言う) だろうと、全てウィンドウであって、味付けが違うだけです。

フォームに貼り付ける部品には、他にもメニューバーやツールバーなどがあります。タイマーも視覚効果は無いけれど部品の1つです。


部品の登録

Visual Studio (の左) にツールボックスがあり、そこには様々な部品が準備されています。これをウィンドウにドラッグ&ドロップすることで、これらのサブクラス化、インスタンス生成、宣言や定義などの初期的なコードが自動的に追記されます。

今回は、時間表示用に ラベル(コモンコントロール)とタイマー (コンポーネント) を使うことにします。

左にあるツールボックスをクリックて一旦ピン止めし、ラベルとタイマーをドラッグ&ドロップするとこんな感じになります。

部品登録 

フォーム内に label1 があり、フォーム外の下に timer1 があります。

この段階で、Display.cs と Program.cs は変更されず、
DisplayDesigner.cs では多くのコードが自動生成されているのが分かります。

namespace MyClock
{
 partial class Display
 {
  /// <summary>  /// 必要なデザイナー変数です。
  /// </summary>

  private System.ComponentModel.IContainer components = null;

  /// <summary>  /// 使用中のリソースをすべてクリーンアップします。
  /// </summary>
  /// <param name="disposing">マネージ リソースを破棄する場合は true を指定し、その他の場合は false を指定します。
  protected override void Dispose(bool disposing)
  {
   if (disposing && (components != null))
   {
    components.Dispose();
   }
   base.Dispose(disposing);
  }

  #region Windows フォーム デザイナーで生成されたコード

  /// <summary>  /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
  /// コード エディターで変更しないでください。
  /// </summary>

  private void InitializeComponent()
  {
   this.components = new System.ComponentModel.Container();
   this.label1 = new System.Windows.Forms.Label();
   this.timer1 = new System.Windows.Forms.Timer(this.components);
   this.SuspendLayout();
   //
   // label1
   //
   this.label1.AutoSize = true;
   this.label1.Location = new System.Drawing.Point(101, 64);
   this.label1.Name = "label1";
   this.label1.Size = new System.Drawing.Size(35, 12);
   this.label1.TabIndex = 0;
   this.label1.Text = "label1";
   //
   // Display
   //
   this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
   this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
   this.ClientSize = new System.Drawing.Size(284, 261);
   this.Controls.Add(this.label1);
   this.Name = "Display";
   this.Text = "MyClock";
   this.ResumeLayout(false);
   this.PerformLayout();

  }

  #endregion

  private System.Windows.Forms.Label label1;
  private System.Windows.Forms.Timer timer1;
 }
}

ここでは、上の方でアプリケーション終了時に各部品を解放する処理、それ以下で追加した部品の定義とデフォルトのプロパティの設定が記述されています。


ラベルとフォームのプロパティ設定

ラベルとフォームのプロパティを設定して、以下のような外観にします。

Ver1.00外観作成 

先ずはラベルの設定:
ラベルをクリックすると(右下に)ラベルのプロパティが表示されるので、そこで以下のように変更しますます。
  1. デザイン - (Name) を currentTime
  2. 配置 - Dock を Fill
  3. 表示 - Font を MS UI Gothic のまま 36pt、太文字
  4. 表示 - Text を 12:34:56
  5. 配置 - Size は 192, 48 (マウスで大きさを調整するとこのくらいになる)
Text を 12:34:56 とすることで実際に時刻が表示された時のラベルのサイズを調整できます。
Doc を Fill にすることで、ラベルがフォームにうまく張り付きます。


次は、フォームの設定:
フォームのタイトルバーをクリックすると(右下に)フォームのプロパティを表示されるので、そこで以下のように変更します。
  1. ウィンドウ スタイル - Opacity を 50%
  2. ウィンドウ スタイル - TopMost を True
  3. デザイン - (Name) は Display になっている筈
  4. 表示 - FormBoderStyle を FixedToolWindow
  5. 表示 - Text は MyClock になっている筈
  6. 配置 - Size は 207, 85 (マウスで大きさを調整するとこのくらいになる)
Opacity 50% で半透明になり、TopMost True で最前面に表示されます。

では、[F5] を押して、ビルドとデバッグモードでアプリを実行をすると、

Ver1.00外観 

こんな感じで、アプリが起動します。半透明で最前面表示になっていることを確認します。

右上の[X]ボタンをクリックすれば終了。なおデバッグモードで実行している時は、
  • [デバッグの停止]ボタンを押すか、
  • メニューで [デバッグ(D)] - [デバッグの停止] を選ぶ
ことで、アプリを強制的に終了できます。

これで外観ができたので、時刻を表示する機能を作ります。


タイマーの設定

タイマーは 1 Tick が 1 ms (ミリ秒) です。1秒ごとに数字が変わるデジタル時計を作るのでタイマーの間隔 (Interval) は 1000 ms になります。そこで、タイマーの名前を secTimer に変更します。すると、タイマークラスの名前が自動的に secTimerに変更されます。

実際の作業は、ドラッグ&ドロップした timer1 をクリックして、(右下にある) timer1 のプロパティを変更することです。
  1. デザイン - (Name) を secTimer
  2. 動作 - Enabled を True  (これを忘れるとタイマーは動作しない)
  3. 動作 - Interval を 1000
フォーム、ラベルそしてタイマーのプロパティの設定を変更した結果は、全て DisplayDesigner.cs に反映されています。チョット眺めてみると、それぞれのクラスとメソッド(関数)の使い方のヒントが得られて大いに参考になると思います。但し、くれぐれも不用意な編集・変更には注意しましょう。


 現在の時刻を表示させる方法

ここまで一切コーディングせずに進めてきましたが、これ以降は実際にコードを書く必要があります。

Windowsプログラミングでは、発生したイベントを捕らえて、そこで必要な処理を記述するのが基本です。これは、ある単独の処理がCPUを占有しないための方策です。そうしないとマルチタスク処理が破綻してしまいます。

イベントを捕らえて必要な処理を行う部分をイベントハンドラと呼びます。

今回は、タイマーイベントが 1000 ms (=1秒) ごとに発生するのを利用します。タイマーイベントハンドラを作り、その中で現在の時刻をラベルに渡すようにコーディングするだけです。


タイマーイベントハンドラの作成

既に、secTimer という名前 (クラス名) でタイマーを作りました。

secTimerコントロール  

secTimer コントロールを、マウスの左ボタンでダブルクリックします。すると、自動的にイベントハンドラのテンプレートを作成し、それを表示してくれます。

タイマーイベントハンドラのテンプレート 



現在の時刻をラベルに渡す

コモンコントロールという視覚的に機能する部品は、データを受け取って表示する機能があります。

例えば、文字列を受け取れるコントロールに文字列を渡すには、以下のようにコーデイングします。

(コントロールのクラス名).Text = "文字列";

今回は currentTime と名前をつけたラベルコントロールに時刻の文字列を表示させるので、

currentTime.Text = (現在時刻の文字列);

とすれば良いわけです。currentTime クラスはラベルの基本クラスから全ての機能を引き継いでいて、Text プロパティも引き継いでいます。上の作業で自動的に作成された MyClockDesinger.cs には、この引き継ぎに必要なコードとプロパティ設定のコードが含まれています。

具体的には、

//
// currentTime
//

の下に currentTime に必要な処理が書かれています。


さて (現在時刻の文字列)を取得するには、DateTime クラスを利用します。DateTime クラスには Now というプロパティがあって、現在時刻を取得してくれます。さらに Now に対して ToSring() 関数も使えるようになっていて、これは時刻を書式に従って文字列に変換してくれます。つまり、

DateTime.Now.ToString("HH:mm:ss");

と書けば、現在時刻の文字列を返します。

従って、

currentTime.Text = DateTime.Now.ToString("HH:mm:ss");

の1行で、ラベルに現在時刻が渡されます。

Private void secTimer_Tick(object sender, EventArgs e)
{
  currentTimer.Text = DateTime.Now.ToString("HH:mm:ss");
}

それでは、[F5] を押して、ビルド後にデバッグモードで実行してみます。一応時計として動作しますが、起動直後の一瞬だけ以下の表示になります。

Ver1.00外観 

起動直後は、タイマーイベントハンドラが働かないのが原因です。


フォームの描画

タイマーイベントが発生する時(1秒ごと)に現在時刻の表示を行うようにコーディングしました。それ以外のタイミングでは時刻を表示しません。そしてフォームが表示されると同時にタイマーイベントが発生する保証はありません。

そこで、MyClock を起動し、そのフォームが描画されるタイミングで時刻表示をさせれば、問題が解決しそうです。フォームの描画はメッセージ を受け取ることで動作するのが Windows プログラムの基本なので、フォームを描画するイベントを捕らえて、現在時刻をラベル currentTime に渡せば良さそうです。

C# で最初に自動で作成されるソースコードには、フォーム描画のイベントハンドラが自動作成されていないので、自分で作る必要があります。タイマーイベントハンドラを作ったのと同様に、マウス操作だけでフォーム描画するイベントハンドラのテンプレートが作れます。

MyClockのフォーム (Display) のデザイナー画面を開きます。
  • ソリューションエクスプローラで Display.cs をダブルクリックするか、
  • ソリューションエクスプローラで Display.cs を右クリック - [ビューデザイナー(D)] を選ぶ
MyClock.cs 

ビューデザイナーを開く
 


Display.cs [デザイン] (フォームデザイナー) が開いたら、タイトルバーあたりをダブルクリックします。


Displayビューデザイナ 

すると、イベントハンドラのテンプレートが自動作成され、そのコードが表示されます。

フォームイベントハンドラ 

今自動作成されたイベントハンドラの中に

currentTime.Text = DateTime.Now.ToString("HH:mm:ss");

をコーディングすれば、フォーム描画時に現在の時刻が表示されます。

private void Display_Load(object sender, EventArgs e)
{
 currentTime.Text = DateTime.Now.ToString("HH:mm:ss");
}

では、[F5] を押して、ビルドと実行をします。

MyClock2

フォームが表示された直後から正しく時刻を表示されていることが確認できます。


コードの重複を避ける

取り敢えず機能面では完成ですが、少し気になることがあります。Display.cs のコードを眺めてください。

フォーム描画イベントハンドラ完成


ラベル currentTime に現在時刻を渡すコード

currentTime.Text = DateTime.Now.ToString("HH:mm:ss");

が、そのまま2カ所に記述されています。機能追加やプログラムの複雑化に備えて、関数に置き換えることにします。時刻を表示する関数なので、DisplayTime() とします。

DislayTime() の中に、この1行のコードを入れます。

Display_cs完成

念のため [F5] を押して動作確認します。


 MyClock Ver 0.10 を作る (2/2)







応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ



    

keywords: プログラム関数電卓、Windowsプログラミング

リンク集 | ブログ内マップ

テーマ : プログラム関数電卓
ジャンル : コンピュータ

最新記事
最新コメント
カテゴリ
C# (3)
検索フォーム
Visitors
Online Counter
現在の閲覧者数:
プロフィール

やす (Krtyski)

Author:やす (Krtyski)
since Oct 30, 2013


プログラム関数電卓は、プログラムを作り・使ってナンボ!

実際に触って気づいたこと、自作プログラム、電卓プログラミングについて書いています

おもしろい・役に立つならクリックしてください。励みになります。
にほんブログ村 IT技術ブログ 開発言語へ
にほんブログ村


人気ブログランキングへ


FC2ブログランキングへ


写真: 「4駆で泥んこ遊び@オックスフォード郊外」

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

RSSリンクの表示
最新トラックバック
ブロとも申請フォーム

この人とブロともになる

QRコード
QR