Discussion:
What are the differences between Picture, StdPicture and IPicture?
(too old to reply)
Fatih Argun
2005-11-18 10:46:13 UTC
Permalink
What are the differences between Picture, StdPicture and IPicture? Which
should i use?
Mike D Sutton
2005-11-18 15:58:15 UTC
Permalink
Post by Fatih Argun
What are the differences between Picture, StdPicture and IPicture? Which
should i use?
This should answer your first question:

'***
Dim x As StdPicture

Set x = Me.Image
Debug.Print TypeOf x Is IPicture
Debug.Print TypeOf x Is IPictureDisp
Debug.Print TypeOf x Is Picture
Set x = Nothing
'***

AFAIK StdPicture is a class that simply implements the IPictureDisp interface (a slightly cut down version of the full
IPicture interface based on the IDispach interface (used for automation)), and Picture is an alias for StdPicture (not
sure on this one though.)
If you're just using pictures within VB and don't require the additional methods exposed by the IPicture interface
(which may or may not even be hooked up in the StdPicture object) then it's probably best to simply use the StdPicture
type.
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: ***@mvps.org
WWW: Http://EDais.mvps.org/
Fatih Argun
2005-11-18 17:34:05 UTC
Permalink
Thanks Mike,

I have other questions about StdPicture:
- How can i create blank StdPicture at a specific size (without loading
picture file)
- How can i get this picture's hdc? (createcompatibledc, selectobject???),
what is CurDC of IPicture?

Dim std as StdPicture
Set std = New StdPicture
............................

after setting std, std.Handle=0 (why), width=0, height=0 (how can i resize
it)
Mike D Sutton
2005-11-18 18:47:44 UTC
Permalink
Post by Fatih Argun
- How can i create blank StdPicture at a specific size (without loading
picture file)
You'd need to create a GDI Bitmap object and wrap it in a StdPicture object, grab the OLEPicture library off my site and
use something like this:

'***
Private Declare Function CreateDIBSection Lib "GDI32.dll" (ByVal hDC As Long, _
ByRef pBitmapInfo As BitmapInfo8, ByVal un As Long, ByVal lplpVoid As Long, _
ByVal handle As Long, ByVal dw As Long) As Long

Private Type BitmapInfoHeader ' 40 bytes
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type

Private Type BitmapInfo8
bmiHeader As BitmapInfoHeader
bmiColors(0 To 255) As Long
End Type

Private Function CreateBMPPicture(ByVal inWidth As Long, ByVal inHeight As Long, _
Optional ByVal inDepth As Long = 24) As StdPicture
Dim hDIB As Long
Dim BMInf As BitmapInfo8

With BMInf.bmiHeader
.biSize = Len(BMInf.bmiHeader)
.biWidth = inWidth
.biHeight = inHeight
.biBitCount = inDepth
.biPlanes = 1
End With

hDIB = CreateDIBSection(0&, BMInf, 0&, 0&, 0&, 0&)
If (hDIB) Then Set CreateBMPPicture = GDIToPicture(hDIB, True, 0&, True)
End Function
'***

Note; whilst this will create Bitmaps at <= 8-bit, it does nothing about the palette. If you require a palette then put
the palette entries in the BMInf.bmiColors() array, and set the .biClrUsed member of the header to the number of colours
used. Also note that for 1-BPP Bitmaps the maximum palette size is 2 colours, 4-BPP is 16 colours and 8-BPP is 256
colours.
Post by Fatih Argun
- How can i get this picture's hdc? (createcompatibledc, selectobject???),
The StdPicture normally doesn't keep the object selected into a DC (since many GDI functions require exclusive access to
the object.) If you need the object to be selected into a DC then use the SelectObject() API call and select it into a
DC you've created using the CreateCompatibleDC() API call.
Post by Fatih Argun
what is CurDC of IPicture?
CurDC is the current DC the internal object is selected into, however this only works if the SelectObject() method of
the IPicture interface was used to select the object (direct calls using the SelectObject() API call will not update
this property.) The reason for having this property is because as mentioned above, some GDI calls require exclusive
access to the object and as such it must temporarily be de-selected from wherever it currently is.
Post by Fatih Argun
Dim std as StdPicture
Set std = New StdPicture
............................
after setting std, std.Handle=0 (why), width=0, height=0 (how can i resize
it)
The StdPicture object is simply a wrapper which can handle many different types of graphics objects (Bitmaps, Metafiles,
Enhanced metafiles, Icons and Cursors) and provide reasonably generic access to them. Since all you've done here is to
instantiate an object, it doesn't know what kind of object you want it to wrap and as such won't store anything in it's
internal handle. As mentioned above, what you want to do is to create a new GDI Bitmap object and wrap that in a
StdPicture object (which in turn (optionally) manages it's destruction when the object's ref.-count drops to 0.)
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: ***@mvps.org
WWW: Http://EDais.mvps.org/
Fatih Argun
2005-11-19 17:16:17 UTC
Permalink
Mike, please see the following codes.

I will use (I'm testing) the GetPictureFromFile function for displaying png
files. VB does'nt support this type and I don't use this picture as bmp or
jpeg. Because this files have transparent field, some of them 32 bit icon
pictures (what is it, alpha channel??, I'm very ignorant about graphic
topics (to be more exact every topic)). I'm using this files with
picturebox, commandbutton vs. I did try creating background layer with
control's background color in Photoshop, but XP style change every controls
background color. This code use png files directly and change background
colors dynamically (I will capture WM_SYSCOLORCHANGE message later).
PictureBox has AutoRedraw property but CommandButton has not. If I use these
files in PictureBox then I don't need to create StdPicture, but I need the
picture object for CommandButton.

And other questions:
- How can I use GDI+ for filling background colors (GdipFillRectangle,
GdipFillRectangleI, GdipGraphicsClear vs.) instead of FillRect api. I did
create solid brush with GdipCreateSolidFill but GdipFillRectangleI doesn't
fill rect (image)

- Is the following GDI+ image same quality with StretchBlt image
(StretchMode=4)

My English is very bad, I hope you understand me. Thanks again...


FORM CODE:
--------------------------
'PictureBox: AutoRedraw = True, ScaleMode=3 (Pixel), Width=1920 (128),
Height=1920 (128)

Option Explicit

Private Declare Function GetBkColor Lib "gdi32" (ByVal hdc As Long) As Long

Private Sub Form_Load()
StartUpGDIPlus GdiPlusVersion
End Sub

Private Sub Command1_Click()
Set Picture1.Picture = GetPictureFromFile(App.Path & "\test.png", 128,
128, GetBkColor(Picture1.hdc))
End Sub

Private Sub Form_Unload(Cancel As Integer)
ShutdownGDIPlus
End Sub



MODULE CODE
----------------------
Option Explicit

Private Type BitmapInfoHeader ' 40 bytes
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type

Private Type BitmapInfo8
bmiHeader As BitmapInfoHeader
bmiColors(0 To 255) As Long
End Type

Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Private Type PictDesc
cbSizeOfStruct As Long
picType As Long
hgdiObj As Long
hPalOrXYExt As Long
End Type
Private Type Guid
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type

Private Declare Function CreateDIBSection Lib "GDI32.dll" (ByVal hdc As
Long, ByRef pBitmapInfo As BitmapInfo8, ByVal un As Long, ByVal lplpVoid As
Long, ByVal handle As Long, ByVal dw As Long) As Long

Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As
Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As
Long
Private Declare Function FillRect Lib "user32" (ByVal hdc As Long, ByRef
lpRect As RECT, ByVal hBrush As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal
hObject As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long)
As Long

Public Const GdiPlusVersion As Long = 1

Private Const QualityModeInvalid As Long = -1
Private Const QualityModeDefault As Long = 0
Private Const QualityModeLow As Long = 1
Private Const QualityModeHigh As Long = 2

Private Type GDIPlusStartupInput
GdiPlusVersion As Long
DebugEventCallback As Long
SuppressBackgroundThread As Long
SuppressExternalCodecs As Long
End Type

Private Enum InterpolationMode
InterpolationModeInvalid = QualityModeInvalid
InterpolationModeDefault = QualityModeDefault
InterpolationModeLowQuality = QualityModeLow
InterpolationModeHighQuality = QualityModeHigh
InterpolationModeBilinear = QualityModeHigh + 1
InterpolationModeBicubic = QualityModeHigh + 2
InterpolationModeNearestNeighbor = QualityModeHigh + 3
InterpolationModeHighQualityBilinear = QualityModeHigh + 4
InterpolationModeHighQualityBicubic = QualityModeHigh + 5
End Enum

Private Enum SmoothingMode
SmoothingModeInvalid = QualityModeInvalid
SmoothingModeDefault = QualityModeDefault
SmoothingModeHighSpeed = QualityModeLow
SmoothingModeHighQuality = QualityModeHigh
SmoothingModeNone = QualityModeHigh + 1
SmoothingModeAntiAlias8x4 = QualityModeHigh + 2
SmoothingModeAntiAlias = SmoothingModeAntiAlias8x4
'SmoothingModeAntiAlias8x8
End Enum

Private Enum PixelOffsetMode
PixelOffsetModeInvalid = QualityModeInvalid
PixelOffsetModeDefault = QualityModeDefault
PixelOffsetModeHighSpeed = QualityModeLow
PixelOffsetModeHighQuality = QualityModeHigh
PixelOffsetModeNone = QualityModeHigh + 1
PixelOffsetModeHalf = QualityModeHigh + 2
End Enum

Private Enum CompositingQualityMode
CompositingQualityInvalid = QualityModeInvalid
CompositingQualityDefault = QualityModeDefault
CompositingQualityHighSpeed = QualityModeLow
CompositingQualityHighQuality = QualityModeHigh
CompositingQualityGammaCorrected = QualityModeHigh + 1
CompositingQualityAssumeLinear = QualityModeHigh + 2
End Enum

Private Enum CompositingModeMode
CompositingModeSourceOver = 0
CompositingModeSourceCopy = 1
End Enum

Private Declare Function GdipCreateBitmapFromFile Lib "gdiplus" (ByVal
FileName As Long, ByRef bitmap As Long) As Long
Private Declare Function GdipCreateFromHDC Lib "gdiplus" (ByVal hdc As Long,
ByRef graphics As Long) As Long
Private Declare Function GdipSetSmoothingMode Lib "gdiplus" (ByVal graphics
As Long, ByVal SmoothingMode As SmoothingMode) As Long
Private Declare Function GdipSetInterpolationMode Lib "gdiplus" (ByVal
graphics As Long, ByVal InterpolationMode As InterpolationMode) As Long
Private Declare Function GdipSetPixelOffsetMode Lib "gdiplus" (ByVal
graphics As Long, ByVal PixelOffsetMode As PixelOffsetMode) As Long
Private Declare Function GdipSetCompositingQuality Lib "gdiplus" (ByVal
graphics As Long, ByVal CompositingQuality As CompositingQualityMode) As
Long
Private Declare Function GdipSetCompositingMode Lib "gdiplus" (ByVal
graphics As Long, ByVal CompositingMode As CompositingModeMode) As Long
Private Declare Function GdipDrawImageRectI Lib "gdiplus" (ByVal graphics As
Long, ByVal Image As Long, ByVal x As Long, ByVal y As Long, ByVal Width As
Long, ByVal Height As Long) As Long
Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal Image As
Long) As Long
Private Declare Function GdipDeleteGraphics Lib "gdiplus" (ByVal graphics As
Long) As Long
Private Declare Function GdiplusStartup Lib "gdiplus" (ByRef token As Long,
ByRef lpInput As GDIPlusStartupInput, Optional ByRef lpOutput As Any) As
Long
Private Declare Function GdiplusShutdown Lib "gdiplus" (ByVal token As Long)
As Long
Private Declare Function GdipGetImageWidth Lib "gdiplus.dll" (ByVal Image As
Long, Width As Long) As Long
Private Declare Function GdipGetImageHeight Lib "gdiplus.dll" (ByVal Image
As Long, Height As Long) As Long
Private Declare Sub OleCreatePictureIndirect Lib "oleaut32.dll" (lpPictDesc
As PictDesc, riid As Guid, ByVal fOwn As Boolean, lplpvObj As Object)

Public GdipInitialized As Boolean
Private GdipToken As Long

Public Function GetPictureFromFile(ByVal sPicture As String, Optional ByVal
lWidth As Long, Optional ByVal lHeight As Long, Optional ByVal BgColor As
Long) As IPicture
Dim rc As RECT
Dim lBitmap As Long
Dim lngGraphics As Long
Dim lHdc As Long
Dim std As StdPicture
Dim lOldBitmap As Long
Dim lBrush As Long
Dim aaa As Long
Dim bbb As Long

If GdipCreateBitmapFromFile(StrPtr(sPicture), lBitmap) = 0 Then
If lWidth = 0 Then
GdipGetImageWidth lBitmap, lWidth
End If
If lHeight = 0 Then
GdipGetImageHeight lBitmap, lHeight
End If

Set std = CreateBMPPicture(lWidth, lHeight)
lHdc = CreateCompatibleDC(0)
lOldBitmap = SelectObject(lHdc, std)

lBrush = CreateSolidBrush(BgColor)
rc.Right = lWidth
rc.Bottom = lHeight
FillRect lHdc, rc, lBrush

If GdipCreateFromHDC(lHdc, lngGraphics) = 0 Then
GdipSetSmoothingMode lngGraphics, SmoothingModeHighQuality
GdipSetInterpolationMode lngGraphics,
InterpolationModeHighQualityBicubic
GdipSetPixelOffsetMode lngGraphics, PixelOffsetModeHighQuality
GdipSetCompositingQuality lngGraphics,
CompositingQualityHighQuality
GdipSetCompositingMode lngGraphics, CompositingModeSourceOver

GdipDrawImageRectI lngGraphics, lBitmap, 0&, 0&, lWidth, lHeight

GdipDeleteGraphics lngGraphics
End If

GdipDisposeImage lBitmap

SelectObject lHdc, lOldBitmap

Set GetPictureFromFile = std

DeleteObject lOldBitmap
DeleteObject lBrush
Set std = Nothing
End If
End Function

Private Function CreateBMPPicture(ByVal inWidth As Long, ByVal inHeight As
Long) As StdPicture
Dim hDIB As Long
Dim BMInf As BitmapInfo8

With BMInf.bmiHeader
.biSize = Len(BMInf.bmiHeader)
.biWidth = inWidth
.biHeight = inHeight
.biBitCount = 32
.biPlanes = 1
End With

hDIB = CreateDIBSection(0&, BMInf, 0&, 0&, 0&, 0&)
If (hDIB) Then
Set CreateBMPPicture = GDIToPicture(hDIB)
End If
End Function

Public Function GDIToPicture(ByVal lBitmap As Long) As IPicture
Dim tPictDesc As PictDesc
Dim PictureGUID As Guid

With tPictDesc
.cbSizeOfStruct = Len(tPictDesc)
.picType = vbPicTypeBitmap
.hgdiObj = lBitmap
.hPalOrXYExt = 0
End With

With PictureGUID
.Data1 = &H7BF80980
.Data2 = &HBF32
.Data3 = &H101A
.Data4(0) = &H8B
.Data4(1) = &HBB
.Data4(3) = &HAA
.Data4(5) = &H30
.Data4(6) = &HC
.Data4(7) = &HAB
End With
OleCreatePictureIndirect tPictDesc, PictureGUID, True, GDIToPicture
End Function

Public Function StartUpGDIPlus(ByVal GdipVersion As Long) As Long
Dim GdipStartupInput As GDIPlusStartupInput

GdipStartupInput.GdiPlusVersion = GdipVersion
StartUpGDIPlus = GdiplusStartup(GdipToken, GdipStartupInput, ByVal 0&)
GdipInitialized = (StartUpGDIPlus = 0)
End Function

Public Function ShutdownGDIPlus() As Long
If GdipInitialized Then
ShutdownGDIPlus = GdiplusShutdown(GdipToken)
End If
End Function
Mike D Sutton
2005-11-19 22:29:27 UTC
Permalink
Post by Fatih Argun
I will use (I'm testing) the GetPictureFromFile function for displaying png
files. VB does'nt support this type and I don't use this picture as bmp or
jpeg. Because this files have transparent field, some of them 32 bit icon
pictures (what is it, alpha channel??, I'm very ignorant about graphic
topics (to be more exact every topic)).
What you're referring to here is a 32-bit image with 4 channels; red, green, blue and alpha. The colour is made up of a
combination of red, green and blue and by combining various amounts of these primaries other colours can be created.
The Alpha channel then defines how transparent/opaque each pixel should be rendered, so any pixel with an alpha value of
0 will be completely transparent regardless of it's colour, where as pixels with an alpha value of 128 will be blended
50/50 with whatever background they're displayed on. By defining per-pixel alpha, icons can achieve effects such as
smooth edges and drop-shadows which properly blend over the background.
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: ***@mvps.org
WWW: Http://EDais.mvps.org/
Fatih Argun
2005-11-20 00:32:59 UTC
Permalink
"32 bit icon pictures" is wrong statement. I did mean "32 bit icon's
picture". I'm saving some 32 bit icons as png files using Microangelo (icon
editor).

Regards...

Larry Serflaten
2005-11-19 03:12:13 UTC
Permalink
Post by Fatih Argun
Thanks Mike,
- How can i create blank StdPicture at a specific size (without loading
picture file)
- How can i get this picture's hdc? (createcompatibledc, selectobject???),
what is CurDC of IPicture?
Dim std as StdPicture
Set std = New StdPicture
............................
after setting std, std.Handle=0 (why), width=0, height=0 (how can i resize
it)
If you plan on drawing or printing on the image, you might find it easier
to hide a picturebox and use that for drawing and printing. When done,
you can save its contents in a StdPicture object and reuse the picture box
for other images....

It would be easier because the picturebox uses the documented VB
commands and you might not need to resort to using the API for
simple tasks....

LFS
Fatih Argun
2005-11-19 17:21:22 UTC
Permalink
I'm using some picturebox for drawing pictures (as you say). But I need to
picture object for some other controls (CommandButton vs) and I'm using png
files. I'm using StdPicture for creating CommandButton's (or other
control's) picture instead of using PictureBox, see my answer to Mike.

Thanks for reply..
Loading...