![]() |
![]() |
|
|
||
| NetCam | |||||||||||||||
|
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ (Destination As Any, Source As Any, ByVal Length As Long) Private Function ArrayInitialized(vArray As Variant) As Boolean Dim pSA As Long ' Make sure an array was passed in: If IsArray(vArray) Then ' Get the pointer out of the Variant: CopyMemory pSA, ByVal VarPtr(vArray) + 8, 4& If pSA Then ' Try to get the descriptor: CopyMemory pSA, ByVal pSA, 4 ' Array is initialized only if we got ' the SAFEARRAY descriptor: ArrayInitialized = (pSA <> 0) End If End If End Function
There's also a really slick routine, first published by Brad Martinez, that can load an image into a StdPicture object directly from memory. This allows things such as reading graphic image from the internet, or a resource file, as a series of bytes and transforming those to a Picture without ever needing to write to disk first. In other words, you can also use it to load GIF or JPG images straight from a resource file!
' ******************************************************************** ' This function inspired by the work of Brad Martinez. ' http://btmtz.mvps.org/_misc/index.htm ' ******************************************************************** ' Download complete project (below) for API declarations. ' ******************************************************************** Public Function LoadImage(ImageBytes() As Byte) As StdPicture Dim nBytes As Long Dim hMem As Long Dim lpMem As Long Dim oStream As IUnknown Dim oPicture As IPicture Dim IID_IPicture As GUID Const sIID_IPicture As String = "{7BF80980-BF32-101A-8BBB-00AA00300CAB}" ' GIGO: return Nothing. If ArrayInitialized(ImageBytes) = False Then Exit Function ' Calculate the array size nBytes = UBound(ImageBytes) - LBound(ImageBytes) + 1 ' Create and lock a memory buffer for image bytes. hMem = GlobalAlloc(GMEM_MOVEABLE, nBytes) If hMem Then lpMem = GlobalLock(hMem) If lpMem Then ' Copy image bytes to memory buffer, and unlock. Call CopyMemory(ByVal lpMem, ImageBytes(LBound(ImageBytes)), nBytes) Call GlobalUnlock(hMem) ' Create an IStream object in global memory buffer. If (CreateStreamOnHGlobal(hMem, False, oStream) = S_OK) Then ' Translate CLSID string to IPicture interface ID. If (CLSIDFromString(StrPtr(sIID_IPicture), IID_IPicture) = S_OK) Then ' Create an IPicture from the IStream (the docs say the call does not ' AddRef its last param, but it looks like the reference counts are correct..) Call OleLoadPicture(ByVal ObjPtr(oStream), nBytes, False, IID_IPicture, oPicture) End If End If End If ' Release global memory object. Call GlobalFree(hMem) End If ' Return results. Set LoadImage = oPicture End Function
Anyway, this is kind of a fun one. I've used it to create a good handful of funky little utilities. Two of my favorites are a Mt. St. Helens screensaver and an I-5 traffic cam monitor for my local region. I'd enjoy hearing how you use it.
This sample hasn't been published anywhere except here on this website, but first rights to such publication are jealously guarded - you have been warned. <g>
This sample uses the following API calls:
Module Library Function NetCam.ctl kernel32
ole32
olepro32
user32GetTickCount
GlobalAlloc
GlobalFree
GlobalLock
GlobalUnlock
RtlMoveMemory
CLSIDFromString
CreateStreamOnHGlobal
OleLoadPicture
GetWindowLong
SetWindowLong
SetWindowPosDon't see what you're looking for? Here's a complete API cross-reference.
![]()
Please, enjoy and learn from this sample. Include its code within your own projects, if you wish. But, in order to insure only the most recent code is available to all, I ask that you don't share the sample by any form of mass distribution. Download NetCam.zip, 14Kb, Last Updated: Tuesday, 10 April 2007
The following resources may also be of interest:
- NetGrab - Shows how to use the AsyncRead method of VB5/6 UserControls to download anything to memory or file.