前回は画像を読み込んでウインドウを作っていたため タイトルバーないためにCloseBoxの代わりに、フォームのクリックイベットで閉じるようにして逃げていました。
また、同じくタイトルバーがないために、ドラッグしてのフォームの移動が出来ませんでした
今回は上記の点を変更し、独自に画像ファイルを使用してCloseBoxを表示し、フォームのドラッグも出来るように変更してみます。
前回のソースを変更して対応していますので、前回説明した部分ははしょってるかもしれませんので、前回分をみられていない方は前回のエントリーも参照してください
以下のような画像ファイルを用意しました。
Skin.bmp
Close.bmp
20 X 60 の中に、20 X 20で、左から、「通常状態」「マウスがポイントしている状態」「Boxを押下している状態」の3つをまとめて描いてあります。
クラス変数は、画像を格納する変数と、マウスの状態を格納する変数、背景画像上の CloseBoxの描画位置とサイズ情報などを格納した変数を用意しました。
// 背景画像とCloseBox画像を格納する変数 private Bitmap backBmp = null; private Bitmap closeBmp = null; // マウスの左ボタンが押下されているかの状態を格納 private bool isMouseDown = false; // マウスポインタがCloseBox上に位置しているかを格納 private bool isMouseOverBox = false; // マウスがCloseBox上で押下されたかを格納 private bool isMouseDownOnClose = false; // マウスポインタの位置を格納 private Point mousePoint; // CloseBoxの位置とサイズを格納した、 // readonly修飾しているので実質的な実行時定数 private readonly Point boxLocation = new Point(323, 43); private readonly Size boxSize = new Size(20, 20); // 「arayan's」と書かれた背景画像上ボタンの位置とサイズを格納した、 // readonly修飾しているので実質的な実行時定数 private readonly Point titleLocation = new Point(16, 15); private readonly Size titleSize = new Size(137, 30);
フォームのコンストラクタには、CloseBox画像の読み込みを追加しています。
// // コンストラクタ(初期化処理) // public Form1() { InitializeComponent(); // 今回はこのイベントハンドラの登録およびハンドラは削除 //this.Click += new System.EventHandler(this.Form1_Click); // 以下3つのイベントハンドラ登録部今回追加 this.MouseDown += new System.Windows.Forms. MouseEventHandler(this.Form1_MouseDown); this.MouseUp += new System.Windows.Forms. MouseEventHandler(this.Form1_MouseUp); this.MouseMove += new System.Windows.Forms. MouseEventHandler(this.Form1_MouseMove); // 境界線なしにする。 this.FormBorderStyle = FormBorderStyle.None; // 。ダブル バッファリングを使用するように動作を設定する。 this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); // 背景画像ファイルを読み込む bmp =(Bitmap) Bitmap.FromFile("skin.bmp"); // CloseBox画像を読み込む(今回追加部) closeBmp = (Bitmap)Bitmap.FromFile("Close.bmp"); // ウインドウサイズを調整(前回分とは少し変更しました。) this.Width = bmp.Width; this.Height = bmp.Height; // ウインドウ領域を設定する。 this.Region = BitmapToRegion(bmp, Color.FromArgb(255, 0, 255)); // 原点の色を使う場合は以下のようにする // this.Region = BitmapToRegion(bmp, bmp.GetPixel(0, 0)); }背景描画の部分にCloseBoxの描画メソッドのコール追加しています。
BitmapToRegionメソッドは前回のエントリーに書いたコードを参照してください。
// // コントロールの背景を描画。 // (OnPaintBackground をオーバーライド) // protected override void OnPaintBackground(PaintEventArgs e) { // 座標単位を設定 e.Graphics.PageUnit = GraphicsUnit.Pixel; // 背景描画(画像を描画) e.Graphics.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height); // CloseBoxの描画メソッドを呼ぶ(今回追加部) DrawCloaseBox(e.Graphics); } // // CloseBoxを状態に合わせて異なる画像を描画する(今回追加部) // private void DrawCloseBox(Graphics g) { // closeBmp中の今回使用するCloseBox画像の矩形を格納する変数 Rectangle rectSrc; if (isMouseOverBox) { if (isMouseDown) { // CloseBoxが押下された画像 rectSrc = new Rectangle(new Point(boxSize.Width * 2, 0), boxSize); } else { // CloseBoxがアクティブ状態の画像 rectSrc = new Rectangle(new Point(boxSize.Width, 0), boxSize); } } else { // 通常時の画像 rectSrc = new Rectangle(new Point(0, 0), boxSize); } // 状態にあった画像でCloseBoxを描画 g.DrawImage(this.closeBmp, new Rectangle(boxLocation,boxSize), rectSrc, GraphicsUnit.Pixel); }「OnPaintBackground」では、前回分に追加してCloseBoxを描画するメソッド「DrawCloseBox」をGraphicsオブジェクトを渡して読んでいます。
「DrawCloseBox」では、マウスイベントハンドラで設定したフラグで状態を判断し、状態にあったCloseBox画像を描画しています。
下図のような表示になります。
以下は今回追加したイベントハンドラ部でです。
private void Form1_MouseDown(object sender, MouseEventArgs e) { // マウス左クリック時位置を記録 if (e.Button == MouseButtons.Left) mousePoint = new Point(e.X, e.Y); // CloseBox上の押下か?を記録 isMouseDownOnClose = isMouseOverButton; // マウスの押下状態を記録 isMouseDown = true; // 再描画 Refresh(); }ここでは、マウス左ボタンの押下状態を記録。
private void Form1_MouseUp(object sender, MouseEventArgs e) { // マウス押下記録を消去 isMouseDown = false; // CloseBox上にマウスがあり且、CloseBox上で // 押下さたのであればウインドウを閉じる if (isMouseOverButton && isMouseDownOnClose) this.Close(); else isMouseDownOnClose = false; }ここでは、変数の値を確認判定して、条件を満たしていればウインドウを閉じています。
private void Form1_MouseMove(object sender, MouseEventArgs e) { // マウス左ボタンか確認 if ( e.Button == MouseButtons.Left) { // ポインタ位置が「arayan's」ボタンの中にある場合 if (e.X > titleLocation.X) && (e.X < titleLocation.X + titleSize.Width) && (e.Y > titleLocation.Y) && (e.Y < titleLocation.Y + titleSize.Height)) { // フォームの位置をMouseDown時からの移動分調節(移動)する。 this.SetDesktopLocation(this.Left - mousePoint.X + e.X, this.Top - mousePoint.Y + e.Y); } // ポインタ位置がCloseBoxの中にある場合 if ((e.X > buttonLocation.X) && (e.X < buttonLocation.X + buttonSize.Width) && (e.Y > buttonLocation.Y) && (e.Y < buttonLocation.Y + buttonSize.Height)) { // 変数にフラグを立てる isMouseOverButton = true; } else { isMouseOverButton = false; ; } // 再描画 Refresh(); } }ここで、フォームのドラッグを処理しています。また、マウスがCloseBox上に位置するかも記録しています。
以上で「arayan's」ボタンをタイトルバーのようにドラッグで移動できるようになり、右上のボタンで閉じることが出来るようになりました。