1

.NETアプリケーションをプラグインとして別の.NETアプリケーションに含める必要があります。プラグインインターフェイスでは、テンプレートフォームから継承する必要があります。プラグインがロードされると、フォームはMDIに添付されます。

これまでのところすべてが機能していますが、ドラッグアンドドロップイベントに登録するたびに、コンボボックスのオートコンプリートモードを設定するか、その他のさまざまな状況で次の例外が発生します。

... OLE呼び出しを行う前に、現在のスレッドをシングルスレッドアパートメント(STA)モードに設定する必要があります。Main関数にSTAThreadAttributeがマークされていることを確認してください...

メインアプリケーションはMTAで実行されており、他社によって開発されているため、私にできることは何もありません。

STAスレッドでこれらの例外を引き起こすことを試みましたが、それでも問題は解決しませんでした。

誰かが同じ状況にありましたか?問題を解決するために私にできることはありますか?

4

3 に答える 3

2

新しいスレッドを生成し、0を指定してCoInitializeを呼び出し(アパーメントスレッド)、このスレッドでアプリケーションを実行することができます。ただし、このスレッド内でコントロールを直接更新することはありません。UIを変更するたびにControl.Invokeを使用する必要があります。

これが確実に機能するかどうかはわかりませんが、試してみることができます。

于 2009-06-30T12:07:55.303 に答える
1

私は最近、Webカメラから画像を読み取ろうとしているときに、この問題に自分で遭遇しました。私がやったことは、シングルスレッドメソッドが実行される新しいSTAスレッドを生成するメソッドを作成することでした。

問題

private void TimerTick(object sender, EventArgs e)
{
   // pause timer
   this.timer.Stop();

        try
        {
            // get next frame
            UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraGetFrame, 0, 0);

            // copy frame to clipboard
            UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraCopy, 0, 0);

            // notify event subscribers
            if (this.ImageChanged != null)
            {
                IDataObject imageData = Clipboard.GetDataObject();

                Image image = (Bitmap)imageData.GetData(System.Windows.Forms.DataFormats.Bitmap);

                this.ImageChanged(this, new WebCamEventArgs(image.GetThumbnailImage(this.width, this.height, null, System.IntPtr.Zero)));
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error capturing the video\r\n\n" + ex.Message);
            this.Stop();
        }
    }
   // restart timer
   Application.DoEvents();

   if (!this.isStopped)
   {
      this.timer.Start();
   }
}

解決策:シングルスレッドロジックを独自のメソッドに移動し、新しいSTAスレッドからこのメソッドを呼び出します。

private void TimerTick(object sender, EventArgs e)
{
    // pause timer
    this.timer.Stop();

    // start a new thread because GetVideoCapture needs to be run in single thread mode
    Thread newThread = new Thread(new ThreadStart(this.GetVideoCapture));
    newThread.SetApartmentState(ApartmentState.STA);
    newThread.Start();

    // restart timer
    Application.DoEvents();

    if (!this.isStopped)
    {
        this.timer.Start();
    }
}

/// <summary>
/// Captures the next frame from the video feed.
/// This method needs to be run in single thread mode, because the use of the Clipboard (OLE) requires the STAThread attribute.
/// </summary>
private void GetVideoCapture()
{
    try
    {
        // get next frame
        UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraGetFrame, 0, 0);

        // copy frame to clipboard
        UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraCopy, 0, 0);

        // notify subscribers
        if (this.ImageChanged!= null)
        {
            IDataObject imageData = Clipboard.GetDataObject();

            Image image = (Bitmap)imageData.GetData(System.Windows.Forms.DataFormats.Bitmap);

            // raise the event
            this.ImageChanged(this, new WebCamEventArgs(image.GetThumbnailImage(this.width, this.height, null, System.IntPtr.Zero)));
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error capturing video.\r\n\n" + ex.Message);
        this.Stop();
    }
}
于 2011-02-16T20:44:09.083 に答える
0

更新:同社は新しいSTAバージョンをリリースしました。質問はもはや関係ありません。

于 2009-09-08T09:50:33.133 に答える