Screen Capture through Winsock

I know there are many / many examples out there of different ways to grab screen captures through API, keyboard commands, etc...  

However, I am creating an application for remote assistance that will need to work slightly differently, in that it will be the server controlling the client and receiving screen captures of the client.  I currently have a version that is capturing the screen as a BMP to a file and then reading that file and killing it, sending the data to the other computer, which stores it as a file, reads it and then kills and displays it.

My problems are, that this seems to be more work than is necessary.  Are there any quick ways to create a smaller footprint to transfer without having to write it to file on one or both ends?  I would rather send them as JPG's since, the BMP file is coming in at over 4MB!

Also, is there a way to capture the data and send directly through winsock and then put it directly into the picture/image box control without having to save the file and call loadimage?

Thanks in Advance on this one!
I'll add more points for a really helpfull answer!

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Richie_SimonettiIT OperationsCommented:
Interesting...but poor points amount :)
HHSBAuthor Commented:
Like I said above...

I'll add more points for a really helpfull answer!

You could zip the bmp files as they should compress quite a bit.I remember doing something like that a while back.What I would recommend is installing the free version of tridiavnc on the machines as a service.It comes with a reg script you can run to disable the system tray icon.Then you can shell the viewer from your vb program.The viewer supports a /viewonly switch so you can view the other screen in real time.If you launch it without the /viewonly switch then you will be able to take control of the desktop similar to pcANYWHERE.
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

as a partial solution, use glabcore component

it will enable you to grab the desktop picture and save it as a jpg which will reduce the traffic
HHSBAuthor Commented:

     I took a look at the glabcore component, and it looks great.  The question I had is, would it be possible to use that library to send the compressed data through winsock and then recompress it on the other end without having to create files on either end?  

How would I accomplish this if it is possible?


HHSBAuthor Commented:
Here is what I am doing now:

On the Send Side of Things:
(gPic1 is a screen capture)

    Dim gPic1 As New GlabPicture
    Dim gSend As New GlabBuffer
    Dim gJpg As New GlabJPEG


    gJpg.Grayscale = False
    gJpg.ForceBaseline = True
    gJpg.OptimizeCoding = True
    gJpg.Upsample = True
    gJpg.DCT = glabjpegFastDCT
    gJpg.Quality = 10
    gJpg.DecompressorSmoothing = True
    gJpg.CompressorSmoothing = 0
    Set gSend = gJpg.Compress(gPic1)


   winsock.senddata "[START]" & gSend.binarystring & _

On the Receive side of things:

    If InStr(strData, "[START]") Then
        Set buffer = Nothing
        buffer.BinaryString = Replace( _  
                  strData, "[START]", "")
        process = True
    End If
    If InStr(strData, "[STOP]") Then
        If process = True Then
            'Small Image was Sent
            buffer.BinaryString = _
                  Replace(buffer.BinaryString, _
                  "[STOP]", "")
            buffer.BinaryString = buffer.BinaryString & _
                Replace(strData, "[STOP]", "")
            process = True
        End If
        Set gJPG = Nothing
        set gPic1 = gJPG.Decompress(buffer)
        gPic1.ScaleTo _
            ScaleX(Picture1.Width, vbTwips, vbPixels), _
            ScaleX(Picture1.Height, vbTwips, vbPixels)
        Picture1.Picture = gPic1.Picture
        End If
    If process = False Then
        buffer.BinaryString = buffer.BinaryString & strData
    End If


    The data seems to make it okay, as long as the picture is small enough that the entire image gets sent (more on this below).  When I print out the binarystring that is sent, it matches the one that arrives, however, when I decompress it I get an error.  

    Also, when the image is large, the binarystring seems to get chopped short when it is being sent, is there a simple way to chop the data into smaller chunks?

Thanks in advance everyone for your help.  I will give 450 points for a correct answer that helps me get this working.

I think that what you should do is this:
take the ByteArray from the glab buffer. build a string that contains the hex representation of each byte, send that over (this will make sure that the data sent is only the letters 0-9,A-F:
untested code:
dim sBuff as string,Ix as long,Buff() as byte
for ix=lbound(buff) to ubound(buff)
   sbuff=sbuff & hex(buff(ix))
next ix
sbuff="[START]" & sbuff & "[END]"

on the recieveing side, then recieving the data concat it into a string variable and not the glab buffer. at the end of it string the "[START]","[END]" delimiters and decode the buffer back into a byte array and set that byte array to the glab buffer:
again untested code
redim buff(len(sbuff)/2) as byte
dim sTmp as string,Ix as long
while len(sBuff)>0
   buff(ix)=val("&h" & stmp)
then give this buff to the glab buffer.

note that on this side the redim might not work and might contain an extra cell (debug it to make sure it's ok)

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
HHSBAuthor Commented:
I have updated my code to include the suggestions above.  I'm not sure what you meant by contain an extra cell, but this may be happening.  When I debug the program I learn that the redim statement breaks down to an odd number for the len(sbuff), which makes 1/2 of that a fractional number (X.5)

The code then halts on the line:
buff(ix) = val("&h" & stmp)

with the message: Subscript Out of Range.

The conversions and the redmin statement are all new to me, so I'm not exactly sure what to do at this point to fix this error.

Here is the code I have on the send Side:

Dim sBuff As String, Ix As Long, Buff() As Byte
Buff = gSend.ByteArray
For Ix = LBound(Buff) To UBound(Buff)
sBuff = sBuff & Hex(Buff(Ix))
Next Ix
sBuff = "[START]" & sBuff & "[STOP]"
ok = safeSend(sBuff)

Here is the code I have on the Receive Side:

ReDim Buff(Len(buffer2) / 2) As Byte
Dim sTmp As String, Ix As Long
Ix = 0

While Len(buffer2) > 0
     sTmp = Left(buffer2, 2)
     sbuff = Mid(buffer2, 3)
     Buff(Ix) = Val("&h" & sTmp)
     Ix = Ix + 1
Set buffer.ByteArray = Buff
Any more insight that you could provide would be very helpful, and thanks for all your help so far.

HHSBAuthor Commented:
There was a typo in the section:

While Len(buffer2) > 0
    sTmp = Left(buffer2, 2)
    sbuff = Mid(buffer2, 3)
    Buff(Ix) = Val("&h" & sTmp)
    Ix = Ix + 1

the 3rd line should have read, and now reads, buffer2 = mid(buffer2,3)

This then pushes the error down to later in the code, to the same place it was before the hex conversion...

Set buffer = Nothing
buffer.ByteArray = Buff

'Same Settings as used to compress
'Don't know if this matters
Set gJPG = Nothing
gJPG.Grayscale = False
gJPG.ForceBaseline = True
gJPG.OptimizeCoding = True
gJPG.Upsample = True
gJPG.DCT = glabjpegFastDCT
gJPG.Quality = 100
gJPG.DecompressorSmoothing = True
gJPG.CompressorSmoothing = 10

'This line gives the error:
set gPic1 = gJPG.Decompress(buffer)

The Error is:

Method 'Decompress' of object 'IGlabJPEG' failed

HHSBAuthor Commented:
The data converts to Hex and transfers byte for byte from the client the the server, however, it does not convert back to the same value when the recieving computer rebuilds the byte array as it existed on the sending computer.

HHSBAuthor Commented:
Turned out to be the hex conversion code.  Otherwise, it seems to be working now.  I will play around with it over the weekend.  If it all works out I will deposit the points for the question on Monday.  Thanks!

Original: sbuff = sbuff & hex(buff(ix))
Modified: sbuff = sbuff & right("0", + hex(buff(ix)),2)


This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
Experts: Post your closing recommendations!  Who deserves points here?
Moderator, my recommended disposition is:

    Split points between: vinnyd79 and DanAvni

DanRollins -- EE database cleanup volunteer
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.