⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cicoparser.cls

📁 AeroSuite--一组非常漂亮的VISTA控件集
💻 CLS
📖 第 1 页 / 共 3 页
字号:
        End If
    End If
    
    If bIconFile Then
    
        ' Through experience, I have found the bitcount of the icons
        ' contained within the IconDirectoryEntry structures may be
        ' wrong or may not be filled in. Here, we will erase them & fill
        ' them in from the bitmap info headers that exist in the array.
        icBytesNeed = 0&
        For icEntry = 1 To m_icDir.idCount
            m_icDirE(icEntry).wPlanes = 1 ' not required, but used as a flag internally as indicating valid or invalid image
            ' get bitcount from the bitmap header
            CopyMemory icBytesNeed, m_Bits(m_icDirE(icEntry).dwImageOffset + 14), 2&
            
            If icBytesNeed = 0 Then ' if it is zero (shouldn't be); use the bitcount from the icon entry structure
                ' ensure the icon entry bitcount is not zero...
                If m_icDirE(icEntry).wBitCount = 0 Then
                    bIconFile = False
                Else
                    CopyMemory m_Bits(m_icDirE(icEntry).dwImageOffset + 14), m_icDirE(icEntry).wBitCount, 2&
                End If
                
            ElseIf icBytesNeed = 21060& Then
                ' flag for PNG, double check & abort if not -- then it is not an icon file
                bIconFile = ParsePNGheader(icEntry)
                
            Else    ' use the bitcount from the bitmap header
                m_icDirE(icEntry).wBitCount = icBytesNeed
            End If
        Next
    
        If bIconFile = True Then
            LoadStream = True

            If Not cHost Is Nothing Then
            
                ' appears we have a valid icon file. Find closest match for requested size
                If desiredWidth < 1 Then desiredWidth = 32& ' default if none provided
                If desiredHeight < 1 Then desiredHeight = 32&
                icEntry = GetBestMatch(desiredWidth, desiredHeight, icoBitDepth)
                
                If Not icEntry = 0 Then ' else something is wrong with the icon structure(s) in this file
                
                    If IsIconPNG(icEntry) Then ' png flag
                        
                        ' we need to pass this off to a PNG class for parsing/processing
                        Set cPNG = New cPNGparser
                        LoadStream = cPNG.LoadStream(inStream, cHost, m_icDirE(icEntry).dwImageOffset, m_icDirE(icEntry).dwBytesInRes, GlobalToken)
                        Set cPNG = Nothing
                        If Not cHost.Handle = 0& Then cHost.ImageType = imgPNGicon
                        
                    Else
                        ' create the main application's image, blank.
                        cHost.InitializeDIB Width(icEntry), Height(icEntry)
                        
                        ' copy the bitmap information header and fix it. Per MSDN, not all
                        ' members of the header are required to be filled in. We need them.
                        CopyMemory tBMPI.bmiHeader, m_Bits(m_icDirE(icEntry).dwImageOffset), 40&
                        With tBMPI.bmiHeader
                            .biClrUsed = ColorCount(icEntry)    ' fix when bitcount <= 8bpp
                            .biHeight = Height(icEntry)         ' height is doubled; fix it
                            .biSizeImage = 0                    ' erase; don't need this
                            .biXPelsPerMeter = 0                ' erase; don't need this
                            .biYPelsPerMeter = 0                ' erase; don't need this
                        End With
                        ' copy the fixed header back into the array
                        CopyMemory m_Bits(m_icDirE(icEntry).dwImageOffset), tBMPI.bmiHeader, 40&
                        
                        ' the next part of the routine is to create a compatible bitmap using
                        ' maximum screen colors on the system.  We will use the API to create it
                        ' for us from the bitmap header we just tweaked above. Otherwise we would
                        ' have to parse the bits ourselves, bloating code to handle 7 possible bit
                        ' depths in combination with several compression algorithms & various RGB masks.
                        tDC = GetDC(0&)
                        hDib = CreateDIBitmap(tDC, tBMPI.bmiHeader, 4, m_Bits(ColorByteOffset(icEntry)), m_Bits(m_icDirE(icEntry).dwImageOffset), 0&)
                        
                        If hDib = 0& Then
                            ReleaseDC 0&, tDC
                            cHost.DestroyDIB
                            ' major problem here; the icon contained in the stream appears to be faulty
                            ' we can't use it. Abort.
                        Else
                            ' here we are defining our application's image.
                            With tBMPI.bmiHeader
                                .biSize = 40&
                                .biBitCount = 32            ' 32bpp
                                .biHeight = cHost.Height    ' same width & height
                                .biWidth = cHost.Width      ' of the source image
                                .biPlanes = 1
                                .biSizeImage = .biHeight * .biWidth * 4&
                            End With
                            ' transfer the image bits from the bitmap created from the array to
                            ' our application's image
                            GetDIBits tDC, hDib, 0&, cHost.Height, ByVal cHost.BitsPointer, tBMPI, 0&
                            ReleaseDC 0&, tDC               ' release dc; don't need it any longer
                            DeleteObject hDib               ' kill the source bitmap; not needed
                            ApplyAlphaMask icEntry, cHost   ' add the alpha channel to app's image
                        End If
                    End If
                End If
            End If
        End If
    End If
    CopyMemory ByVal VarPtrArray(m_Bits), 0&, 4&    ' remove overlay
    
End Function

Public Function ConvertstdPicTo32bpp(Handle As Long, cHost As c32bppDIB) As Boolean

    ' Purpose: Convert a single icon from a stdPicture or handle to a 32bpp bitmap

    If Handle = 0& Then Exit Function
    
    Dim tSA As SafeArray
    Dim icoInfo As ICONINFO, tBMPI As BITMAPINFO
    Dim tBMPc As BITMAPINFO, tBMPm As BITMAPINFO
    Dim tDC As Long, hostDC As Long
    Dim x As Long, y As Long
    
    ' see if we can get the icon information
    If GetIconInfo(Handle, icoInfo) = 0& Then Exit Function
    
    m_icDir.idCount = 1
    m_icDir.idType = icoInfo.fIcon ' 0=icon, 1=cursor
    ReDim m_icDirE(1 To 1)  ' we will have 1 entry
    
    tDC = GetDC(0&)
    
    If Not icoInfo.hbmColor = 0& Then    ' do we have a color image? no for B&W
        tBMPc.bmiHeader.biSize = 40    ' let's fill in the BitmapInfo header
        If GetDIBits(tDC, icoInfo.hbmColor, 0&, 0&, ByVal 0&, tBMPc, 0&) = 0& Then
            m_icDir.idCount = 0 ' oops; something critical happened
        Else
            With tBMPI.bmiHeader    ' now fill in our destination description
                .biBitCount = 32
                .biHeight = tBMPc.bmiHeader.biHeight
                .biWidth = tBMPc.bmiHeader.biWidth
                .biPlanes = 1
                .biSize = 40&
                cHost.InitializeDIB .biWidth, .biHeight ' setup destination DIB
            End With
            ' use API again, to pass the bits from the color icon image to our DIB
            GetDIBits tDC, icoInfo.hbmColor, 0&, tBMPc.bmiHeader.biHeight, ByVal cHost.BitsPointer, tBMPI, 0&
        
            ' we will ensure the passed icon is not already a 32bpp ARGB image
            ' stdPictures won't be this way, but a call to LoadIconFromFile API can load XP icons
            With tSA
                .cbElements = 1
                .cDims = 2
                .pvData = cHost.BitsPointer
                .rgSABound(0).cElements = cHost.Height
                .rgSABound(1).cElements = cHost.scanWidth
            End With
            CopyMemory ByVal VarPtrArray(m_Bits), VarPtr(tSA), 4&
            m_icDirE(1).wBitCount = 1
            For y = 0 To cHost.Height - 1
                For x = 3 To cHost.scanWidth - 1 Step 4
                    If Not m_Bits(x, y) = 0 Then
                        m_icDirE(1).wBitCount = 32  ' looking for any non-zero alpha byte
                        y = cHost.Height            ' force outer loop to terminate
                        Exit For
                    End If
                Next
            Next
            If m_icDirE(1).wBitCount = 32 Then
                ' premultiply DIB as needed & set host imagetype, alpha properties
                iparseValidateAlphaChannel m_Bits, True, True, 0&
                If m_icDir.idType = 1 Then cHost.ImageType = imgIconARGB Else cHost.ImageType = imgCursorARGB
                cHost.Alpha = True
            End If
            CopyMemory ByVal VarPtrArray(m_Bits), 0&, 4&
        End If
    Else
        m_icDirE(1).wBitCount = 1   ' b&w icon/cursor
    End If
    
    ' pretty much same thing for the B&W, 1bpp mask
    ' Valid icons always have a mask, so no need to check .hbmMask=0 since this
    ' icon exists in a stdPicture and that, in itself, validated the icon for us
    If m_icDirE(1).wBitCount = 1 Then   ' else already processed as 32bpp icon/cursor
        If m_icDir.idCount = 1 Then
            tBMPm.bmiHeader.biSize = 40&
            If GetDIBits(tDC, icoInfo.hbmMask, 0, 0, ByVal 0&, tBMPm, 0) = 0 Then
                m_icDir.idCount = 0 ' oops; something critical happened
            Else
                With tBMPI.bmiHeader
                    If icoInfo.hbmColor = 0& Then
                        ' we have a b&w icon
                        .biBitCount = 32
                        .biHeight = tBMPm.bmiHeader.biHeight \ 2
                        .biWidth = tBMPm.bmiHeader.biWidth
                        .biPlanes = 1
                        .biSize = 40&
                        ' render the icon onto our dib
                        ' Note: in IDE, icon/cursor will be b&w, but when compiled
                        ' if the cursor had colors, the colors will be shown
                        cHost.InitializeDIB .biWidth, .biHeight  ' setup destination DIB
                        hostDC = cHost.LoadDIBinDC(True)
                        DrawIcon hostDC, 0, 0, Handle
                        cHost.LoadDIBinDC False
                        
                    End If
                    ' size our local array to hold the mask bits; these will be used
                    ' to tweak the 32bpp DIB's alpha channel in ApplyAlphaMask
                    ReDim m_Bits(0 To iparseByteAlignOnWord(1, .biWidth) * .biHeight - 1&)
                End With
                
                ' prepare bitmap info for our 1bpp mask array
                tBMPI.bmiPalette(1) = vbWhite
                With tBMPI.bmiHeader
                    .biBitCount = 1
                    .biClrUsed = 2
                End With
                ' use API again to pass the 1bpp image to our array
                GetDIBits tDC, icoInfo.hbmMask, 0&, tBMPI.bmiHeader.biHeight, m_Bits(0), tBMPI, 0&
                
                ' fill in the icon entry structure
                With m_icDirE(1)
                    .bHeight = tBMPI.bmiHeader.biHeight
                    .bWidth = tBMPm.bmiHeader.biWidth
                    .dwBytesInRes = UBound(m_Bits) + 1& ' we only have a mask in our array
                    .wBitCount = 1  ' the bitmap retrieved from the icon/cursor can be 32bpp
                    .wPlanes = 1    ' so we force the ApplyAlphaMask to use the 1bpp parsing routine
                End With
            
            End If
        End If
    End If
    ReleaseDC 0&, tDC
    
    ' clean up; GetIconInfo creates up to 2 bitmaps we must destroy
    If Not icoInfo.hbmColor = 0& Then DeleteObject icoInfo.hbmColor
    If Not icoInfo.hbmMask = 0& Then DeleteObject icoInfo.hbmMask
    
    If m_icDir.idCount = 1 Then           ' no errors encountered
        If m_icDirE(1).wBitCount = 1 Then ' now apply the mask
            ApplyAlphaMask 1&, cHost
            Erase m_Bits()
        End If
        ConvertstdPicTo32bpp = True
    End If
    
End Function

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -