Ciao !
Quando richiami la SetPixel non fai altro che assegnare un colore ad un pixel su un device context (di cui hdc è l'handle).Infatti questa modifica è immediatamente visibile nella PictureBox.
Quando richiami SavePicture non salvi su file il contenuto del DeviceContext ma solamente l'immagine originariamente caricata su di esso.
Hai bisogno di una funzioncina che crei un DeviceContext e vi copi quello di origine, poi crei in memoria una bitmap per il nuovo device context.
Ti metto giù un po' di codice. Bada che non l'ho riscritto adattandolo alle tue esigenze (purtroppo non ho molto tempo): l'ho usato di recente per catturare immagini dal Desktop.
Noterai infatti che, ad un certo punto del codice, viene recuperato l'hWnd del Desktop, poi il suo hDc. Devi solamente adattare un po' il codice afinchè possa lavorare con l'hDc della tua PictureBox anzichè con quello del destkop.
La funzione principale è la "CaptureDesktop" che restituisce una Picture. Dopo che avrai adattato il codice, potrai utilizzare il valore restituito per richiamare la SavePicture.
codice:
'
Function CaptureDestkop() As Picture
'***********************************************
' Restituisce l'immagine catturata dal Desktop
'***********************************************
Dim hDesktopWnd As Long
Dim hDesktopDC As Long
Dim rcDektop As RECT
Dim x As Long, y As Long
Dim w As Long, h As Long
Dim hDCMemory As Long
Dim hBitmap As Long
Dim hBitmapPrev As Long
Dim SysPalE As Long
Dim hPalette As Long
Dim hPreviousPalette As Long
Dim RasterCaps As Long
Dim HasPalette As Long
Dim PaletteSize As Long
Dim LogPal As LOGPALETTE
hDesktopWnd = GetDesktopWindow() ' ottiene l'handle-window del desktop
hDesktopDC = GetDC(hDesktopWnd) ' recupera l'handle del device context
GetWindowRect hDesktopWnd, rcDektop ' recupera il rect del desktop
x = 0
y = 0
w = rcDektop.Right - rcDektop.Left ' calcola larghezza e altezza della cattura
h = rcDektop.Bottom - rcDektop.Top
hDCMemory = CreateCompatibleDC(hDesktopDC) ' crea un DeviceContext compatibile
hBitmap = CreateCompatibleBitmap(hDesktopDC, w, h) ' crea una bitmap compatibile
hBitmapPrev = SelectObject(hDCMemory, hBitmap) ' ??? seleziona la bitmap dal device context
RasterCaps = GetDeviceCaps(hDesktopDC, RasterCaps) ' Ottiene Raster capabilities
HasPalette = RasterCaps And RC_PALETTE ' la bitmap usa PALETTE ?
PaletteSize = GetDeviceCaps(hDesktopDC, SIZEPALETTE) ' ottiene le dimensioni della PALETTE
If HasPalette And (PaletteSize = 256) Then
LogPal.palVersion = &H300 ' imposta versione palette
LogPal.palNumEntries = 256 ' numero delle palette
SysPalE = GetSystemPaletteEntries(hDesktopDC, 0, 256, LogPal.palPalEntry(0)) 'system palette entries
hPalette = CreatePalette(LogPal) ' crea la palette
hPreviousPalette = SelectPalette(hDCMemory, hPalette, 0) ' seleziona palette
SysPalE = RealizePalette(hDCMemory) ' relaizza la palette
End If
'Copia l'immagine di origine nel device Context
SysPalE = BitBlt(hDCMemory, 0, 0, w, h, hDesktopDC, x, y, vbSrcCopy)
hBitmap = SelectObject(hDCMemory, hBitmapPrev) ' ripristina bitmap precedente
' Seleziona la palette
If HasPalette And (PaletteSize = 256) Then hPalette = SelectPalette(hDCMemory, hPreviousPalette, 0)
SysPalE = DeleteDC(hDCMemory) ' elimina device context
Set CaptureDestkop = CreateBitmapPicture(hBitmap, hPalette)
End Function
'
Private Function CreateBitmapPicture(ByVal hBmp As Long, ByVal hPal As Long) As Picture
Dim lRetVal As Long
Dim pic As PicBmp
Dim IPic As IPicture
Dim IID_IDispatch As GUID
'Fill GUID info
With IID_IDispatch
.Data1 = &H20400
.Data4(0) = &HC0
.Data4(7) = &H46
End With
'Fill picture info
With pic
.Size = Len(pic) ' dimensioni della struttura
.Type = vbPicTypeBitmap ' tipo di Picture (bitmap)
.hBmp = hBmp ' Handle della bitmap
.hPal = hPal ' Handle della palette
End With
OleCreatePictureIndirect pic, IID_IDispatch, 1, IPic ' Crea la picture
Set CreateBitmapPicture = IPic ' Restituisce la nuova picture
End Function
Ed ecco le dichiarazioni API che ti servono:
codice:
Option Explicit
'* x CaptureDesktop
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function GetDesktopWindow Lib "user32.dll" () As Long
Private Declare Function GetDC Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hwnd As Long, ByRef lpRect As RECT) As Long
Const RC_PALETTE As Long = &H100
Const SIZEPALETTE As Long = 104
Const RasterCaps As Long = 38
Private Type PALETTEENTRY
peRed As Byte
peGreen As Byte
peBlue As Byte
peFlags As Byte
End Type
Private Type LOGPALETTE
palVersion As Integer
palNumEntries As Integer
palPalEntry(255) As PALETTEENTRY ' Enough for 256 colors
End Type
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type
Private Type PicBmp
Size As Long
Type As Long
hBmp As Long
hPal As Long
Reserved As Long
End Type
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As PicBmp, RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal iCapabilitiy As Long) As Long
Private Declare Function GetSystemPaletteEntries Lib "gdi32" (ByVal hdc As Long, ByVal wStartIndex As Long, ByVal wNumEntries As Long, lpPaletteEntries As PALETTEENTRY) As Long
Private Declare Function CreatePalette Lib "gdi32" (lpLogPalette As LOGPALETTE) As Long
Private Declare Function SelectPalette Lib "gdi32" (ByVal hdc As Long, ByVal hPalette As Long, ByVal bForceBackground As Long) As Long
Private Declare Function RealizePalette Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Ciao ciao
Simo