JumpyNET Posted October 11, 2007 Posted October 11, 2007 I'm trying to acces "My.Computer.Clipboard" from a thread and I get an error "Object reference not set to an instance of an object.". Any ideas where I go wrong?? Here is my code (Form1 + one class). The program listens for a printscreen press in a low priority thread. And once the print screen is pressed it should save the picture to disk, but thats when I get the error. Form1 code: Public Class Form1 Public Shared Snooper As New SnoopClass Public Shared ImageCounter As Integer = 0 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Start snooping for Print Screen key press Snooper.StartSnoopingThread() AddHandler Snooper.MainLoopClass.PrntScrPressed, AddressOf PrntScrnPressed End Sub Public Shared Sub PrntScrnPressed() 'Increment image counter ImageCounter += 1 'Set image name Dim ImgName As String = IO.Path.Combine("C:\temp", "Capt Screen " & ImageCounter & ".png") 'Get image from clipboard Dim ClipImage As Image = My.Computer.Clipboard.GetImage() 'Save image to selected path ClipImage.Save(ImgName, System.Drawing.Imaging.ImageFormat.Png) End Sub End Class SnoopClass code: Imports System.Threading Public Class SnoopClass Private Declare Function GetKeyState Lib "user32" (ByVal KeyCode As Integer) As Integer Public Class MainLoopClass Public Shared Event PrntScrPressed() Private Shared PrntScrn_mem As Boolean = False Public Sub MainLoop() While True If IsKeyPressedPosEdge(44, PrntScrn_mem) Then RaiseEvent PrntScrPressed() End If End While End Sub Public Function IsKeyPressed(ByVal KeyCode As Integer) As Boolean Dim RetVal As Boolean = False Dim KeyStat As Integer = GetKeyState(KeyCode) If KeyStat < -1 Or KeyStat > 1 Then RetVal = True End If Return RetVal End Function Public Function IsKeyPressedPosEdge(ByVal KeyCode As Integer, ByRef MemoryBit As Integer) As Boolean Dim RetVal As Boolean = False Dim KeyStat As Integer = GetKeyState(KeyCode) If ((KeyStat < -1 Or KeyStat > 1) And MemoryBit <> KeyStat) Then RetVal = True End If MemoryBit = KeyStat Return RetVal End Function Private Function ListPressedKeys() As List(Of Integer) Dim PressedKeys As List(Of Integer) = New List(Of Integer) Dim i As Integer For i = 0 To 254 If IsKeyPressed(i) = True Then PressedKeys.Add(i) End If Next Return PressedKeys End Function End Class Public Sub StartSnoopingThread() Dim ca As New SnoopClass.MainLoopClass Dim t As New Thread(AddressOf ca.MainLoop) t.Name = "Snoop Thread" t.Priority = ThreadPriority.Lowest t.IsBackground = True t.Start() End Sub End Class Quote
Administrators PlausiblyDamp Posted October 11, 2007 Administrators Posted October 11, 2007 Looking at http://msdn2.microsoft.com/en-us/library/a2kwzzs8(VS.80).aspx seems to indicate threading issues with the My.Computer.Clipboard object. It might be easier to just use the Clipboard Class directly. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
JumpyNET Posted October 18, 2007 Author Posted October 18, 2007 It might be easier to just use the Clipboard Class directly. Do you mean like this: Public Shared Sub PrntScrnPressed() 'Increment image counter ImageCounter += 1 'Set image name Dim ImgName As String = IO.Path.Combine("C:\temp", "Capt Screen " & ImageCounter & ".png") 'Get image from clipboard Dim ClipImage As Image = System.Windows.Forms.Clipboard.GetImage 'My.Computer.Clipboard.GetImage() 'Save image to selected path ClipImage.Save(ImgName, System.Drawing.Imaging.ImageFormat.Png) End Sub It ends up in the same "not set to an instance" error. :( Quote
JumpyNET Posted October 18, 2007 Author Posted October 18, 2007 Solved Looking at http://msdn2.microsoft.com/en-us/library/a2kwzzs8(VS.80).aspx seems to indicate threading issues with the My.Computer.Clipboard object. Thank you, I found the answer from the link above. :) Just needed to add this line: "t.SetApartmentState(ApartmentState.STA)". Just incase some one else is interested here's where you must put the new line: Public Sub StartSnoopingThread() Dim ca As New SnoopClass.MainLoopClass Dim t As New Thread(AddressOf ca.MainLoop) t.SetApartmentState(ApartmentState.STA) t.Name = "Snoop Thread" t.Priority = ThreadPriority.Lowest t.IsBackground = True t.Start() End Sub Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.