zoukankan      html  css  js  c++  java
  • 在网页中显示CHM

    CHM即“已编译的帮助文件”,主要由.hhc(目录文件)、.hhk(索引文件)以及相应的帮助主题文件(.html,.htm)这些内容编译而成。

    方法对比

    在网页中显示CHM内容,大致有以下几种办法:

    1. 使用某些工具来反编译,把CHM文件还原成以上相关的文件,并通过hhc文件来列出目录,内容链接到相应的html文件
    2. 依然是反编译这些文件,把相关目录及html文件内容直接存到数据库中
    3. 直接解析chm文件

    这些方法有优点也有缺点:

    1. 方法1的优点是方便快捷;缺点也很明显,分散的html不便于管理也不利于搜索
    2. 方法2的优点是直接存在数据库,查询方便;需要通过遍历目录把结构和内容插入到数据库,以及重新组织图片资源文件的位置,稍微有点繁琐而已
    3. 方法3的优点是不需要反编译,直接使用最方便;缺点是,解析chm难度太高

    个人认为直接存入数据库是相对较好的办法,但这不是本文的目的,本文使用直接解析CHM文件的方式。

    使用开源类库

    本文主要使用Codeproject上的一个开源类库:http://www.codeproject.com/KB/cs/htmlhelp.aspx,并针对web稍加改造。

    这个htmlhelp类库包括了几乎hh.exe(即windows桌面版的chm查看器)所有功能,可以说是非常强大。

    但它有一个问题,对于不标准的chm文件,搜索功能支持不太好,猜测可能也是编码有关系

    我试了好多工具来生成CHM文件,但都无法很好的使用它的搜索功能;好在它解析CHM文件的时候,同时也把所有的主题文件(.htm,.html)都读取出来了,所以可以通过这些内容以及标题来改造一下搜索功能,以适应我的不标准的CHM文件。

    搜索功能主要改造主要代码如下:

    public bool SearchTopics(string key, TreeView treeview)
    {
       return SearchTopics(key, treeview, true);
    }
    
    public bool SearchTopics(string key, TreeView treeview, bool filterHtml)
    {
        ArrayList result = new ArrayList();
        SearchTopic(key, result, chmHelp.TableOfContents.TOC, filterHtml);
        bool hasData = result.Count > 0;
        if (hasData)
        {
            treeview.Nodes.Clear();
            foreach (TOCItem item in result)
            {
                TreeNode node = new TreeNode(item.Name);
                node.NavigateUrl = urlPrefix + item.Local;
                treeview.Nodes.Add(node);
            }
        }
        return hasData;
    }
    
    static Regex reHtmlFilter = new Regex("<[^>]*>", RegexOptions.Compiled);
    
    private void SearchTopic(string topic, ArrayList result, ArrayList searchIn, bool filterHtml)
    {
        foreach (TOCItem curItem in searchIn)
        {
            if (curItem.Children.Count == 0)
            {
                string temp = curItem.FileContents;
                if (filterHtml && !string.IsNullOrEmpty(temp))
                {
                    temp = reHtmlFilter.Replace(temp, string.Empty);
                }                                        
                if ((!string.IsNullOrEmpty(curItem.Name) && curItem.Name.Contains(topic)) ||
                    (!string.IsNullOrEmpty(temp) && temp.Contains(topic)))
                {
                    result.Add(curItem);
                }
            }
            else
            {
                SearchTopic(topic, result, curItem.Children, filterHtml);
            }
        }
    }

    对于获取单个主题,htmlhelp只提供了通过标题搜索,但考虑到标题可能不唯一,所以本文也增加了通过url来搜索。

    单独创建一个页面,通过接收url来获取相应的主题,并显示出来;在此也要注意,url可能存在一些特殊字符如“#”、“%20”等符号,导致参数不能正确传递的问题。

    预览:

    代码不多贴了,完整的例子:点击下载

    作者:囧月
    出处:http://lwme.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    JDK里面包含jre,为什么还要下载一个jre呢?
    2021年11月2日,面试经历
    linux内核学习心得
    关于QQ短信接口的使用。
    软件测试--开发者测试例子
    此博客相关声明·AP2017060911I
    21RNC201906034I·代码重构
    20RNC201901313I·代码重构
    19RND201808172·层次设定
    18RND201801311·图像方案日记
  • 原文地址:https://www.cnblogs.com/lwme/p/2254325.html
Copyright © 2011-2022 走看看