Quantcast
Channel: VBForums
Viewing all articles
Browse latest Browse all 15567

[RESOLVED] Cloning stdole.StdPicture instance

$
0
0
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:

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

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. ;)

Viewing all articles
Browse latest Browse all 15567

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>