鄙人查当懒,望大家见谅。正好今天回复VB版的某贴子写了几行字,感觉有点用处,就记录下来
虽然代码都是现成的,但是要改成VB,那也不是很简单的事情。如果你把所有的东西都弄完,粗粗估计也要半个月到一个月,而且还要求其中所有的技术访问都比较娴熟。
如果只是把资源数据的结构分解出来,倒不算难。MSDN(http://msdn.microsoft.com/en-us/library/ms648027(VS.85).aspx)已经说得很清楚。
基本上:
- struct RESOURCEHEADER {
- DWORD DataSize;
- DWORD HeaderSize;
- [Ordinal or name TYPE];
- [Ordinal or name NAME];
- DWORD DataVersion;
- WORD MemoryFlags;
- WORD LanguageId;
- DWORD Version;
- DWORD Characteristics;
- };
改为VB就是:
- Type RESOURCEHEADER
- DataSizeas Long
- HeaderSizeas Long
- ResTypeas Variant' [Ordinal or name TYPE];
- ResNameas Variant'需要说明的就是这里的Type和Name,有可能是一个字符串,也有可能是一个双字节整型,所以用Variant[Ordinal or name NAME];
- DataVersionas Long
- MemoryFlagsas Integer
- LanguageIdas Integer
- Versionas Long
- Characteristicsas Long
- ResData()as Byte '这是具体的数据,可以留给后续处理时使用,仅当DataSize<>0时才有
- End Type
读取的时候,可以直接读取八个字节到DataSize+HeaderSize
其中HeaderSize是包括DataSize和HeadSize在内的整个资源描述头的占用字节数,当这个HeaderSize确定之后,自然就可以根据DataSize读取具体的数据住处到ResData(读入前记得ReDim,仅当DataSize不为“零”时处理),剩余的就是下一段的数据的,可以不用理会
接着就是ResType和ResName的处理.先假定整个头部的信息为ResHead,那么前面已经处理了八个字节,接下来就从第九个字节开始处理,如果第9+第10个字节合起来为一个字(Word),可以直接Copy到Integer类型当中,如果其值为&hFFFF(一个无效的Unicode字)相当于-1(Integer),则后面接着的两个字节就是一个数字,即ResType为两个字节的数值(具体代表是什么资源可以自己查MSDN:http://msdn.microsoft.com/en-us/library/ms648009(VS.85).aspx),如果第9和第10个字节合起来不是&hFFFF,则表示ResType是了个Unicode字串,那么就两个字节两个字节的查,直到为0(Integer),假字第11和12字节合起来是0值,则9和10组成了一个Unicode字,只时只需要使用一个string变量分配一个字节,比如StrResType = space(1),然后再通过CopyMemory复制两个字节到StrResType当中,就取得了ResType,把11和12这个0值抛弃,(提示:请记录从第9个字节开始已经处理了多少个字节,比如记作nResType,后面还有用)。
接着是ResName的处理,处理方法跟ResType一样,同样的也要记录处理了多少字节,记作nResName
计算nResType+nResName 模(mod)上4,如果不为0(只能是2),则继续抛弃2个字节,否则不需要继续往下。
后面就非常简单了,DataVersion要四个字节,MemoryFlags要两个字节,LanguageId要两个字节,Version要四个字节,Characteristics要四个字节。
如此一段资源就分解完了。
数据部分则要根据ResType去处理,如果是系统预定义的类型,则参考具体的资源结构进行分解和处理。但是有些结构是用户自定义的,你就只能把它当二进制数据读取出来。当然,如果其中是二进制文件资源的话,比如PE文件(包括.exe或.dll等)可以通过检测PE文件的格式来确定。