VB6使用32位图标 代码收藏

本文详细介绍了如何在VB6中使用`CreateIconFromResourceEx`和`DrawIconEx`函数处理32位带Alpha通道的图标,包括源码展示和实际操作示例,展示了从文件加载图标并动态在窗体上绘制的过程。
摘要由CSDN通过智能技术生成

看到带Alpha通道的32位图标那绚丽性感的外表,对于无法逃离“爱美之心人皆有之”这句俗话的人(包括我)早就垂涎三尺了。感谢微软给我们选择美丽的机会,能让我们自己的软件也在外表上成为让别人倾慕甚至以身相许的筹码。想起来容易,做起来才发现整容工作原来还真没那么简单。对于饱读“有志者事竟成,破釜沉舟百二秦关终属楚......”的我......嗯嗯嗯,夸张的天昏地暗、飞沙走石...... 终于皇天不负苦心人(又来了,其实我官方身份是诗人。)一个Very very简单的类诞生了。说了一堆废话,还是贴上源码吧,免得被人唾骂。
' ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
'   VB6中使用32位图标
' :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 

Option   Explicit

Private  Type ICONDIRENTRY
    bWidth   As   Byte
    bHeight   As   Byte
    bColorCount   As   Byte
    bReserved   As   Byte
    wPlanes   As   Integer
    wBitCount   As   Integer
    dwBytesInRes   As   Long
    dwImageOffset   As   Long
End  Type

Private  Type ICONDIR
    idReserved  As   Integer
    idType  As   Integer
    idCount  As   Integer
    idEntries()  As  ICONDIRENTRY
End  Type

Private   Declare   Function  CreateIconFromResourceEx  Lib   " user32 "  (presbits  As   Byte ,  ByVal  dwResSize  As   Long ,  ByVal  fIcon  As   Long ,  ByVal  dwVer  As   Long ,  ByVal  cxDesired  As   Long ,  ByVal  cyDesired  As   Long ,  ByVal  uFlags  As   Long )  As   Long
Private   Declare   Function  DrawIconEx  Lib   " user32.dll "  ( ByVal  hdc  As   Long ,  ByVal  xLeft  As   Long ,  ByVal  yTop  As   Long ,  ByVal  hIcon  As   Long ,  ByVal  cxWidth  As   Long ,  ByVal  cyWidth  As   Long ,  ByVal  istepIfAniCur  As   Long ,  ByVal  hbrFlickerFreeDraw  As   Long ,  ByVal  diFlags  As   Long )  As   Long
Private   Declare   Function  DestroyIcon  Lib   " user32 "  ( ByVal  hIcon  As   Long )  As   Long
Private   Declare   Sub  CopyMemory  Lib   " kernel32.dll "   Alias   " RtlMoveMemory "  ( ByRef  Destination  As  Any,  ByRef  Source  As  Any,  ByVal  Length  As   Long )

Private  m_Data()  As   Byte
Private  m_iCount  As   Integer
Private  m_iDir  As  ICONDIR

Public   Property   Get  Count()  As   Long
    Count  =  m_iCount
End Property

Public   Property   Get  Height( Optional   ByVal  Index  As   Long )  As   Long
    Height  =  m_iDir.idEntries(Index).bHeight
End Property

Public   Property   Get  Width( Optional   ByVal  Index  As   Long )  As   Long
    Width  =  m_iDir.idEntries(Index).bWidth
End Property

Public   Property   Get  Length( Optional   ByVal  Index  As   Long )  As   Long
    Length  =  m_iDir.idEntries(Index).dwBytesInRes
End Property

Public   Property   Get  Data( Optional   ByVal  Index  As   Long )  As   Byte ()
     Dim  o  As   Long , l  As   Long , d()  As   Byte
    o  =  m_iDir.idEntries(Index).dwImageOffset
    l  =  m_iDir.idEntries(Index).dwBytesInRes
     ReDim  d(l  -   1 )
    CopyMemory d( 0 ), m_Data(o), l
    Data  =  d
End Property

Public   Function  LoadFromData(Data()  As   Byte )  As   Boolean
     Dim  i  As   Long
    m_Data  =  Data
    CopyMemory m_iCount, m_Data( 4 ),  2                        ' 取得图标个数
     If  m_iCount  >   0   Then
         ReDim  m_iDir.idEntries( 0   To  m_iCount  -   1 )           ' 图标目录结构数据
         For  i  =   0   To  m_iCount  -   1
            CopyMemory m_iDir.idEntries(i), m_Data( 6   +   Len (m_iDir.idEntries(i))  *  i),  Len (m_iDir.idEntries(i))
         Next
        LoadFromData  =   True
     End   If
End Function

Public   Function  LoadFromFile( ByVal  FileName  As   String )  As   Boolean
     Dim  hFile  As   Integer
     Dim  Data()  As   Byte

     If   Dir (FileName)  =   ""   Then   Exit Function
    
    hFile  =   FreeFile
    Open FileName  For  Binary  As  #hFile
     ReDim  Data( LOF (hFile)  -   1 )
     Get  #hFile, , Data
    Close #hFile

    LoadFromFile  =  LoadFromData(Data)
End Function

Public   Function  Draw( ByVal  hdc  As   Long ,  ByVal  x  As   Long ,  ByVal  y  As   Long ,  Optional   ByVal  Index  As   Long   =   0 )  As   Boolean
     Dim  d()  As   Byte , l  As   Long , r  As   Long , w  As   Long , h  As   Long
    d  =  Data(Index): l  =  Length(Index)
    w  =  Width(Index): h  =  Height(Index)
    r  =  CreateIconFromResourceEx(d( 0 ), l,  1 ,  & H30000, w, h,  0 )
    Draw  =  DrawIconEx(hdc, x, y, r, w, h,  0 ,  0 ,  3 )  <>   0
    DestroyIcon r
End Function

Private   Sub  Class_Terminate()
     Erase  m_Data
End Sub

示例代码:

Private   Sub  Command1_Click()
     Dim  Icon  As   New  Icon
     Dim  IconIndex  As   Long
    
    IconIndex  =   3   ' 要显示的图标在图标组中的索引
    Icon.LoadFromFile App.Path  &   " a.ico "
    
     Me .Cls
    Icon.Draw  Me .hdc, ( Me .ScaleWidth  -  Icon.Width(IconIndex))  /   2 , ( Me .ScaleHeight  -  Icon.Height(IconIndex))  /   2 , IconIndex
     Me .Refresh
    
     Set  Icon  =   Nothing
End Sub

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
  VB6本身只支持16色(4位)和256色(8位)的图标,这种图标只是早期的Windows版本所采用的 图标格式标准。现在各种高清真彩色(32位带Alpha通道、24位不带Alpha通道)早已经很流行 并且普遍使用了,但在VB6中却不能直接支持、使用。即使想把这种真彩色图标加入图标资源、 或者是把它加入ImageList控件中,也会被提示“无效图片”而不能加入。记得论坛中曾经有某 位高人说过,VB6的Form是支持真彩色图标的,可以给窗体设置真彩色图标。   昨天上午我试了一下,新建一个标准EXE工程,然后随意找了一个高清真彩图标文件,给工 程的Form1设置Icon属性,成功了……… 但是,感觉它显示的图标有点怪异,总觉得有些不对 劲呢…… 于是,我把这个高清图标文件中32×32和16×16这两种规格的真彩色图标单独提取 出来,分别保存为一个.ico格式的文件,然后再用这两个图标文件来给它设置Icon属性。果然, 这两个文件在操作时VB6都提示“无效图片”!!!这就说明:VB6是不支持真彩色图标的。最 开始时“能设置成功”,只不过是因为它从图标组中找到了256色的、它能支持的格式罢了。   闲话不多说了,这个模块进行了简单的封装,提供了一些基础的操作功能。源码中有比较 详细的注释,使用起来应该是很简单的,就不再写什么“应用示例代码”了。首先要调用接口 函数装载图标,从图标文件加载就调用LoadFromFile(),从字节数组加载就调用LoadData()。 加载成功后,即可调用其它接口来使用图标对象了,比如用GDI方式把图标画到窗口内、或者画 到某个PictureBox上、给自己的窗口或别的程序窗口设置一个真彩色图标等。虽然在“资源” 中不能以“图标”的方式把真彩图标加入,但是,却可以按“自定义资源”的方式把图标文件 装入,使用时读取出对应的资源数据,然后调用函数LoadFromData()进行加载。加载成功就可 以使用里面的真彩色图标了。   这个模块只提供了一些基本的功能,如果有需要可以自己再进行扩展。还有就是没有进行 异常处理,因此要求用来加载的文件必须是正确的图标文件、并且可以读取;数组数据则必须 是合法的图标文件数据。否则可能会引起异常,你也可以修改代码进行异常捕获处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

专注VB编程开发20年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值