@@ -58,6 +58,7 @@ Private Const InterpolationModeHighQualityBicubic As Long = 7
58
58
Private Const MatrixOrderAppend As Long = 1
59
59
60
60
Private Declare Sub CopyMemory Lib "kernel32 " Alias "RtlMoveMemory " (lpDst As Any , lpSrc As Any , ByVal ByteLength As Long )
61
+ Private Declare Function ArrPtr Lib "msvbvm60 " Alias "VarPtr " (Ptr() As Any ) As Long
61
62
Private Declare Function OleTranslateColor Lib "oleaut32 " (ByVal lOleColor As Long , ByVal lHPalette As Long , ByVal lColorRef As Long ) As Long
62
63
Private Declare Function CreateCompatibleDC Lib "gdi32 " (ByVal hDC As Long ) As Long
63
64
Private Declare Function DeleteDC Lib "gdi32 " (ByVal hDC As Long ) As Long
@@ -73,6 +74,8 @@ Private Declare Function CreateBitmap Lib "gdi32" (ByVal nWidth As Long, ByVal n
73
74
Private Declare Function CreateIconIndirect Lib "user32 " (pIconInfo As ICONINFO ) As Long
74
75
Private Declare Function DestroyIcon Lib "user32 " (ByVal hIcon As Long ) As Long
75
76
Private Declare Function SHCreateMemStream Lib "shlwapi " Alias "#12" (ByRef pInit As Any , ByVal cbInit As Long ) As IUnknown
77
+ Private Declare Function CreateSolidBrush Lib "gdi32 " (ByVal clrColor As Long ) As Long
78
+ Private Declare Function FillRect Lib "user32 " (ByVal hDC As Long , lpRect As RECT , ByVal hBrush As Long ) As Long
76
79
'--- gdi+
77
80
Private Declare Function GdiplusStartup Lib "gdiplus " (hToken As Long , pInputBuf As Any , Optional ByVal pOutputBuf As Long = 0 ) As Long
78
81
Private Declare Function GdipCreateBitmapFromScan0 Lib "gdiplus " (ByVal lWidth As Long , ByVal lHeight As Long , ByVal lStride As Long , ByVal lPixelFormat As Long , ByVal Scan0 As Long , hBitmap As Long ) As Long
@@ -125,6 +128,23 @@ Private Type PICTDESC
125
128
hPal As Long
126
129
End Type
127
130
131
+ Private Type SAFEARRAY1D
132
+ cDims As Integer
133
+ fFeatures As Integer
134
+ cbElements As Long
135
+ cLocks As Long
136
+ pvData As Long
137
+ cElements As Long
138
+ lLbound As Long
139
+ End Type
140
+
141
+ Private Type RECT
142
+ Left As Long
143
+ Top As Long
144
+ Right As Long
145
+ Bottom As Long
146
+ End Type
147
+
128
148
'=========================================================================
129
149
' Constants and member variables
130
150
'=========================================================================
@@ -629,87 +649,98 @@ Private Function pvPreparePicture(oPicture As StdPicture, ByVal clrMask As OLE_C
629
649
Dim hMemDC As Long
630
650
Dim uInfo As ICONINFO
631
651
Dim baColorBits() As Byte
632
- Dim bHasAlpha As Boolean
633
652
Dim hDib As Long
634
653
Dim lpBits As Long
635
654
Dim hPrevDib As Long
636
- Dim lIdx As Long
637
655
Dim pPic As IPicture
656
+ Dim hBrush As Long
657
+ Dim rc As RECT
638
658
639
659
On Error GoTo EH
640
660
If Not oPicture Is Nothing Then
641
661
If oPicture.Handle <> 0 Then
642
- Select Case oPicture.Type
643
- Case vbPicTypeBitmap
644
- If GdipCreateBitmapFromHBITMAP(oPicture.Handle, 0 , hNewBitmap) <> 0 Then
662
+ lWidth = HM2Pix(oPicture.Width)
663
+ lHeight = HM2Pix(oPicture.Height)
664
+ hMemDC = CreateCompatibleDC(0 )
665
+ If hMemDC = 0 Then
666
+ GoTo QH
667
+ End If
668
+ With uHdr
669
+ .biSize = Len(uHdr)
670
+ .biPlanes = 1
671
+ .biBitCount = 32
672
+ .biWidth = lWidth
673
+ .biHeight = -lHeight
674
+ .biSizeImage = (4 * lWidth) * lHeight
675
+ End With
676
+ If oPicture.Type = vbPicTypeIcon Then
677
+ If GetIconInfo(oPicture.Handle, uInfo) = 0 Then
645
678
GoTo QH
646
679
End If
647
- If clrMask <> -1 Then
648
- If GdipCreateImageAttributes(hNewAttributes) <> 0 Then
680
+ ReDim baColorBits(0 To uHdr.biSizeImage - 1 ) As Byte
681
+ If GetDIBits(hMemDC, uInfo.hbmColor, 0 , lHeight, baColorBits(0 ), uHdr, DIB_RGB_COLORS) = 0 Then
682
+ GoTo QH
683
+ End If
684
+ If Not pvHasAlpha(VarPtr(baColorBits(0 )), uHdr.biSizeImage) Then
685
+ '--- note: GdipCreateBitmapFromHICON is working ok for old-style (single-bit) transparent icons only
686
+ If GdipCreateBitmapFromHICON(oPicture.Handle, hNewBitmap) <> 0 Then
649
687
GoTo QH
650
688
End If
651
- If GdipSetImageAttributesColorKeys(hNewAttributes, 0 , 1 , TranslateColor(clrMask), TranslateColor(clrMask)) <> 0 Then
689
+ Else
690
+ If GdipCreateBitmapFromScan0(lWidth, lHeight, 4 * lWidth, PixelFormat32bppPARGB, VarPtr(baColorBits(0 )), hTempBitmap) <> 0 Then
691
+ GoTo QH
692
+ End If
693
+ If GdipCloneBitmapAreaI(0 , 0 , lWidth, lHeight, PixelFormat32bppARGB, hTempBitmap, hNewBitmap) <> 0 Then
652
694
GoTo QH
653
695
End If
654
696
End If
655
- Case Else
656
- lWidth = HM2Pix(oPicture.Width)
657
- lHeight = HM2Pix(oPicture.Height)
658
- hMemDC = CreateCompatibleDC(0 )
659
- If hMemDC = 0 Then
697
+ Else
698
+ hDib = CreateDIBSection(hMemDC, uHdr, DIB_RGB_COLORS, lpBits, 0 , 0 )
699
+ If hDib = 0 Then
660
700
GoTo QH
661
701
End If
662
- With uHdr
663
- .biSize = Len(uHdr)
664
- .biPlanes = 1
665
- .biBitCount = 32
666
- .biWidth = lWidth
667
- .biHeight = -lHeight
668
- .biSizeImage = (4 * lWidth) * lHeight
669
- End With
670
- If oPicture.Type = vbPicTypeIcon Then
671
- If GetIconInfo(oPicture.Handle, uInfo) = 0 Then
672
- GoTo QH
673
- End If
674
- ReDim baColorBits(0 To uHdr.biSizeImage - 1 ) As Byte
675
- If GetDIBits(hMemDC, uInfo.hbmColor, 0 , lHeight, baColorBits(0 ), uHdr, DIB_RGB_COLORS) = 0 Then
676
- GoTo QH
677
- End If
678
- For lIdx = 3 To UBound(baColorBits) Step 4
679
- If baColorBits(lIdx) <> 0 Then
680
- bHasAlpha = True
681
- Exit For
682
- End If
683
- Next
684
- If Not bHasAlpha Then
685
- '--- note: GdipCreateBitmapFromHICON working ok for old-style (single-bit) transparent icons only
686
- If GdipCreateBitmapFromHICON(oPicture.Handle, hNewBitmap) <> 0 Then
702
+ hPrevDib = SelectObject(hMemDC, hDib)
703
+ If oPicture.Type = vbPicTypeMetafile Or oPicture.Type = vbPicTypeEMetafile Then
704
+ clrMask = vbMagenta
705
+ End If
706
+ If clrMask <> -1 Then
707
+ Call OleTranslateColor (clrMask, 0 , VarPtr(clrMask))
708
+ hBrush = CreateSolidBrush(clrMask)
709
+ rc.Right = lWidth
710
+ rc.Bottom = lHeight
711
+ Call FillRect (hMemDC, rc, hBrush)
712
+ Call DeleteObject (hBrush)
713
+ End If
714
+ Set pPic = oPicture
715
+ pPic.Render hMemDC, 0 , 0 , lWidth, lHeight, 0 , oPicture.Height, oPicture.Width, -oPicture.Height, ByVal 0
716
+ If Not pvHasAlpha(lpBits, uHdr.biSizeImage) Then
717
+ '--- note: GdipCreateBitmapFromHBITMAP is working ok for non-transparent bitmaps
718
+ If oPicture.Type = vbPicTypeBitmap Then
719
+ If GdipCreateBitmapFromHBITMAP(oPicture.Handle, oPicture.hPal, hNewBitmap) <> 0 Then
687
720
GoTo QH
688
721
End If
689
722
Else
690
- If GdipCreateBitmapFromScan0(lWidth, lHeight, 4 * lWidth, PixelFormat32bppPARGB, VarPtr(baColorBits(0 )), hTempBitmap) <> 0 Then
691
- GoTo QH
692
- End If
693
- If GdipCloneBitmapAreaI(0 , 0 , lWidth, lHeight, PixelFormat32bppARGB, hTempBitmap, hNewBitmap) <> 0 Then
723
+ If GdipCreateBitmapFromHBITMAP(hDib, 0 , hNewBitmap) <> 0 Then
694
724
GoTo QH
695
725
End If
696
726
End If
697
727
Else
698
- hDib = CreateDIBSection(hMemDC, uHdr, DIB_RGB_COLORS, lpBits, 0 , 0 )
699
- If hDib = 0 Then
700
- GoTo QH
701
- End If
702
- hPrevDib = SelectObject(hMemDC, hDib)
703
- Set pPic = oPicture
704
- pPic.Render hMemDC, 0 , 0 , lWidth, lHeight, 0 , oPicture.Height, oPicture.Width, -oPicture.Height, ByVal 0
705
728
If GdipCreateBitmapFromScan0(lWidth, lHeight, 4 * lWidth, PixelFormat32bppPARGB, lpBits, hTempBitmap) <> 0 Then
706
729
GoTo QH
707
730
End If
708
731
If GdipCloneBitmapAreaI(0 , 0 , lWidth, lHeight, PixelFormat32bppARGB, hTempBitmap, hNewBitmap) <> 0 Then
709
732
GoTo QH
710
733
End If
711
734
End If
712
- End Select
735
+ End If
736
+ If clrMask <> -1 Then
737
+ If GdipCreateImageAttributes(hNewAttributes) <> 0 Then
738
+ GoTo QH
739
+ End If
740
+ If GdipSetImageAttributesColorKeys(hNewAttributes, 0 , 1 , TranslateColor(clrMask), TranslateColor(clrMask)) <> 0 Then
741
+ GoTo QH
742
+ End If
743
+ End If
713
744
End If
714
745
End If
715
746
'--- commit
@@ -789,6 +820,28 @@ Private Sub pvHandleMouseDown(Button As Integer, Shift As Integer, X As Single,
789
820
m_sngDownY = Y
790
821
End Sub
791
822
823
+ Private Function pvHasAlpha (ByVal lPtr As Long , ByVal lSize As Long ) As Boolean
824
+ Dim uArray As SAFEARRAY1D
825
+ Dim baBuffer() As Byte
826
+ Dim lIdx As Long
827
+
828
+ With uArray
829
+ .cDims = 1
830
+ .fFeatures = 1 ' FADF_AUTO
831
+ .cbElements = 1
832
+ .pvData = lPtr
833
+ .cElements = lSize
834
+ End With
835
+ Call CopyMemory (ByVal ArrPtr(baBuffer), VarPtr(uArray), 4 )
836
+ For lIdx = 3 To UBound(baBuffer) Step 4
837
+ If baBuffer(lIdx) <> 0 Then
838
+ pvHasAlpha = True
839
+ Exit Function
840
+ End If
841
+ Next
842
+ End Function
843
+
844
+
792
845
'= common ================================================================
793
846
794
847
Private Function pvCreateDib (ByVal hMemDC As Long , ByVal lWidth As Long , ByVal lHeight As Long , hDib As Long ) As Boolean
0 commit comments