DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ControlBoxプロパティをFalseにして、フォームを固定する方法

環境/言語:[OS : Windows XP Professional / 言語 : Visual Basic .NET / .NET Framework : 2.0]
分類:[.NET]

【解決したい問題】

2つの画面を1つのフォームのように見せるために、
子画面のほうを、タイトルバーをドラッグしてもフォームが移動しないようにし、なおかつ、×ボタンも表示しないようにしたいのです。

フォームを固定する方法については、以下のページに載っていて
実現できました。
http://dobon.net/vb/bbs/log3-19/11830.html
これで、実現できたと思っていたのですが、
×ボタンを表示させないために、ControlBox = False とすると、
フォームが移動できるようになってしまいました。

×ボタンを表示させず、フォームを固定する方法はあるのでしょうか?
■No21507に返信(hana_yumiさんの記事)
> 2つの画面を1つのフォームのように見せるために、
> 子画面のほうを、タイトルバーをドラッグしてもフォームが移動しないようにし、なおかつ、×ボタンも表示しないようにしたいのです。
> ×ボタンを表示させないために、ControlBox = False とすると、
> フォームが移動できるようになってしまいました。
> ×ボタンを表示させず、フォームを固定する方法はあるのでしょうか?

フォームを移動できないようにする
http://jeanne.wankuma.com/tips/form/moveable.html
http://dobon.net/vb/dotnet/form/formregion.html
2008/02/27(Wed) 10:55:07 編集(投稿者)
2008/02/27(Wed) 10:36:01 編集(投稿者)
2008/02/27(Wed) 01:14:23 編集(投稿者)

(変更履歴)
 1.Form1のprivate void test()内に以下のコードを追加
    frm2.Owner = frm1;
 2.Form1_1内に protected override void OnLocationChanged を追加
 3.上記2.を削除、Form1_1内の protected override void WndProc のif文を変更
(ここまで変更履歴)
 
はじめまして、引っ込んだ略と申します。
 
 # 引っ込んだ(略) → 引っ込んだ略 にハンドルネームを変更いたします。
 
 やじゅさんに先を越されてしまいましたが、(汗
 Formのサイズ変更対策も施してみました。
 以下のコードで試してみて下さい。
 ※ コードがC#ですが、ご了承下さい。
 
 参考文献
  http://dobon.net/vb/dotnet/form/fixformposition.html
 
    public partial class Form1 : Form
    {
        // デザイナでbutton1を配置してください。
        private void button1_Click(object sender, EventArgs e)
        {
            test();
        }
        // 移動できないFormを2つ並べて表示してみる
        private void test()
        {
            Form1_1 frm1 = new Form1_1("frm1", 300, 200);// ←タイトル文字列、幅、高さを指定
            Form1_1 frm2 = new Form1_1("frm2", 300, 200);
            frm1.Show();
            frm2.Show();
            frm2.Owner = frm1; [追記1]この行を追加
            frm2.Location = new Point(frm1.Right, frm1.Top);
        }
    }
 
    // 移動できないForm
    public class Form1_1 : Form
    {
        private const int WM_SYSCOMMAND = 0x0112;
        private const int SC_MOVE = 0xF010;
        private const int SC_MAXIMIZE = 0xF030; // [追記3]この文を追加

        public Form1_1(String title,int wd,int ht)
        {
            this.Text = title;
            this.ControlBox = false;
            this.Size = new Size(wd, ht);
            this.MinimumSize = this.Size;
            this.MaximumSize = this.Size;
        }
        // ↓[追記2]このメソッドを追加 → [追記3]やはり不要なので削除
        //protected override void OnLocationChanged(EventArgs e)
        //{
        //    this.MaximizedBounds = this.Bounds;
        //    base.OnLocationChanged(e);
        //}
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_SYSCOMMAND &&
               ( (m.WParam.ToInt32() & 0xFFF0) == SC_MOVE ||
                 (m.WParam.ToInt32() & 0xFFF0) == SC_MAXIMIZE )) // [追記3]if文の()内の式を変更
            {
                m.Result = IntPtr.Zero;
                return;
            }
 
            base.WndProc(ref m);
        }
    }
 
以上です。
やじゅさん

早速、回答いただきありがとうございました。
紹介してくださったページのコードを実装してみたところ、正しく動作しました。
ありがとうございました。

引っ込んだ略さん、はじめまして。
サンプルコードを書いていただき、ありがとうございました。
VBで、実装し、正しく動作しました。
VBのコードを載せておきます。ありがとうございました。

親画面テストボタン
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim frm1 As Form1 = New Form1("frm1", 300, 200) '←タイトル文字列、幅、高さを指定
Dim frm2 As Form1 = New Form1("frm2", 300, 200)
frm1.Show()
frm2.Show()
frm2.Owner = frm1 ' [追記]この行を追加
frm2.Location = New Point(frm1.Right, frm1.Top)
End Sub


'移動できないForm
Public Class Form1
Public Sub New(ByVal title As String, ByVal wd As Integer, ByVal ht As Integer)
MyBase.New()

' この呼び出しは Windows フォーム デザイナで必要です。
InitializeComponent()
Me.Text = title
Me.ControlBox = False
Me.Size = New Size(wd, ht)
Me.MinimumSize = Me.Size
Me.MaximumSize = Me.Size

End Sub

Protected Overrides Sub WndProc(ByRef m As Message)
Const WM_SYSCOMMAND As Integer = &H112
Const SC_MOVE As Integer = &HF010
Const SC_MASK As Integer = &HFFF0

' フォームの移動を捕捉したら以降の制御をカットする
If m.Msg = WM_SYSCOMMAND AndAlso (m.WParam.ToInt32() And SC_MASK) = SC_MOVE Then
m.Result = IntPtr.Zero
Return
End If

' 基本クラスのメソッドを実行する
MyBase.WndProc(m)
End Sub
End Class

以上です。
引っ込んだ略と申します。
 
 私のコードにミスがあったため(Form最大化時の挙動)、修正いたしました。失礼しました。

以上です。
■No21519に返信(引っ込んだ略さんの記事)
引っ込んだ略さん

いろいろと調べていただき、ありがとうございました。
大変、参考になりました。

DOBON.NET | プログラミング道 | プログラミング掲示板