博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
五笔反查工具
阅读量:6863 次
发布时间:2019-06-26

本文共 4409 字,大约阅读时间需要 14 分钟。

1. 五笔反查工具

     也许你会说,反查什么的,直接一个MAP容器就搞定了,有什么好说的。的确,最简单的就是这样。但即使是这样,还要准备字,五笔码,字根图,以及它们的对应关系。而这些在网上是没有现成的,也就是说要自己准备。我准备的方法是写个小爬虫,到一个五笔反查网站上将这些东西一并弄下来(具体可参考上一篇文章)。准备好最重要的部分后,如果还要弄得像样一点,就要再花一番功夫。所以说,还是有点东西写的。

     先放几张图,再来分享做这东西时遇到的难点。

 

2. 字根图

      一共有6763张字根图,如果直接发布,显然不美观。因此有必要打包下,再发布。可惜的是,在网上没找到合适的打包工具(如果知道,还请告诉偶一下>_<)。剩下的就只有一条路了——自己打包。我用的打包方法看简单:做一个记录文件偏移的文件头,然后将图片按顺序放到文件头之后。

      记录文件偏移用以下这个类表示:

struct FileIndex { //辅助类,打包文件中,单个文件的偏移信息  DWORD dwOffset;       //离文件头偏移多少  DWORD dwSize;         //图片本身多大  char  szName[256];    //图片原本的名称 };

      假如我将1.GIF,2.GIF打包到0.ZERO这个文件中,那么0.ZERO的文件结构应该是这样的

(2) (FileIndex) (FileIndex) (content of 1.GIF) (content of 2.GIF)

上面的2表示一共有两个文件或者两个FileIndex,第一个FileIndex就是第1.GIF的信息,第二个FileIndex是2.GIF的信息,接着的是1.GIF和2.GIF的内容

      具体的打包代码如下:

//将strSrcDirectory目录下的全部文件打包到strDestFile中 BOOL CFilePack::MakePack(const std::string& strSrcDirectory, const std::string& strDestFile) {
std::vector
arFileList; CString szDirectory; szDirectory.Format("%s", strSrcDirectory.c_str()); GetAllFileNameInDirectory(szDirectory, arFileList); //将指定文件夹内的文件名都放到vector容器中 FILE* fp = fopen(strDestFile.c_str(), "wb"); if (!fp) {
return FALSE; } DWORD dwSize = arFileList.size(); fwrite(&dwSize, 1, 4, fp); //写入一共有几个文件 FileIndex* pFileList = new FileIndex[arFileList.size()]; fwrite(pFileList, 1, arFileList.size() * sizeof(FileIndex), fp); //先预留一块地方保存文件偏移信息 //按顺序打包文件 for (int i = 0; i < arFileList.size(); ++i) {
strcpy(pFileList[i].szName, arFileList[i].c_str()); std::string filePath = strSrcDirectory + "\\" + arFileList[i]; FILE* fbuf = fopen(filePath.c_str(), "rb"); if (!fbuf) {
fclose(fp); delete pFileList; return FALSE; } DWORD fsize = filelength(fileno(fbuf)); pFileList[i].dwSize = fsize; pFileList[i].dwOffset = ftell(fp); char* buf = new char[fsize]; fread(buf, 1, fsize, fbuf); fclose(fbuf); fwrite(buf, 1, fsize, fp); delete buf; } //将文件的偏移信息写到之前预留的地方 fseek(fp, 4, SEEK_SET); fwrite(pFileList, 1, arFileList.size() * sizeof(FileIndex), fp); fclose(fp); delete pFileList; return TRUE; }

        打好包,要取出来也很简单:先读出全部的FileIndex,再根据文件名查找到相应的FileIndex,最后根据偏移值和文件大小就能将原来的内容读出来了。

 

3. 显示GIF

     字根图全是GIF格式的,MFC自带的Picture控件不支持GIF格式,所以。。。不幸中的万幸,第三方图片显示支持很容易就能找到。经过一番比较后,最后选择的是PictureEx。原因是PictureEx很小,只有一个头文件和一个CPP文件。此外,使用也很方便:调用Load(图片路径),再调用Draw()就能将图显示出来了。不过前面已经将图片全部打包成一个文件了,难道使用时还要将图片内容读出来,再写到XX.GIF上吗?回答这个问题前,先来看下Load有哪些重载形式吧

// loads a picture from a file // i.e. Load(_T("mypic.gif"));  BOOL Load(LPCTSTR szFileName); // loads a picture from a global memory block (allocated by GlobalAlloc) // Warning: this function DOES NOT free the global memory, pointed to by hGlobal  BOOL Load(HGLOBAL hGlobal, DWORD dwSize); // loads a picture from a program resource // i.e. Load(MAKEINTRESOURCE(IDR_MYPIC),_T("GIFTYPE"));  BOOL Load(LPCTSTR szResourceName,LPCTSTR szResourceType);

     从以上描述看,能用的是第二个重载形式——将一个内存块的内容当图片内容显示。具体的做法是将图片内容从打包文件中读出来后,再拷贝到hGlobal所指的内存块,最后调用Load函数。代码如下:

//显示fileName指定的图片 void CWuBiFangCha_ZeroDlg::Display86ZiGen(CString fileName) {
std::string strFileName(fileName.GetBuffer(0)); char* buf = m_packFile.GetFile(strFileName); //从打包文件中,读取fileName指定文件的内容 if( buf ) {
int iFileSize = m_packFile.GetFileSize(strFileName); //得到fileName指定文件的大小 HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, iFileSize); if( hGlobal == NULL ) {
MessageBox(_T("内存不足")); AfxPostQuitMessage(0); //退出程序 } LPVOID pvData = GlobalLock(hGlobal); if( pvData == NULL ) {
GlobalUnlock(hGlobal); MessageBox(_T("无法锁定内存")); AfxPostQuitMessage(0); } memcpy(pvData, buf, iFileSize); GlobalUnlock(hGlobal); m_86ZiGen.Load(hGlobal, iFileSize); //读图片内容 m_86ZiGen.Draw(); //显示图片 delete[] buf; ::GlobalFree(hGlobal); } fileName.ReleaseBuffer(); }

     

4. 资源

a. PictureEx

b. 五笔反查_零式 V1.0

c. MFC42D.DLL的介绍

 

//-----------------------------------------------------------------------------------------

2011.12.25下午更新

感谢提出的无法运行问题。缺少的MFC42D.DLL是DEBUG版才需要的DLL,现在改成了Release版本,并用了静态编译。

如果还有什么问题,请留言。

 

转载于:https://www.cnblogs.com/FengYan/archive/2011/12/25/2296417.html

你可能感兴趣的文章
Docker背后的内核知识:命名空间资源隔离
查看>>
《圣殿祭司的ASP.NET4.0专家技术手册》---- 1-13 ClientBuilderManager类别的编译功能...
查看>>
《Java编码指南:编写安全可靠程序的75条建议(英文版)》—— 2.7 修复错误...
查看>>
《Redis入门指南(第2版)》一3.2 字符串类型
查看>>
《Adobe Flash Professional CC经典教程》——1.3 使用“库”面板
查看>>
《Android应用开发入门经典(第3版)》——导读
查看>>
xmemcached发布1.3.6
查看>>
《Nmap渗透测试指南》—第6章6.4节IP欺骗
查看>>
Samba 系列(九):将 CentOS 7 桌面系统加入到 Samba4 AD 域环境中
查看>>
《精通自动化测试框架设计》目录—导读
查看>>
全球投资者为阿里尖叫!阿里CEO张勇详解天猫商业新力量
查看>>
《C Primer Plus(第6版)中文版》一第1章 初识C语言1.1 C语言的起源
查看>>
升级到12c云数据库的最佳实践
查看>>
《C语言及程序设计》实践参考——分数的累加
查看>>
每个设计师需知的40个设计素材站
查看>>
《C语言及程序设计》实践参考——当年第几天
查看>>
[LeetCode]130.Surrounded Regions
查看>>
从月薪5千到月薪3万,优秀的程序员是这样做的...
查看>>
[转载]《吴恩达深度学习核心笔记》发布,黄海广博士整理!
查看>>
前端使用fis3开启本地服务器,并实现热加载功能
查看>>