I have a PictureBox Picture1 that contains a bitmap image. I want to grab Picture1.Picture but I don't know what the client intends to do with it.
Normally this isn't a problem for StdPicture instances in VB but that isn't always the case. The client might reach in and alter it with GDI calls and I don'r want the original altered. So I want a full clone, a duplicate, not merely another reference to the same object.
I don't do a lot of this. GDI experts, suggestions?
This seems to work, with a potential limitation regarding colors:
Is it better to replace the use of a compatible memory DC and BitBlt... by something like GetDIBits() and SetDIBits() using just Picture1.hDC instead?
That might address the palette (and mask and gamma and profile) issues, but is it a lot slower?
Screens seldom have 16-bit color (or below) now in the Post-XP Era and I'm not working with DCs for other devices. For general use color palette issues might matter a lot more (e.g. persisting to GIF, PNG, etc.) but I'm not doing that in this Project.
If you spot any GDI handle leaks above speak up. As long as I have additional eyeballs engaged I may as well take advantage of them. ;)
Normally this isn't a problem for StdPicture instances in VB but that isn't always the case. The client might reach in and alter it with GDI calls and I don'r want the original altered. So I want a full clone, a duplicate, not merely another reference to the same object.
I don't do a lot of this. GDI experts, suggestions?
This seems to work, with a potential limitation regarding colors:
Code:
Public Property Get Picture() As StdPicture
'Don't merely copy the object reference, create a complete copy, a new StdPicture
'with the same bits that Picture1.Picture has.
Dim hDCMem As Long
Dim W As Long
Dim H As Long
Dim PICTDESC As PICTDESC
Dim hBitmapOrig As Long
Dim HRESULT As Long
'Limitation:
'
'This code does not clone and use the hPal of Picture1.Picture's bitmap (if any).
'So when the screen has a color depth of 16 bits or below, the copy we return
'might have distorted colors in it.
With Picture1
.AutoRedraw = True 'Picture.hDC becomes the hDC of the persistent image.
hDCMem = CreateCompatibleDC(.hDC)
W = ScaleX(.ScaleWidth, .ScaleMode, vbPixels)
H = ScaleY(.ScaleHeight, .ScaleMode, vbPixels)
With PICTDESC
.cbSizeOfStruct = LenB(PICTDESC)
.picType = vbPicTypeBitmap
.hHandle = CreateCompatibleBitmap(Picture1.hDC, W, H)
hBitmapOrig = SelectObject(hDCMem, .hHandle)
End With
BitBlt hDCMem, 0, 0, W, H, .hDC
.AutoRedraw = False
End With
SelectObject hDCMem, hBitmapOrig
DeleteDC hDCMem
HRESULT = OleCreatePictureIndirect(PICTDESC, IID_IPicture, WIN32_TRUE, Picture)
If HRESULT <> S_OK Then
DeleteObject PICTDESC.hHandle
Err.Raise &H8004AA00, _
TypeName(Me), _
"OleCreatePictureIndirect system error " & CStr(HRESULT)
End If
End Property
That might address the palette (and mask and gamma and profile) issues, but is it a lot slower?
Screens seldom have 16-bit color (or below) now in the Post-XP Era and I'm not working with DCs for other devices. For general use color palette issues might matter a lot more (e.g. persisting to GIF, PNG, etc.) but I'm not doing that in this Project.
If you spot any GDI handle leaks above speak up. As long as I have additional eyeballs engaged I may as well take advantage of them. ;)