フォームの端をドラッグしてサイズ変更する機能を提供するクラス(C#用)
C#のフォームは標準でフォームの端をドラッグしてサイズ変更が可能ですが、フォームのスタイルをサイズ変更が出来ないスタイルに変更したとしても、このクラスを使ってサイズ変更させることが可能です。
具体的には、FormBorderStyleをNoneにしたフォームでも、枠をドラッグすることでサイズ変更が可能になります。
色々ツッコミ所はあるかもしれませんが、ご容赦を。
(たぶん、もっとスマートに書けるはずです)
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; /// <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; // 現時点でのカーソルを保存しておく 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 (e.Button == MouseButtons.Left) { // ドラッグにより移動した距離を計算 int diffX = e.X - lastMouseDownPoint.X; int diffY = e.Y - lastMouseDownPoint.Y; // 上 if ((resizeStatus & ResizeDirection.Top) == ResizeDirection.Top) { // まず、ドラッグした距離分だけサイズを変更する // その後、フォームの位置を調整する // (順番を逆にすると、ちょっとちらつく?) int h = resizeForm.Height; resizeForm.Height -= diffY; resizeForm.Top += h - resizeForm.Height; } // 左 if ((resizeStatus & ResizeDirection.Left) == ResizeDirection.Left) { // 上と同じ int w = resizeForm.Width; resizeForm.Width -= diffX; resizeForm.Left += w - resizeForm.Width; } // 下 if ((resizeStatus & ResizeDirection.Bottom) == ResizeDirection.Bottom) { // マウスクリックした時点のサイズを基点として、 // ドラッグした距離分だけサイズを変更する resizeForm.Height = lastMouseDownSize.Height + diffY; } // 右 if ((resizeStatus & ResizeDirection.Right) == ResizeDirection.Right) { // マウスクリックした時点のサイズを基点として、 // ドラッグした距離分だけサイズを変更する resizeForm.Width = lastMouseDownSize.Width + diffX; } } } /// <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); }
第2引数は、サイズ変更を許す位置を指定します。
第3引数は、ドラッグを有効にする範囲を、フォームの端からの距離で指定します。
例では、フォームの端から8ドット分がドラッグが有効な範囲になります。
フォームをドラッグして移動させる機能を提供するクラスd:id:among_ev:20110306と一緒に使う場合は、下記のようにします。
// 両方の変数を定義しておき FormDragResizer formResizer; FormDragMover formMover; private void InitializeForm() { // Formのイニシャル処理で生成する formResizer = new FormDragResizer(this, FormDragResizer.ResizeDirection.All, 8); formMover = new FormDragMover(this, 8); }
FormDragResizerとFormDragMoverのマージンは同じ値にするか、FormDragMoverのマージンの方を大きくする必要があります。
フォームをドラッグして移動させる機能を提供するクラス(C#用)
以前に『フォームをドラッグして移動させる方法』d:id:among_ev:20101023という記事を書きましたが、この機能をクラス化したので公開します。
色々ツッコミ所はあるかもしれませんが、ご容赦を。
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; /// <summary> /// コンストラクタ /// </summary> /// <param name="moveForm">移動の対象となるフォーム</param> /// <param name="noDragAreaWidth">ドラッグを無効とする幅</param> public FormDragMover(Form moveForm, int noDragAreaWidth) { this.moveForm = moveForm; this.noDragAreaWidth = noDragAreaWidth; // 現時点でのカーソルを保存しておく 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; // フォームの移動 //*//通常の場合 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; } } }
使い方
// 変数を定義しておき FormDragMover formMover; private void InitializeForm() { // Formのイニシャル処理で生成する formMover = new FormDragMover(this, 8); }
第2引数はドラッグを有効にする範囲を、フォームの端からの距離(マージン)で指定します。
例では、フォームの端から8ドットはドラッグしても移動しません。
これは、フォームの枠をドラッグしてサイズ変更をさせるためです。
前バージョンの設定を引き継ぐ方法(C#用メモ)
C#でアプリケーションの設定を保存するにはApplicationSettingsBaseを利用するのが簡単ですが、この設定はアプリケーションのバージョン毎に設定を持つため、バージョンアップ時には前バージョンの設定を引き継ぐ必要があります。
単に引き継ぐだけならUpgrade()を実行すれば良いのですが、これだけだと起動するごとに前バージョンの設定を読み込んでしまい現行バージョンの設定が上書きされてしまうため、Upgradeを実行したかどうかを判断させる必要があります。
まず、「Upgradeを実行したかどうか」の情報をSettingsへ追加します。
bool型で、名前は“IsUpgrade”、初期値はfalseとします。
次に、アプリケーションのイニシャル処理で下記のようにします。
// 前バージョンからのUpgradeを実行していないときは、Upgradeを実施する if (Properties.Settings.Default.IsUpgrade == false) { // Upgradeを実行する Properties.Settings.Default.Upgrade(); // 「Upgradeを実行した」という情報を設定する Properties.Settings.Default.IsUpgrade = true; // 現行バージョンの設定を保存する Properties.Settings.Default.Save(); }
IsUpgradeの初期値はfalseにしたため、現バージョンで設定を保存していないとき、つまり、新規インストール時,前バージョンからUpgradeされていないとき,両方ともfalseになり、Upgradeが実行されます。
新規インストール時、つまり、前バージョンの情報がないときにUpgradeを実行しても、初期値が有効になるため問題ありません。
Twitter用クライアント TLBar (表示専用、.NET Framework 4使用、oAuth認証) Ver.0.0.0.5公開
概要
TLBarはTwitterの投稿を電光掲示板の流れる文字のように表示するクライアントです。
ツールの公開は自分のサイトでやることにしました。
今後ははてなでは紹介しないと思います。
ツールの詳細についてはこちらを参照してください。
TLBar - Twitterクライアント
Twitter用クライアント TLBar (表示専用、.NET Framework 4使用、oAuth認証) Ver.0.0.0.2公開
ダウンロード
動作環境
.NET Framework 4以降が導入されている必要があります。
下記サイトなどからインストールして下さい。
Download Microsoft .NET Framework 4 (Web インストーラー) from Official Microsoft Download Center
インストール方法
インストーラは付属しておりません。
ダウンロードした圧縮ファイルを適当なフォルダに展開してご利用ください。
使い方
最初にTLBarを起動すると、認証画面が開きます。ここで認証を行わないと使用できません。
認証されると画面の下の方に半透明の黒いウィンドウが表示されます。
ここに最新20件のタイムラインがスクロールされながら表示されます。
終了する場合は、ウィンドウ上で右クリック→終了(Q)を選ぶと、終了します。
認証に失敗していた場合は、ウィンドウ上で右クリック→認証設定(A)を選ぶと、もう一度認証画面が開くので、認証を行って下さい。
フォント&色設定
ウィンドウ上で右クリック→フォント&色設定(F)を選ぶと、フォント&色設定画面が開きます。
ここではフォントの種別・サイズ・スタイルと、文字の色、縁取りの色、を変更することができます。
更新履歴
Ver.0.0.0.2(2011/01/14)
- 描画するフォントの色、縁取りの色を選択できるように改造
- フォントの種類を選択できるように改造
- フォントを縁取り描画するように修正
- 描画処理を改善
- ウィンドウを画面端に吸着させるように修正
- 更新周期,更新件数,透明度を設定できるように改造
- 常に手前に表示するかどうかを選択できるように改造
Ver.0.0.0.1(2010/10/16)
- 暫定版公開
フォームを画面の端に吸着させる方法(C#用メモ)
フォームが画面の端に近づいたときに、端に吸着(スナップ)させる方法。
基本的には力業です。
『フォームをドラッグして移動させる方法(C#用メモ) - amongの雑記』で紹介した方法を使います。
フォームを直接動かすのではなく、フォームの移動先の領域を定義しておき、それが画面の端に吸着しそうな距離であれば、吸着させます。
吸着しそうな距離かどうかは、“フォームの移動先の領域”と“画面の端の領域”を定義して、領域が重なっているかチェックします。
今回はRectangleのIntersectsWithを使用しましたが、if文で判定しても構いません。
//マウスが動いたとき private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) { if ((e.Button & MouseButtons.Left) == MouseButtons.Left) { // 吸着するサイズ Size gap = new Size(16, 16); // 移動先のフォーム位置 Rectangle newPosition = new Rectangle( this.Left + e.X - mousePoint.X, this.Top + e.Y - mousePoint.Y, this.Width, this.Height); // 判定用のRECT Rectangle newRect = new Rectangle(); // 作業領域の取得(この作業領域の内側に吸着する) Size area = new Size( System.Windows.Forms.Screen.GetWorkingArea(this).Width, System.Windows.Forms.Screen.GetWorkingArea(this).Height); // 画面端の判定用(画面の端の位置に、吸着するサイズ分のRECTを定義する) Rectangle rectLeft = new Rectangle( 0, 0, gap.Width, area.Height); Rectangle rectTop = new Rectangle( 0, 0, area.Width, gap.Height); Rectangle rectRight = new Rectangle( area.Width - gap.Width, 0, gap.Width, area.Height); Rectangle rectBottom = new Rectangle( 0, area.Height - gap.Height, area.Width, gap.Height); // 衝突判定 // 判定用のRECTを自分のウィンドウの隅に重ねるように移動し、 // 画面端の判定用のRECTと衝突しているかチェックする。 // 衝突していた場合は、吸着させるように移動する // 左端衝突判定 { newRect = newPosition; newRect.Width = gap.Width; if (newRect.IntersectsWith(rectLeft)) { // 左端に吸着させる newPosition.X = 0; } } // 右端衝突判定 { newRect = newPosition; newRect.X = newPosition.Right - gap.Width; // ウィンドウの右隅 newRect.Width = gap.Width; if (newRect.IntersectsWith(rectRight)) { // 右端に吸着させる newPosition.X = area.Width - this.Width; } } // 上端衝突判定 { newRect = newPosition; newRect.Height = gap.Height; if (newRect.IntersectsWith(rectTop)) { // 上端に吸着させる newPosition.Y = 0; } } // 下端衝突判定 { newRect = newPosition; newRect.Y = newPosition.Bottom - gap.Height; // ウィンドウの下端 newRect.Height = gap.Height; if (newRect.IntersectsWith(rectBottom)) { // 下端に吸着させる newPosition.Y = area.Height - this.Height; } } // 実際に移動させる this.Left = newPosition.Left; this.Top = newPosition.Top; } }
フォームをドラッグして移動させる方法(C#用メモ)
フォームをマウスでドラッグして移動させる方法。
タイトルバーのないウィンドウも、この方法で移動させることが出来ます。
マウスのボタンが押されたとき、マウスポインタの位置を保存しておきます。
次にマウスが動いたとき、保存しておいたマウスポインタの位置と今の座標の差(移動距離)を計算し、フォームを移動させます。
// マウスポインタの位置を保存する private Point mousePoint; //マウスのボタンが押されたとき private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) { if ((e.Button & MouseButtons.Left) == MouseButtons.Left) { //位置を記憶する mousePoint = new Point(e.X, e.Y); } } //マウスが動いたとき private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) { if ((e.Button & MouseButtons.Left) == MouseButtons.Left) { this.Left += e.X - mousePoint.X; this.Top += e.Y - mousePoint.Y; } }
フォームの初期化処理で、MouseDown、MouseMoveイベントハンドラに、定義したメソッドを追加します。
// // コンストラクタ // public Form1() { : : // マウス移動イベントを追加 this.MouseDown += new MouseEventHandler(Form1_MouseDown); this.MouseMove += new MouseEventHandler(Form1_MouseMove); : : }
なお、この状態ではフォーム上でマウスをドラッグした場合は移動できますが、フォーム上のコントロールの上でドラッグした場合は移動できません。これを行うためには、そのコントロールのMouseDown、MouseMoveイベントハンドラにも、定義したメソッドを追加します。方法は、フォームのイベントハンドラに追加したのと同じです。