2006年03月14日

ListView にカラム

引き続きシリーズの外。今回は完全に外。@IT の ネイティブアプリとCLRアプリの違い スレッドより。

スレ主さん曰く、Becky! のリストビューは第一カラムが幅固定であると。.NET のプロパティにはそう設定できるプロパティがないと。まあそういうことらしいです。しかし考えてみれば生 API 使うのならもともとプロパティだのなんて存在しませんし、MFC の CListView クラスなどにもそんなのありません。あるのはただ WM_NOTIFY と いくつかのメッセージのみ。別にこの辺がアンマネージドというわけでは、まあありますが、幸いメモリのことは一切勘案することなく、unsafe にもしないで、Marshal クラスも使わず書ける部分です。

WndProc のオーバーライドだって普通に存在しているんだから使わなければ損損。と言う比較的現実主義な私としては早速実装してみるのでした。

続きを読む
posted by Hongliang at 05:56| Comment(0) | TrackBack(0) | C# | このブログの読者になる | 更新情報をチェックする

2006年03月13日

CInt とオーバーフロー

今回はちょっとシリーズを離れてオーバーフローのお話です。なんか似た話題を以前にやった気もしますが。

アンマネージドとやりとりしていると、異なる数値型間の変換が必要になる場面が出てきます。今回 Task クラスの実装を書いている場面でも、それが必要になる場面がありました。

アンマネージドとは DWORD つまり UInt32 でやりとりしますが、そのままでは意味を取りづらいので TimeSpan 型としてプロパティを定義し、内部で Int32 に変換するというやり方です。DWORD を あえて Int32 で書くのはまあ CLS 準拠を目指すための癖みたいなもんです。今考えるとこれが悩みの元になったわけなんですが。

そのアンマネージドのメソッドは 0 から 0xFFFFFFFFL まで受け入れるため、TimeSpan.TotalMilliseconds を 一旦 Int64 にキャストし、最大値チェックを行った後 Int32 にキャストし直そうという算段でした。

unchecked を使える C# はともかく、VB.NET での Int64 から Int32 へのキャストは CInt か Convert.ToInt32 になりますが、この二つはいずれもオーバーフローを抑止するオプションが存在しないため、変換元の値を確認して &H80000000L 以上だったら &H100000000L を引く、そして変換ってのがわかりやすい手段です。

この過程で、何を思ったか Int64 に And &HFFFFFFFFL の演算をしてやればどうだろう? という思考にたどり着きました。確かに 32bit にはなりますがだからって CInt したときオーバーフローするのには変わらないのに。

ところがどっこい、これが何故かエラーが出なかったのです。もとの Int64 に &HFFFFFFFEL が入っていた場合、CInt した結果普通に -2 になります。気持ち悪。ちなみに C# でも checked ステートメント内で同じ結果になります。

IL レベルでも問題なく conv.ovf.i4 が発行されているため、さっぱり原因がつかめません。いい加減煮詰まったので 2ch で聞いてみたら、いくつかやりとりがあった末に こういう結論に。つまり定数が 32bit で収まること、また And 演算のため計算結果も必ず 32 bit 以下になることから、定数の下位 32bit で演算するように最適化する。そのとき正しくは通るべきオーバーフローチェックがパスされてしまう、と。また Mono では普通にオーバーフローするらしいです。つきあってくださった方々、改めてありがとうございました。

And &HFFFFFFFFL 後の CInt が決してオーバーフローしないのなら利用価値はありますが、x64 版でどうなるか知れたものじゃないし Mono でも普通にオーバーフローするとなると使ってもバグの元になるだけですので封印封印。

まあそう言う顛末の話でした。

しかし VB.NET にもオーバーフローの制御とか三項演算子とか欲しいんですが。IIf は Object でのやりとりになるから IIf(Of T) があればいいんだけどなー。

posted by Hongliang at 21:55| Comment(0) | TrackBack(1) | VB.NET | このブログの読者になる | 更新情報をチェックする

2006年03月12日

COM クライアント実装の道程 for TaskScheduler その6

死亡フラグって言いますよね。「この戦争が終わったら、俺、結婚するんだ」とか言うの。これ、死にフラグって表現もあると言うことを最近知りました。しかし死にフラグってのは、まるで上げ下げはしてるんだけどだれもそのフラグを参照してない孤独なフラグってイメージが。いやどうでも良いんですが。

今回から Task と TaskTrigger の解説に入るわけですが、いきなりクラスの解説をし出しても理解しにくいでしょうから、まずその下準備として ITask インターフェイスを中心にタスクアイテムの構造を述べていくことにします。

と切り出しておいて何ですが、実のところタスクアイテムの構成ってのはタスクのプロパティダイアログに表示されている奴ほぼそのままなんですよね。

続きを読む
posted by Hongliang at 17:38| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2006年03月11日

COM クライアント実装の道程 for TaskScheduler その5

ID3タグってーのは調べれば調べるほど混沌としてきますね。あと v2.4 が出てもう5年以上立ってるけど結局 v2.3 の方が使われているような。WMP も v2.3 みたいだし。

さて、今回は前回の資産を生かして ITaskScheduler を .NET に相応しいクラスにラッピングします。まずは改めて ITaskScheduler のメンバを一覧しましょう。

メソッド 機能
SetTargetComputerこのインスタンスが操作の対象とするコンピュータの名前を設定する。
GetTargetComputerこのインスタンスが操作の対象とするコンピュータの名前を取得する。
Enum 現在のタスクフォルダに入っているタスクを列挙する。
Activate 操作するタスクを取得する。
Delete タスクを削除する。
NewWorkItem 新しいタスクアイテムをメモリに作成する。
AddWorkItem 新しいタスクアイテムのファイルを作成する。
IsOfType 指定したタスクアイテムが特定のインターフェイスをサポートしているかどうかを確認する。
続きを読む
posted by Hongliang at 18:08| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2006年03月10日

COM クライアント実装の道程 for TaskScheduler その番外編2 〜 COM オブジェクトと GC とファイナライザ

ノートの方には MSDN の Platform SDK 部分は入れていなかったので、この記事を書くのにオンラインの MSDN を参照することもあります。で、気づいたんですが、なんか TaskScheduler の関連インターフェイスが増殖してる……。え嘘マジ? と大慌てで調べてみたら、その辺全部 Vista で追加されるインターフェイスのようです。…………。ふ、今やってるのも Vista までの寿命か……。いや後方互換性は残されるみたいですけど。Vista では ITaskScheduler の代わりに ITaskService を使って操作するスタイルになるようですね。増えたインターフェイスは ITaskScheduler では構造体として扱っていた部分みたいです。あるいはそもそも WinFX でサポートされるようになるのかしらん。

さて、今回のお題は COM オブジェクトの面倒くささについてです。知っている人は知っている、というか最近特にクローズアップされだしているような気がしますが(というか私がそう言う情報に敏感になっただけかも)、CLI の基礎でもあるガベージコレクタと COM オブジェクトとは、ひたすら食い合わせが悪いのです。

続きを読む
posted by Hongliang at 03:09| Comment(1) | TrackBack(1) | .NET | このブログの読者になる | 更新情報をチェックする

2006年03月08日

COM クライアント実装の道程 for TaskScheduler その4

いつまでもデスクトップを使っているのは電気代にも優しくないので、そう言えば、と初代ノート PC を引っ張り出してきました。液晶モニタが割れたので新しいのに買い換えたんですが、逆に言えば液晶モニタの問題だけでしたので、デスクトップで使っているモニタが二系統の入力を受け付けているのに目を付け、バルクのモニタケーブルを調達してきてでかいモニタでノートです。操作感的には大して不都合もないのですが(意外に液晶部分もそんな気になりません)、難点は致命的に重いってこと。やたら HDD へのアクセスが発生してるところからみてスワップしまくってんでしょうね。HDD も 4200rpm と旧式ですし。メモリが 240 MB( 16 MB はビデオメモリに割り当て)ってのはやはり厳しいものがあるようです。特に開発に使うものじゃありません。あまつさえ .NET となるともう、OpenFileDialog 開けるだけでなんか 30 秒とか待たされたり、ってなんかほかの要因もあるような気が。

さて、前回の続き。今回はインターフェイスの残りをまとめてやってしまいましょう。TaskScheduler の項目にある六つのインターフェイスのうち、一つは無視すると初めに宣言しました。さらに IScheduledWorkItem は完全に ITask に吸収させることにしました。ので、残りは二つ。いずれも小さい単純なインターフェイスです。

続きを読む
posted by Hongliang at 03:43| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

ここ(hongliang.seesaa.net)で公開しているものについて、利用は自由に行って頂いて構いません。改変、再頒布もお好きになさって下さい。利用に対しこちらが何かを要求することはありません。

ただし、公開するものを使用、または参考したことによって何らかの損害等が生じた場合でも、私はいかなる責任も負いません。

あ、こんなのに使ったってコメントを頂ければ嬉しいです。

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。