private void createIconResources(ResImageGroupData idata, byte[] iconbytes) { //now we've re-created the .ico file as a memory stream //extract each icon from it by the icon dimensions from the data directory MemoryStream ms = new MemoryStream(iconbytes); ResData image = null; for (int i = 0; i < idata.entries.Count; i++) { ResImageGroupDataEntry ientry = idata.entries[i]; ms.Position = 0; Icon iconRes = new Icon(ms, (int)ientry.bWidth, (int)ientry.bHeight); //get the icon ientry.image = iconRes; //link it to this res obj foreach (ResData imagedata in iconItems) { if (imagedata.id == ientry.nID) { image = imagedata; break; } } //and add it to the ICON resource list as well if (image != null) { addIcon(image.id, image.name, image.lang, iconRes); getDataItem(icons, image.id, image.name).getItem(image.lang).dataBuf = image.data; } } }
//- icon loading -------------------------------------------------------------- //we create an .ico file in memory for icon resources private byte[] buildIconFile(ResImageGroupData idata) { //build .ico file header byte[] hdrbytes = { 0, 0, 1, 0, 0, 0 }; hdrbytes[4] = (byte)(idata.entries.Count % 0x100); hdrbytes[5] = (byte)(idata.entries.Count / 0x100); //build .ico data directory int datapos = 6 + (0x10 * idata.entries.Count); byte[] dirbytes = new byte[0x10 * idata.entries.Count]; int dirpos = 0; for (int i = 0; i < idata.entries.Count; i++) { ResImageGroupDataEntry ientry = idata.entries[i]; dirbytes[dirpos++] = (byte)ientry.bWidth; dirbytes[dirpos++] = (byte)ientry.bHeight; dirbytes[dirpos++] = (byte)ientry.bColorCount; dirbytes[dirpos++] = 0; dirbytes[dirpos++] = (byte)(ientry.wPlanes % 0x100); dirbytes[dirpos++] = (byte)(ientry.wPlanes / 0x100); dirbytes[dirpos++] = (byte)(ientry.wBitCount % 0x100); dirbytes[dirpos++] = (byte)(ientry.wBitCount / 0x100); byte[] sizebytes = BitConverter.GetBytes(ientry.dwBytesInRes); Array.Copy(sizebytes, 0, dirbytes, dirpos, 4); byte[] posbytes = BitConverter.GetBytes(datapos); Array.Copy(posbytes, 0, dirbytes, dirpos + 4, 4); dirpos += 8; datapos += (int)ientry.dwBytesInRes; } byte[] iconbytes = new byte[datapos]; //total .ico data buf Array.Copy(hdrbytes, 0, iconbytes, 0, 6); Array.Copy(dirbytes, 0, iconbytes, 6, dirbytes.Length); //copy the .ico header to it //append icon data for each icon in directory datapos = 6 + (0x10 * idata.entries.Count); ResData image = null; for (int i = 0; i < idata.entries.Count; i++) { ResImageGroupDataEntry ientry = idata.entries[i]; foreach (ResData imagedata in iconItems) //find the matching icon data { if (imagedata.id == ientry.nID) { image = imagedata; break; } } if (image != null) { Array.Copy(image.data, 0, iconbytes, datapos, image.data.Length); //and add it to the data buf datapos += image.data.Length; } } return iconbytes; }
//- cursor loading ------------------------------------------------------------ //the C# Cursor class is limited for displaying as an image, so we use an Icon obj instead //we create an .ico file in memory for cursor resources private byte[] buildCursorFile(ResImageGroupData idata, int entrynum) { //build .ico file header byte[] hdrbytes = { 0, 0, 1, 0, 1, 0 }; //build .ico data directory for a single cursor resource int datapos = 0x16; byte[] dirbytes = new byte[0x10]; int dirpos = 0; ResImageGroupDataEntry ientry = idata.entries[entrynum]; dirbytes[dirpos++] = (byte)ientry.bWidth; dirbytes[dirpos++] = (byte)ientry.bWidth; //square icon dirbytes[dirpos++] = 2; //monochrome dirbytes[dirpos++] = 0; dirbytes[dirpos++] = 1; dirbytes[dirpos++] = 0; dirbytes[dirpos++] = 1; dirbytes[dirpos++] = 0; uint bsize = ientry.dwBytesInRes - 4; byte[] sizebytes = BitConverter.GetBytes(bsize); Array.Copy(sizebytes, 0, dirbytes, dirpos, 4); byte[] posbytes = BitConverter.GetBytes(datapos); Array.Copy(posbytes, 0, dirbytes, dirpos + 4, 4); dirpos += 8; datapos += (int)ientry.dwBytesInRes; byte[] cursorbytes = new byte[datapos]; //total .cur data buf Array.Copy(hdrbytes, 0, cursorbytes, 0, 6); Array.Copy(dirbytes, 0, cursorbytes, 6, 0x10); //copy the .cur header to it //append cursor data for each icon in directory ResData image = null; foreach (ResData imagedata in cursorItems) //find the matching cursor data { if (imagedata.id == ientry.nID) { image = imagedata; break; } } if (image != null) { Array.Copy(image.data, 4, cursorbytes, 0x16, image.data.Length - 4); //and add it to the data buf, skip the hotspot bytes } return cursorbytes; }
private void createCursorResources(ResImageGroupData idata, byte[] cursorbytes, int entrynum) { //get the cursor image from the .ico file we've created in memory MemoryStream ms = new MemoryStream(cursorbytes); ms.Position = 0; Icon curRes = new Icon(ms); //get the cursor ResImageGroupDataEntry ientry = idata.entries[entrynum]; ientry.image = curRes; //link it to this res obj ResData image = null; foreach (ResData curdata in cursorItems) { if (curdata.id == ientry.nID) { image = curdata; break; } } //and add it to the CUSROR resource list as well if (image != null) { addCursor(image.id, image.name, image.lang, curRes); getDataItem(cursors, image.id, image.name).getItem(image.lang).dataBuf = image.data; } }
//leaf node of resource directory tree, this rec points to actual data private void parseResourceData(BinaryIn source) { uint datapos = source.getFour(); uint datasize = source.getFour(); uint codepage = source.getFour(); uint reserved = source.getFour(); datapos -= resourceRVA; byte[] resdata = source.getRange(datapos, datasize); //get resource data //get the store type/id/lang vals we stored in our decent to this node uint restype = resIdNameValues[0]; uint resid = resIdNameValues[1]; String resname = (resid >= 0x80000000) ? getResourceName(source, resid) : null; uint reslang = resIdNameValues[2]; switch (restype) { case 1: ResData curdata = new ResData(resid, resname, reslang, resdata); cursorItems.Add(curdata); break; case 2: Bitmap bmp = ResBitmap.parseData(resdata); addBitmap(resid, resname, reslang, bmp); getDataItem(bitmaps, resid, resname).getItem(reslang).dataBuf = resdata; break; case 3: ResData icondata = new ResData(resid, resname, reslang, resdata); iconItems.Add(icondata); break; case 4: addMenu(resid, resname, reslang, resdata); //List<String> menu = ResMenu.parseData(resdata); //addMenu(resid, resname, reslang, menu); getDataItem(menus, resid, resname).getItem(reslang).dataBuf = resdata; break; case 5: addDialog(resid, resname, reslang, resdata); //List<String> dlg = ResDialog.parseData(resdata); //addDialog(resid, resname, reslang, dlg); getDataItem(dialogs, resid, resname).getItem(reslang).dataBuf = resdata; break; case 6: List<String> strings = ResStringTable.parseData(resdata); addStringTable(resid, resname, reslang, strings); getDataItem(stringtable, resid, resname).getItem(reslang).dataBuf = resdata; break; case 7: addFontDirectory(resid, resname, reslang, resdata); getDataItem(fontDirectories, resid, resname).getItem(reslang).dataBuf = resdata; break; case 8: addFont(resid, resname, reslang, resdata); getDataItem(fonts, resid, resname).getItem(reslang).dataBuf = resdata; break; case 9: List<String> accel = ResAccelerator.parseData(resdata); addAccelerator(resid, resname, reslang, accel); getDataItem(accelerators, resid, resname).getItem(reslang).dataBuf = resdata; break; case 10: addUserData(resid, resname, reslang, resdata); getDataItem(userData, resid, resname).getItem(reslang).dataBuf = resdata; break; case 12: ResImageGroupData cg = ResImageGroupData.parseData(resdata); addCursorGroup(resid, resname, reslang, cg); getDataItem(cursorGroups, resid, resname).getItem(reslang).dataBuf = resdata; break; case 14: ResImageGroupData ig = ResImageGroupData.parseData(resdata); addIconGroup(resid, resname, reslang, ig); getDataItem(iconGroups, resid, resname).getItem(reslang).dataBuf = resdata; break; case 16: addVersion(resid, resname, reslang, resdata); //List<String> version = ResVersion.parseData(resdata); //addVersion(resid, resname, reslang, version); getDataItem(versions, resid, resname).getItem(reslang).dataBuf = resdata; break; default: addUserData(resid, resname, reslang, resdata); getDataItem(userData, resid, resname).getItem(reslang).dataBuf = resdata; break; } }