[c#]dxライブラリとwebbrowser

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ウインドウマン

[c#]dxライブラリとwebbrowser

#1

投稿記事 by ウインドウマン » 11年前

現在C#フォームアプリケーションでdxライブラリを使ったゲームを作成しています。
フォームにはピクチャーボックスとwebbrowserが張り付けてあります。
ピクチャボックス内でdxライブラリを使ったゲームを表示させます。
ここで質問があります。
webbrowserを使ってサイトを表示させようとしたときにゲーム画面がカクカクする現象が起きてしまいます。
これをどのようにしたら解決できるでしょうか。

最悪縁なしのフォームを一つ作ってそれをwebbrawserがあったスペースに重ねる方法があるのですが効率が悪いと思います。
下記のようなプログラムを
http://qiita.com/hart_edsf/items/0301f17e2d9acd890c5e
を参考にして書きました。ブラウザは貼り付けてオプションで設定しました。

コード:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DxLibDLL;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        int i = 0;
        public Form1()
        {
            InitializeComponent();
            DX.SetUserWindow(this.Handle);
            DX.SetUserChildWindow(pictureBox1.Handle);
            DX.DxLib_Init();
            DX.SetDrawScreen(DX.DX_SCREEN_BACK);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            DX.DxLib_End();
        }
        public void MainLoop()
        {
            // 画面に描かれているものを一回全部消す
            DX.ClsDrawScreen();
            DX.DrawString(0, i, "Hello C# World!", -1);
            i++;
            if (i > 200) i = 0;
            // 裏画面の内容を面画面に反映される
            DX.ScreenFlip();
        }

    }
}


ウインドウマン

Re: [c#]dxライブラリとwebbrowser

#2

投稿記事 by ウインドウマン » 11年前

少し考えてマルチスレッドでフォームを作ることにしました。
しかしform1のFormObj.Show()で
型 'System.InvalidOperationException' のハンドルされていない例外が System.Windows.Forms.dll で発生しました
追加情報:有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'Form1' がアクセスされました。
と表示されます。

どうしたら解決できるでしょうか。

下記がプログラムです。form2.csは何も弄っていません。
program.cs

コード:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace MFORM
{
    static class Program
    {
        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main()
        {
            // Form1 オブジェクトを生成
            Form1 f1 = new Form1();
            // Form2 オブジェクトを生成
            Form2 f2 = new Form2();

            // Form1 オブジェクトを実行するスレッドを生成し、それを実行
            System.Threading.Thread ThreadObj1 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(RunForm1Thread));
            ThreadObj1.SetApartmentState(System.Threading.ApartmentState.STA);
            ThreadObj1.Start(f1);

            // Form2 オブジェクトを実行するスレッドを生成し、それを実行
            System.Threading.Thread ThreadObj2 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(RunForm2Thread));
            ThreadObj2.SetApartmentState(System.Threading.ApartmentState.STA);
            ThreadObj2.Start(f2);
        }

        static void RunForm1Thread(object data)
        {
            // スレッド引数から、実行対象フォームを取得
            Form1 FormObj = (Form1)data;

            // フォームの実行
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            FormObj.Show();
            while (FormObj.Created) //Application.Runしないで自分でループを作る
            {
                FormObj.MainLoop();
                Application.DoEvents(); //←必要
            }
        }

        static void RunForm2Thread(object data)
        {
            // スレッド引数から、実行対象フォームを取得
            Form2 FormObj = (Form2)data;

            // フォームの実行
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            FormObj.Show();
            while (FormObj.Created) //Application.Runしないで自分でループを作る
            {
                FormObj.MainLoop();
                Application.DoEvents(); //←必要
            }
        }
    }
}
form1.cs

コード:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DxLibDLL;

namespace MFORM
{
    public partial class Form1 : Form
    {
        int i;
        public Form1()
        {
            InitializeComponent();
            DX.SetUserWindow(this.Handle);
            DX.SetUserChildWindow(pictureBox1.Handle);
            DX.SetOutApplicationLogValidFlag(DX.FALSE);
            DX.DxLib_Init();
            DX.SetDrawScreen(DX.DX_SCREEN_BACK);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            DX.DxLib_End();
        }

        public void MainLoop()
        {
            // 画面に描かれているものを一回全部消す
            DX.ClsDrawScreen();
            DX.DrawString(0, 100 + (int)(100 * Math.Sin(i * Math.PI / 180.0)), "Hello C# World!", -1);
            i++;
            if (i > 360) i = 0;
            // 裏画面の内容を面画面に反映される
            DX.ScreenFlip();
        }
    }
}


アバター
バグ
記事: 130
登録日時: 14年前
住所: 愛媛県
連絡を取る:

Re: [c#]dxライブラリとwebbrowser

#3

投稿記事 by バグ » 11年前

少し記事が古いですが、ここが参考になるかと思います。

ウインドウマン

Re: [c#]dxライブラリとwebbrowser

#4

投稿記事 by ウインドウマン » 11年前

回答ありがとうございます。
さっそくサイトを見てみましたが書いたプログラムにどのように適用すればいいのかわかりません。
その辺のところも教えていただきたいのですが。
よろしくおねがいします。

ウインドウマン

Re: [c#]dxライブラリとwebbrowser

#5

投稿記事 by ウインドウマン » 11年前

program.cs
form1.cs
のどちらにもinvokeを書かなければならないでしょうか。

ウインドウマン

Re: [c#]dxライブラリとwebbrowser

#6

投稿記事 by ウインドウマン » 11年前

c#でマルチスレッドは難しいのでしょうか。
もっと専門的なサイトに質問するべきですか?

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: [c#]dxライブラリとwebbrowser

#7

投稿記事 by YuO » 11年前

ウインドウマン さんが書きました:c#でマルチスレッドは難しいのでしょうか。
もっと専門的なサイトに質問するべきですか?
C#でマルチスレッドが難しいかと問われればYESです。
ただし,それはマルチスレッド一般における難しさそのもので,
つまり,アクセスのアトミック性,同期・排他などをちゃんと考えないといけない,という点に関してです。

.NET FrameworkやC#のマルチスレッドプログラミングは,相対的には簡単だと思いますし,簡単になってきています。
ref) http://dixq.net/forum/blog.php?u=546&b=3452

ウインドウマン さんが書きました:program.cs
form1.cs
のどちらにもinvokeを書かなければならないでしょうか。
InvokeはWinFormsのUI ControlがCOMのSTAモデルに基づいており,クロススレッドのアクセスが禁じられているために利用されるものです。
つまり,Formを定義したスレッドでInvokeを使う必要はまったくありません。
使えばよいかが判断できないというのであれば,InvokeRequiredプロパティを毎回確認すればよいでしょう。
オフトピック
WebBrowserコントロールなんていう重量級コンポーネントを使う以上,UIスレッドが(ユーザーに分からない程度に)ブロックされるのは仕方がないかと。
WinRTの設計思想でも50ms以上かかる処理は非同期 = 50ms程度の処理は許容範囲内であり,
ユーザーアクションから100ms程度ウィンドウメッセージが処理されなくても,通常のアプリケーションにおいては問題ないことが多いです。
ある程度のリアルタイム性能が求められる通信などは別スレッドで処理するのが普通でしょうし。

ウインドウマン

Re: [c#]dxライブラリとwebbrowser

#8

投稿記事 by ウインドウマン » 11年前

回答ありがとうございます。
具体的にはどのようにやればいいでしょうか?

ウインドウマン

Re: [c#]dxライブラリとwebbrowser

#9

投稿記事 by ウインドウマン » 11年前

webbrowserとDXライブラリを同じフォームに表示させているので一瞬でも止まると残念な形になります。
2つフォームを作り独立させて動かそうと思たのですが連動しているようで片方が止まるともう片方も止まってしまいます。
フォームのマルチスレッドを考えましたがうまくいきませんでした。

ウインドウマン

Re: [c#]dxライブラリとwebbrowser

#10

投稿記事 by ウインドウマン » 11年前

webbrowser内でjavascriptを使用して自動的にページを更新しようとしているのですが、その時に瞬間的にフォームが止まるのですがこれはどうすれば解決できるでしょうか。

閉鎖

“C言語何でも質問掲示板” へ戻る