Word - use of clipboard and STA threading

Add-in Express™ Support Service
That's what is more important than anything else

Word - use of clipboard and STA threading
Clipboard class can only be used in threads set to single thread apartment (STA) mode 
Ian Smith




Posts: 5
Joined: 2011-02-28
I have a Word add-in that I'm upgrading from VB6 to .NET. I'm also using Add-in Express for the first time. The Word add-in takes screen captures and pastes them into the word document. The old VB6 version worked fine.

The issue I'm having is that the screen-captures are not making it into the clipboard. To be sure I was capturing the screen, I added a picturebox to my Windows form and output to that first. The image is clearly visible in the picturebox but doesn't make it to the clipboard. Code extract shown below.


Dim bmpScreenshot = New Bitmap( Width, Height)
Dim g As Graphics = Graphics.FromImage(bmpScreenshot)

g.CopyFromScreen(Left, Top, 0, 0, bmpScreenshot.Size)
PictureBox1.Image = bmpScreenshot
Clipboard.SetImage(PictureBox1.Image)

I have also tried SetDataObject

I have a feeling it is something to do with the following that I found on MSDN. I think this because when debugging the log shows error messages relating to Threading.

"The Clipboard class can only be used in threads set to single thread apartment (STA) mode. To use this class, ensure that your Main method is marked with the STAThreadAttribute attribute."

Frankly, that's out of my depth.

I also tried to avoid the clipboard entirely by saving the image to a file:
PictureBox1.Image.Save(MyFile, Imaging.ImageFormat.Bmp)

This worked fine a couple of times but then caused a crash, again with Threading messages in the debug log.

I'd like to use the clipboard but any solution that anyone can come up with which will allow me to reliably get a screen shot into a Word document would be extremely welcome.
Posted 12 May, 2011 08:10:04 Top
Eugene Astafiev


Guest


Hi Ian,

Did you try to debug? Do you get any error message or exception? Could you please provide me with a sample add-in project which can reproduce the issue? I will test it on my PC.

BTW What version and build number of Add-in Express do you use?
Posted 12 May, 2011 09:03:41 Top
Ian Smith




Posts: 5
Joined: 2011-02-28
Good news! I found a solution. May help other people with this problem.

From Word I am starting a form that has recording controls (start and stop) that, when recording, waits for events from another application indicating that the screen has changed or a button has been pressed etc.. My application then captures the screen, button, whatever, and pastes it to Word. This is what was working in VB6 and not .NET.

The MSDN posting I referred to earlier is correct. The solution is to use Threading and has nothing to do with Add-in Express (which is working perfectly). Abbreviated code below.


   Private Sub ScreenGrab()
        Dim bmpScreenshot = New Bitmap(iWidth, iHeight)
        Dim g As Graphics = Graphics.FromImage(bmpScreenshot)

        g.CopyFromScreen(iLeft, iTop, 0, 0, bmpScreenshot.Size)

        PictureBox1.Image = bmpScreenshot

        myClipper()
    End Sub


    Private Sub myClipper()
        On Error Resume Next

        If th IsNot Nothing Then
            If th.IsAlive Then
                While th.IsAlive
                    th.Join(50)
                End While
            End If
        End If

        th = New Thread(AddressOf PutToClipboard)
        th.SetApartmentState(ApartmentState.STA)
        th.IsBackground = False

        th.Start()

        While th.IsAlive
            th.Join(50)
        End While
    End Sub

    Private Sub PutToClipboard()
        System.Windows.Forms.Clipboard.SetImage(PictureBox1.Image)
End Sub

Posted 15 May, 2011 04:49:15 Top
Eugene Astafiev


Guest


Hi Ian,

Good news! You broke the ice!

Thank you for sharing the solution for other forum readers.
Posted 15 May, 2011 05:20:14 Top