🦒 C# 学習3日目 シンプルなWindowsプログラム作ってみた
作成日: 2023/01/09
0

シンプルなWindowsデスクトップアプリを作ってみました。
「やさしいC#」に載っていたサンプルを元に新たに機能を付け加えてみました。
学習3日目でここまでできるなんて、この本選んで良かったです。

C# 学習3日目 シンプルなWindowsプログラム作ってみた

実は、体調の悪いときにこの本をコーディングせずに読み進めました。
学習2日目の背景にバス(書籍では自動車)の画像と文字を載せるだけの
プログラムを作ったのですが、何となくこのプログラムの演習を進み続けたら、
バスの画像を動かせるのではないかと思って読み進めたのですが、
「タイマーを使えばアニメーションできます」という事みたいです。

タイマーを使う一例として、現在時刻を表示するプログラムがありました。
これだけでデスクトップアプリ成立するんじゃないかと思って、
バスの画像を動かすのをよそに、
さらに、オリジナルを付け加えた形で、
今日のタイムリミット時計」を作ってみました。

現在時刻とともに、今日の残り時間を表示するだけのプログラムです。

using System;
using System.Windows.Forms;
using System.Drawing;

class TodayClock: Form
{
    private Label lb_time;//現在時刻
    private Label lb_time_label;//「現在時刻」文字表示
    private Label lb_limit_time;//残り時間
    private Label lb_limit_label;//「残り時間」文字表示

    public static void Main()
    {
        Application.Run(new TodayClock()); 
    }

    public TodayClock()
    {
		//ウィンドウ
        this.Text = "今日のタイムリミット時計";
        this.Width= 400;
        this.Height= 100;
        this.BackgroundImage = Image.FromFile("c:\\images\\bg_blue.png");

		//タイマー
        Timer tm = new Timer();
        tm.Interval= 1000;
        tm.Start();
		
		//「現在時刻」というラベル文字のラベル
        lb_time_label = new Label();
        lb_time_label.Left = 0;
        lb_time_label.Font = new Font("Helvatica", 16, FontStyle.Regular);
        lb_time_label.BackColor = Color.Transparent;
        lb_time_label.ForeColor = Color.Orange;
        lb_time_label.Text = "現在時刻:";
        lb_time_label.AutoSize = true;

		//「残り時間」というラベル文字のラベル
        lb_limit_label = new Label();
        lb_limit_label.Top = 30;
        lb_limit_label.Left = 0;
        lb_limit_label.Font = new Font("Helvatica", 16, FontStyle.Regular);
        lb_limit_label.BackColor = Color.Transparent;
        lb_limit_label.ForeColor = Color.Orange;
        lb_limit_label.Text = "残り時間:";
        lb_limit_label.AutoSize = true;

		//現在時刻の表示
        lb_time = new Label();
        lb_time.Left = 110;
        lb_time.Font = new Font("Helvatica", 16, FontStyle.Bold);
        lb_time.BackColor = Color.Transparent;
        lb_time.ForeColor = Color.Orange;
        lb_time.AutoSize= true;

		//残り時間の表示
        lb_limit_time = new Label();
        lb_limit_time.Top = 30;
        lb_limit_time.Left = 110;
        lb_limit_time.Font = new Font("Helvatica", 16, FontStyle.Bold);
        lb_limit_time.BackColor = Color.Transparent;
        lb_limit_time.ForeColor = Color.Orange;

		//各ラベルをどの親オブジェクトの上に載せるかを設定
        lb_time.Parent= this;
        lb_time_label.Parent = this;
        lb_limit_time.Parent = this;
        lb_limit_label.Parent = this;
		
		//イベントハンドラを登録
        tm.Tick += new EventHandler(tm_tick);
    }

    public void tm_tick(object sender, EventArgs e)
    {
		//現在時刻を代入
        DateTime dt = DateTime.Now;
        lb_time.Text = dt.ToLongTimeString();

		//追加部分 今日の残り時間  (たったこれだけですが苦労しました)
		//残り時間
        DateTime dt1 = new DateTime(2023, 1, 1, dt.Hour, dt.Minute, dt.Second);
        DateTime dt2 = new DateTime(2023, 1, 2, 0, 0, 0);
        TimeSpan dt_diff = dt2.Subtract(dt1);
		//残り時間を代入
        lb_limit_time.Text = dt_diff.ToString();
    }
}

タイマーは、タイマーオブジェクトを作成し、
Intervalプロパティに間隔をミリ秒で指定し、
Start()でタイマーを開始します。

実は、早く何か作りたくて、イベントハンドラの項目の学習をすっ飛ばしました。
ですので、イベントハンドラの部分は今回ここでは記事にしません。
(追記:C#のイベント処理の理解にはデリゲートがわかっていたほうが良さそう)
改めて、学習した際に書きたいと思います。//

「残り時間」は本日24時(翌日0時)まで、何時間あるか?というのを出しています。
その算出する記述の仕方をネットで調べたのですが、なかなかわからず、苦労しました。
残り時間を算出するにはTimeSpan型というのを使うのですが、TimeSpanの計算例をやっても
上手く動きませんでした。

あるサイトのQ&A記事で、
「DateTime型の計算結果がTimeSpan型になるのですか?」
「そうです」
という趣旨のやり取りが載っていて、「そんなことがあるのか」と試してみたら、
実はそれが正解でした。

実行結果

todayClock_sample1.jpg

今回、学習を飛び越えすぎたので、次回は元に戻りたいと思います。

(追記) 現在の日付を元に日付計算する形に修正

元のプログラムは、作り物の1月1日に時刻を設定して、1月2日00:00:00との差から
今日の残り時間出していましたが、
できれば、今の日付時刻と、明日の00:00:00の差から、出したいと思い
後日、この検証記事を書きました。
時間計算 ~DateTime型とTimeSpan型の理解~
この記事に従って、tm_tick()の中身を修正してみました。
以下、修正したtm_tick()の部分の抜粋です。

修正後のソースコード (2023-01-13)

    public void tm_tick(object sender, EventArgs e)
    {
        // 修正版
        DateTime dt = DateTime.Now;
        lb_time.Text = dt.ToLongTimeString();
        DateTime todayDate = new DateTime(dt.Year, dt.Month, dt.Day);
        DateTime tomorrowDate = todayDate.AddDays(1);//明日の零時
        TimeSpan dt_span = tomorrowDate.Subtract(dt);//明日の零時 - 今の時刻
        lb_limit_time.Text = dt_span.ToString();//今日の残り時間反映
    }

修正後の結果

見た目動作は同じですが、中身が修正済みです。
todaylimittime_modi.jpg


これからゲームアプリとWindowsアプリを作りたい初心者です。 ゲームアプリとWindowsアプリ、共に経験ゼロです。 これからの体験が少しでも参考になれば幸いです。 目指す事 ・C言語学習→C#学習 ・Unity (C#) の勉強 ・Unityゲーム作成 ・Windowsアプリ(C#) 作成