今天在做搜索引擎的资料准备,无意见到了cocosoft的文章,于是,按照原文一步一步,做了下来,运行后,感觉挺不错的,跟我前面写过的c#读取网页有些相识,但多了个地址栏的记忆功能.
本文描述了如何建立一个简单的、常用的用户控件——地址栏。
你只需要输入部分字符,它在其下拉列表框中,就显示出来与你所输入相关的内容(记忆功能)。
如果只要求输入字符串就可以的话。那么,我们可以直接使用TextBox等控件完成输入框。但如果你要让你的输入框有记忆功能的话。那么,我们所需要的就是要求能把以前所输入的内容读取出来。
我们从下面开始讲解如何让我们的地址栏有记忆功能的。
建立自己的地址栏:
首先,我们要分两步走。
第一步,我们首先要明白我们IE地址栏的历史记忆内容是从哪来的。因为只有知道它是从哪来的,我们才能明白我们的数据。
先看一下,IE在regedit(注册表)里面都有些什么内容。因为regeidt是Windows里面一个非常不错的数据库,它可以把整台机子相关的一些东西都存放在里面。
在regedit里面,与IE相关的内容有这些:
我们要的是“Software\Microsoft\Internet Explorer\TypedURLs”的数据。不然,我们写的记忆功能就起不了什么作用了。或者,出现一些其它数据。要知道,在regedit里面保存的数据可都是一些关键数据。如果一不小心被人XX掉的话,那么,L。
OK,现在已经找到我们要的数据是从什么地方来的了。那么,我们就要开始打造我们自己的带记忆功能的地址栏了。
那么,达到这些够了吗?当然,够是够了。但,你不想让你的地址栏功能再强大一点吗?那么,我们写这样的一个类来看看:
1、 新建项目,选择新建类库,名字就顺意了。比如:ControlSet.URLControl。
2、 在资源管理里面添加引用System.Windows.Forms.dll。
3、 然后,在资源管理器里面把Class1.cs改为UnManagedMethods.cs,然后,用下面的代码替换:
using System;
using System.Runtime.InteropServices;

namespace ControlSet.URLControl

{
[StructLayout(LayoutKind.Sequential)]

internal struct Rect


{

public int left;

public int top;

public int right;

public int bottom;

}

[StructLayout(LayoutKind.Sequential)]

internal struct ComboBoxInfo


{

public int cbSize;

public Rect rcItem;

public Rect rcButton;

public IntPtr stateButton;

public IntPtr hwndCombo;

public IntPtr hwndEdit;

public IntPtr hwndList;

}

/// <summary>

/// All unmanaged DllImport methods used in this assembly

/// </summary>

internal class UnManagedMethods


{

[DllImport("User32.dll")]

internal static extern bool GetComboBoxInfo(IntPtr hwndCombo, ref ComboBoxInfo info);

[DllImport("Shlwapi.dll")]

internal static extern void SHAutoComplete(IntPtr hwnd, IntPtr flags);

}

}
第二步,我们的地址栏出现了。那么,要用什么做为它的基控件呢?
因为我们要有记忆功能,那么,当然,要有一个能下拉的东西了。什么?ComboBox就是最好的选择。那好,我们开始用ComboBox来构建我们自己的控件。
using System;
using Microsoft.Win32;
using System.Windows.Forms;

namespace ControlSet.URLControl

{

/**//// <summary>
/// URLComboBox 的摘要说明。
/// </summary>
/// /// <summary>

/// A simple enumeration that wraps various auto complete flags of SHAutoComplete.

/// See documenation of SHAutoComplete for details

/// </summary>

[Flags]

public enum AutoCompleteFlags : int


{


/**//// <summary>

/// This includes the File System as well as the rest of the shell (Desktop\My Computer\Control Panel\)

/// </summary>

FileSystem = 0x00000001,


/**//// <summary>

/// URLs in the User's History

/// </summary>

URLHistory = 0x00000002,


/**//// <summary>

/// URLs in the User's Recently Used list.

/// </summary>

URLMRU = 0x00000004,


/**//// <summary>

/// Use the tab to move thru the autocomplete possibilities instead of to the next dialog/window control.

/// </summary>

UseTab = 0x00000008,


/**//// <summary>

/// This includes the File System

/// </summary>

FileSystemOnly = 0x00000010,


/**//// <summary>

/// Same as FileSystemOnly except it only includes directories, UNC servers, and UNC server shares.

/// </summary>

FileSystemDirs = 0x00000020,


/**//// <summary>

/// Ignore the registry default and force the auto suggest feature on.

/// </summary>

AutoSuggestForceOn = 0x10000000,


/**//// <summary>

/// Ignore the registry default and force the auto suggest feature off

/// </summary>

AutoSuggestForceOff = 0x20000000,


/**//// <summary>

/// Ignore the registry default and force the auto append on.

/// </summary>

AutoAppendForceOn = 0x40000000,


/**//// <summary>

/// Ignore the registry default and force auto append off.

/// </summary>

AutoAppendForceOff = -2147483648

}

/**//// <summary>
/// Enumeration for possible types of registry base keys for storing most recntly typed URLs
/// </summary>
public enum MRUKeyHive : int


{


/**//// <summary>

/// Value that indicates HKEY_CURRENT_USER should be used for MRUKey property

/// </summary>

CurrentUser = 1,


/**//// <summary>

/// Value that indicates HKEY_LOCAL_MACHINE should be used for MRUKey property

/// </summary>

LocalMachine = 2,

}


public class URLComboBox : ComboBox

{

/**//// <summary>
/// Member variable which stores the autocomplete flags
/// </summary>
private AutoCompleteFlags _flags = AutoCompleteFlags.FileSystem | AutoCompleteFlags.URLHistory | AutoCompleteFlags.URLMRU;

/**//// <summary>
/// Member variable which stores the mru key
/// </summary>
private string _mruKey = @"Software\Microsoft\Internet Explorer\TypedURLs";

/**//// <summary>
/// Member variable which stores the mru key hive
/// </summary>
private MRUKeyHive _mruKeyHive = MRUKeyHive.CurrentUser;



/**//// <summary>
/// Gets or sets the auto complete flags
/// </summary>
public AutoCompleteFlags Flags

{
get

{
return _flags;
}
set

{
_flags = value;
}
}


/**//// <summary>
/// Gets or sets the registry key name where the combo box maintains MRU list.
/// </summary>
public string MRUKey

{
get

{
return _mruKey;
}
set

{
_mruKey = value;
}
}


/**//// <summary>
/// Gets or sets the registry key hive for the MRUKey property.
/// </summary>

public MRUKeyHive MRUKeyHive

{
get

{
return _mruKeyHive;
}
set

{
_mruKeyHive = value;
}
}

/**//// <summary>
/// Initilaizes a new instance of URLComboBox
/// </summary>

public URLComboBox() : base()


{

}


/**//// <summary>
/// Gets the registry key where MRU URLs are stored
/// </summary>
/// <param name="writable">Indicates whether to get the key so that it values written to it</param>
/// <returns>RegistryKey object for the MRU registry key or null if none exists</returns>
private RegistryKey GetMRUKey(bool writable)


{

if (_mruKey.Length == 0)

return null;


RegistryKey ret = null;


switch(_mruKeyHive)


{

case MRUKeyHive.LocalMachine:

ret = Registry.LocalMachine.OpenSubKey(_mruKey, writable);

break;

case MRUKeyHive.CurrentUser:

ret = Registry.CurrentUser.OpenSubKey(_mruKey, writable);

break;

}


return ret;

}


/**//// <summary>
/// Writes information about any ignored exception to the trace.
/// </summary>
/// <param name="e">The exception which is being ignored</param>

private void TraceIgnoredError(Exception e)

{

//It's ok if there is any error
System.Diagnostics.Trace.WriteLine(e.Message);
System.Diagnostics.Trace.WriteLine(e.StackTrace);

}


/**//// <summary>

/// Utility function to fill the combob box most recently typed URLs read from registry.

/// </summary>

private void MRUFill()

{

if (DesignMode)

return;

RegistryKey mruKey = null;

try

{

int i = 1;

string strFormat = "url{0}";

object defaultValue = String.Empty;

object url;

mruKey = GetMRUKey(false);

if (mruKey != null)

{
while((url = mruKey.GetValue(String.Format(strFormat, i), defaultValue)) != defaultValue)

{
Items.Add(url);
i++;
}
}
}
catch(Exception e)

{
TraceIgnoredError(e);
}
finally

{

if (mruKey != null)

mruKey.Close();

}
}

/**//// <summary>
/// Writes the recntly typed URL to the registry if it is not already there
/// </summary>
/// <param name="e"></param>

protected override void OnValidated(System.EventArgs e)

{

if (DesignMode)

return;

if ((Text.Length != 0) && (Items.IndexOf(Text) == -1))

{
Items.Add(Text);

RegistryKey mruKey = null;

//Finally add it to the registry

try

{
mruKey = GetMRUKey(true);

if (mruKey != null)

mruKey.SetValue(String.Format("url{0}", Items.Count), Text);
}
catch(Exception ex)

{
TraceIgnoredError(ex);
}
finally


{

if (mruKey != null)

mruKey.Close();
}
}
base.OnValidated(e);
}


/**//// <summary>
/// Finds the handle to the edit control and calls SHAutoComplete on it.
/// Also fills the combobox from the values read from the registry
/// </summary>
/// <param name="e">Ignored</param>

protected override void OnHandleCreated(System.EventArgs e)

{

base.OnHandleCreated(e);

if (DesignMode)
return;

//This is the right place do auto completion
ComboBoxInfo info = new ComboBoxInfo();
info.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(info);

if (UnManagedMethods.GetComboBoxInfo(Handle, ref info))

{
UnManagedMethods.SHAutoComplete(info.hwndEdit, (IntPtr)_flags);
}
MRUFill();

}

}

}

我们的带记忆功能的地址栏已经构建完成。你可以在菜单【生成(B)】里面,调试生成解决方案。
建立示例程序:
1、 新建项目,选择Windows应用程序,名称:TestrulComboBox。
2、 我们把我们所需要的控件放到工具箱里面。在工具箱上面点右键。添加/移除项。打开Com组件,选择刚才项目生成的ControlSet.URLControl.dll。
3、 把刚才添加到工具箱上面的Microsoft Web 浏览器控件,和ControlSet.URLControl.dll控件,拖放到主窗口上,并进行排列。
4、 添加一个控钮。并在它的事件中输入如下代码:
private void btnSure_Click(object sender, System.EventArgs e)

{
Cursor currentCursor = Cursor.Current;

try


{
Cursor.Current = Cursors.WaitCursor;
object arg1 = 0; object arg2 = ""; object arg3 = ""; object arg4 = "";
axWebBrowser1.Navigate(urlComboBox1.Text,ref arg1,ref arg2, ref arg3, ref arg4);
}
finally

{
Cursor.Current = currentCursor;
}

}
运行,测试就可以了.
到此,你也可以自己试着做一个自己的、个性化的浏览器了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述