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

■34592 / 親記事)  新たにshowしたフォームでのボタンのクリック
  
□投稿者/ 未熟者ケンイチ 一般人(1回)-(2020/12/09(Wed) 14:29:09)
  • アイコン環境/言語:[c#] 
    分類:[.NET] 

    いつも参考にさせて頂いております。初めて投稿いたします。よろしくお願いいたします。

    c#にて

    Form_02 open_form = new Form_02 ();
    // フォーム表示
    open_form.Show (this);
    // 通信処理など、長時間かかる処理
    open_form.form_02_proc ();

    としました。するとForm_02が表示され、表示と同時にメソッドform_02_procが呼び出されます。ここまでは意図した通りです。

    Form_02にはボタンがいくつかありどのボタンも現象は同じで、最初のクリックでは反応せず、2回目のクリックでやっと処理が行われます。

    現在form_02_procはテスト用のコードが書かれており、
    internal void form_02_proc ()
    {
    Int32 loop = 0;
    // お仕事シミュレーション
    while ((15000 > loop) &&
    (false == exit_flag))
    {
    Application.DoEvents ();
    loop++;
    textBox_test.Text = loop.ToString ();
    }
    // 「戻る」クリックと同じとする
    p_result = RESULTS.ABORT;
    exit_flag = true;
    }
    となっております。

    上記「2度クリックしないとボタンの処理が起動しない」点について悩んでおり、諸先輩方のお力をお借りしたく投稿させていただきました。よろしくお願いいたします。
マルチポストを報告
違反を報告
引用返信 削除キー/
■34593 / ResNo.1)  Re[1]: 新たにshowしたフォームでのボタンのクリック
□投稿者/ 魔界の仮面弁士 大御所(1308回)-(2020/12/10(Thu) 13:06:48)
  • アイコンNo34592に返信(未熟者ケンイチさんの記事)
    > c#にて
    c# ではなく、
    C# ですね。

    > // 通信処理など、長時間かかる処理
    > open_form.form_02_proc ();
    長時間かかる処理を UI スレッドで実施してはいけません。

    ループ待機 + DoEvents での待ち合わせなどを行うのではなく、
    C# 5.0 以上であれば async 、それ未満なら BackgroundWorker を使うなどして
    時間のかかる処理を別スレッドに分離することを検討してみてください。
違反を報告
引用返信 削除キー/
■34596 / ResNo.2)  Re[2]: 新たにshowしたフォームでのボタンのクリック
□投稿者/ 未熟者ケンイチ 一般人(2回)-(2020/12/10(Thu) 17:01:16)
  • アイコン返信いただき、ありがとうございます。

    > ループ待機 + DoEvents での待ち合わせなどを行うのではなく、
    > C# 5.0 以上であれば async 、それ未満なら BackgroundWorker を使うなどして
    > 時間のかかる処理を別スレッドに分離することを検討してみてください。

    ご指摘いただいた通り、本番のコードはそのようにする予定です。
    ただ、このような方法でテスト用のコードを書き、表示と操作を行っているフォームがいくつもあるのですが、こちらで質問させていただいたもの「だけ」がこのようになるので、どこかのプロパティか、呼び出し方法の問題か、別件で色々いじったので「何かあるのかな?」と考えた次第です。

    ボタンやテキストボックス等のない、フォームをクリックした後でもボタンが効きますので、どうも「1回目のクリックでフォームがアクティブ?になり、2回目のクリックでボタンクリックが認識されている」感じです。

    誠に申し訳ありません。お手すきの方、もう少しお相手して頂けると幸いです。
違反を報告
引用返信 削除キー/
■34597 / ResNo.3)  Re[3]: 新たにshowしたフォームでのボタンのクリック
□投稿者/ 魔界の仮面弁士 大御所(1309回)-(2020/12/11(Fri) 10:17:43)
  • アイコンNo34596に返信(未熟者ケンイチさんの記事)
    > どうも「1回目のクリックでフォームがアクティブ?になり、
    > 2回目のクリックでボタンクリックが認識されている」感じです。

    そのあたりの動作は、コントロールによっても異なっており、
    たとえば Button と ToolStripButton でも異なる動作となります。
    具体的には、非アクティブフォームの ToolStripButton をクリックした場合、
    初回はボタンが動作せず、単にフォームがアクティブ化するだけで、
    2 回目のクリックで、ようやくボタンが押されることになります。

    もしも一回のクリックでアクティブ化とボタン動作を同時にこなしたい場合、
    該当コントロールの WndProc をオーバーライドして、
    WM_MOUSEACTIVATE 時の戻り値を、MA_ACTIVATEANDEAT から
    MA_ACTIVATE に差し替える必要が生じます。
    https://docs.microsoft.com/ja-jp/windows/win32/inputdev/wm-mouseactivate
    https://docs.microsoft.com/en-us/archive/blogs/rickbrew/how-to-enable-click-through-for-net-2-0-toolstrip-and-menustrip


    あるいは、コントロールの種類が他のフォームの場合と同様であるのに
    該当フォームだけ動作が異なるというのであれば、継承フォームや
    NativeWindow クラスで処理されている可能性、あるいは別の UI スレッドで
    動作していたために、フォーカス遷移が阻害されている箇所があったなどの
    理由かもしれません。ソースを追わないと何とも言えないですが。
違反を報告
引用返信 削除キー/
■34599 / ResNo.4)  Re[4]: 新たにshowしたフォームでのボタンのクリック
□投稿者/ 未熟者ケンイチ 一般人(3回)-(2020/12/14(Mon) 17:44:20)
  • アイコンNo34597に返信(魔界の仮面弁士さんの記事)
    > ■No34596に返信(未熟者ケンイチさんの記事)
    >>どうも「1回目のクリックでフォームがアクティブ?になり、
    >>2回目のクリックでボタンクリックが認識されている」感じです。
    >
    > あるいは、コントロールの種類が他のフォームの場合と同様であるのに
    > 該当フォームだけ動作が異なるというのであれば、継承フォームや
    > NativeWindow クラスで処理されている可能性、あるいは別の UI スレッドで
    > 動作していたために、フォーカス遷移が阻害されている箇所があったなどの
    > 理由かもしれません。ソースを追わないと何とも言えないですが。

    お忙しい中でのお返事、どうもありがとうございます。
    せっかくお返事を頂いたのに、反応が遅くなってしまいました。申し訳ありません。
    URLもご教示いただきましたが英語が苦手なため、Googleさんに聞きながら悪戦苦闘しております。

    一応、ソースを貼ります。コメントは削除しましたが、その他はソースコードのままです。

    ・呼び出し側
    Form_02 open_form = new Form_02 ();
    open_form.Show (this);
    open_form.form_02_proc ();
    // 処理終了で結果を取得
    a_result = open_form.A_RESULT;


    ・呼ばれる側
    public Form_02 ()
    {
    InitializeComponent ();
    }
    private void Form_02_Load (object sender, EventArgs e)
    {
    // 表示位置調整
    this.Location = new Point (0, 0);
    // サイズ変更の禁止
    this.MaximumSize = this.Size;
    this.MinimumSize = this.Size;
    // タイムアウトタイマを起動
    timeout_timer = 1000;
    timer_a.Enabled = true;
    }
    private void button_1_Click (object sender, EventArgs e)
    {
    a_type = A_TYPE.MEMBER;
    a_machine = A_MACHINE.MACHINE01;
    p_result = A_RESULTS.SUCCESS;
    exit_flag = true;
    }
    internal void form_02_proc ()
    {
    Int32 loop = 0;
    // お仕事シミュレーション
    while (false == exit_flag)
    {
    Application.DoEvents ();
    loop++;
    textBox_test.Text = loop.ToString ();
    }
    }


違反を報告
引用返信 削除キー/
■34600 / ResNo.5)  Re[4]: 新たにshowしたフォームでのボタンのクリック…自己解決
□投稿者/ 未熟者ケンイチ 一般人(5回)-(2020/12/14(Mon) 18:47:07)
  • アイコン自己解決いたしました。魔界の仮面弁士様、お忙しい中のご教示、どうもありがとうございました。

    ソースコードは以下のように
    Form_02 open_form = new Form_02 ();
    this.Visible = false;
    open_form.Show (this);
    open_form.form_02_proc ();
    と、それまで表示していたフォームを非表示にするコードを挿入するだけでした。
    確かに他のフォームは、
    open_form.Close ();
    してからさらに別フォームを表示していたので、おそらくこの1行が効いているのだと思います。また上記「this」で指されるフォームは、アプリケーションを起動した時に表示されるフォームだったので、盲点になっておりました。

    魔界の仮面弁士様はじめお読みいただいた皆様、どうもありがとうございました。
    またお世話になることがあるかもしれませんが、その時はどうぞよろしくお願いいたします。
    とりあえずは、これで解決といたします。
解決み!
違反を報告
引用返信 削除キー/



スレッド内ページ移動 / << 0 >>

このスレッドに書きこむ

Mode/  Pass/


- Child Tree -