パソコン・メモメモ備忘録

気の向くままパソコン関係等で気になることを書き記す。時々更新!

C# に挑戦

会社で C# なプログラムを作っていて、そのメンテナンスというかデバッグというかのために、ちょっと中を見てみた。かなり C++ に近い表記なので、読むのには特に面倒は無いのだが、やはり .NET Framework は知識がないとわかりづらい。

やりたかったのは、画像を表示するフォームを作ること。ただし、マウスホイールで拡大縮小ができて、拡大時には、マウスのドラッグでスクロールさせることができるもの。フォームのウィンドウのサイズも自由に変えられること。で、他の人に作ってもらったものが、結構ちらついたり、半ピクセル画像がずれていたりして難あり状態だった。それをいじってもうまくいきそうに無かったので、そのフォームだけ1から作ってみることにした。


ウィザード通りにやれば、フォームが出るまでは名前と保存場所を決めるくらい。で、画像を出すには PictureBox をフォームに設置して、フォームの AutoScroll を true にして... 画像を出すだけなら PictureBox の image に Bitmap を設定してしまえばおしまいだが、スクロールとか拡大縮小のためには、もう少し自分で色々実装しないといけない。ま、その後の詳細は置いておいて、今回の引っかかりポイントを挙げておこう。

知っている人には当たり前そうなものから、
・ 画像は PictureBox の Paint イベントのフック で実際に DrawImage で描画する
・ 適宜 Refresh() で再描画(Paint イベントが発生するらしい)
・ 画像の拡大縮小は、PixtureBox の大きさを変えると勝手に。
・ イベント内での描画はパラメータ e の e.Graphics を使って e.Graphics.DrawImage() みたいな感じ。これでやらないで、CreateGraphics() していたら、もとの PictureBox のバックグラウンドと描画した画像がちらついてしまった。
・ 未だによく理解していないのだが、拡大表示したら顕著に描画が(拡大前の画像の)半ピクセル分ずれているのがわかる。要するに、PictureBox の中に描画した画像が半ピクセル左上にずれていて、右と下に半ピクセルの背景がついているのだ(PictureBox の背景色をフォームの背景色と変えておく)。これの回避方法としては、Graphics.PixelOffsetMode を Half にすればいいようだ。
・ AutoScrollPosition がまったくわけわからん仕様だった。値を読み出すときは正の値でいいのだが、値を設定する際には、その値の負の値を入れるとちょうどスクロールせずに静止した状態。そういう仕様なのだろう。
・ PictureBox の大きさが フォームの ClientRectangle より小さくなったときは、フォームの中心に PictureBox がくるようにしたい。一つは、PictureBox の Location を変えてもいいのだが(そう実装した)、AutoScrollMergin でもできるような気が(こっちが正解か?)

思ったより簡単に実現できた。この辺が新しい言語(というか .NET Framework?)の利点か。ただ、細かい文法がわからないので、一番安全そうな効率の悪い書き方をしている気がする。C++ でも .NET Framework 上で動くもの(C++/CLI)があるらしいので、それにも挑戦してみる?