C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

親フォームをアクティブにできなくする

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■100915 / inTopicNo.1)  親フォームをアクティブにできなくする
  
□投稿者/ ミミズ (1回)-(2022/11/26(Sat) 12:22:09)

分類:[.NET 全般] 




C#2017に関する質問です。

ある親フォームの上に子フォームを表示している間で
親フォームをクリックしてもフォーカスおよびコントロール操作できないようにしたいのですが、
普通なら、ShowDialogを使って子フォームを表示すれば、
このようなことが実現できます。

しかし、いろいろな事情があって、
ShowDialogではなく、Form.Showでこれを実現したいのですが可能でしょうか?

Form.Showでも常に前面表示はできるのですが、
親フォームをクリックするとコントロールを操作できてしまいます。
Form.Enabled = Falseにすると操作できなくなるのですが、
外観がグレー色になってしまうため、
外観をそのままでコントロール操作できないようにすることって可能でしょうか?




引用返信 編集キー/
■100917 / inTopicNo.2)  Re[1]: 親フォームをアクティブにできなくする
□投稿者/ 魔界の仮面弁士 (3496回)-(2022/11/26(Sat) 14:32:54)
No100915 (ミミズ さん) に返信
> Form.Enabled = Falseにすると操作できなくなるのですが、
(false 表記では無く False 表記だったので、Visual Basic なのかと一瞬誤解しちゃいました)


> 外観がグレー色になってしまうため、
> 外観をそのままでコントロール操作できないようにすることって可能でしょうか?

Enabled = true のまま、WM_SETREDRAW で再描画を止めてしまう…という手はあります。
ただし、親フォームは Visible = false 相当の動作になってしまいますが。


public partial class Form1 : Form
{
  public Form1()
  {
    InitializeComponent();
  }

  private void button1_Click(object sender, EventArgs e)
  {
    var f = new Form2();
    f.Shown += delegate { SetRedraw(false); };
    f.FormClosing += delegate { SetRedraw(true); Activate(); };
    f.Show(this);
  }

  private void SetRedraw(bool redraw)
  {
    const int WM_SETREDRAW = 0xB;
    var m = Message.Create(panel1.Handle, WM_SETREDRAW, new IntPtr(redraw ? 1 : 0), IntPtr.Zero);
    DefWndProc(ref m);
  }
}
引用返信 編集キー/
■100918 / inTopicNo.3)  Re[2]: 親フォームをアクティブにできなくする
□投稿者/ ミミズ (2回)-(2022/11/26(Sat) 15:18:45)
ありがとうございます。

Formを継承して新しいクラスを作らずに
Formをそのまま使う方法はないでしょうか?

引用返信 編集キー/
■100919 / inTopicNo.4)  Re[3]: 親フォームをアクティブにできなくする
□投稿者/ Azulean (1258回)-(2022/11/26(Sat) 15:41:56)
No100918 (ミミズ さん) に返信
> Formを継承して新しいクラスを作らずに
> Formをそのまま使う方法はないでしょうか?

普通にフォームを作った場合、「Form を継承したクラス」を作ることになりますが、そうしたことをしていないんですか…?
なぜ、「Form を継承して新しいクラスを作らずに」と言われるのですか?
そういった背景を示さず、トリッキーな方法を教えてと言われても、答えを得づらくなるでしょう。

もっとも、魔界の仮面弁士さんのサンプルは「Form 継承したクラスを作らなくても書ける範囲のサンプル」ですので、意味を理解して取り出せば良いかと。
-----
そもそもとして「ShowDialog は親を操作させない表示方法」であり、逆に言えば、「親を操作させたくないなら ShowDialog を使う」のが普通です。
なぜ、ShowDialog だとダメなんですか?
引用返信 編集キー/
■100920 / inTopicNo.5)  Re[2]: 親フォームをアクティブにできなくする
□投稿者/ 魔界の仮面弁士 (3497回)-(2022/11/26(Sat) 17:37:19)
No100917 (魔界の仮面弁士) に追記
> WM_SETREDRAW で再描画を止めてしまう…という手はあります。

> const int WM_SETREDRAW = 0xB;
> var m = Message.Create(panel1.Handle, WM_SETREDRAW, new IntPtr(redraw ? 1 : 0), IntPtr.Zero);
> DefWndProc(ref m);

すみません、上記は転記ミスです。
WM_SETREDRAW を送出する所は、「panel1.Handle」に対してではなく、
ただの「Handle」に対して投げるつもりでした。

Form 自体の再描画を無効化した場合、フォームをクリックしても、
まるで Visible = false のように、下のウィンドウが操作される動作になります。


Form の背面要素が操作されてしまうことを避ける場合は、代替策として
Form1 いっぱいに Panel を貼っておき、その上にコントロールを配置することで、
背面操作が行えてしまう状況を防げるのではないか…という意図で、実験的に
panel1.Handle を指定していたのですが、その時の中途半端なコードを貼ってしまったようで。

(panel1.Handle の場合、Form1 の移動やリサイズなども封じる必要がありますね…)
引用返信 編集キー/
■100921 / inTopicNo.6)  Re[1]: 親フォームをアクティブにできなくする
□投稿者/ KOZ (357回)-(2022/11/26(Sat) 21:27:18)
No100915 (ミミズ さん) に返信
> Form.Showでも常に前面表示はできるのですが、
> 親フォームをクリックするとコントロールを操作できてしまいます。
> Form.Enabled = Falseにすると操作できなくなるのですが、
> 外観がグレー色になってしまうため、
> 外観をそのままでコントロール操作できないようにすることって可能でしょうか?

EnableWindow を使ったらどうでしょう?

【Form1.cs】
using System;
using System.Windows.Forms;

public partial class Form1 : Form
{
    public Form1() {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e) {
        var f = new Form2();
        f.Show(this);
    }
}


【Form2.cs】
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public partial class Form2 : Form
{
    public Form2() {
        InitializeComponent();
    }

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool EnableWindow(IntPtr hWnd, bool bEnable);

    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
        if (Owner != null) {
            EnableWindow(Owner.Handle, false);
        }
    }

    protected override void OnFormClosed(FormClosedEventArgs e) {
        base.OnFormClosed(e);
        if (Owner != null) {
            EnableWindow(Owner.Handle, true);
            Owner.Activate();
        }
    }
}

引用返信 編集キー/
■100927 / inTopicNo.7)  Re[2]: 親フォームをアクティブにできなくする
□投稿者/ ミミズ (3回)-(2022/11/27(Sun) 20:21:11)
No100921 (KOZ さん) に返信


まさに、これです。
これを探していました。

どうもありがとうございました。

解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ