サンプル時計
創ってみた。
むかーしにVC++で創ったものの焼き直し。
とはいえ、プログラミングは勿論勉強を兼ねて一から。
(VC++版のソースを紛失してるから、とも。。。
さて、csOriginalClock というプロジェクト名でプロジェクトを新規作成するところから。
まずは Form のプロパティを色々いじったんだけど、細かい部分はコードをご覧あれ。
namespace csOriginalClock { partial class baseForm { /// <summary> /// 必要なデザイナ変数です。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 使用中のリソースをすべてクリーンアップします。 /// </summary> /// <param name="disposing">マネージ リソースが破棄される場合 true、破棄されない場合は false です。</param> 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(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(baseForm)); this.nowLabel = new System.Windows.Forms.Label(); this.timer = new System.Windows.Forms.Timer(this.components); this.SuspendLayout(); // // nowLabel // this.nowLabel.AutoSize = true; this.nowLabel.BackColor = System.Drawing.Color.Transparent; this.nowLabel.Font = new System.Drawing.Font("Nina", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.nowLabel.ForeColor = System.Drawing.Color.Cyan; this.nowLabel.Location = new System.Drawing.Point(5, 8); this.nowLabel.Name = "nowLabel"; this.nowLabel.Size = new System.Drawing.Size(114, 16); this.nowLabel.TabIndex = 0; this.nowLabel.Text = "1999/12/31 23:59:59"; this.nowLabel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OnMouseDown); this.nowLabel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OnMouseMove); this.nowLabel.MouseClick += new System.Windows.Forms.MouseEventHandler(this.OnMouseClick); this.nowLabel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OnMouseUp); // // timer // this.timer.Enabled = true; this.timer.Interval = 4; this.timer.Tick += new System.EventHandler(this.OnTick); // // baseForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.DimGray; this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage"))); this.ClientSize = new System.Drawing.Size(124, 33); this.Controls.Add(this.nowLabel); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "baseForm"; this.Opacity = 0.8; this.ShowIcon = false; this.ShowInTaskbar = false; this.Text = "Form1"; this.TopMost = true; this.TransparencyKey = System.Drawing.Color.White; this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.OnMouseClick); this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OnMouseUp); this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.OnKeyPress); this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OnMouseMove); this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OnMouseDown); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Label nowLabel; private System.Windows.Forms.Timer timer; } }
いくつかポイントになりそうな部分だけ解説しておく。
見ての通り、コントロールは三つ。
Form / Timer / Label のみの至ってシンプルな構造。
Form。
BackgroundImage は自力で作った手抜きの画像をローカルリソースからインポートした。
TopMost を true にすることで、他のウィンドウよりも前面に。
Lable。
Text に指定しているのは、幅の検証に使った無意味な値。
Font は単なる好み。
マウス系の各イベントハンドラは、Form に合わせておく。
これをしないと、ラベルにフォーカスがある(見えないけど)と、ドラッグでのウィンドウ移動などが出来ない。
さて、次に Form1.cs を提示。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace csOriginalClock { public partial class baseForm : Form { public baseForm() { InitializeComponent(); } private bool mouseIsDown = false; private Point mouseDownPoint; private void OnMouseDown(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { mouseDownPoint = new Point(e.X, e.Y); mouseIsDown = true; } } private void OnMouseUp(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { mouseIsDown = false; } } private void OnMouseMove(object sender, MouseEventArgs e) { if (mouseIsDown && e.Button == System.Windows.Forms.MouseButtons.Left) { this.Left += e.X - mouseDownPoint.X; this.Top += e.Y - mouseDownPoint.Y; } } private void OnTick(object sender, EventArgs e) { this.nowLabel.Text = System.DateTime.Now.ToString(); this.Invalidate(); } private void OnKeyPress(object sender, KeyPressEventArgs e) { e.KeyChar = Char.ToUpper(e.KeyChar); if (e.KeyChar == Convert.ToChar(System.Windows.Forms.Keys.U)) { if (this.Opacity < 1) { this.Opacity += 0.1; } this.Invalidate(); } if (e.KeyChar == Convert.ToChar(System.Windows.Forms.Keys.D)) { if (this.Opacity > 0.3) { this.Opacity -= 0.1; } this.Invalidate(); } } private void OnMouseClick(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) { Application.Exit(); } } } }
難しい処理はほとんどない、と思う。
ウィンドウ移動処理に関しては、以下を参考にした。
宇宙仮面のC#プログラミング - アナログクロック その2(自由な形のウィンドウを作る):
http://uchukamen.com/Programming1/AnalogClock/TransparentClock.htm
MouseDown / MouseUp / MouseMove の各イベントを捕まえてウィンドウの移動処理を実装。
Timer の Tick イベントで日時の更新。
MouseClick で右クリックの場合、終了の処理。
最後におまけ。
KeyPress イベントで'U','D'の各キーを押した時に時計ウィンドウの透明度を10%ずつ上昇、下降。
ん?逆か…?
C#に不慣れなため、もっと苦戦するかと思ったが、意外と早く出来た、かな?
自分で書いたコードなんてたかが知れているが、約一時間程度で完成。
デザイナやウィザードの恩恵に与ってしまった部分も多い。
CreateWindow でごちゃごちゃやっていた時代が懐かしい気もする(笑
内部的には同じようなことをしているはずではあるものの。
ちょうど Jitta さんがそんなことをテーマにBlog記事を書かれていた。
何となく Blog by Jitta - 簡単になるのはいいことなのか?:
http://blogs.wankuma.com/jitta/archive/2007/11/29/110975.aspx
肯定的にも否定的にも受け取る方がいるようだけど。
私個人としては、考えさせられるテーマではあるけど、肯定派でも否定派でもない。
(人類の、とか、文明が、とか多少議題の飛躍は感じるが、違和感はさほど感じない
一応、意味があるアプリをC#で創るのは初めてかもしれないので、大したことはしていないが公開。
シンプルでサンプルな時計:
http://www.grimsagaproject.com/tools/csOriginalClock.zip
※サーバから直で実行されないように圧縮してるので、DLして使ってネ
これまでに取り上げてきた技術や言語仕様を生かせてるわけではないので、もう少し精進して色々なものを創ってみたい。