Windows 時間入力用のコントロール

Windowsのコモンコントロールの1つにDTPコントロールというのがあって、CreateWindowEx関数にDATETIMEPICK_CLASS ("SysDateTimePick32") を指定して作る事が出来る。

1つのコントロールで年月日や時分秒の入力が出来るのでコンパクトで便利。Editの右側にドロップダウンカレンダーを出すボタンか、もしくはスピンコントロールを表示出来るようになっている。

Edit部分は1文字1文字自由に入力出来る通常のEditの入力方式では無くてCaretの点滅表示もされない。フォーカスが合っている時には現在編集している入力項目がハイライトで反転表示される。1つのEdit内に複数の入力項目が存在するようにも捉えられる。

日時入力用のコントロールできちんと正しい日時形式の入力なのかをチェックする作りになっていて、例えば日にち部分に選択を合わせて '9' と入力すると ' 9' と選択中の日付場所に表示されるけれど、月のうちの日数は最大でも31なので10の位が9の日付は存在しない為、他の数字を入力しても1の位が変わるようになっている。

そこそこ拡張性が高い作りになっていて、DTM_SETFORMATメッセージで文字列で入力フォーマットをある程度自由に指定する事が出来る。用意された形式で満足できない場合は、"X" という文字を使ってコールバック方式で動作を制御可能で、その場合は、DTN_WMKEYDOWN, DTN_FORMAT, DTN_FORMATQUERYメッセージが親ウィンドウに送られてくるのでユーザーアプリケーション側で処理する。

このコールバックでの拡張に Windows.FormsのDateTimePickerクラスは対応していない。
http://msdn.microsoft.com/en-us/library/system.windows.forms.datetimepicker.customformat.aspx
http://msdn.microsoft.com/en-us/library/aa921603.aspx

自前で代わりにコントロールを作る事を少し考えて色々調べてみると、
http://www.codeproject.com/KB/edit/csNumericFieldControl.aspx
こういうのがあったけれど、入力方式がまたDTPコントロールとは違う感じだし、Spinも付いていない。


VisualStyleRendererでSpinの描画が出来たけど、クラシック表示にも対応するためにControlPaintだとSpinが描けないっぽい。イベント処理とかも考えると、
http://starwing.net/documents/spincontrol.html
を使うのが良さそう。
Editの枠は、VisualStyleRendererやTextBoxRendererを使って書いても何故かVista以降の少し角丸なのが描画されない。DrawThemeBackground自体がそういう作りなんだろうか?フォーカスが合わないEditをダミーで置いてそれに描画を任せるのが良いんだろうか。。Editはオーナードロー出来ないみたいだけれど。

http://stackoverflow.com/questions/4009701/windows-visual-themes-gallery-of-parts-and-states
と思ったら、EP_EDITBORDER系のパーツだときちんとした表示なので、DrawThemeBackgroundを直接使うのが良さそうだ。Windows.Forms中のVisualStyleElementの定義が不足しているというか、素直に1対1にマッピングしていれば良かったんだろうけれど、まとめ直しちゃったせいで自由度が低くなってしまっている。と思ったけれど、VisualStyleElement.CreateElement メソッドで指定して作れば良いみたいだ。それなら最初からまったく用意しない方が混乱しないような。。うぅ、ドキュメントをきちんと読めという事なのだろうか。
http://wiz.came.ac/blog/2011/03/visualstyle-2.html

MicrosoftはラッパーのWindows.Formsをある程度整備した後はWPFとかに開発を移行してしまっているのでもうWindows.Formsには手が入らないだろうな。
http://wpf.codeplex.com/
下記のBLOGで状況がわかりやすく書かれている。
http://ufcpp.wordpress.com/2011/06/24/%E9%96%8B%E7%99%BA%E8%80%85%E3%81%AB%E3%81%A8%E3%81%A3%E3%81%A6%E3%81%AEwindows-8/

Windows.Formsを使う利点は Windows2000とかWindowsXPとかの古いOS上で動作するアプリケーションが作れる事だと思う。.NET FWも2.0までだとインストーラーのサイズが小さいし。.NET FWのランタイムがインストールされていない環境もあるかもしれないので、それを考慮したら.NET FWを使わないのが好ましいけれど。

ここ10年程のMSが進めている、新しいOSを発売してそれ上でしか動きませんよ!っていうテクノロジー、を利用する気持ちが薄れてきている。単に時代に付いていけなくなったのかもしれないけど、何の付加価値に魅力を感じるか?っていう点で考えると、DirectX10とかDirectX11でハードを活用した綺麗なゲームが遊べる!だと魅力を感じるけれど、〜テクノロジでリッチなネイティブアプリをXMLC#で記述して楽々開発!と言われても食指が伸びない。原因としては、自分がそれを動かすユーザーを対象にしたソフト開発の仕事をしていない為、とか、ネイティブアプリから叩くものじゃ無かった、とか。まぁ自分だけで使うために利用するのも良いかも知れないけれど。

Windows2000以降から32bit色のフレームバッファをメモリ上に確保出来てディスプレイデバイスにも送れていたんだから、GDI+ベースだとアレだとしても、また別のDLLでGUIを構築する仕組みをMSがストイックに開発してたら良かったんだろうか?歴史のifを考えてもしょうがないけれど。。ネイティブコードだとランタイム情報が少ないし柔軟に作れないよ、結局拡張性が求められるんだから!って事で.NETに舵を切ったんだろうか。

.NET以降に色々とテクノロジが出てきたけどあまりパッとしないというか広まらないというか。。古いOSを切り捨てるせいか古いOSにランタイムを提供しないのもMSの技術が広まらない理由になっている気がする。まぁ考え方を柔軟にすれば古いものが消えていくのは自然の流れなのだから、それも受け入れて時代に合わせてやっていくしかない。これからはブラウザとAndroidですね。多分。