解决方案二:
使用IE自己的history对象. 封装其实现, 暴露给用户Add, Query, Delete等方法.
使用次方法的重点是windows的com的调用.关于hisroty的主要接口:
IEnumSTATURL ---- 用于遍历当前history中所有的历史纪录. 在windows api中, 每一个历史记录都是STATURL对象.在后面会介绍该对象. 既然该接口是用于遍历, 很容易想到一下方法:
//Returns the next \"celt\" URLS from the cache
void Next(int celt, ref STATURL rgelt, out int pceltFetched);
//Skips the next \"celt\" URLS from the cache. doed not work.
void Skip(int celt);
//Resets the enumeration
void Reset();
//Clones this object
void Clone(out IEnumSTATURL ppenum);
//Sets the enumeration filter
void SetFilter([MarshalAs(UnmanagedType.LPWStr)] string poszFilter, STATURL_FLAGS dwFlags);
IUrlHistoryStg ---- 此接口代表着history对象.可以对其进去添加, 删除, 查询等操作.
//Adds a new history entry
void AddUrl(string url, string title, ADDURL_FLAG dwFlags);
//Deletes an entry by its URL. does not work!
void DeleteUrl(string url, int dwFlags);
//Returns a STATURL for a given URL
void QueryUrl([MarshalAs(UnmanagedType.LPWStr)] string url, STATURL_QUERYFLAGS dwFlags, ref STATURL lpSTATURL);
//Binds to an object. does not work!
void BindToObject([In] string url, [In] UUID riid, IntPtr ppvOut);
//Returns an enumerator for URLs
object EnumUrls { [return: MarshalAs(UnmanagedType.IUnknown)] get; }
IUrlHistoryStg2 ---- 加强版本的IUrlHistoryStg.在其基础上, 添加了新的方法. 实际应用中主要使用的接口.
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("3C374A42-BAE4-11CF-BF7D-00AA006946EE")]
public interface IEnumSTATURL
{
//Returns the next \"celt\" URLS from the cache
void Next(int celt, ref STATURL rgelt, out int pceltFetched);
//Skips the next \"celt\" URLS from the cache. doed not work.
void Skip(int celt);
//Resets the enumeration
void Reset();
//Clones this object
void Clone(out IEnumSTATURL ppenum);
//Sets the enumeration filter
void SetFilter([MarshalAs(UnmanagedType.LPWStr)] string poszFilter, STATURL_FLAGS dwFlags);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("3C374A41-BAE4-11CF-BF7D-00AA006946EE")]
public interface IUrlHistoryStg
{
//Adds a new history entry
void AddUrl(string url, string title, ADDURL_FLAG dwFlags);
//Deletes an entry by its URL. does not work!
void DeleteUrl(string url, int dwFlags);
//Returns a STATURL for a given URL
void QueryUrl([MarshalAs(UnmanagedType.LPWStr)] string url, STATURL_QUERYFLAGS dwFlags, ref STATURL lpSTATURL);
//Binds to an object. does not work!
void BindToObject([In] string url, [In] UUID riid, IntPtr ppvOut);
//Returns an enumerator for URLs
object EnumUrls { [return: MarshalAs(UnmanagedType.IUnknown)] get; }
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("AFA0DC11-C313-11D0-831A-00C04FD5AE38")]
public interface IUrlHistoryStg2 : IUrlHistoryStg
{
//Adds a new history entry
new void AddUrl(string url, string title, ADDURL_FLAG dwFlags);
//Deletes an entry by its URL. does not work!
new void DeleteUrl(string url, int dwFlags);
//Returns a STATURL for a given URL
new void QueryUrl([MarshalAs(UnmanagedType.LPWStr)] string url, STATURL_QUERYFLAGS dwFlags, ref STATURL lpSTATURL);
//Binds to an object. does not work!
new void BindToObject([In] string url, [In] UUID riid, IntPtr ppvOut);
//Returns an enumerator for URLs
new object EnumUrls { [return: MarshalAs(UnmanagedType.IUnknown)] get; }
//does not work!
void AddUrlAndNotify(string url, string title, int dwFlags, int fWriteHistory, object poctNotify, object punkISFolder);
//Removes all history items
void ClearHistory();
}
//UrlHistory class
[ComImport]
[Guid("3C374A40-BAE4-11CF-BF7D-00AA006946EE")]
public class UrlHistoryClass
{
}
1. STATURL对象
该对象是存储在hisroty对应于一个url的对象.![](https://www.cnblogs.com/images/cnblogs_com/joechen/STATURL.png)
2. STATURL对象操作时用到的enum
public enum STATURL_QUERYFLAGS : uint
{
/// <summary>
/// The specified URL is in the content cache.
/// </summary>
STATURL_QUERYFLAG_ISCACHED = 0x00010000,
/// <summary>
/// Space for the URL is not allocated when querying for STATURL.
/// </summary>
STATURL_QUERYFLAG_NOURL = 0x00020000,
/// <summary>
/// Space for the Web page's title is not allocated when querying for STATURL.
/// </summary>
STATURL_QUERYFLAG_NOTITLE = 0x00040000,
/// <summary>
/// //The item is a top-level item.
/// </summary>
STATURL_QUERYFLAG_TOPLEVEL = 0x00080000,
}
public enum STATURL_FLAGS : uint
{
/// <summary>
/// Flag on the dwFlags parameter of the STATURL structure
/// indicating that the item is in the cache.
/// </summary>
STATURL_FLAG_ISCACHED = 0x00000001,
/// <summary>
/// Flag on the dwFlags parameter of the STATURL structure
/// indicating that the item is a top-level item.
/// </summary>
STATURL_FLAG_ISTOPLEVEL = 0x00000002,
}
public enum ADDURL_FLAG : uint
{
/// <summary>
/// Write to both the visited links and the dated containers.
/// </summary>
ADDURL_ADDTOHISTORYANDCACHE = 0,
/// <summary>
/// Write to only the visited links container.
/// </summary>
ADDURL_ADDTOCACHE = 1
}
3. 对hisroty的包装.
3.1 在cache history中的遍历类.
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
public class STATURLEnumerator
{
IEnumSTATURL enumrator;
int index;
STATURL staturl;
/// <summary>
/// Constructor for <c>STATURLEnumerator</c> that accepts IEnumSTATURL object that represents the <c>IEnumSTATURL</c> COM Interface.
/// </summary>
/// <param name="enumrator">the <c>IEnumSTATURL</c> COM Interface</param>
public STATURLEnumerator(IEnumSTATURL enumrator)
{
this.enumrator = enumrator;
}
/// <summary>
/// Advances the enumerator to the next item of the url history cache.
/// </summary>
/// <returns>true if the enumerator was successfully advanced to the next element;
/// false if the enumerator has passed the end of the url history cache.
/// </returns>
public bool MoveNext()
{
staturl = new STATURL();
enumrator.Next(1, ref staturl, out index);
if (index == 0)
return false;
else
return true;
}
/// <summary>
/// Gets the current item in the url history cache.
/// </summary>
public STATURL Current
{
get
{
return staturl;
}
}
/// <summary>
/// Skips a specified number of Call objects in the enumeration sequence. does not work!
/// </summary>
/// <param name="celt"></param>
public void Skip(int celt)
{
enumrator.Skip(celt);
}
/// <summary>
/// Resets the enumerator interface so that it begins enumerating at the beginning of the history.
/// </summary>
public void Reset()
{
enumrator.Reset();
}
/// <summary>
/// Creates a duplicate enumerator containing the same enumeration state as the current one. does not work!
/// </summary>
/// <returns>duplicate STATURLEnumerator object</returns>
public STATURLEnumerator Clone()
{
IEnumSTATURL ppenum;
enumrator.Clone(out ppenum);
return new STATURLEnumerator(ppenum);
}
/// <summary>
/// Define filter for enumeration. MoveNext() compares the specified URL with each URL in the history list to find matches. MoveNext() then copies the list of matches to a buffer. SetFilter method is used to specify the URL to compare.
/// </summary>
/// <param name="poszFilter">The string of the filter.
/// <example>SetFilter('http://', STATURL_QUERYFLAGS.STATURL_QUERYFLAG_TOPLEVEL) retrieves only entries starting with 'http.//'. </example>
/// </param>
/// <param name="dwFlags">STATURL_QUERYFLAGS Enumeration<exapmle><c>STATURL_QUERYFLAGS.STATURL_QUERYFLAG_TOPLEVEL</c></exapmle></param>
public void SetFilter(string poszFilter, STATURL_FLAGS dwFlags)
{
enumrator.SetFilter(poszFilter, dwFlags);
}
/// <summary>
///Enumerate the items in the history cache and store them in the IList object.
/// </summary>
/// <param name="list">IList object
/// <example><c>ArrayList</c>object</example>
/// </param>
public void GetUrlHistory(IList list)
{
while (true)
{
staturl = new STATURL();
enumrator.Next(1, ref staturl, out index);
if (index == 0)
break;
list.Add(staturl);
}
enumrator.Reset();
}
}
3.2 使用该遍历的包装类
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
public class UrlHistoryWrapper
{
private UrlHistoryClass m_urlHisrotyClass = null;
private IUrlHistoryStg2 m_urlObj = null;
public UrlHistoryWrapper()
{
m_urlHisrotyClass = new UrlHistoryClass();
m_urlObj = m_urlHisrotyClass as IUrlHistoryStg2;
}
#region Operations
/// <summary>
/// Clean up any resources being used.
/// </summary>
public void Dispose()
{
Marshal.ReleaseComObject(m_urlObj);
m_urlHisrotyClass = null;
}
/// <summary>
/// Places the specified URL into the history. If the URL does not exist in the history,
/// an entry is created in the history. If the URL does exist in the history,
/// it is overwritten.
/// </summary>
/// <param name="url">the string of the URL to place in the history</param>
/// <param name="title">the string of the title associated with that URL</param>
/// <param name="dwFlags">the flag which indicate where a URL is placed in the history.
/// <example><c>ADDURL_FLAG.ADDURL_ADDTOHISTORYANDCACHE</c></example>
/// </param>
public void AddHistoryEntry(string url, string title, ADDURL_FLAG dwFlags)
{
m_urlObj.AddUrl(url, title, dwFlags);
}
/// <summary>
/// Deletes all instances of the specified URL from the history. does not work!
/// </summary>
/// <param name="url">the string of the URL to delete.</param>
/// <param name="dwFlags"><c>dwFlags = 0</c></param>
public void DeleteHistoryEntry(string url, int dwFlags)
{
try
{
m_urlObj.DeleteUrl(url, dwFlags);
}
catch (Exception)
{
}
}
/// <summary>
///Queries the history and reports whether the URL passed as the pocsUrl parameter has been visited by the current user.
/// </summary>
/// <param name="url">the string of the URL to querythe string of the URL to query.</param>
/// <param name="dwFlags">STATURL_QUERYFLAGS Enumeration
/// <example><c>STATURL_QUERYFLAGS.STATURL_QUERYFLAG_TOPLEVEL</c></example></param>
/// <returns>Returns STATURL structure that received additional URL history information. If the returned STATURL's pwcsUrl is not null, Queried URL has been visited by the current user.
/// </returns>
public STATURL QueryUrl(string url, STATURL_QUERYFLAGS dwFlags)
{
STATURL STATURL = new STATURL();
try
{
//In this case, queried URL has been visited by the current user.
m_urlObj.QueryUrl(url, dwFlags, ref STATURL);
//lpSTATURL.pwcsUrl is NOT null;
return STATURL;
}
catch (FileNotFoundException)
{
//Queried URL has not been visited by the current user.
//lpSTATURL.pwcsUrl is set to null;
return STATURL;
}
}
/// <summary>
/// Delete all the history except today's history, and Temporary Internet Files.
/// </summary>
public void ClearHistory()
{
m_urlObj.ClearHistory();
}
/// <summary>
/// Create an enumerator that can iterate through the history cache.
/// UrlHistoryWrapper does not implement IEnumerable interface
/// </summary>
/// <returns>Returns STATURLEnumerator object that can iterate through the history cache.</returns>
public STATURLEnumerator GetEnumerator()
{
return new STATURLEnumerator((IEnumSTATURL)m_urlObj.EnumUrls);
}
#endregion
}