VB动态更改窗口图标的类(支持WinXP的32位图标)

该VB6类库用于从文件或字节数组中加载图标资源,并为应用程序设置图标。支持获取图标的不同尺寸、颜色等属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Option Explicit

'======== clsIcon.cls ========

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 Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam 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 iCount As Integer
Private iDir As ICONDIR
Private lpData() As Byte

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

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

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

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

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

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

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

If Dir(lpFileName) = "" Then Exit Function

hFile = FreeFile
Open lpFileName For Binary As #hFile
ReDim Data(LOF(hFile) - 1)
Get #hFile, , Data
Close #hFile

LoadFromFile = LoadFromData(Data)
End Function

Public Property Get hIcon(Optional ByVal Index As Long) As Long
Dim d() As Byte, l As Long, w As Long, h As Long
d = Data(Index): l = Length(Index)
w = Width(Index): h = Height(Index)
hIcon = CreateIconFromResourceEx(d(0), l, 1, &H30000, w, h, 0)
End Property

Public Function Draw(ByVal hdc As Long, ByVal x As Long, ByVal y As Long, Optional ByVal Index As Long = 0) As Boolean
Dim w As Long, h As Long
w = Width(Index): h = Height(Index)
Draw = DrawIconEx(hdc, x, y, hIcon(Index), w, h, 0, 0, 3) <> 0
DestroyIcon hIcon
End Function

Public Sub SetFormIcon(ByVal lhWnd As Long, Optional ByVal Index As Long = 0)
SendMessageLong lhWnd, &H80, 0, hIcon(Index)
End Sub

Private Sub Class_Terminate()
Erase lpData
End Sub


'使用如下代码更改一个窗口的图标

If Dir(App.Path & "/Icon.ico") = "" Then Exit Sub 'Function
Dim ic As New clsIcon
ic.LoadFromFile App.Path & "/Icon.ico"
ic.SetFormIcon Me.hWnd 'hWnd Of a Window
Set ic = Nothing

  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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值