2011年03月27日

フォームの端をドラッグしてサイズ変更する機能を提供するクラス・吸着機能付き(C#用)

以前、紹介しました「フォームをドラッグして移動させる機能を提供するクラス」に、スクリーンの端に吸着させる機能を追加しました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace Com.Mirano.Forms
{
    /// <summary>
    /// フォームの端をドラッグしてサイズ変更するクラス
    /// </summary>
    class FormDragResizer
    {
        // サイズ変更の対象となるフォーム
        Form resizeForm;

        /// <summary>
        /// サイズ変更の対象となる枠の位置
        /// </summary>
        public enum ResizeDirection
        {
            None = 0,
            Top = 1,
            Left = 2,
            Bottom = 4,
            Right = 8,
            All = 15
        }

        // サイズ変更が有効になる枠
        ResizeDirection resizeDirection;

        // サイズ変更中を表す状態
        ResizeDirection resizeStatus;

        // サイズ変更が有効になる範囲の幅
        int resizeAreaWidth;

        // 標準のカーソル
        Cursor defaultCursor;

        // マウスをクリックした位置
        Point lastMouseDownPoint;

        // マウスをクリックした時点のサイズ
        Size lastMouseDownSize;

        // ウィンドウをスクリーンに吸着させる機能の有効/無効
        bool isAdsorb;

        // ウィンドウをスクリーンに吸着させる場合の吸着させるマージン
        Size adsorbGap;

        // ウィンドウの最小サイズ
        Size minimumSize;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="resizeForm">サイズ変更の対象となるフォーム</param>
        /// <param name="resizeDirection">サイズ変更が有効になる枠</param>
        /// <param name="resizeAreaWidth">サイズ変更が有効になる範囲の幅</param>
        public FormDragResizer(Form resizeForm, ResizeDirection resizeDirection, int resizeAreaWidth)
        {
            this.resizeForm = resizeForm;
            this.resizeDirection = resizeDirection;
            this.resizeAreaWidth = resizeAreaWidth;
            this.isAdsorb = false;
            
            // 最小サイズの設定
            // サイズ変更が有効になる範囲を確実に残すため、上下左右のマージン+1ドットを最小サイズにする
            this.minimumSize = new Size(resizeAreaWidth * 2 + 1, resizeAreaWidth * 2 + 1);

            // 現時点でのカーソルを保存しておく
            defaultCursor = resizeForm.Cursor;

            // イベントハンドラを追加
            resizeForm.MouseDown += new MouseEventHandler(resizeForm_MouseDown);
            resizeForm.MouseMove += new MouseEventHandler(resizeForm_MouseMove);
            resizeForm.MouseUp += new MouseEventHandler(resizeForm_MouseUp);
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="resizeForm">サイズ変更の対象となるフォーム</param>
        /// <param name="resizeDirection">サイズ変更が有効になる枠</param>
        /// <param name="resizeAreaWidth">サイズ変更が有効になる範囲の幅</param>
        /// <param name="isAdsorb">吸着機能の有効/無効</param>
        /// <param name="adsorbGap">吸着させるマージン</param>
        public FormDragResizer(Form resizeForm, ResizeDirection resizeDirection, int resizeAreaWidth, bool isAdsorb, Size adsorbGap)
        {
            this.resizeForm = resizeForm;
            this.resizeDirection = resizeDirection;
            this.resizeAreaWidth = resizeAreaWidth;
            this.isAdsorb = isAdsorb;
            this.adsorbGap = adsorbGap;

            // 最小サイズの設定
            // サイズ変更が有効になる範囲を確実に残すため、上下左右のマージン+1ドットを最小サイズにする
            this.minimumSize = new Size(resizeAreaWidth * 2 + 1, resizeAreaWidth * 2 + 1);

            // 現時点でのカーソルを保存しておく
            defaultCursor = resizeForm.Cursor;

            // イベントハンドラを追加
            resizeForm.MouseDown += new MouseEventHandler(resizeForm_MouseDown);
            resizeForm.MouseMove += new MouseEventHandler(resizeForm_MouseMove);
            resizeForm.MouseUp += new MouseEventHandler(resizeForm_MouseUp);
        }

        /// <summary>
        /// マウスボタン押下イベントハンドラ
        /// </summary>
        void resizeForm_MouseDown(object sender, MouseEventArgs e)
        {
            // クリックしたポイントを保存する
            lastMouseDownPoint = e.Location;

            // クリックした時点でのフォームのサイズを保存する
            lastMouseDownSize = resizeForm.Size;

            // クリックした位置から、サイズ変更する方向を決める
            resizeStatus = ResizeDirection.None;

            // 上の判定
            if ((resizeDirection & ResizeDirection.Top) == ResizeDirection.Top)
            {
                Rectangle topRect = new Rectangle(0, 0, resizeForm.Width, resizeAreaWidth);
                if (topRect.Contains(e.Location))
                {
                    resizeStatus |= ResizeDirection.Top;
                }
            }

            // 左の判定
            if ((resizeDirection & ResizeDirection.Left) == ResizeDirection.Left)
            {
                Rectangle leftRect = new Rectangle(0, 0, resizeAreaWidth, resizeForm.Height);
                if (leftRect.Contains(e.Location))
                {
                    resizeStatus |= ResizeDirection.Left;
                }
            }

            // 下の判定
            if ((resizeDirection & ResizeDirection.Bottom) == ResizeDirection.Bottom)
            {
                Rectangle bottomRect = new Rectangle(0, resizeForm.Height - resizeAreaWidth, resizeForm.Width, resizeAreaWidth);
                if (bottomRect.Contains(e.Location))
                {
                    resizeStatus |= ResizeDirection.Bottom;
                }
            }

            // 右の判定
            if ((resizeDirection & ResizeDirection.Right) == ResizeDirection.Right)
            {
                Rectangle rightRect = new Rectangle(resizeForm.Width - resizeAreaWidth, 0, resizeAreaWidth, resizeForm.Height);
                if (rightRect.Contains(e.Location))
                {
                    resizeStatus |= ResizeDirection.Right;
                }
            }

            // サイズ変更の対象だったら、マウスキャプチャー
            if (resizeStatus != ResizeDirection.None)
            {
                resizeForm.Capture = true;
            }
        }

        /// <summary>
        /// マウス移動イベントハンドラ
        /// </summary>
        void resizeForm_MouseMove(object sender, MouseEventArgs e)
        {
            // サイズ変更が有効になる枠の上にカーソルが乗ったら
            // マウスカーソルをサイズ変更用のものに変更する

            // どの枠の上にカーソルが乗っているか
            ResizeDirection cursorPos = ResizeDirection.None;

            // 上の判定
            if ((resizeDirection & ResizeDirection.Top) == ResizeDirection.Top)
            {
                Rectangle topRect = new Rectangle(0, 0, resizeForm.Width, resizeAreaWidth);
                if (topRect.Contains(e.Location))
                {
                    cursorPos |= ResizeDirection.Top;
                }
            }

            // 左の判定
            if ((resizeDirection & ResizeDirection.Left) == ResizeDirection.Left)
            {
                Rectangle leftRect = new Rectangle(0, 0, resizeAreaWidth, resizeForm.Height);
                if (leftRect.Contains(e.Location))
                {
                    cursorPos |= ResizeDirection.Left;
                }
            }

            // 下の判定
            if ((resizeDirection & ResizeDirection.Bottom) == ResizeDirection.Bottom)
            {
                Rectangle bottomRect = new Rectangle(0, resizeForm.Height - resizeAreaWidth, resizeForm.Width, resizeAreaWidth);
                if (bottomRect.Contains(e.Location))
                {
                    cursorPos |= ResizeDirection.Bottom;
                }
            }

            // 右の判定
            if ((resizeDirection & ResizeDirection.Right) == ResizeDirection.Right)
            {
                Rectangle rightRect = new Rectangle(resizeForm.Width - resizeAreaWidth, 0, resizeAreaWidth, resizeForm.Height);
                if (rightRect.Contains(e.Location))
                {
                    cursorPos |= ResizeDirection.Right;
                }
            }

            // カーソルを変更

            // 左上(左上から右下への斜め矢印)
            if (((cursorPos & ResizeDirection.Left) == ResizeDirection.Left)
                && ((cursorPos & ResizeDirection.Top) == ResizeDirection.Top))
            {
                resizeForm.Cursor = Cursors.SizeNWSE;
            }
            // 右下(左上から右下への斜め矢印)
            else if (((cursorPos & ResizeDirection.Right) == ResizeDirection.Right)
                && ((cursorPos & ResizeDirection.Bottom) == ResizeDirection.Bottom))
            {
                resizeForm.Cursor = Cursors.SizeNWSE;
            }
            // 右上(右上から左下への斜め矢印)
            else if (((cursorPos & ResizeDirection.Right) == ResizeDirection.Right)
                && ((cursorPos & ResizeDirection.Top) == ResizeDirection.Top))
            {
                resizeForm.Cursor = Cursors.SizeNESW;
            }
            // 左下(右上から左下への斜め矢印)
            else if (((cursorPos & ResizeDirection.Left) == ResizeDirection.Left)
                && ((cursorPos & ResizeDirection.Bottom) == ResizeDirection.Bottom))
            {
                resizeForm.Cursor = Cursors.SizeNESW;
            }
            // 上(上下矢印)
            else if ((cursorPos & ResizeDirection.Top) == ResizeDirection.Top)
            {
                resizeForm.Cursor = Cursors.SizeNS;
            }
            // 左(左右矢印)
            else if ((cursorPos & ResizeDirection.Left) == ResizeDirection.Left)
            {
                resizeForm.Cursor = Cursors.SizeWE;
            }
            // 下(上下矢印)
            else if ((cursorPos & ResizeDirection.Bottom) == ResizeDirection.Bottom)
            {
                resizeForm.Cursor = Cursors.SizeNS;
            }
            // 右(左右矢印)
            else if ((cursorPos & ResizeDirection.Right) == ResizeDirection.Right)
            {
                resizeForm.Cursor = Cursors.SizeWE;
            }
            // どこにも属していない(デフォルト)
            else
            {
                resizeForm.Cursor = defaultCursor;
            }

            // リサイズ中の場合のみ処理。リサイズ中でなければ何もせず終わる
            if (resizeStatus == ResizeDirection.None) return;

            // 左ボタン押下中のみ処理する。押下中ではないときは何もしない。
            if ((e.Button & MouseButtons.Left) != MouseButtons.Left) return;

            // サイズ変更の処理

            // ドラッグにより移動した距離を計算
            int diffX = e.X - lastMouseDownPoint.X;
            int diffY = e.Y - lastMouseDownPoint.Y;

            // サイズ変更後のフォーム位置
            Rectangle newPosition = new Rectangle(resizeForm.Location, resizeForm.Size);

            // 判定用のRECT(一時領域)
            Rectangle newRect = new Rectangle();

            // 作業領域の取得(吸着させる場合は、この作業領域の内側に吸着する)
            Size area = new Size(
                System.Windows.Forms.Screen.GetWorkingArea(resizeForm).Width,
                System.Windows.Forms.Screen.GetWorkingArea(resizeForm).Height);

            // 画面端の判定用(画面の端の位置に、吸着するサイズ分のRECTを定義する)
            Rectangle rectLeft = new Rectangle(0, 0, adsorbGap.Width, area.Width);
            Rectangle rectTop = new Rectangle(0, 0, area.Width, adsorbGap.Height);
            Rectangle rectRight = new Rectangle(area.Width - adsorbGap.Width, 0, adsorbGap.Width, area.Height);
            Rectangle rectBottom = new Rectangle(0, area.Height - adsorbGap.Height, area.Width, adsorbGap.Height);

            // 上
            if ((resizeStatus & ResizeDirection.Top) == ResizeDirection.Top)
            {
                // まず、ドラッグした距離分だけサイズを変更する
                // その後、フォームの位置を調整する
                // (順番を逆にすると、ちょっとちらつく?)
                int h = resizeForm.Height;
                newPosition.Height -= diffY;
                newPosition.Y += h - newPosition.Height;
                // 小さくなりすぎるのを防ぐ
                if (newPosition.Height < minimumSize.Height)
                {
                    newPosition.Y = resizeForm.Top;
                    newPosition.Height = resizeForm.Height;
                }
                // 吸着の処理
                if (this.isAdsorb)
                {
                    // 上端衝突判定
                    newRect = newPosition;
                    newRect.Height = adsorbGap.Height;

                    if (newRect.IntersectsWith(rectTop))
                    {
                        // 上端に吸着させる
                        newPosition.Height = resizeForm.Bottom;
                        newPosition.Y = 0;
                    }
                }
            }
            // 左
            if ((resizeStatus & ResizeDirection.Left) == ResizeDirection.Left)
            {
                // 上と同じ
                int w = resizeForm.Width;
                newPosition.Width -= diffX;
                newPosition.X += w - newPosition.Width;
                // 小さくなりすぎるのを防ぐ
                if (newPosition.Width < minimumSize.Width)
                {
                    newPosition.X = resizeForm.Left;
                    newPosition.Width = resizeForm.Width;
                }
                // 吸着の処理
                if (this.isAdsorb)
                {
                    // 左端衝突判定
                    newRect = newPosition;
                    newRect.Width = adsorbGap.Width;

                    if (newRect.IntersectsWith(rectLeft))
                    {
                        // 左端に吸着させる
                        newPosition.Width = resizeForm.Right;
                        newPosition.X = 0;
                    }
                }
            }
            // 下
            if ((resizeStatus & ResizeDirection.Bottom) == ResizeDirection.Bottom)
            {
                // マウスクリックした時点のサイズを基点として、
                // ドラッグした距離分だけサイズを変更する
                newPosition.Height = lastMouseDownSize.Height + diffY;
                // 小さくなりすぎるのを防ぐ
                if (newPosition.Height < minimumSize.Height)
                {
                    newPosition.Y = resizeForm.Top;
                    newPosition.Height = resizeForm.Height;
                }
                if (this.isAdsorb)
                {
                    // 下端衝突判定
                    newRect = newPosition;
                    newRect.Y = newPosition.Bottom - adsorbGap.Height; // ウィンドウの下端
                    newRect.Height = adsorbGap.Height;

                    if (newRect.IntersectsWith(rectBottom))
                    {
                        // 下端に吸着させる
                        newPosition.Height = area.Height - resizeForm.Top;
                    }
                }
            }
            // 右
            if ((resizeStatus & ResizeDirection.Right) == ResizeDirection.Right)
            {
                // マウスクリックした時点のサイズを基点として、
                // ドラッグした距離分だけサイズを変更する
                newPosition.Width = lastMouseDownSize.Width + diffX;
                // 小さくなりすぎるのを防ぐ
                if (newPosition.Width < minimumSize.Width)
                {
                    newPosition.X = resizeForm.Left;
                    newPosition.Width = resizeForm.Width;
                }
                // 吸着の処理
                if (this.isAdsorb)
                {
                    // 右端衝突判定
                    newRect = newPosition;
                    newRect.X = newPosition.Right - adsorbGap.Width;  // ウィンドウの右隅
                    newRect.Width = adsorbGap.Width;

                    if (newRect.IntersectsWith(rectRight))
                    {
                        // 右端に吸着させる
                        newPosition.Width = area.Width - resizeForm.Left;
                    }
                }
            }
            // 実際にサイズ変更させる
            resizeForm.Left = newPosition.Left;
            resizeForm.Top = newPosition.Top;
            resizeForm.Width = newPosition.Width;
            resizeForm.Height = newPosition.Height;
        }

        /// <summary>
        /// マウスボタン押上イベントハンドラ
        /// </summary>
        void resizeForm_MouseUp(object sender, MouseEventArgs e)
        {
            // マウスキャプチャーを終了する
            resizeForm.Capture = false;
        }
    }
}

使い方

// 変数を定義しておき 
FormDragResizer formResizer;
  
private void InitializeForm()
{
    // Formのイニシャル処理で生成する 
    formResizer = new FormDragResizer(this, FormDragResizer.ResizeDirection.All, 8, true, new Size(16, 16));
}

第4引数に、吸着させる機能を有効にするため、trueを指定。 第5引数に、吸着させる距離(マージン)を指定します。

良かったらクリックしてください
にほんブログ村 IT技術ブログ プログラム・プログラマーへ  人気ブログランキングへ

posted by among at 20:50 | Comment(0) | TrackBack(0) | C#

2011年03月26日

SyntaxHighlighter 3.0 導入手順

ソースコードのハイライト表示をするためにSyntaxHighlighterを導入してみます。< br/> この記事で実験を兼ねて、導入手順をメモっておきます。

1.SyntaxHighlighterの入手

http://alexgorbatchev.com/SyntaxHighlighter/download/
上記サイトからSyntaxHighlighterをダウンロードします。(私がダウンロードしたときは 3.0.83でした)

2.javascriptとCSSファイルのアップロード

解凍してできた「scripts」と「styles」をアップロードします。
自分のサイトの場合は任意の場所に置けば良いです。
さくらのブログの場合は「ファイルマネージャ」で「scripts」「styles」のディレクトリを追加し、中身のファイルを全てアップロードします。「ファイルマネージャ」だとファイルは10個ずつしかアップロードできないので、ディレクトリを追加したあとはFTPで転送します。もちろん、「ファイルマネージャ」でアップロードしても良いのですが、面倒ですし、余計なサムネイルが表示されるので、私はFTPで転送しました。

さくらのブログでアップロードしたファイルのリンクは下記のようになります。
***はそれぞれのアカウント名になります。
http://***.sakura.ne.jp/sblo_files/***/scripts/shCore.js

3.CSSリンク追加

head部の末尾にCSSのリンクを追加します。
さくらのブログの場合は「デザイン」→「HTML」から編集できます。一度も編集したことが無い場合は、右上の「HTMLの追加」をクリックすると、新しいテンプレートを編集することができます。

<head>

〜省略〜

<!-- SyntaxHighlighter -->
<link type="text/css" rel="stylesheet" href="http://***.sakura.ne.jp/sblo_files/***/styles/shCore.css">
<link type="text/css" rel="stylesheet" href="http://***.sakura.ne.jp/sblo_files/***/styles/shThemeDefault.css">

</head>

4.Javascript追加

body部の終わりにJavascriptを追加します。

<body>

〜省略〜

<!-- SyntaxHighlighter -->
<script type="text/javascript" src="http://***.sakura.ne.jp/sblo_files/***/scripts/shCore.js"></script>
<script type="text/javascript" src="http://***.sakura.ne.jp/sblo_files/***/scripts/shAutoloader.js"></script>
<script type="text/javascript" 
  SyntaxHighlighter.autoloader(
     "xml xhtml xslt html       http://***.sakura.ne.jp/sblo_files/***/scripts/shBrushXml.js",
     "cpp c                     http://***.sakura.ne.jp/sblo_files/***/scripts/shBrushCpp.js",
     "c# c-sharp csharp         http://***.sakura.ne.jp/sblo_files/***/scripts/shBrushCSharp.js"
     <!-- ここに使用するBrushを追加します -->
  );
  SyntaxHighlighter.defaults['toolbar'] = false;  <!-- ツールバー非表示 -->
  SyntaxHighlighter.config.bloggerMode = true;    <!-- 自動改行の対応 -->
  SyntaxHighlighter.all();
</script>
</body>

SyntaxHighlighter.autoloader( 〜 )
上記はハイライト表示する定義ファイル(shBrush***.js)を自動で読み込ませるための設定です。必要な定義をあらかじめ定義しておくと、その定義を使用したときに自動で読み込まれます。

SyntaxHighlighter.defaults['toolbar'] = false;
上記はツールバーを非表示にするための設定です。ツールバーを使用しない場合は設定しておかないと、バージョン情報を表す「?」だけが表示されてしまいます。

SyntaxHighlighter.config.bloggerMode=true;
上記はブログなどで改行を<br>タグに自動変換する場合に対応するものです。

5.ソースの記述

実際にソースを記述するときは<pre>タグを使って記述します。このとき、"<",">"が含まれると、HTMLのタグと解釈されてしまうため、"&lt;","&gt;"と記述します。

<pre class="brush:c" title="サンプル">
#include&lt;stdio.h&gt;
int main()
{
  puts("Hello World !\n");
  return 0;
}
</pre>

上記のように記述すると、下記のように表示されます。

#include<stdio.h>
int main()
{
  puts("Hello World !\n");
  return 0;
}

良かったらクリックしてください
にほんブログ村 IT技術ブログ プログラム・プログラマーへ  人気ブログランキングへ

posted by among at 07:25 | Comment(0) | TrackBack(0) | メモ

2011年03月25日

フォームをドラッグして移動させる機能を提供するクラス・吸着機能付き(C#用)

以前、紹介した「フォームをドラッグして移動させる機能を提供するクラス(C#用)」に、スクリーンの端に吸着させる機能を追加しました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace Com.Mirano.Forms
{
    /// <summary>
    /// フォームをドラッグして移動するクラス
    /// </summary>
    class FormDragMover
    {
        // 移動の対象となるフォーム
        Form moveForm;

        // 移動中を表す状態
        bool moveStatus;

        // ドラッグを無効とする幅(フォームの端をサイズ変更に使うときなど)
        int noDragAreaWidth;

        // 標準のカーソル
        Cursor defaultCursor;

        // マウスをクリックした位置
        Point lastMouseDownPoint;

        // ウィンドウをスクリーンに吸着させる機能の有効/無効
        bool isAdsorb;

        // ウィンドウをスクリーンに吸着させる場合の吸着させるマージン
        Size adsorbGap;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="moveForm">移動の対象となるフォーム</param>
        /// <param name="noDragAreaWidth">ドラッグを無効とする幅</param>
        public FormDragMover(Form moveForm, int noDragAreaWidth)
        {
            this.moveForm = moveForm;
            this.noDragAreaWidth = noDragAreaWidth;
            this.isAdsorb = false;

            // 現時点でのカーソルを保存しておく
            defaultCursor = moveForm.Cursor;

            // イベントハンドラを追加
            moveForm.MouseDown += new MouseEventHandler(moveForm_MouseDown);
            moveForm.MouseMove += new MouseEventHandler(moveForm_MouseMove);
            moveForm.MouseUp += new MouseEventHandler(moveForm_MouseUp);
        }
        /// <summary>
        /// コンストラクタ(吸着機能を使用する場合)
        /// </summary>
        /// <param name="moveForm">移動の対象となるフォーム</param>
        /// <param name="noDragAreaWidth">ドラッグを無効とする幅</param>
        /// <param name="isAdsorb">吸着機能の有効/無効</param>
        /// <param name="adsorbGap">吸着させるマージン</param>
        public FormDragMover(Form moveForm, int noDragAreaWidth, bool isAdsorb, Size adsorbGap)
        {
            this.moveForm = moveForm;
            this.noDragAreaWidth = noDragAreaWidth;
            this.isAdsorb = isAdsorb;
            this.adsorbGap = adsorbGap;

            // 現時点でのカーソルを保存しておく
            defaultCursor = moveForm.Cursor;

            // イベントハンドラを追加
            moveForm.MouseDown += new MouseEventHandler(moveForm_MouseDown);
            moveForm.MouseMove += new MouseEventHandler(moveForm_MouseMove);
            moveForm.MouseUp += new MouseEventHandler(moveForm_MouseUp);
        }

        /// <summary>
        /// マウスボタン押下イベントハンドラ
        /// </summary>
        void moveForm_MouseDown(object sender, MouseEventArgs e)
        {
            // 左クリック時のみ処理する。左クリックでなければ何もしない
            if ((e.Button & MouseButtons.Left) != MouseButtons.Left) return;

            // 移動が有効になる範囲
            // 例えばフォームの端から何ドットかをサイズ変更用の領域として使用する場合、
            // そこを避けるために使う。
            Rectangle moveArea = new Rectangle(
                noDragAreaWidth, noDragAreaWidth,
                moveForm.Width - (noDragAreaWidth * 2), moveForm.Height - (noDragAreaWidth * 2));

            // クリックした位置が移動が有効になる範囲であれば、移動中にする
            if (moveArea.Contains(e.Location))
            {
                // 移動中にする
                moveStatus = true;

                // クリックしたポイントを保存する
                lastMouseDownPoint = e.Location;

                // マウスキャプチャー
                moveForm.Capture = true;
            }
            else
            {
                moveStatus = false;
            }
        }

        /// <summary>
        /// マウス移動イベントハンドラ
        /// </summary>
        void moveForm_MouseMove(object sender, MouseEventArgs e)
        {
            // 移動中の場合のみ処理。移動中でなければ何もせず終わる
            if (moveStatus == false) return;

            // 左ボタン押下中のみ処理する。押下中ではないときは何もしない。
            if ((e.Button & MouseButtons.Left) != MouseButtons.Left) return;

            // マウスカーソルの変更
            moveForm.Cursor = Cursors.SizeAll;

            // フォームの移動
            if (this.isAdsorb)
            {
                // ウィンドウを吸着させる場合

                // 移動先のフォームの位置を計算しておく
                Rectangle newPosition = new Rectangle(
                    moveForm.Left + e.X - lastMouseDownPoint.X,
                    moveForm.Top + e.Y - lastMouseDownPoint.Y,
                    moveForm.Width, moveForm.Height);

                // 判定用のRECT(一時領域)
                Rectangle newRect = new Rectangle();

                // 作業領域の取得(この作業領域の内側に吸着する)
                Size area = new Size(
                    System.Windows.Forms.Screen.GetWorkingArea(moveForm).Width,
                    System.Windows.Forms.Screen.GetWorkingArea(moveForm).Height);

                // 画面端の判定用(画面の端の位置に、吸着するサイズ分のRECTを定義する)
                Rectangle rectLeft = new Rectangle(0, 0, adsorbGap.Width, area.Width);
                Rectangle rectTop = new Rectangle(0, 0, area.Width, adsorbGap.Height);
                Rectangle rectRight = new Rectangle(area.Width - adsorbGap.Width, 0, adsorbGap.Width, area.Height);
                Rectangle rectBottom = new Rectangle(0, area.Height - adsorbGap.Height, area.Width, adsorbGap.Height);

                // 衝突判定
                // 判定用のRECTを自分のウィンドウの隅に重ねるように移動し、
                // 画面端の判定用のRECTと衝突しているかチェックする。
                // 衝突していた場合は、吸着させるように移動する

                // 左端衝突判定
                {
                    newRect = newPosition;
                    newRect.Width = adsorbGap.Width;

                    if (newRect.IntersectsWith(rectLeft))
                    {
                        // 左端に吸着させる
                        newPosition.X = 0;
                    }
                }
                // 右端衝突判定
                {
                    newRect = newPosition;
                    newRect.X = newPosition.Right - adsorbGap.Width;  // ウィンドウの右隅
                    newRect.Width = adsorbGap.Width;

                    if (newRect.IntersectsWith(rectRight))
                    {
                        // 右端に吸着させる
                        newPosition.X = area.Width - moveForm.Width;
                    }
                }
                // 上端衝突判定
                {
                    newRect = newPosition;
                    newRect.Height = adsorbGap.Height;

                    if (newRect.IntersectsWith(rectTop))
                    {
                        // 上端に吸着させる
                        newPosition.Y = 0;
                    }
                }
                // 下端衝突判定
                {
                    newRect = newPosition;
                    newRect.Y = newPosition.Bottom - adsorbGap.Height; // ウィンドウの下端
                    newRect.Height = adsorbGap.Height;

                    if (newRect.IntersectsWith(rectBottom))
                    {
                        // 下端に吸着させる
                        newPosition.Y = area.Height - moveForm.Height;
                    }
                }

                // 実際に移動させる
                moveForm.Left = newPosition.Left;
                moveForm.Top = newPosition.Top;
            }
            else
            {
                // 通常の移動の場合
                moveForm.Left += e.X - lastMouseDownPoint.X;
                moveForm.Top += e.Y - lastMouseDownPoint.Y;
            }
        }

        /// <summary>
        /// マウスボタン押上イベントハンドラ
        /// </summary>
        void moveForm_MouseUp(object sender, MouseEventArgs e)
        {
            // 左ボタンのみ処理する。左ボタンではないときは何もしない。
            if ((e.Button & MouseButtons.Left) != MouseButtons.Left) return;

            // 移動を終了する
            moveStatus = false;

            // マウスキャプチャーを終了する
            moveForm.Capture = false;

            // マウスカーソルを戻す
            moveForm.Cursor = defaultCursor;
        }
    }
}

使い方

// 変数を定義しておき 
FormDragMover formMover;
 
private void InitializeForm()
{
    // Formのイニシャル処理で生成する 
    formMover = new FormDragMover(this, 8, true, new Size(16, 16));
}

第3引数に、吸着させる機能を有効にするため、trueを指定。 第4引数に、吸着させる距離(マージン)を指定します。

[2011-04-10追記] moveForm_MouseUpにマウスカーソルを戻す処理を追加しました。

良かったらクリックしてください
にほんブログ村 IT技術ブログ プログラム・プログラマーへ  人気ブログランキングへ

posted by among at 22:07 | Comment(1) | TrackBack(0) | C#