在浏览器编程中,似乎必不可少的功能之一就是现实历史记录,若在某个时候想访问某天的一个网站,但又不记得具体地址了,就可从IE历史记录中查找。IE的历史记录按照日期先分类,然后按网站顶级域名分类,然后才是具体的地址。该记录包含了近期访问过的网站,具体近期是多久,那就看IE选项里面设置的时间长短了。

 

    至于如何分类,那是第二步的事情了。第一步是如何访问这些记录。

 

    最专业的莫过于用IUrlHistoryStg接口了,使用这个接口可获得所有历史记录的非常详细的信息,此时即可按照自己的需要设计算法来将这些历史记录分类。尽管这个过程可能比较繁琐,但由于可以获得很详细的信息,所以比较灵活。

   

    但自从IE升级到IE7、IE8后,发现使用该接口的DeleteUrl方法删除项目时,某些项目无法删除。将地址UTF8编码后,该状况有所改善,但有些项目还是无法删除,具体原因不明,不知道是不是MS有意为之?

 

    该问题困扰笔者多年,今日打开系统盘的历史文件夹查看时,可以看到这些文件夹,如前所说,这些文件夹已经是分门别类的了,其结构与IE侧边栏看到的结构是一样的。且发现IE打开历史记录的时候其速度是非常快的,不像是列举出所有项目再分类的。于是想,能否获取这些目录,按照其结构添加,岂不是很完美?

 

    这些文件夹是虚拟文件夹,只能用类似IShellFolder这些接口来获得,但在实验过程中,发现该接口的BindToObject方法始终返回错误(WIN7下测试),很无奈,只得另想办法。(若有朋友实验通过,希望给以指点,先谢过)

 

    其实可以使用Microsoft Shell Controls And Automation来完成这个事情。该对象由shell32.dll提供。

 

    此时即可先获得历史记录文件夹对应的shell32.Folder,然后一步步枚举所有项目,即可比较快速的将这些项目加载到类似Treeview中去,其结构与IE显示出来的完全一样,也不用自己去分类,非常方便。

 

    但问题随之而来,获得的对象都是shell32.FolderItem,这些对象无法获取其URL的,这样在访问这些记录的时候就有困难了。解决办法是枚举这个对象的shell32.FolderItemVerb,检查哪个是期望的动作,之后shell32.FolderItemVerb.DoIt即可。管理这些对象的时候稍显麻烦,比如右键的时候显示什么菜单等等,但都是逻辑问题,只要思路对了,没有多少难度。