特集:Windowsフォームにスパイスを――MessengerやOutlookに見る不定形フォームテクVisual Studio Magazine(2/4 ページ)

» 2004年11月09日 10時41分 公開
[Andrew Flick, Jason Beres,FTPOnline]

 適切な背景色を設定した画像を作成したならば、フォームのBackgroundImageプロパティに、その作成した画像を設定する。そして次に、FormBorderStyleプロパティをデフォルトのSizableからNoneに変更する。

 FormBorderStyleプロパティをNoneに設定すると、フォームの境界線(訳注:およびタイトルバー)が描画されなくなる。すなわちフォームの背景として設定した画像がフォームの境界となるわけだ。

 最後に、フォームのTransparencyKeyプロパティを、画像の背景色と同じ色に設定する。すなわち、たとえば、ライム色なら「#00FF00」だ(具体的な手順については、以下のコラム「色数を変更する」を参考にしてほしい)。

コラム■色数を変更する

 Windows Formには、透明色ウィンドウの処理に重大なバグがある。正確に表示するためには、画面の色数を32ビット未満に設定しなければならない。そうしないと、環境によって問題が生じることがある。実行時にファイルやリソースから画像を読み込み、TransparencyKeyプロパティに設定するには、以下のようにコーディングする。

  • 画像を読み込み、Bitmapオブジェクトに取得する
Dim bmp As New Bitmap("Sherv.Tif")

  • 画像の(1, 1)の位置にあるピクセルを取り出し、それを透明にする
bmp.MakeTransparent(bmp.GetPixel(1, 1))

  • フォームの背景としてその画像を設定する
Me.BackgroundImage = bmp

  • TransparencyKeyプロパティを画像の(1, 1)の位置にあるピクセルに設定する
Me.TransparencyKey = bmp.GetPixel(1, 1)

 より詳細については、Microsoft Knowledge Baseの「Q822495」「Q820640」「Q824337」を参照してほしい。

 アプリケーションを実行すれば、画面2のように、角丸の境界をもつフォームが表示される。次のステップとして、フォームを閉じたり移動したりできるイベント処理を加えていこう。

画面2■境界が設定されたが動かないフォーム

 この角丸の境界をもつフォームは、一見うまく機能しているように思える。しかし、「Alt」+「F4」キー以外の操作で、閉じることはおろか、動かすこともできない(訳注:上記の画面で[×]などのボタンは、画面1で用意した単なる画像であり、ボタンではない。FormBorderStyleプロパティをNoneにしておりタイトルバーがないため、実際には[×]ボタンはなく、タイトルバーをドラッグしてのウィンドウの移動もできない)。

 フォームを閉じることは簡単だ。単純にボタンを加えて、Clickイベントに次のコードを書けばよい。

this.Close();

 フォームの移動は、不定型な形のフォームにとっては不可欠だが、少し難しい。

 マウスをハンドリングし、フォームのドラッグ操作を制御するために「MouseDown」「MouseMove」「MouseUp」の3つのイベントを定義しよう(リスト1)。

 マウスをハンドリングし、フォームのドラッグ操作を制御するために「MouseDown」「MouseMove」「MouseUp」の3つのイベントを定義する。このコードリスト1では、「マウスの左ボタンがどこでクリックされたか」「フォームの境界からどれだけ離れているか」「ユーザーがフォームをドラッグした場所はどこか」を追跡する。

リスト1■MouseDown、MouseMove、MouseUpイベントを定義する(C#)
private void Form1_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{

if (e.Button == MouseButtons.Left)
{
dragging = true;
offsetX = e.X;
offsetY = e.Y;
}
}

private void Form1_MouseMove(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if (dragging)
{
Left = e.X + Left - offsetX;
Top = e.Y + Top - offsetY;
}
}

private void Form1_MouseUp(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
dragging = false;
}
}

 必要なのは、マウスのドラッグ操作が始まった時に、フォームをスクリーン上でスムースに動かすことであり、(クリックされた位置に)フォームをジャンプさせることではない。リスト1では、ユーザーがフォームをクリックした場所を追跡するために、offxetXとoffsetYという2つの変数を利用している。

 ドラッグが始まった時には、現在のマウス位置からクリック時に保存しておいたオリジナルのoffsetXとoffsetYの値を引いたものを、フォームの新しい位置として設定する。ドラッグ中であるか否かを調べるには、マウスのボタンが押されたか離されたかを追うだけでよく単純だ。

 もしリスト1において、MouseUpイベント中の下記のコードを削除すれば、ユーザーがマウスボタンを押したあとに離してマウスを動かした時にもフォームが動くようになる。

if (e.Button == MouseButtons.Left)

フォームに拡張機能を加える

 さて、基本的な実装を終えたところで、不定形なWindowsフォームに、さらなる小さな改良を加えたいと思うかもしれない。

 フォームのサイズ変更をしたいだろうか、それとも、Windows Media Playerのように、マウスの動きによってメニューを再表示したいだろうか、それとも、MSN Messengerのようにマウスのクリックによってメインメニューを表示したいだろうか。

 ここでは例として、フォームにメニューを加えてみよう。メニューには、幾つかのメインメニューアイテムを加える。

 メニューやメインメニューアイテムを加えたならば、次に、背景画像の背景色を変更する。この色は、透明色として作用するばかりでなく、表示される色にもなる。我々は、背景色をライムグリーン色からより適切なグレーに変更してみた。そして、フォームのLoadイベントにおいて、それぞれのメニューアイテムのVisibleプロパティをFalseにして非表示にする。

 次のステップは、ボタンがクリックされたときに引き起こされるイベントを処理し、メニューを表示したり、背景を表示したりするようにすることだ。

 メニューを加えるとフォームの背景の大きさが変わるため、フォームのサイズ変更についても考慮に入れなければならないフォームとメニューとの間隔は、背景画像として使っている境界の大きさに直接依存する。コードは次のようになる。

if(this.FormBorderStyle ==
FormBorderStyle.None)
{
this.FormBorderStyle
= FormBorderStyle.Fixed3D;
this.TransparencyKey =
Color.SomeDifferentColor;

this.Height = 425;

// 高さと幅を新しいフォームの大きさに合わせるよう変更する

this.Width = 467;
menuItem1.Visible = true;
}

© Copyright 2001-2005 Fawcette Technical Publications

注目のテーマ