138上位机VC MFC指定程序图标的提取与保存
138上位机VC MFC指定程序图标的提取与保存
功能展示
有时候看中别人的程序图标,想占为自用,我们就得提取出图标,我们当前例程实现指定程序图标的提取,进取的结果会显示出来,点击保存,可保存已经提取的图标,效果如图; 要点提示 程序图标的提取我们可以用微软提供的函数ExtractIcon()函数原型可以查阅MSDN,我们当前例程使用的形式为HICON hicon =::ExtractIcon(AfxGetInstanceHandle(),sPath,0); sPath为要提取的程序的带路径的程序名称 图标的保存 需要依次保存图标的头文件,资源索引及图标数据三个部份
实现功能 1.新建基于对话框的应用程序 2.拖拽些控件,用于提取图标的操作:1.提取图标按钮ID改为IDC_BUTTON1;2.保存图标的按钮,ID改为IDC_BUTTON2,3.显示已提取图标的图片控件,ID改为IDC_ICONSHOW。4.显示要提取程序的绝对路径,ID改为IDC_PATH;
3.自定义些结构体,用于保存图标的各个组成部分信息 - #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//定义图像数据
- {
- LPBITMAPINFO icheader; // 位图信息头
- RGBQUAD iccolors; //色彩表,同位图的色彩表。
- LPBYTE lpXOR;
- LPBYTE lpAND; // AND掩码
- } iconimage, *lpiconimage;
- typedef struct//定义图标资源索引目录
- {
- byte bwidth; // 图像宽度,以像素为单位
- byte bheight; // 图像高度,以像素为单位
- byte bcolorcount; //图像中的颜色数,如果是大于8的位图,此值为零
- byte breserved; //保留,必须为零
- WORD wplanes; //位面数,一般为1
- WORD wbitcount; //每像素所占位数
- DWORD dwbytesinres; // 资源的字节数
- DWORD dwimageoffset; //图像数据距离资源开始处偏移位置
- } icondirentry, *lpicondirentry;
- typedef struct//定义图标文件头
- {
- WORD idreserved; // 保留,必须为零
- WORD idtype; // 资源类型,1是图标,2是光标
- WORD idcount; // 图像个数
- icondirentry identries[1]; // 每个图像的入口定义
- } icondir, *lpicondir;
复制代码4.添加自定义函数GetImageOffset (),用于获取图标的数据
我们来演示下功能实现的整个过程 - #pragma pack( pop)
- typedef struct//定义图像数据
- {
- LPBITMAPINFO icheader; // 位图信息头
- RGBQUAD iccolors; //色彩表,同位图的色彩表。
- LPBYTE lpXOR;
- LPBYTE lpAND; // AND掩码
- } iconimage, *lpiconimage;
- typedef struct//定义图标资源索引目录
- {
- byte bwidth; // 图像宽度,以像素为单位
- byte bheight; // 图像高度,以像素为单位
- byte bcolorcount; //图像中的颜色数,如果是大于8的位图,此值为零
- byte breserved; //保留,必须为零
- WORD wplanes; //位面数,一般为1
- WORD wbitcount; //每像素所占位数
- DWORD dwbytesinres; // 资源的字节数
- DWORD dwimageoffset; //图像数据距离资源开始处偏移位置
- } icondirentry, *lpicondirentry;
- typedef struct//定义图标文件头
- {
- WORD idreserved; // 保留,必须为零
- WORD idtype; // 资源类型,1是图标,2是光标
- WORD idcount; // 图像个数
- icondirentry identries[1]; // 每个图像的入口定义
- } icondir, *lpicondir;
复制代码
4.添加自定义函数GetImageOffset (),用于获取图标的数据 - DWORD CGkbc8Dlg::GetImageOffset(HMODULE hmodule ,UINT index,DWORD& cursize ,LPBYTE pbitinfo )
- {
- DWORD imagesize=0;
- HRSRC himage;
- HGLOBAL gimage;
- imagesize = sizeof(WORD)*3+sizeof(icondirentry)*m_lpMemDir->idCount;
- //计算图像数据的偏移量
-
复制代码- for (int j=0; j<index;j++)
- {
- himage= FindResource(hmodule,MAKEINTRESOURCE(m_lpMemDir->idEntries[j].nID),RT_ICON);
- if (himage ==NULL)
- return 0;
- gimage= LockResource(himage);
- imagesize+= SizeofResource(hmodule,himage);
- UnlockResource(gimage);
- }
- himage= FindResource(hmodule,MAKEINTRESOURCE(m_lpMemDir->idEntries[index].nID),RT_ICON);
- gimage= LoadResource(hmodule,himage);
- DWORD size= SizeofResource(hmodule,himage);
- m_lpData = (LPBYTE)malloc(size);
- if (cursize != NULL)
- cursize = size;
- memcpy(m_lpData ,LockResource(gimage),size);
- UnlockResource(gimage);
- return imagesize;
- }
复制代码- 5.添加一回调函数EnumResNameProc(),实现整个图标的获取
- LPSTR m_iconname;
- BOOL CALLBACK EnumResNameProc( HANDLE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG lParam )
- {
-
- if (HIWORD(lpszName)==0)//如果高字节为零,低字节表示图标ID
- {
- m_iconname = MAKEINTRESOURCE(LOWORD(lpszName));
- }
- else //如果高字节不为零,整个lpszName为图标name
- {
- m_iconname = strdup(lpszName);
- }
- return true;
- }
复制代码- 5.实现图标提取与保存按钮功能
- void CGkbc8Dlg::OnButton1()
- {
- CFileDialog dlg(TRUE,"exe",NULL,NULL,"可执行文件(.exe)|*.exe",this);
- if (dlg.DoModal()==IDOK)
- {
- CString sPath = dlg.GetPathName();
- SetDlgItemText(IDC_PATH,sPath);
- HICON hicon = ::ExtractIcon(AfxGetInstanceHandle(),sPath,0);
- if (hicon != NULL)
- {
- ((CStatic *)GetDlgItem(IDC_ICONSHOW))->SetIcon(hicon);
- }
- }
- }
复制代码我们来演示整个功能实现过程
|