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

わんくま同盟

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

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


(過去ログ 172 を表示中)
■99033 / )  Re[2]: C#で別スレッドで動作するコントロールをフォームに貼付けたい
□投稿者/ KOZ (213回)-(2022/02/01(Tue) 07:17:14)
No99031 (KOZ さん) に返信
> Control.CheckForIllegalCrossThreadCalls プロパティを false にしてみましょう。
> これで貼り付けることができるはずです。

すみません。Controls.Add でチェックされていたようです。
SetParent API を使いましょう。

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using Timer = System.Windows.Forms.Timer;

public partial class Form1 : Form
{
    public Form1() {
        InitializeComponent();
        var th = new Thread(new ParameterizedThreadStart(OtherThread));
        th.Start(this);
    }

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

    private static void OtherThread(object args) {
        Form mainForm = args as Form;
        if (mainForm != null) {
            var subForm = new ThreadForm();
            subForm.Visible = true;
            subForm.Location = Point.Empty;
            subForm.Size = new Size(100, 20);
            Control.CheckForIllegalCrossThreadCalls = false;
            //mainForm.Controls.Add(subForm); // ダメ!チェックがかかっている
            SetParent(subForm.Handle, mainForm.Handle);
            Application.Run(subForm);
        }
    }

    private class ThreadForm : Form
    {
        Timer timer;

        public ThreadForm() {
            TopLevel = false;
            FormBorderStyle = FormBorderStyle.None;
            ControlBox = false;
            timer = new Timer();
            timer.Interval = 1000;
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void Timer_Tick(object sender, EventArgs e) {
            Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e) {
            e.Graphics.Clear(Color.White);
            using (var f = new Font("MS UI Gothic", 9.75F)) {
                TextRenderer.DrawText(e.Graphics, DateTime.Now.ToString("hh:mm:ss"),f, Point.Empty, Color.Black);
            }
            base.OnPaint(e);
        }
    }

    private void button1_Click(object sender, EventArgs e) {
        Thread.Sleep(10000); // 重い処理
    }
}

重い処理を実行しても時刻が更新されています。

返信 編集キー/


管理者用

- Child Tree -