Diary of Sacred Fox - October 09, 2004

The Quintetには通算 179067 人(今日:0, 昨日:1)のお客様が来場しています

2004/10/09(1)

気がつけば今日も

バイトで午前様
世の中叩けば幾らでも埃が出るもので…
次は何処に火がつくんだろ

先月の給与明細が来た
> 出勤日数: 16.00
月の半分以上をバイトに費やしたのね…
時間レベルの解析は恐くて出来ない…
ただいえるのはバイトのための片道40分ほど @ 昼, 終電付近だともっと時間がかかる移動だけでも1日近く使っている計算になってしまうということ…考えると鬱になりそう

Comments (0):

2004/10/09(2)

成績表

普通に結局忙しくて集中講義には参加せず未受験な科目成績未報告で成績表に☆がプリントされているもの, 別に不可を暗示してこういった書き方にしているわけではないお星様な科目以外は単位が来ていて…
とりあえずあと必修+2単位来れば今学期は必修のみで条件は, 第4学期科目(必修11, 計19以上) + 必修科目全部(48単位) + 選択科目(10単位, 内6以上はISから)卒業できる計算

Comments (0):

2004/10/09(3)

台風

が来ているので今日は自主的な自宅待機…というより, 外に出たくない
折角直ってきた風邪を悪化させたくないしね
…ということで, 布石としてちょっと早めの昼食買い出し, 帰ってきた瞬間に雨足が強くなる, いつになくグッドタイミング, いつもこうなってくれれば嬉しいのだけどねぇ…

ちょっと時間軸を遡った話だけど, 今日の0時台の帰宅風景
バイト先周辺: 強風との戦い, 幸いにも屋外の区間は数10mしかないので楽しいとか何とかほざいていられるので問題は無い
寮周辺: 風は幸いにしてそれほど強くないが, 雨足が最強に強い, 坂になっているところなど地面に出来た水の膜が流れているのが分かるぐらい, 坂になっていない所では風によってできる膜の厚さの変化が街路灯によって映し出されていて, 呆けた頭の中では『3次元の不可視なオブジェクトである風のz = 0切片における2次元的状態の自然におけるビジュアリゼーションか…』等とくだらないことを考えてしまっていた

Comments (0):

2004/10/09(4)

Perl tips

複数のファイルを順次処理するスクリプトを書くとき, こんなのがあるとちょっと幸せかも

$| = 1;
foreach (@files) {
  printf '%-48.48s%s', $_, "\r";
  # process file $_;
}

ポイントは3つあって, まずは"\n"(改行)ではなくて"\r"(復帰)を使う点
コンソールでの"\r"は一般的にカーソルをその行の先頭に運ぶ働きがあったりします, これで高速に処理対象が変わっていくときにも情報をスクロールアウトさせることなく表示することができるようになります, しかも"\e"(ESC)を使うタイプのエスケープシーケンスと違って少なくともWindowsとUnixでは使える技だと思います(OSXでないMacでも使えるかは自信が無いですが)端末に対する依存性が小さいのも魅力だったり
でも, これを使うときには十分注意が必要だったりします, それが残る2つのポイント
1つはわざわざ『%左詰め-最小幅48.最大幅48s』と桁指定して出力しているところ
これをやっておかないと, LFNとか8.3とかではなくて, 単純に文字列として長いファイル名のあとに短いファイル名が来た時に, 長いほうのファイル名の残骸が残りつづけてしまうので必須, 48のところは今回聖狐がこれを実装したツールでは出力が殆ど無いので50 x 8のコンソールを使っていましたコンソールの出力幅を超えない範囲で適当につけてあげてください, 所謂最小幅制御というやつで, 足りない部分は空白文字で埋まってくれます
また, 本当に長すぎるファイル名がコンソールの1行幅を超えてしまって折角の"\r"が機能しなくなることを防ぐための最大幅制御も入っています
最後のポイントは実は最大の嵌まりどころ
最初にあるおまじないの『$| = 1;』です, $| はもし使うなら必ずperldoc Englishを一読しましょう, オプションをつけないと正規表現と併用する時にパフォーマンス上の問題を引き起こす場合がありますEnglishモジュールを使うと$OUTPUT_AUTOFLUSHという名前がつくことから分かる通り, 標準出力のバッファリングを抑制します
なぜこれが要るかと言うと, Perlは"\n"と違って"\r"ではBufferをフラッシュしてくれないからです(少なくともActivePerl v5.8.3 built for MSWin32-x86-multi-threadでは)
このまま放っておくと, 最悪の場合全ファイルの処理が終わった後に初めてとはいえ, 最後以外は上書きされて表示されませんが全ファイル名が出力されるということになってしまいます, これでは意味が無いですね

Comments (0):

2004/10/09(5)

.NET tips

コントロールの描画(の一部)をシステムに任せずに完全に自前でやること, 上手に使えばCoolなことができるが, 失敗すると目も当てられない…オーナードローで色選択のコンボボックスを作ってみた
やりたいことは各項目の左に少しだけ余白を入れてそこに該当する色の四角を描画するということ, これをオーナードローで実現してみることにした
オーナードローにはDrawMode.OwnerDrawFixedOwnerDrawFixedDrawMode.OwnerDrawVariableOwnerDrawVariableの2種類があり, 後者はアイテムごとに異なるサイズを指定できるらしい, 今回の目的だけだと一見前者でよさそうだったが, 以下の理由により後者を選択した

ということで, 以下のようなイベントハンドラを用意して, ItemHeightは弄らないことにする

private void comboBox1_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e) {
    e.ItemHeight = (int) comboBox1.Font.GetHeight();
}

これでサイズ的な見た目は確保される
次に以下のようなコードを入れると, オーナードローで普通のコンボボックスと同じ外見を確保できる

private void comboBox1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e) {
    この辺便利, よきにはからえって感じで使えるe.DrawBackground();
    このクラスのインスタンスはDispose()する必要がありますので…using (SolidBrush foreBrush = new SolidBrush(これも状況依存で中身が変わってくれるので便利e.ForeColor))
        e.Graphics.DrawString(この辺はe.GetItemText()とかで簡単に取りたかった気がするcomboBox1.GetItemText(この辺はe.Itemとかで簡単に取りたかった気がするcomboBox1.Items[e.Index]), e.Font,
            foreBrush, MSDNの文書にはe.Boundsをそのまま指定するコードが書いてあったが, リストをたたんでいる時にオリジナルと違って微妙に上のほうにずれるのでこれを補正, ついでに横には項目が並ばないのでWidth, Heightは無視して1行描画e.Bounds.Left, e.Bounds.Top + (e.Bounds.Height - e.Font.Height) / 2);
    この辺も便利e.DrawFocusRectangle();
}

あとはこれに色情報を表示する四角をつけるだけ
こんな感じになる

private void comboBox1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e) {
    e.DrawBackground();
    using (SolidBrush foreBrush = new SolidBrush(e.ForeColor))
        e.Graphics.DrawString(comboBox1.GetItemText(comboBox1.Items[e.Index]), e.Font,
            foreBrush, e.Bounds.Left + 12, e.Bounds.Top + (e.Bounds.Height - e.Font.Height) / 2);
    col = (comboBox1.Items[e.Index]からColor構造体のインスタンスを計算);
    if (!col.IsEmpty) {
        int tx = e.Bounds.Left + 2;
        int ty = e.Bounds.Top + (e.Bounds.Height - 10) / 2;
        using (SolidBrush backBrush = new SolidBrush(col))
            e.Graphics.FillRectangle(backBrush, tx, ty, 9, 9);
        e.Graphics.DrawRectangle(もうちょい適当なのがあったかなぁ?Pens.Black, tx, ty, 9, 9);
    }
    e.DrawFocusRectangle();
}

これを適当に応用すれば背景に項目ごとに色がついたドロップダウンリストぐらいなら簡単に作れると思います
そのうちこれを組み込んだブツを密かにUpする予定…

Comments (0):