2

Window1 の Page_load イベントから、パブリック クラスの関数を呼び出し、同じ Window1 としてパラメーターを渡します。関数が呼び出された後、スレッドが開始されます。スレッドは Window1 の Page_Loaded イベントで呼び出されます。コードは次のようになります。

Private Sub StartScreen_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        Try
            TmHeartbeat.Stop()
            TmHeartbeat.Interval = 600000
            TmHeartbeat.Start()
            ResetVariables()
            FormLoadSetting(Me)
            SetButtonProperty(btnEnglish, "\Images\ButtonBgBig.png", GetFormLabel("Start Screen", "Common", "Button English"))
            SetButtonProperty(btnSpanish, "\Images\ButtonBgBig.png", GetFormLabel("Start Screen", "Common", "Button Spanish"))
            SetDisplayTimer(DGT, False, Me, 1800000)

            MediaElement1.Source = New Uri(GetPath("Images\EnglishVideo\" & GetFormLabel("Start Screen", "Common", "Video")))

            If GetFormLabel("Start Screen", "Common", "Audio") <> "" Then
                PlayAudio(APlay, GetFormLabel("Start Screen", "Common", "Audio"))
            End If

            Dim AudioPlay As New System.Media.SoundPlayer

            Dim sc As New Screenshot
            sc.TakeScreenshot(Me)
        Catch ex As Exception
            AliLogFileEntry(TransactionType.ErrorOnForm, "Error In Function: StartScreen_Loaded: " & Me.Title & ", ErrorMessage: " & ex.Message)
        End Try
    End Sub

TakeScreenshot(Me)クラスにある関数Screenshotが呼び出されます。Screenshot クラスに加えて、という名前の別のクラスGetScreenshotと functionもありますTakeScreenshot1。クラスファイルのコードは次のようになります。

Imports System.IO
Imports System.Threading
Public Class Screenshot
    Public Sub TakeScreenshot(ByVal formname As Window)
        Dim GT As New GetScreenshot
        GT.source = formname
        Dim newThread As New Thread(AddressOf GT.TakeScreenshot1)
        newThread.Start()
    End Sub

End Class

Public Class GetScreenshot
    Public source As Window
    Public Function TakeScreenshot1()
        Thread.Sleep(2000)
        If OG.GetValue("TakeScreenshot") <> "0" Then
            Try
                AliLogFileEntry(TransactionType.System, "In Function: TakeScreenshot")
                Dim scale As Double = OG.GetValue("Screenshot_Scale") / 100
                AliLogFileEntry(TransactionType.System, "In Function: GetJpgImage")
                Dim renderHeight As Double = source.RenderSize.Height * scale
                Dim renderWidth As Double = source.RenderSize.Width * scale
                Dim renderTarget As New RenderTargetBitmap(CInt(Math.Truncate(renderWidth)), CInt(Math.Truncate(renderHeight)), 96, 96, PixelFormats.Pbgra32)
                Dim sourceBrush As New VisualBrush(source)
                Dim drawingVisual As New DrawingVisual()
                Dim drawingContext As DrawingContext = drawingVisual.RenderOpen()
                Using drawingContext
                    drawingContext.PushTransform(New ScaleTransform(scale, scale))
                    drawingContext.DrawRectangle(sourceBrush, Nothing, New Rect(New Point(0, 0), New Point(source.RenderSize.Width, source.RenderSize.Height)))
                End Using
                renderTarget.Render(drawingVisual)
                Dim jpgEncoder As New JpegBitmapEncoder()
                jpgEncoder.QualityLevel = 100

                jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget))
                Dim _imageArray As [Byte]()
                Using outputStream As New MemoryStream()
                    jpgEncoder.Save(outputStream)
                    _imageArray = outputStream.ToArray()
                End Using
                Dim screenshot As Byte() = _imageArray
                Dim dir As DirectoryInfo = New DirectoryInfo("Screenshots")
                If Not dir.Exists Then dir = Directory.CreateDirectory(dir.FullName)
                Dim path As String = AppDomain.CurrentDomain.BaseDirectory
                Dim fileStream As New IO.FileStream("Screenshots\" & source.Title & ".jpg", FileMode.Create, FileAccess.ReadWrite)
                Dim binaryWriter As New IO.BinaryWriter(fileStream)
                binaryWriter.Write(screenshot)
                binaryWriter.Close()
            Catch ex As Exception
                AliLogFileEntry(TransactionType.ErrorOnForm, "Error In Function: TakeScreenshot , ErrorMessage: " & ex.Message)
            End Try
        End If
    End Function
End Class

このファイルをデバッグすると、次のエラーが発生します。 ここに画像の説明を入力

そして、エラーはオンラインで生成されます

Dim sourceBrush As New VisualBrush(source)

助けてください

4

1 に答える 1

3

source作成されたスレッドとは別のスレッドから使​​用しています。別のスレッドで Windows コントロールを使用するには、元のスレッドにコールバックする必要があります。詳細については、「方法: Windows フォーム コントロールに対してスレッド セーフな呼び出しを行う」を参照してください

于 2013-09-18T20:11:35.640 に答える