无线我的无限

让无线技术给生活带来无限快乐
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

利用hha.dll生成chm格式电子书

Posted on 2008-10-04 21:20  freemobile  阅读(2224)  评论(0编辑  收藏  举报

Joymobiler角摩手机电子书专家V2.3发布,采用hha.dll来编译生成chm电子书,经过测试支持:windowXP/2000/2003/Vista环境运行,不过压缩包由原来的200多k,变到了600多K,打了不少,主要是hha.dll有800多k。

下面是自己包的一个CChm类


typedef BOOL (WINAPI *MYFUNC)(const char*, LPVOID,  LPVOID, int);

class CChm
{
public:
    CChm();
    virtual ~CChm();

public:
    void AddChapter(CChapter chap);
    BOOL PrepareChm(CString& sBookName, CString& sAuth,CString& sMaker, CString& sAppDir, CString& sFilePath);
    BOOL MakeChm();
    CArray<CChapter, CChapter&> m_aryChapters;

protected:
    CString m_sAppDIR;
    static BOOL   CALLBACK   FunLog(char* pstr); // 日志回调函数
    static BOOL   CALLBACK   FunProc(char* pstr); // 编译进度回调函数

private:
    HINSTANCE m_hinstLib;
    MYFUNC ProcAdd;    // hha.dll中的HHA_CompileHHP函数
    CString m_sIndex; // chm主目录首页字串
    CString m_sHhp; // hhp字串
    CString m_sHhc; // hhc字串
    CString m_sHhcItem; // 子目录字串
    CString m_sBookName;
};


CChm::CChm()
{
    m_hinstLib = LoadLibrary("hha.dll");
    ProcAdd = NULL;
    // If the handle is valid, try to get the function address.
    
    if (m_hinstLib != NULL)
    {
        ProcAdd = (MYFUNC) GetProcAddress(m_hinstLib, "HHA_CompileHHP");
    }

    // 定义hhp,hhc等文件内容
    m_sIndex = _T("<html><head><meta http-equiv=""Content-Type"" content=""text/html; charset=gb2312""><title></title></head><body><div align=""center""><table border=""1"" width=""400"" cellspacing=""0"" cellpadding=""0""  id=""table1""><tr><td bgcolor=""#CCCCFF"" align=""center"" height=30px><b><a href=""http://www.joymo.cn/"" target=_blank>角摩手机乐园-免费手机资源</a></b></td></tr><tr><td height=""200"" align=center><font color=""#FF0000""><b>%s</b></font><p> </p><p>作者:%s</p><p>制作:%s</td></tr><tr><td bgcolor=""#CCCCFF""><font size=""2"">本书籍由Joymobiler角摩手机电子书专家生成! <a href=""http://www.joymo.cn/"" target=_blank>角摩网http://www.joymo.cn</a>提供在线手机电子书制作、手机小说、游戏、铃声、主题免费下载。作者:freemobile,QQ:19149653</font></td></tr></table></div></body></html>");
    m_sHhp = _T("[OPTIONS]"r"nCompatibility=1.1 or later"r"nCompiled file=%s"r"nContents file=hhc.hhc"r"nDisplay compile progress=No"r"nLanguage=0x804 中文(中国)"r"n"r"n[FILES]"r"nindex.htm"r"n"r"n[INFOTYPES]"r"n"r"n");
    m_sHhc = _T("<!DOCTYPE HTML PUBLIC ""-//IETF//DTD HTML//EN"">"r"n<HTML>"r"n<HEAD>"r"n<meta name=""GENERATOR"" content=""Microsoft&reg; HTML Help Workshop 4.1"">"r"n<!-- Sitemap 1.0 -->"r"n</HEAD><BODY>"r"n<OBJECT type=""text/site properties"">"r"n    <param name=""Window Styles"" value=""0x800025"">"r"n</OBJECT>"r"n<UL>"r"n    <LI> <OBJECT type=""text/sitemap"">"r"n        <param name=""Name"" value=""%s"">"r"n        <param name=""Local"" value=""index.htm"">"r"n        </OBJECT>"r"n    <UL>"r"n%s"r"n    </UL>"r"n</UL>"r"n</BODY></HTML>");
    m_sHhcItem = _T("<LI> <OBJECT type=""text/sitemap"">"r"n<param name=""Name"" value=""%s"">"r"n<param name=""Local"" value=""%d.txt"">"r"n</OBJECT>"r"n");
 }

CChm::~CChm()
{
    FreeLibrary(m_hinstLib);
}

//////////////////////////////////////////
// 添加目录章节
// 参数:chapter
// 作者:Freemobile
// 网站:角摩手机乐园(http://www.joymo.cn)
//////////////////////////////////////////
void CChm::AddChapter(CChapter chap)
{
    m_aryChapters.Add(chap);
}
//////////////////////////////////////////
// 编译制作chm文档
// 参数:
// 作者:Freemobile
// 网站:角摩手机乐园(http://www.joymo.cn)
//////////////////////////////////////////
BOOL CChm::MakeChm()
{
    CString sFileName;
    try
    {
        sFileName.Format("%s""hhp""%s.hhp",m_sAppDIR,m_sBookName);
        LPCSTR pzFileNmae = sFileName.GetBuffer(sFileName.GetLength());

        if(ProcAdd != NULL)
        {
            ProcAdd(pzFileNmae, FunLog, FunProc, 0); // 编译出来 www.joymo.cn
        }
        else
            return FALSE;

        sFileName.ReleaseBuffer();
    }
    catch(CException *e)
    {
        e->Delete();
        return FALSE;
    }
    return TRUE;
}
//////////////////////////////////////////
// 为编译chm做的准备工作
// 参数:书名,作者,制作者,应用程序所在目录,生成的文件名
// 作者:Freemobile
// 网站:角摩手机乐园(http://www.joymo.cn)
//////////////////////////////////////////
BOOL CChm::PrepareChm(CString& sBookName, CString& sAuth, CString& sMaker, CString& sAppDir, CString& sFilePath)
{
    if(m_aryChapters.GetSize()<1)
        return FALSE;

    CString sFileMsg;
    CString sDir,sTmp;
    CFile file;

    m_sAppDIR = sAppDir;
    m_sBookName = sBookName;

    sDir.Format("%s""hhp""",m_sAppDIR);
    DWORD dwAttr = GetFileAttributes(sDir);  
    if(dwAttr==-1||(dwAttr&FILE_ATTRIBUTE_DIRECTORY)==0)//目录不存在  
    {  
        if(!CreateDirectory(sDir,  NULL))  // 创建hhp工程目录
        {  
            return FALSE;  
        }  
    }   

    sFileMsg.Format(m_sIndex,sBookName,sAuth,sMaker);
    try
    {
        // 生成主目录显示文件index.htm
        if(file.Open(sDir+"index.htm",CFile::modeCreate|CFile::modeWrite|CFile::typeBinary))
        {
            file.WriteHuge(sFileMsg, sFileMsg.GetLength());
            file.Close();
        }
        else
            return FALSE;

        // 生成hhp工程所需内容文件和hhc的二级目录结构
        sFileMsg.Empty();
        for(int i=0;i<m_aryChapters.GetSize();i++)
        {
            CChapter chap = m_aryChapters.GetAt(i);
            if(chap.m_nFmt == FMT_TXT)
            {
                sTmp.Format(m_sHhcItem, chap.m_sTitle, i);
                sFileMsg += sTmp;
                sDir.Format("%s""hhp""%d.txt",m_sAppDIR,i);
                file.Open(sDir,CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
                file.WriteHuge(chap.m_sContent, chap.m_nLen);
                file.Close();
            }
        }

        // 生成hhc.hhc目录文件
        sTmp.Format(m_sHhc, sBookName, sFileMsg);
        sDir.Format("%s""hhp""hhc.hhc",m_sAppDIR);
        file.Open(sDir,CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
        file.WriteHuge(sTmp, sTmp.GetLength());
        file.Close();

        // 生成hhp工程文件
        sTmp.Format(m_sHhp, sFilePath);
        sDir.Format("%s""hhp""%s.hhp",m_sAppDIR,sBookName);
        file.Open(sDir,CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
        file.WriteHuge(sTmp, sTmp.GetLength());
        file.Close();
    }
    catch(CException *e)
    {
        e->Delete();
        return FALSE;
    }
    
    
    return TRUE;
}

BOOL CChm::FunLog(char* pstr)
{
    ASSERT(pstr);
    return true;
}

BOOL CChm::FunProc(char* pstr)
{
    ASSERT(pstr);
    return true;
}

调用的顺序是:AddChapters()-> PrepareChm()->MakeChm(),使用非常简单。hhp和hhc预先做成格式后字串,PrepareChm中就设定好hhp工程所需的配置。hhp和hhc的格式,很简单,安装个html help workshop自己生成一个,查看一下内容就很清楚了。