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

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

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.92410 の関連記事表示

<< 0 >>
■92410  消えないフォーム
□投稿者/ 犬夜叉 -(2019/09/24(Tue) 08:53:27)

    分類:[.NET 全般] 

    環境です。

    Windwos10
    VisualStudio2017
    C#


    ボタン1つを装備しtForm1を作ります。
    private void button1_Click(object sender, EventArgs e)
    {
     From2 frm = new From2();
     frm.Show();
    }

    Form2を作ります。
    public From2()
    {
     InitializeComponent();
    }

    private void From2_Load(object sender, EventArgs e)
    {
     this.Capture = true;
    }

    private void From2_MouseDown(object sender, MouseEventArgs e)
    {
     if(!GetWindowContainState(this)) this.Close();
    }

    private bool GetWindowContainState(Control ctrl)
    {
     Rectangle rect = GetWindowRectangle(ctrl);
     Point mouseScreenPos = Control.MousePosition;
     Point mouseClientPos = ctrl.PointToClient(mouseScreenPos);
     return rect.Contains(mouseClientPos);
    }

    private Rectangle GetWindowRectangle(Control ctrl)
    {
     Debug.Assert(ctrl.Bounds.Location == ctrl.Location);
     Debug.Assert(ctrl.Location == new Point(ctrl.Left, ctrl.Top));
     Debug.Assert(ctrl.Bounds.Size == ctrl.Size);
     Debug.Assert(ctrl.Size == new Size(ctrl.Right - ctrl.Left, ctrl.Bottom - ctrl.Top));

     if (ctrl is Form)
     {
      Point winRectLocation = ctrl.PointToClient(ctrl.Bounds.Location);
      Rectangle winRect = new Rectangle(winRectLocation, ctrl.Bounds.Size);
      return winRect;
     }
     else
     {
      Point screenLocation = ctrl.Parent.PointToScreen(ctrl.Bounds.Location);
      Point winRectLocation = ctrl.PointToClient(screenLocation);
      Rectangle winRect = new Rectangle(winRectLocation, ctrl.Bounds.Size);
      return winRect;
     }
    }

    この状態で実行しForm1を表示し、Form1のボタンを押してForm2を表示させます。
    その状態でFomr2以外の場所をクリックするとForm2は消えるのですが、
    Form2をクリックすると、消えなくなります。
    Form2以外をクリックするとForm2が消えるようにするにはどうすればよいのでしょうか?

親記事 /過去ログ159より / 関連記事表示
削除チェック/

■92414  Re[1]: 消えないフォーム
□投稿者/ 魔界の仮面弁士 -(2019/09/24(Tue) 09:54:17)
    2019/09/24(Tue) 10:37:43 編集(投稿者)

    No92410 (犬夜叉 さん) に返信
    > Form2を作ります。
    > public From2()

    ありがちなミスですね。
    From / Form とか Namae / Name とか Expect / Except とか Drag / Drug とか…。


    > その状態でFomr2以外の場所をクリックすると

    こっちのスペルミスは珍しいかも。(^^;


    > private void From2_Load(object sender, EventArgs e)
    > {
    >  this.Capture = true;
    > }

    こんなことをしたら、Form2 上に TextBox があっても、
    その上にマウスを重ねても「I カーソル」になりませんよね。

    Form2 上のコントロールを選択する場合も、
    1 回目のクリックが捨てられてしまい、2 回目のクリックで
    ようやくアクティブになる状態となり、操作性が悪くなりそうですが…。


    > Form2をクリックすると、消えなくなります。

    最初のクリックで消えないのは、
     GetWindowContainState(this)
    で領域内かどうかを判定しているからですね。
    常に消したいなら、領域判定せずに Close(); すれば消えます。

    領域内であれ領域外であれ、一度クリックすれば、キャプチャーは終了するので、
    それ以降はもう、領域外操作では MouseDown イベントは発生しません。
    再 Capture するなどしない限りは。


    > Form2以外をクリックするとForm2が消えるようにするにはどうすればよいのでしょうか?

    RawInput を捉えるとか。

    // Install-Package SharpDX.RawInput

    あるいはマウスクリックに拘らないなら、Deactivate イベントで。

    public partial class Form2 : Form
    {
     public Form2()
     {
      InitializeComponent();
     }
     private void Form2_Load(object sender, EventArgs e)
     {
      Deactivate += delegate { Close(); };
     }
    }
記事No.92410 のレス /過去ログ159より / 関連記事表示
削除チェック/

■92415  Re[2]: 消えないフォーム
□投稿者/ 犬夜叉 -(2019/09/24(Tue) 10:32:59)
    No92414 (魔界の仮面弁士 さん) に返信

    > RawInput を捉えるとか。

    RawInput ってなんですか?
    どうやって使うのでしょうか?
記事No.92410 のレス /過去ログ159より / 関連記事表示
削除チェック/

■92418  Re[3]: 消えないフォーム
□投稿者/ 魔界の仮面弁士 -(2019/09/24(Tue) 12:16:32)
    No92415 (犬夜叉 さん) に返信
    >> RawInput を捉えるとか。
    > RawInput ってなんですか?

    DirectX の機能で、入力デバイスから得られる情報を直接受け取るものです。
    自アプリがアクティブではない状態で、キーボードやマウス等の入力を受け取る場合にも使えます。


    > どうやって使うのでしょうか?
    メニューに [ツール]-[NuGet パッケージ マネージャー] がありませんか?

    もしあれば、[ソリューションの NuGet パッケージの管理] ダイアログで
    [参照] タブで「SharpDX.RawInput」と検索して、自プロジェクトにインストールすれば
    参照設定が行われます。

    もしくは、パッケージ マネージャ コンソールにて
     Install-Package SharpDX.RawInput
    のコマンドを入力する方法でも OK です。

    https://www.nuget.org/packages/SharpDX.RawInput/


    たとえばこんな感じ。


    using SharpDX.RawInput;
    using SharpDX.Multimedia;
    public partial class Form1 : Form
    {
      public Form1()
      {
        InitializeComponent();
      }

      private void Form1_Load(object sender, EventArgs e)
      {
        // 自フォーム外のマウス操作も捉える
        Device.RegisterDevice(UsagePage.Generic, UsageId.GenericMouse, DeviceFlags.InputSink, Handle);
        Device.MouseInput += Device_MouseInput;
      }

      private void Device_MouseInput(object sender, MouseInputEventArgs e)
      {
        // こちらはカーソルの絶対座標
        label1.Text = Cursor.Position.ToString();

        // こちらはマウスの相対的な動作
        // (1px 未満の微細な動きも捉えられるが、絶対座標は得られない)
        var sb = new StringBuilder();
        sb.AppendFormat("OffsetXY=({0}, {1})", e.X, e.Y);
        if(e.WheelDelta !=0)
        {
          sb.AppendFormat(", Wheel={0}", e.WheelDelta);
        }
        if (e.ButtonFlags != MouseButtonFlags.None)
        {
          sb.AppendFormat(", Button={0}", e.ButtonFlags);
        }
        listBox1.Items.Insert(0, sb.ToString());

        // 左ボタンが押された時に、フォーム外の座標だったらフォームを閉じる
        if (e.ButtonFlags == MouseButtonFlags.LeftButtonDown)
        {
          if(!IsDisposed && !GetWindowContainState(this))
          {
            Close();
          }
        }
      }
    }
記事No.92410 のレス /過去ログ159より / 関連記事表示
削除チェック/

■92419  Re[4]: 消えないフォーム
□投稿者/ 犬夜叉 -(2019/09/24(Tue) 13:11:03)
    No92418 (魔界の仮面弁士 さん) に返信

    .Net4.0 環境下では使えないようなのですが。
記事No.92410 のレス /過去ログ159より / 関連記事表示
削除チェック/

■92420  Re[5]: 消えないフォーム
□投稿者/ 魔界の仮面弁士 -(2019/09/24(Tue) 13:33:20)
    No92419 (犬夜叉 さん) に返信
    > .Net4.0 環境下では使えないようなのですが。

    .NET Framework 4 で開発されているとは、どこにも書かれていなかったような…?

    とりあえず当方では、ターゲット フレームワークを「.NET Framework 4」にした上で、
    先の「非アクティブ時に閉じる」手法と、「SharpDX.RawInput で判定して閉じる手法」の
    いずれの手法も動作することを確認できました。


    そちらの環境では、どちらの方法とも駄目だったのでしょうか?
    それとも RawInput の方だけが NG だったのでしょうか?


    ちなみに SharpDX.RawInput バージョン 4.2.0 には、
     \net40\SharpDX.dll
     \net45\SharpDX.dll
    の 2 種類が存在しますので、参照先のパスが正しいかも確認してみてください。
    (その依存関係にある SharpDX バージョン 4.2.0 にも、フレームワーク別にアセンブリがあります)
記事No.92410 のレス /過去ログ159より / 関連記事表示
削除チェック/

■92421  Re[4]: 消えないフォーム
□投稿者/ 魔界の仮面弁士 -(2019/09/24(Tue) 14:44:27)
    No92418 (魔界の仮面弁士) に追記
    > if(!IsDisposed && !GetWindowContainState(this))
    > {
    >   Close();
    > }

    上記の GetWindowContainState は、犬夜叉さんが書かれたものを
    そのまま利用していますが、座標判定部分は自作メソッドを呼ばずに、
     if (!IsDisposed && !DesktopBounds.Contains(Cursor.Position))
    だけでも良さそうです。


    ところで、Form2 の座標に重なるように、別のウィンドウが(TopMost 状態などで)存在していた場合、
    その別ウィンドウをクリックした時に、Form2 は Close されるべきなのでしょうか?


    (1) クリック座標が Form2 の領域内だったのであれば、別ウィンドウをクリックしても、Form2 を Close させたくない。
    (2) 別ウィンドウをクリックしたのなら、現在座標は無関係で、常に Form2 を Close したい。


    もしも (1) を求めるのなら、RawInput の座標判定の方が良いでしょうし、
    (2) を求めるなら、非アクティブ時(Deactivate イベントまたは OnDeactivate メソッド)に
    Close させる方が良いと思います。要件によっては、両者併用というパターンもあるかも知れません。
記事No.92410 のレス /過去ログ159より / 関連記事表示
削除チェック/

■92422  Re[5]: 消えないフォーム
□投稿者/ 犬夜叉 -(2019/09/24(Tue) 15:40:19)
    2019/09/24(Tue) 15:42:04 編集(投稿者)

    No92421 (魔界の仮面弁士 さん) に返信

    開発環境では .Net 4.5.2 を使用しています。
    properties の設定は以下の通り変更しています。

    @ターゲットフレームワーク 4
    Aプラットフォームターゲット x86

    これをリビルドしたのですが
    以下の警告が表示され実行されませんでした。
    RawInputを4.0用にすることができるのでしょうか?


    警告 プライマリ参照 "SharpDX.RawInput, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL" は、".NETFramework,Version=v4.5" フレームワークに対して作成されたアセンブリ "SharpDX, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1" に間接的に依存するため、解決できませんでした。これは現在ターゲットされているフレームワーク ".NETFramework,Version=v4.0" よりも新しいバージョンです。 WindowsFormsApp2
記事No.92410 のレス /過去ログ159より / 関連記事表示
削除チェック/

■92423  Re[6]: 消えないフォーム
□投稿者/ 魔界の仮面弁士 -(2019/09/24(Tue) 15:56:16)
    No92422 (犬夜叉 さん) に返信
    > これをリビルドしたのですが
    > 以下の警告が表示され実行されませんでした。
    > RawInputを4.0用にすることができるのでしょうか?

    NuGet 後に、ターゲット フレームワーク を変更したのではないでしょうか。
    だとしたら、リビルドしただけでは依存関係が解決されません。

    NuGet 管理画面から該当するライブラリを一度アンインストールし、
    [ビルド]-[クリーン] 作業を行ってから、もう一度 NuGet をやりなおしてみてください。
記事No.92410 のレス /過去ログ159より / 関連記事表示
削除チェック/

■92424  Re[7]: 消えないフォーム
□投稿者/ 犬夜叉 -(2019/09/24(Tue) 16:07:06)
    No92423 (魔界の仮面弁士 さん) に返信
    アンインストール
    ビルドクリーン
    インストール
    ビルド

    しましたが、実行されませんでした。
    表示されるのは以下の警告だけです。
    でもフォームが表示されません。

    警告 プライマリ参照 "SharpDX, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL" は、".NETFramework,Version=v4.5" フレームワークに対して作成されているため、解決できませんでした。これは現在ターゲットされているフレームワーク ".NETFramework,Version=v4.0" よりも新しいバージョンです。

    警告 プライマリ参照 "SharpDX.RawInput, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL" は、".NETFramework,Version=v4.5" フレームワークに対して作成されたアセンブリ "SharpDX, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1" に間接的に依存するため、解決できませんでした。これは現在ターゲットされているフレームワーク ".NETFramework,Version=v4.0" よりも新しいバージョンです。

    警告 一部の NuGet パッケージが現在のターゲット フレームワークとは異なるターゲット フレームワークを使用してインストールされていて、再インストールが必要になる可能性があります。詳細については、http://docs.nuget.org/docs/workflows/reinstalling-packages を参照してください。影響を受けるパッケージ: SharpDX
記事No.92410 のレス /過去ログ159より / 関連記事表示
削除チェック/

■92426  Re[8]: 消えないフォーム
□投稿者/ 魔界の仮面弁士 -(2019/09/24(Tue) 16:22:26)
    No92424 (犬夜叉 さん) に返信
    > 表示されるのは以下の警告だけです。
    > でもフォームが表示されません。

    (1) SharpDX.RawInput をアンインストールします。

    (2) 続いて、SharpDX をアンインストールします。

    (3) ソリューション エクスプローラーで、[WindowsFormsApp2] の
     プロジェクト(≠ソリューションではなく)を右クリックし、
     [クリーン]を選択します。

    (4) [WindowsFormsApp2] - [参照] の配下に、SharpDX と SharpDX.RawInput が
     存在していないことを確認します。

    (5) [WindowsFormsApp2] - [Properties] をダブルクリックし、
     [アプリケーション] タブの ターゲット フレームワークが
     「.NET Framework 4」になっていることを確認します。

    (6) 念のため、ソリューションを一度閉じてから、再度開きなおします。(多分不要だけど)

    (7) NuGet パッケージ マネージャーから、SharpDX.RawInput 4.2.0 をインストールします。
     このとき、出力ウィンドウの 出力元: [パッケージマネージャー] には、
     このようなメッセージが出力されるはずです。


    '.NETFramework,Version=v4.0' を対象とするプロジェクト 'WindowsFormsApp2' に関して、パッケージ 'SharpDX.RawInput.4.2.0' の依存関係情報の収集を試行しています
    〜〜〜中略〜〜〜
    パッケージ 'SharpDX.RawInput.4.2.0' を 'packages.config' に追加しました
    'SharpDX.RawInput 4.2.0' が WindowsFormsApp2に正常にインストールされました


    (8) [WindowsFormsApp2] の下にある packages.config は、下記の内容になっているはずです。

    <?xml version="1.0" encoding="utf-8"?>
    <packages>
    <package id="SharpDX" version="4.2.0" targetFramework="net40" />
    <package id="SharpDX.RawInput" version="4.2.0" targetFramework="net40" />
    </packages>


    (9) [WindowsFormsApp2] - [参照] にある、SharpDX.RawInput を選択してプロパティを見ると、
    「パス」欄にあるファイル名は、下記のように net40 フォルダー内のものを指しているはずです。


    C:\〜〜〜\WindowsFormsApp2\packages\SharpDX.RawInput.4.2.0\lib\net40\SharpDX.RawInput.dll


    (10) 同様に、SharpDX も net40 側が参照されていることを確認し、
    プロジェクトをビルド・実行します。これで当方では問題なく動作しています。
記事No.92410 のレス /過去ログ159より / 関連記事表示
削除チェック/

■92425  Re[8]: 消えないフォーム
□投稿者/ 犬夜叉 -(2019/09/24(Tue) 16:17:01)
    No92423 (魔界の仮面弁士 さん) に返信

    すみませんでした。
    SharpDX.RawInput だけでなく
    SharpDx もアンインストールしないといけなかったようです。

    2つアンインストールして、
    SharpDX.RawInput をインストールすると自動的に
    SharpDx もインストールされ
    ビルドできるようになりました。

記事No.92410 のレス /過去ログ159より / 関連記事表示
削除チェック/

■92429  Re[9]: 消えないフォーム
□投稿者/ 犬夜叉 -(2019/09/25(Wed) 16:34:46)
    No92425 (犬夜叉 さん) に返信

    できました。
    ありがとうございました。


記事No.92410 のレス / END /過去ログ159より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -