Ok... this is the code I use to load an empty surface:

VB Code:
  1. Public Type KSurface
  2.     SURF As DirectDrawSurface7
  3.     DESC As DDSURFACEDESC2
  4.     Width As Long
  5.     Height As Long
  6. End Type
  7.  
  8. 'Loads an empty surface, based on width/height
  9. Sub LoadEmptySurface(Width As Long, Height As Long, Dest As KSurface, Optional SpecialEffect As Boolean = False)
  10.     'Set the surface's width and height
  11.     Dest.Width = Width
  12.     Dest.Height = Height
  13.    
  14.     'Set the flags
  15.     Dest.DESC.lFlags = DDSD_CAPS Or DDSD_HEIGHT Or DDSD_WIDTH
  16.    
  17.     If Not SpecialEffect Then
  18.         'Load it as a regular surface
  19.         Dest.DESC.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
  20.     Else
  21.         'System memory is faster when it comes to special effects :)
  22.         Dest.DESC.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN Or DDSCAPS_SYSTEMMEMORY
  23.     End If
  24.    
  25.     'Width/height of the image...
  26.     Dest.DESC.lWidth = Width
  27.     Dest.DESC.lHeight = Height
  28.    
  29.     'Create it...
  30.     Set Dest.SURF = DDraw.CreateSurface(Dest.DESC)
  31.    
  32.     'Set the color key to black
  33.     Dim Key As DDCOLORKEY
  34.     Key.low = 0
  35.     Key.high = Key.low
  36.     Dest.SURF.SetColorKey DDCKEY_SRCBLT, Key
  37. End Sub

And this one to manipulate it as an array:

VB Code:
  1. Dim EmptyRect As RECT
  2.     Dim DestArray() As Byte
  3.     Backbuffer.SURF.Lock EmptyRect, Backbuffer.DESC, DDLOCK_NOSYSLOCK Or DDLOCK_WAIT, 0
  4.     Backbuffer.SURF.GetLockedArray DestArray()
  5.  
  6.     'Manipulate it here... I assume you already know how the array is organized :) (BGR-BGR-BGR...)
  7.  
  8.     Backbuffer.SURF.Unlock EmptyRect

Hope that helps

You can remove the NOSYSLOCK flag to speed up your app, but that means that windows won't be running while the surface is locked so you can't use any Windows APIs and NO errors can occur or your computer will crash