#include "..\include_eapi_header.h"#include <algorithm>/*开源库icon.h*/namespace eapi_openlib_icon {#pragma region 开源库代码#pragma warning(disable :28183)#pragma warning(disable :6387)#pragma warning(disable :6385)#pragma warning(disable :6386)#pragma warning(disable :6011)#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#pragma pack( push )#pragma pack( 2 )typedef struct{BYTE bWidth;BYTE bHeight;BYTE bColorCount;BYTE bReserved;WORD wPlanes;WORD wBitCount;DWORD dwBytesInRes;WORD nID;} MEMICONDIRENTRY, * LPMEMICONDIRENTRY;typedef struct{WORD idReserved;WORD idType;WORD idCount;MEMICONDIRENTRY idEntries[1];} MEMICONDIR, * LPMEMICONDIR;#pragma pack( pop )typedef struct{BYTE bWidth;BYTE bHeight;BYTE bColorCount;BYTE bReserved;WORD wPlanes;WORD wBitCount;DWORD dwBytesInRes;DWORD dwImageOffset;} ICONDIRENTRY, * LPICONDIRENTRY;typedef struct{WORD idReserved;WORD idType;WORD idCount;ICONDIRENTRY idEntries[1];} ICONDIR, * LPICONDIR;typedef struct{UINT Width, Height, Colors;LPBYTE lpBits;DWORD dwNumBytes;LPBITMAPINFO lpbi;LPBYTE lpXOR;LPBYTE lpAND;} ICONIMAGE, * LPICONIMAGE;typedef struct{BOOL bHasChanged;CHAR szOriginalICOFileName[MAX_PATH];CHAR szOriginalDLLFileName[MAX_PATH];UINT nNumImages;ICONIMAGE IconImages[1];} ICONRESOURCE, * LPICONRESOURCE;typedef struct{DWORD dwBytes;DWORD dwOffset;} RESOURCEPOSINFO, * LPRESOURCEPOSINFO;typedef struct{LPCSTR szFileName;HINSTANCE hInstance;LPSTR lpID;} EXEDLLICONINFO, * LPEXEDLLICONINFO;#define MAX_ICON_WIDTH 128#define MIN_ICON_WIDTH 16#define MAX_ICON_HEIGHT MAX_ICON_WIDTH#define MIN_ICON_HEIGHT MIN_ICON_WIDTHclass MyIcon{public:MyIcon();virtual ~MyIcon();public:LPICONRESOURCE ReadIconFromICOFile(LPCSTR szFileName);BOOL WriteIconToICOFile(LPICONRESOURCE lpIR, LPCSTR szFileName);HICON MakeIconFromResource(LPICONIMAGE lpIcon);LPICONRESOURCE ReadIconFromEXEFile(LPCSTR szFileName, LPCSTR lpID);BOOL IconImageToClipBoard(LPICONIMAGE lpii);BOOL IconImageFromBMPFile(LPCSTR szFileName, LPICONIMAGE lpii, BOOL bStretchToFit);BOOL IconImageToBMPFile(LPCSTR szFileName, LPICONIMAGE lpii);private:UINT ReadICOHeader(HANDLE hFile);BOOL AdjustIconImagePointers(LPICONIMAGE lpImage);BOOL WriteICOHeader(HANDLE hFile, UINT nNumEntries);DWORD CalculateImageOffset(LPICONRESOURCE lpIR, UINT nIndex);BOOL DIBToIconImage(LPICONIMAGE lpii, LPBYTE lpDIB, BOOL bStretch);};#if _MSC_VER > 1000#pragma once#endif#define WIDTHBYTES(bits) ((((bits) + 31)>>5)<<2)class MyDib{public:MyDib();virtual ~MyDib();public:LPSTR FindDIBBits(LPSTR lpbi);WORD DIBNumColors(LPSTR lpbi);WORD PaletteSize(LPSTR lpbi);DWORD BytesPerLine(LPBITMAPINFOHEADER lpBMIH);LPBYTE ConvertDIBFormat(LPBITMAPINFO lpSrcDIB, UINT nWidth, UINT nHeight, UINT nColors, BOOL bStretch);void SetMonoDIBPixel(LPBYTE pANDBits, DWORD dwWidth, DWORD dwHeight, DWORD x, DWORD y, BOOL bWhite);LPBYTE ReadBMPFile(LPCSTR szFileName);BOOL WriteBMPFile(LPCSTR szFileName, LPBYTE lpDIB);private:BOOL CopyColorTable(LPBITMAPINFO lpTarget, LPBITMAPINFO lpSource);};MyDib::MyDib(){}MyDib::~MyDib(){}LPSTR MyDib::FindDIBBits(LPSTR lpbi){return (lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi));}WORD MyDib::DIBNumColors(LPSTR lpbi){WORD wBitCount;DWORD dwClrUsed;dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;if (dwClrUsed)return (WORD)dwClrUsed;wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;switch (wBitCount){case 1: return 2;case 4: return 16;case 8: return 256;default:return 0;}return 0;}WORD MyDib::PaletteSize(LPSTR lpbi){return (DIBNumColors(lpbi) * sizeof(RGBQUAD));}DWORD MyDib::BytesPerLine(LPBITMAPINFOHEADER lpBMIH){return WIDTHBYTES(lpBMIH->biWidth * lpBMIH->biPlanes * lpBMIH->biBitCount);}LPBYTE MyDib::ConvertDIBFormat(LPBITMAPINFO lpSrcDIB, UINT nWidth, UINT nHeight, UINT nbpp, BOOL bStretch){LPBITMAPINFO lpbmi = NULL;LPBYTE lpSourceBits, lpTargetBits, lpResult;HDC hDC = NULL, hSourceDC, hTargetDC;HBITMAP hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap;DWORD dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize;// Allocate and fill out a BITMAPINFO struct for the new DIB// Allow enough room for a 256-entry color table, just in casedwTargetHeaderSize = sizeof(BITMAPINFO) + (256 * sizeof(RGBQUAD));lpbmi = (LPBITMAPINFO)malloc(dwTargetHeaderSize);lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);lpbmi->bmiHeader.biWidth = nWidth;lpbmi->bmiHeader.biHeight = nHeight;lpbmi->bmiHeader.biPlanes = 1;lpbmi->bmiHeader.biBitCount = nbpp;lpbmi->bmiHeader.biCompression = BI_RGB;lpbmi->bmiHeader.biSizeImage = 0;lpbmi->bmiHeader.biXPelsPerMeter = 0;lpbmi->bmiHeader.biYPelsPerMeter = 0;lpbmi->bmiHeader.biClrUsed = 0;lpbmi->bmiHeader.biClrImportant = 0;// Fill in the color tableif (!CopyColorTable(lpbmi, (LPBITMAPINFO)lpSrcDIB)){free(lpbmi);return NULL;}// Gonna use DIBSections and BitBlt() to do the conversion, so make 'emhDC = GetDC(NULL);hTargetBitmap = CreateDIBSection(hDC, lpbmi, DIB_RGB_COLORS, (void**)&lpTargetBits, NULL, 0);hSourceBitmap = CreateDIBSection(hDC, lpSrcDIB, DIB_RGB_COLORS, (void**)&lpSourceBits, NULL, 0);hSourceDC = CreateCompatibleDC(hDC);hTargetDC = CreateCompatibleDC(hDC);// Flip the bits on the source DIBSection to match the source DIBdwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight * BytesPerLine(&(lpSrcDIB->bmiHeader));dwTargetBitsSize = lpbmi->bmiHeader.biHeight * BytesPerLine(&(lpbmi->bmiHeader));memcpy(lpSourceBits, FindDIBBits((LPSTR)lpSrcDIB), dwSourceBitsSize);// Select DIBSections into DCshOldSourceBitmap = (HBITMAP)SelectObject(hSourceDC, hSourceBitmap);hOldTargetBitmap = (HBITMAP)SelectObject(hTargetDC, hTargetBitmap);// Set the color tables for the DIBSectionsif (lpSrcDIB->bmiHeader.biBitCount <= 8)SetDIBColorTable(hSourceDC, 0, 1 << lpSrcDIB->bmiHeader.biBitCount, lpSrcDIB->bmiColors);if (lpbmi->bmiHeader.biBitCount <= 8)SetDIBColorTable(hTargetDC, 0, 1 << lpbmi->bmiHeader.biBitCount, lpbmi->bmiColors);// If we are asking for a straight copy, do itif ((lpSrcDIB->bmiHeader.biWidth == lpbmi->bmiHeader.biWidth) && (lpSrcDIB->bmiHeader.biHeight == lpbmi->bmiHeader.biHeight)){BitBlt(hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY);}else{// else, should we stretch it?if (bStretch){SetStretchBltMode(hTargetDC, COLORONCOLOR);StretchBlt(hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, lpSrcDIB->bmiHeader.biWidth, lpSrcDIB->bmiHeader.biHeight, SRCCOPY);}else{// or just take the upper left corner of the sourceBitBlt(hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY);}}// Clean up and delete the DCsSelectObject(hSourceDC, hOldSourceBitmap);SelectObject(hSourceDC, hOldTargetBitmap);DeleteDC(hSourceDC);DeleteDC(hTargetDC);ReleaseDC(NULL, hDC);// Flush the GDI batch, so we can play with the bitsGdiFlush();// Allocate enough memory for the new CF_DIB, and copy bitslpResult = (LPBYTE)malloc(dwTargetHeaderSize + dwTargetBitsSize);memcpy(lpResult, lpbmi, dwTargetHeaderSize);memcpy(FindDIBBits((LPSTR)lpResult), lpTargetBits, dwTargetBitsSize);// final cleanupDeleteObject(hTargetBitmap);DeleteObject(hSourceBitmap);free(lpbmi);return lpResult;}BOOL MyDib::CopyColorTable(LPBITMAPINFO lpTarget, LPBITMAPINFO lpSource){// What we do depends on the target's color depthswitch (lpTarget->bmiHeader.biBitCount){// 8bpp - need 256 entry color tablecase 8:if (lpSource->bmiHeader.biBitCount == 8){ // Source is 8bpp too, copy color tablememcpy(lpTarget->bmiColors, lpSource->bmiColors, 256 * sizeof(RGBQUAD));return TRUE;}else{ // Source is != 8bpp, use halftone paletteHPALETTE hPal;HDC hDC = GetDC(NULL);PALETTEENTRY pe[256];UINT i;hPal = CreateHalftonePalette(hDC);ReleaseDC(NULL, hDC);GetPaletteEntries(hPal, 0, 256, pe);DeleteObject(hPal);for (i = 0; i < 256; i++){lpTarget->bmiColors[i].rgbRed = pe[i].peRed;lpTarget->bmiColors[i].rgbGreen = pe[i].peGreen;lpTarget->bmiColors[i].rgbBlue = pe[i].peBlue;lpTarget->bmiColors[i].rgbReserved = pe[i].peFlags;}return TRUE;}break; // end 8bpp// 4bpp - need 16 entry color tablecase 4:if (lpSource->bmiHeader.biBitCount == 4){ // Source is 4bpp too, copy color tablememcpy(lpTarget->bmiColors, lpSource->bmiColors, 16 * sizeof(RGBQUAD));return TRUE;}else{ // Source is != 4bpp, use system paletteHPALETTE hPal;PALETTEENTRY pe[256];UINT i;hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);GetPaletteEntries(hPal, 0, 16, pe);for (i = 0; i < 16; i++){lpTarget->bmiColors[i].rgbRed = pe[i].peRed;lpTarget->bmiColors[i].rgbGreen = pe[i].peGreen;lpTarget->bmiColors[i].rgbBlue = pe[i].peBlue;lpTarget->bmiColors[i].rgbReserved = pe[i].peFlags;}return TRUE;}break; // end 4bpp// 1bpp - need 2 entry mono color tablecase 1:lpTarget->bmiColors[0].rgbRed = 0;lpTarget->bmiColors[0].rgbGreen = 0;lpTarget->bmiColors[0].rgbBlue = 0;lpTarget->bmiColors[0].rgbReserved = 0;lpTarget->bmiColors[1].rgbRed = 255;lpTarget->bmiColors[1].rgbGreen = 255;lpTarget->bmiColors[1].rgbBlue = 255;lpTarget->bmiColors[1].rgbReserved = 0;break; // end 1bpp// no color table for the > 8bpp modescase 32:case 24:case 16:default:return TRUE;break;}return TRUE;}void MyDib::SetMonoDIBPixel(LPBYTE pANDBits, DWORD dwWidth, DWORD dwHeight, DWORD x, DWORD y, BOOL bWhite){DWORD ByteIndex;BYTE BitNumber;// Find the byte on which this scanline beginsByteIndex = (dwHeight - y - 1) * WIDTHBYTES(dwWidth);// Find the byte containing this pixelByteIndex += (x >> 3);// Which bit is it?BitNumber = (BYTE)(7 - (x % 8));if (bWhite)// Turn it onpANDBits[ByteIndex] |= (1 << BitNumber);else// Turn it offpANDBits[ByteIndex] &= ~(1 << BitNumber);}LPBYTE MyDib::ReadBMPFile(LPCSTR szFileName){HANDLE hFile;BITMAPFILEHEADER bfh;DWORD dwBytes;LPBYTE lpDIB = NULL, lpTemp = NULL;WORD wPaletteSize = 0;DWORD dwBitsSize = 0;// Open the fileif ((hFile = CreateFileA(szFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE){return NULL;}// Read the headerif ((!ReadFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwBytes, NULL)) || (dwBytes != sizeof(BITMAPFILEHEADER))){CloseHandle(hFile);return NULL;}// Does it look like a BMP file?if ((bfh.bfType != 0x4d42) || (bfh.bfReserved1 != 0) || (bfh.bfReserved2 != 0)){CloseHandle(hFile);return NULL;}// Allocate some memoryif ((lpDIB = (LPBYTE)malloc(sizeof(BITMAPINFO))) == NULL){CloseHandle(hFile);return NULL;}// Read in the BITMAPINFOHEADERif ((!ReadFile(hFile, lpDIB, sizeof(BITMAPINFOHEADER), &dwBytes, NULL)) || (dwBytes != sizeof(BITMAPINFOHEADER))){CloseHandle(hFile);free(lpDIB);return NULL;}if (((LPBITMAPINFOHEADER)lpDIB)->biSize != sizeof(BITMAPINFOHEADER)){CloseHandle(hFile);free(lpDIB);return NULL;}// How big are the elements?wPaletteSize = PaletteSize((LPSTR)lpDIB);dwBitsSize = ((LPBITMAPINFOHEADER)lpDIB)->biHeight * BytesPerLine((LPBITMAPINFOHEADER)lpDIB);// realloc to account for the total size of the DIBif ((lpTemp = (LPBYTE)realloc(lpDIB, sizeof(BITMAPINFOHEADER) + wPaletteSize + dwBitsSize)) == NULL){CloseHandle(hFile);free(lpDIB);return NULL;}lpDIB = lpTemp;// If there is a color table, read itif (wPaletteSize != 0){if ((!ReadFile(hFile, ((LPBITMAPINFO)lpDIB)->bmiColors, wPaletteSize, &dwBytes, NULL)) || (dwBytes != wPaletteSize)){CloseHandle(hFile);free(lpDIB);return NULL;}}// Seek to the bits// checking against 0 in case some bogus app didn't set this elementif (bfh.bfOffBits != 0){if (SetFilePointer(hFile, bfh.bfOffBits, NULL, FILE_BEGIN) == 0xffffffff){CloseHandle(hFile);free(lpDIB);return NULL;}}// Read the image bitsif ((!ReadFile(hFile, FindDIBBits((LPSTR)lpDIB), dwBitsSize, &dwBytes, NULL)) || (dwBytes != dwBitsSize)){CloseHandle(hFile);free(lpDIB);return NULL;}// clean upCloseHandle(hFile);return lpDIB;}BOOL MyDib::WriteBMPFile(LPCSTR szFileName, LPBYTE lpDIB){HANDLE hFile;BITMAPFILEHEADER bfh;DWORD dwBytes, dwBytesToWrite;LPBITMAPINFOHEADER lpbmih;// Open the fileif ((hFile = CreateFileA(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE){return FALSE;}bfh.bfType = 0x4d42;bfh.bfReserved1 = 0;bfh.bfReserved2 = 0;bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + PaletteSize((LPSTR)lpDIB);bfh.bfSize = (bfh.bfOffBits + ((LPBITMAPINFOHEADER)lpDIB)->biHeight * BytesPerLine((LPBITMAPINFOHEADER)lpDIB)) / 4;// Write the headerif ((!WriteFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwBytes, NULL)) || (dwBytes != sizeof(BITMAPFILEHEADER))){CloseHandle(hFile);return FALSE;}lpbmih = (LPBITMAPINFOHEADER)lpDIB;// lpbmih->biHeight /= 2;dwBytesToWrite = bfh.bfOffBits + (lpbmih->biHeight * BytesPerLine(lpbmih));if ((!WriteFile(hFile, lpDIB, dwBytesToWrite, &dwBytes, NULL)) || (dwBytes != dwBytesToWrite)){CloseHandle(hFile);return FALSE;}lpbmih->biHeight *= 2;CloseHandle(hFile);return TRUE;}MyDib* pDib;MyIcon::MyIcon(){}MyIcon::~MyIcon(){}HICON MyIcon::MakeIconFromResource(LPICONIMAGE lpIcon){HICON hIcon = NULL;// Sanity Checkif (lpIcon == NULL)return NULL;if (lpIcon->lpBits == NULL)return NULL;// Let the OS do the real work :)hIcon = CreateIconFromResourceEx(lpIcon->lpBits, lpIcon->dwNumBytes, TRUE, 0x00030000,(*(LPBITMAPINFOHEADER)(lpIcon->lpBits)).biWidth, (*(LPBITMAPINFOHEADER)(lpIcon->lpBits)).biHeight / 2, 0);// It failed, odds are good we're on NT so try the non-Ex wayif (hIcon == NULL){// We would break on NT if we try with a 16bpp imageif (lpIcon->lpbi->bmiHeader.biBitCount != 16){hIcon = CreateIconFromResource(lpIcon->lpBits, lpIcon->dwNumBytes, TRUE, 0x00030000);}}return hIcon;}/* End MakeIconFromResource() **********************************************//****************************************************************************** FUNCTION: ReadIconFromICOFile** PURPOSE: Reads an Icon Resource from an ICO file** PARAMS: LPCSTR szFileName - Name of the ICO file** RETURNS: LPICONRESOURCE - pointer to the resource, NULL for failure**\****************************************************************************/LPICONRESOURCE MyIcon::ReadIconFromICOFile(LPCSTR szFileName){LPICONRESOURCE lpIR = NULL, lpNew = NULL;HANDLE hFile = NULL;LPRESOURCEPOSINFO lpRPI = NULL;UINT i;DWORD dwBytesRead;LPICONDIRENTRY lpIDE = NULL;// Open the fileif ((hFile = CreateFileA(szFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE){//MessageBox(AfxGetMainWnd()->m_hWnd, "ͼ���ļ���ɦ����!", szFileName, MB_OK);return NULL;}// Allocate memory for the resource structureif ((lpIR = (LPICONRESOURCE)malloc(sizeof(ICONRESOURCE))) == NULL){//MessageBox(AfxGetMainWnd()->m_hWnd, "ͼ������ڴ�ɦ����!", szFileName, MB_OK);CloseHandle(hFile);return NULL;}// Read in the headerif ((lpIR->nNumImages = ReadICOHeader(hFile)) == (UINT)-1){//MessageBox(AfxGetMainWnd()->m_hWnd, "��ͼ���ļ�ͷɦ����!", szFileName, MB_OK);CloseHandle(hFile);free(lpIR);return NULL;}// Adjust the size of the struct to account for the imagesif ((lpNew = (LPICONRESOURCE)realloc(lpIR, sizeof(ICONRESOURCE) + ((lpIR->nNumImages - 1) * sizeof(ICONIMAGE)))) == NULL){//MessageBox(AfxGetMainWnd()->m_hWnd, "ͼ���ڴ����·������!", szFileName, MB_OK);CloseHandle(hFile);free(lpIR);return NULL;}lpIR = lpNew;// Store the original namelstrcpyA(lpIR->szOriginalICOFileName, szFileName);lstrcpyA(lpIR->szOriginalDLLFileName, "");// Allocate enough memory for the icon directory entriesif ((lpIDE = (LPICONDIRENTRY)malloc(lpIR->nNumImages * sizeof(ICONDIRENTRY))) == NULL){//MessageBox(AfxGetMainWnd()->m_hWnd, "ͼ���ļ��ڴ����·������!", szFileName, MB_OK);CloseHandle(hFile);free(lpIR);return NULL;}// Read in the icon directory entriesif (!ReadFile(hFile, lpIDE, lpIR->nNumImages * sizeof(ICONDIRENTRY), &dwBytesRead, NULL)){//MessageBox(AfxGetMainWnd()->m_hWnd, "��ͼ���ļ�ɦ����!", szFileName, MB_OK);CloseHandle(hFile);free(lpIR);return NULL;}if (dwBytesRead != lpIR->nNumImages * sizeof(ICONDIRENTRY)){//MessageBox(AfxGetMainWnd()->m_hWnd, "��ͼ���ļ�ɦ����!", szFileName, MB_OK);CloseHandle(hFile);free(lpIR);return NULL;}// Loop through and read in each imagefor (i = 0; i < lpIR->nNumImages; i++){// Allocate memory for the resourceif ((lpIR->IconImages[i].lpBits = (LPBYTE)malloc(lpIDE[i].dwBytesInRes)) == NULL){//MessageBox(AfxGetMainWnd()->m_hWnd, "ͼ���ڴ����·������!", szFileName, MB_OK);CloseHandle(hFile);free(lpIR);free(lpIDE);return NULL;}lpIR->IconImages[i].dwNumBytes = lpIDE[i].dwBytesInRes;// Seek to beginning of this imageif (SetFilePointer(hFile, lpIDE[i].dwImageOffset, NULL, FILE_BEGIN) == 0xFFFFFFFF){//MessageBox(AfxGetMainWnd()->m_hWnd, "ͼ�����ݶ�λɦ����!", szFileName, MB_OK);CloseHandle(hFile);free(lpIR);free(lpIDE);return NULL;}// Read it inif (!ReadFile(hFile, lpIR->IconImages[i].lpBits, lpIDE[i].dwBytesInRes, &dwBytesRead, NULL)){//MessageBox(AfxGetMainWnd()->m_hWnd, "��ͼ�����ݳ���!", szFileName, MB_OK);CloseHandle(hFile);free(lpIR);free(lpIDE);return NULL;}if (dwBytesRead != lpIDE[i].dwBytesInRes){//MessageBox(AfxGetMainWnd()->m_hWnd, "��ͼ�����ݳ���!", szFileName, MB_OK);CloseHandle(hFile);free(lpIDE);free(lpIR);return NULL;}// Set the internal pointers appropriatelyif (!AdjustIconImagePointers(&(lpIR->IconImages[i]))){//MessageBox(AfxGetMainWnd()->m_hWnd, "ͼ���ڲ���ʽת������!", szFileName, MB_OK);CloseHandle(hFile);free(lpIDE);free(lpIR);return NULL;}}// Clean upfree(lpIDE);free(lpRPI);CloseHandle(hFile);return lpIR;}/* End ReadIconFromICOFile() **********************************************//****************************************************************************** FUNCTION: AdjustIconImagePointers** PURPOSE: Adjusts internal pointers in icon resource struct** PARAMS: LPICONIMAGE lpImage - the resource to handle** RETURNS: BOOL - TRUE for success, FALSE for failure**\****************************************************************************/BOOL MyIcon::AdjustIconImagePointers(LPICONIMAGE lpImage){// Sanity checkif (lpImage == NULL)return FALSE;// BITMAPINFO is at beginning of bitslpImage->lpbi = (LPBITMAPINFO)lpImage->lpBits;// Width - simple enoughlpImage->Width = lpImage->lpbi->bmiHeader.biWidth;// Icons are stored in funky format where height is doubled - account for itlpImage->Height = (lpImage->lpbi->bmiHeader.biHeight) / 2;// How many colors?lpImage->Colors = lpImage->lpbi->bmiHeader.biPlanes * lpImage->lpbi->bmiHeader.biBitCount;// XOR bits follow the header and color tablelpImage->lpXOR = (LPBYTE)pDib->FindDIBBits((LPSTR)lpImage->lpbi);// AND bits follow the XOR bitslpImage->lpAND = lpImage->lpXOR + (lpImage->Height * pDib->BytesPerLine((LPBITMAPINFOHEADER)(lpImage->lpbi)));return TRUE;}/* End AdjustIconImagePointers() *******************************************//****************************************************************************** FUNCTION: ReadICOHeader** PURPOSE: Reads the header from an ICO file** PARAMS: HANDLE hFile - handle to the file** RETURNS: UINT - Number of images in file, -1 for failure**\****************************************************************************/UINT MyIcon::ReadICOHeader(HANDLE hFile){WORD Input;DWORD dwBytesRead;// Read the 'reserved' WORDif (!ReadFile(hFile, &Input, sizeof(WORD), &dwBytesRead, NULL))return (UINT)-1;// Did we get a WORD?if (dwBytesRead != sizeof(WORD))return (UINT)-1;// Was it 'reserved' ? (ie 0)if (Input != 0)return (UINT)-1;// Read the type WORDif (!ReadFile(hFile, &Input, sizeof(WORD), &dwBytesRead, NULL))return (UINT)-1;// Did we get a WORD?if (dwBytesRead != sizeof(WORD))return (UINT)-1;// Was it type 1?if (Input != 1)return (UINT)-1;// Get the count of imagesif (!ReadFile(hFile, &Input, sizeof(WORD), &dwBytesRead, NULL))return (UINT)-1;// Did we get a WORD?if (dwBytesRead != sizeof(WORD))return (UINT)-1;// Return the countreturn Input;}/* End ReadICOHeader() ****************************************************//****************************************************************************** FUNCTION: GetIconFromInstance** PURPOSE: Callback for enumerating resources in a DLL/EXE** PARAMS: HINSTANCE hInstance - Instance handle for this module* LPSTR nIndex - Resource index** RETURNS: HICON - Handle to the icon, NULL for failure**\****************************************************************************//* End GetIconFromInstance() ***********************************************//****************************************************************************** FUNCTION: ReadIconFromEXEFile** PURPOSE: Load an Icon Resource from a DLL/EXE file** PARAMS: LPCSTR szFileName - name of DLL/EXE file* LPCSTR lpID - Index of DLL/EXE file** RETURNS: LPICONRESOURCE - pointer to icon resource**\****************************************************************************/LPICONRESOURCE MyIcon::ReadIconFromEXEFile(LPCSTR szFileName, LPCSTR lpID){LPICONRESOURCE lpIR = NULL, lpNew = NULL;HINSTANCE hLibrary;EXEDLLICONINFO EDII;// Load the DLL/EXE - NOTE: must be a 32bit EXE/DLL for this to workif ((hLibrary = LoadLibraryExA(szFileName, NULL, LOAD_LIBRARY_AS_DATAFILE)) == NULL){// Failed to load - abort//MessageBox(AfxGetMainWnd()->m_hWnd, "װ���ļ�ɦ���� - ��ѡ��һ��WIN32��DLL��EXE�ļ�!", szFileName, MB_OK);return NULL;}// Store the infoEDII.szFileName = szFileName;EDII.hInstance = hLibrary;// Ask the user, "Which Icon?"if (lpID != NULL){HRSRC hRsrc = NULL;HGLOBAL hGlobal = NULL;LPMEMICONDIR lpIcon = NULL;UINT i;// Find the group icon resourceif ((hRsrc = FindResourceA(hLibrary, lpID, MAKEINTRESOURCEA((ULONG_PTR)(RT_ICON)+DIFFERENCE))) == NULL){FreeLibrary(hLibrary);return NULL;}if ((hGlobal = LoadResource(hLibrary, hRsrc)) == NULL){FreeLibrary(hLibrary);return NULL;}if ((lpIcon = (LPMEMICONDIR)LockResource(hGlobal)) == NULL){FreeLibrary(hLibrary);return NULL;}// Allocate enough memory for the imagesif ((lpIR = (LPICONRESOURCE)malloc(sizeof(ICONRESOURCE) + ((lpIcon->idCount - 1) * sizeof(ICONIMAGE)))) == NULL){//MessageBox(AfxGetMainWnd()->m_hWnd, "�ڴ�������!", szFileName, MB_OK);FreeLibrary(hLibrary);return NULL;}// Fill in local struct memberslpIR->nNumImages = lpIcon->idCount;lstrcpyA(lpIR->szOriginalDLLFileName, szFileName);lstrcpyA(lpIR->szOriginalICOFileName, "");// Loop through the imagesfor (i = 0; i < lpIR->nNumImages; i++){// Get the individual imageif ((hRsrc = FindResource(hLibrary, MAKEINTRESOURCE(lpIcon->idEntries[i].nID), RT_ICON)) == NULL){free(lpIR);FreeLibrary(hLibrary);return NULL;}if ((hGlobal = LoadResource(hLibrary, hRsrc)) == NULL){free(lpIR);FreeLibrary(hLibrary);return NULL;}// Store a copy of the resource locallylpIR->IconImages[i].dwNumBytes = SizeofResource(hLibrary, hRsrc);lpIR->IconImages[i].lpBits = (LPBYTE)malloc(lpIR->IconImages[i].dwNumBytes);memcpy(lpIR->IconImages[i].lpBits, LockResource(hGlobal), lpIR->IconImages[i].dwNumBytes);// Adjust internal pointersif (!AdjustIconImagePointers(&(lpIR->IconImages[i]))){//MessageBox(AfxGetMainWnd()->m_hWnd, "ת����ͼ���ڲ���ʽɦ����!", szFileName, MB_OK);free(lpIR);FreeLibrary(hLibrary);return NULL;}}}FreeLibrary(hLibrary);return lpIR;}/* End ReadIconFromEXEFile() ************************************************//****************************************************************************** FUNCTION: WriteICOHeader** PURPOSE: Writes the header to an ICO file** PARAMS: HANDLE hFile - handle to the file* UINT nNumEntries - Number of images in file** RETURNS: BOOL - TRUE for success, FALSE for failure**\****************************************************************************/BOOL MyIcon::WriteICOHeader(HANDLE hFile, UINT nNumEntries){WORD Output;DWORD dwBytesWritten;// Write 'reserved' WORDOutput = 0;if (!WriteFile(hFile, &Output, sizeof(WORD), &dwBytesWritten, NULL))return FALSE;// Did we write a WORD?if (dwBytesWritten != sizeof(WORD))return FALSE;// Write 'type' WORD (1)Output = 1;if (!WriteFile(hFile, &Output, sizeof(WORD), &dwBytesWritten, NULL))return FALSE;// Did we write a WORD?if (dwBytesWritten != sizeof(WORD))return FALSE;// Write Number of EntriesOutput = (WORD)nNumEntries;if (!WriteFile(hFile, &Output, sizeof(WORD), &dwBytesWritten, NULL))return FALSE;// Did we write a WORD?if (dwBytesWritten != sizeof(WORD))return FALSE;return TRUE;}/* End WriteICOHeader() ****************************************************//****************************************************************************** FUNCTION: CalculateImageOffset** PURPOSE: Calculates the file offset for an icon image** PARAMS: LPICONRESOURCE lpIR - pointer to icon resource* UINT nIndex - which image?** RETURNS: DWORD - the file offset for that image**\****************************************************************************/DWORD MyIcon::CalculateImageOffset(LPICONRESOURCE lpIR, UINT nIndex){DWORD dwSize;UINT i;// Calculate the ICO header sizedwSize = 3 * sizeof(WORD);// Add the ICONDIRENTRY'sdwSize += lpIR->nNumImages * sizeof(ICONDIRENTRY);// Add the sizes of the previous imagesfor (i = 0; i < nIndex; i++)dwSize += lpIR->IconImages[i].dwNumBytes;// we're there - return the numberreturn dwSize;}/* End CalculateImageOffset() ***********************************************//****************************************************************************** FUNCTION: WriteIconToICOFile** PURPOSE: Writes the icon resource data to an ICO file** PARAMS: LPICONRESOURCE lpIR - pointer to icon resource* LPCSTR szFileName - name for the ICO file** RETURNS: BOOL - TRUE for success, FALSE for failure**\****************************************************************************/BOOL MyIcon::WriteIconToICOFile(LPICONRESOURCE lpIR, LPCSTR szFileName){HANDLE hFile;UINT i;DWORD dwBytesWritten;// open the fileif ((hFile = CreateFileA(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE){//MessageBox(AfxGetMainWnd()->m_hWnd, "�ļ�����ɦ����!", szFileName, MB_OK);return FALSE;}// Write the headerif (!WriteICOHeader(hFile, lpIR->nNumImages)){//MessageBox(AfxGetMainWnd()->m_hWnd, "дͼ���ļ�ͷɦ����!", szFileName, MB_OK);CloseHandle(hFile);return FALSE;}// Write the ICONDIRENTRY'sfor (i = 0; i < lpIR->nNumImages; i++){ICONDIRENTRY ide;// Convert internal format to ICONDIRENTRYide.bWidth = lpIR->IconImages[i].Width;ide.bHeight = lpIR->IconImages[i].Height;ide.bReserved = 0;ide.wPlanes = lpIR->IconImages[i].lpbi->bmiHeader.biPlanes;ide.wBitCount = lpIR->IconImages[i].lpbi->bmiHeader.biBitCount;if ((ide.wPlanes * ide.wBitCount) >= 8)ide.bColorCount = 0;elseide.bColorCount = 1 << (ide.wPlanes * ide.wBitCount);ide.dwBytesInRes = lpIR->IconImages[i].dwNumBytes;ide.dwImageOffset = CalculateImageOffset(lpIR, i);// Write the ICONDIRENTRY out to diskif (!WriteFile(hFile, &ide, sizeof(ICONDIRENTRY), &dwBytesWritten, NULL))return FALSE;// Did we write a full ICONDIRENTRY ?if (dwBytesWritten != sizeof(ICONDIRENTRY))return FALSE;}// Write the image bits for each imagefor (i = 0; i < lpIR->nNumImages; i++){DWORD dwTemp = lpIR->IconImages[i].lpbi->bmiHeader.biSizeImage;// Set the sizeimage member to zerolpIR->IconImages[i].lpbi->bmiHeader.biSizeImage = 0;// Write the image bits to fileif (!WriteFile(hFile, lpIR->IconImages[i].lpBits, lpIR->IconImages[i].dwNumBytes, &dwBytesWritten, NULL))return FALSE;if (dwBytesWritten != lpIR->IconImages[i].dwNumBytes)return FALSE;// set it backlpIR->IconImages[i].lpbi->bmiHeader.biSizeImage = dwTemp;}CloseHandle(hFile);return FALSE;}/* End WriteIconToICOFile() **************************************************//****************************************************************************** FUNCTION: IconImageToClipBoard** PURPOSE: Copies an icon image to the clipboard in CF_DIB format** PARAMS: LPICONIMAGE lpii - pointer to icon image data** RETURNS: BOOL - TRUE for success, FALSE for failure**\****************************************************************************/BOOL MyIcon::IconImageToClipBoard(LPICONIMAGE lpii){HANDLE hGlobal;LPSTR lpBits;// Open the clipboardif (OpenClipboard(0)){// empty itif (EmptyClipboard()){if (lpii->dwNumBytes == NULL)return false;// Make a buffer to send to clipboardhGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, lpii->dwNumBytes);lpBits = (LPSTR)GlobalLock(hGlobal);// Copy the bits to the buffermemcpy(lpBits, lpii->lpBits, lpii->dwNumBytes);// Adjust for funky height*2 thing((LPBITMAPINFOHEADER)lpBits)->biHeight /= 2;GlobalUnlock(hGlobal);// Send it to the clipboardSetClipboardData(CF_DIB, hGlobal);CloseClipboard();return TRUE;}}return FALSE;}BOOL MyIcon::DIBToIconImage(LPICONIMAGE lpii, LPBYTE lpDIB, BOOL bStretch){LPBYTE lpNewDIB;// Sanity checkif (lpDIB == NULL)return FALSE;// Let the DIB engine convert color depths if need belpNewDIB = pDib->ConvertDIBFormat((LPBITMAPINFO)lpDIB, lpii->Width, lpii->Height, lpii->Colors, bStretch);// Now we have a cool new DIB of the proper size/color depth// Lets poke it into our data structures and be done with it// How big is it?lpii->dwNumBytes = sizeof(BITMAPINFOHEADER) // Header+ pDib->PaletteSize((LPSTR)lpNewDIB) // Palette+ lpii->Height * pDib->BytesPerLine((LPBITMAPINFOHEADER)lpNewDIB) // XOR mask+ lpii->Height * WIDTHBYTES(lpii->Width); // AND mask// If there was already an image here, free itif (lpii->lpBits != NULL)free(lpii->lpBits);// Allocate enough room for the new imageif ((lpii->lpBits = (LPBYTE)malloc(lpii->dwNumBytes)) == NULL){free(lpii);return FALSE;}// Copy the bitsmemcpy(lpii->lpBits, lpNewDIB, sizeof(BITMAPINFOHEADER) + pDib->PaletteSize((LPSTR)lpNewDIB));// Adjust internal pointers/variables for new imagelpii->lpbi = (LPBITMAPINFO)(lpii->lpBits);lpii->lpbi->bmiHeader.biHeight *= 2;lpii->lpXOR = (LPBYTE)pDib->FindDIBBits((LPSTR)(lpii->lpBits));memcpy(lpii->lpXOR, pDib->FindDIBBits((LPSTR)lpNewDIB), lpii->Height * pDib->BytesPerLine((LPBITMAPINFOHEADER)lpNewDIB));lpii->lpAND = lpii->lpXOR + lpii->Height * pDib->BytesPerLine((LPBITMAPINFOHEADER)lpNewDIB);memset(lpii->lpAND, 0, lpii->Height * WIDTHBYTES(lpii->Width));// Free the sourcefree(lpNewDIB);return TRUE;}/* End DIBToIconImage() ***************************************************//****************************************************************************** FUNCTION: IconImageFromBMPFile** PURPOSE: Creates an icon image from a BMP file** PARAMS: LPCSTR szFileName - Filename for BMP file* LPICONIMAGE lpii - pointer to icon image data* BOOL bStretchToFit - TRUE to stretch, FALSE to take* the upper left corner of the DIB** RETURNS: BOOL - TRUE for success, FALSE for failure**\****************************************************************************/BOOL MyIcon::IconImageFromBMPFile(LPCSTR szFileName, LPICONIMAGE lpii, BOOL bStretchToFit){LPBYTE lpDIB = NULL;BOOL bRet = FALSE;if ((lpDIB = pDib->ReadBMPFile(szFileName)) == NULL)return FALSE;// Convert it to an icon imagebRet = DIBToIconImage(lpii, lpDIB, bStretchToFit);free(lpDIB);return bRet;}/* End IconImageFromBMPFile() ********************************************//****************************************************************************** FUNCTION: IconImageToBMPFile** PURPOSE: Creates BMP file from an icon image** PARAMS: LPCSTR szFileName - Filename for BMP file* LPICONIMAGE lpii - pointer to icon image data** RETURNS: BOOL - TRUE for success, FALSE for failure**\****************************************************************************/BOOL MyIcon::IconImageToBMPFile(LPCSTR szFileName, LPICONIMAGE lpii){return pDib->WriteBMPFile(szFileName, (LPBYTE)lpii->lpbi);}#pragma endregion#pragma region 易需要的代码inline std::string TakeUnifiedExtName(std::string paht) {std::string result(paht);std::transform(paht.begin(), paht.end(), result.begin(), tolower);if (!result.empty()){result = result.substr(result.rfind(".") + 1);}return result;}typedef struct ICONINDEXMAT{DWORD TargetIndex;DWORD Count;char* IndexId;}*LPICONINDEXMAT;char* Mystrdup(const char* str){int len = 0;const char* pstr = str;while (*pstr++ != '0円'){len++;}char* pdest = (char*)malloc(len + 1);if (!pdest){return nullptr;}int word_num = len / sizeof(size_t);int byte_num = len % sizeof(size_t);const size_t* wsrc = (size_t*)str;size_t* wdest = (size_t*)pdest;while (word_num--){*wdest++ = *wsrc++;}const char* bsrc = (char*)wsrc;char* bdest = (char*)wdest;while (byte_num--){*bdest++ = *bsrc++;}pdest[len] = '0円';return pdest;}BOOL CALLBACK MyEnumProcedure(HMODULE hModule, LPCSTR lpType, LPSTR lpName, LONG_PTR lParam){LPICONINDEXMAT MatchObj = (LPICONINDEXMAT)lParam;//减少全局变量使用if (++MatchObj->Count == MatchObj->TargetIndex){if (IS_INTRESOURCE(lpName) == FALSE) {MatchObj->IndexId = Mystrdup(lpName);//拷贝构造,因为ID有可能时整数,所以没办法用string,难受!!}else{MatchObj->IndexId = (char*)(int)lpName;}}return 1;}//释放存在些问题,拷贝以后返回的函数并没有去释放,考虑运行周期和命令使用频率,拷贝的字符串内存长度也很小,不会出问题int GetIconFromResource(std::string PathName, bool Extract2ClipBoard, std::string SaveName, DWORD _Index) {LPICONRESOURCE ObjIcon = NULL;MyIcon pIcon;ICONINDEXMAT MatchObj = { _Index,0,(char*)-1 };std::string ExtName = TakeUnifiedExtName(PathName);if (ExtName == "ico"){ObjIcon = pIcon.ReadIconFromICOFile(PathName.c_str());++MatchObj.Count;}else {if (ExtName == "exe" || ExtName == "dll" || ExtName == "icl"){HMODULE hLibModule = LoadLibraryExA(PathName.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE);if (hLibModule){if (!EnumResourceNamesA(hLibModule, MAKEINTRESOURCEA((ULONG_PTR)(RT_ICON)+DIFFERENCE), (ENUMRESNAMEPROCA)MyEnumProcedure, (LONG_PTR)&MatchObj)){FreeLibrary(hLibModule);return 0;}FreeLibrary(hLibModule);if (MatchObj.IndexId != (char*)-1){ObjIcon = pIcon.ReadIconFromEXEFile(PathName.c_str(), MatchObj.IndexId);}}}}if (!ObjIcon){return 0;}if (MatchObj.Count > 0 && MatchObj.TargetIndex <= MatchObj.Count){std::string SaveExtName = TakeUnifiedExtName(SaveName);if (Extract2ClipBoard)//到剪辑板{if (ObjIcon){pIcon.IconImageToClipBoard(ObjIcon->IconImages);}}if (!SaveName.empty()) {//到文件if (SaveExtName == "ico" && ObjIcon) {pIcon.WriteIconToICOFile(ObjIcon, SaveName.c_str());}else if (SaveExtName == "bmp" && ObjIcon){pIcon.IconImageToBMPFile(SaveName.c_str(), ObjIcon->IconImages);}}//?是否需要到字节集??}if (ObjIcon){if (ObjIcon->nNumImages > 0)//读入的图标数量大于0{for (UINT i = 0; i < ObjIcon->nNumImages; i++){free(ObjIcon->IconImages[i].lpBits);}}free(ObjIcon);}return MatchObj.Count;}//#pragma endregion}// 调用格式: SDT_INT 提取资源文件图标, 命令说明: "从指定的资源文件中提取图标,并保存为ICO、BMP文件或复制到剪贴板。成功返回图标数量;失败返回0。"// 参数<1>: 资源文件名 SDT_TEXT, 参数说明: "要提取图标的资源文件名。扩展名为EXE、DLL、ICL、ICO。"// 参数<2>: [是否提取到剪辑板 SDT_INT], 参数说明: "0为假其余为真,兼容之前易库,默认为假"// 参数<3>: [保存文件名 SDT_TEXT], 参数说明: "如需要提取到文件则填写提取的图标要保存的文件名。扩展名为ICO、BMP。,默认为空"// 参数<4>: [图标序号 SDT_INT], 参数说明: "当资源文件中包含多个图标时,表示要提取图标的序号。"EAPI_EXTERN_C void eapi_GetIconFromResource_33_eapi(PMDATA_INF pRetData, INT nArgCount, PMDATA_INF pArgInf){std::string FileNmae, SaveFileName;BOOL ToClipBar = FALSE;DWORD Index = 1;if (pArgInf->m_pText) {FileNmae = pArgInf->m_pText;}if (pArgInf[1].m_dtDataType && pArgInf[1].m_int != 0){ToClipBar = TRUE;}if (pArgInf[2].m_dtDataType && pArgInf[2].m_pText){SaveFileName = pArgInf[2].m_pText;}if (pArgInf[3].m_dtDataType && pArgInf[3].m_int >= 0){Index = pArgInf[3].m_int;}pRetData->m_int = eapi_openlib_icon::GetIconFromResource(FileNmae, ToClipBar, SaveFileName, Index);}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。