首页 > 编程 > .NET > 正文

在Visual C# .NET中建立自己的地址栏

2024-07-10 13:00:13
字体:
来源:转载
供稿:网友
本文内容:

概述

建立自己的地址栏

建立示例程序

最后

---------------------------------------------------------------------------------------------

概述:
本文描述了如何建立一个简单的、常用的用户控件——地址栏。

相信只要上网的朋友,都知道ie里面有一个提供大家输入你想去的网站的输入框。在该输入框中,你只需要输入部分字符,它在其下拉列表框中,就显示出来与你所输入相关的内容(记忆功能)。

如果只要求输入字符串就可以的话。那么,我们可以直接使用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来构建我们自己的控件。

namespace controlset.urlcontrol

{

/// <summary>

/// a control that extends the regular combo box to show urls.

/// </summary>

public class urlcombobox : combobox

{

/// <summary>

/// initilaizes a new instance of urlcombobox

/// </summary>

public urlcombobox() : base()

{

}

}

}




首先,我们添加如下引用:

using microsoft.win32;




在该控件内要用到下面一些东西,我们给它添加如下代码(添加到命名空间里面):

/// <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,

}


然后,再在该类里面加载如下代码来完成它应该有的功能:

/// <summary>

/// a control that extends the regular combo box to show urls.

/// </summary>

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>

/// 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>

/// gets or sets the auto complete flags

/// </summary>

[description("gets or sets the auto complete flags")]

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>

[descriptionattribute("the registry key name where the combo box maintains mru list")]

public string mrukey

{

get

{

return _mrukey;

}

set

{

_mrukey = value;

}

}



/// <summary>

/// gets or sets the registry key hive for the mrukey property.

/// </summary>

[descriptionattribute("the registry hive where the combo box maintains mru list")]

public mrukeyhive mrukeyhive

{

get

{

return _mrukeyhive;

}

set

{

_mrukeyhive = value;

}

}



/// <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组件。如下图:



3、 再把我们自己写的控件也放到工具箱里面。如上图,点击里面的浏览按钮。找到你上一个解决方案存放的目录,然后,找出它所生成的动态链接库文件。就可以直接添加到工具箱上面了。

4、 在现有的项目内,把拖放刚才添加到工具箱上面的microsoft web 浏览器控件,和刚才刚才写好的控件,拖放到主窗口上面。并进行排列。

5、 添加一个控钮。

6、 双击按钮,生成事件,并在事件中输入如下代码:

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;

}




7、 生成解决方案。

---------------------------------------------------------------------------------------------

最后:
好了,你也可以自己试着做一个自己的、个性化的浏览器了。如果还想再加其他功能的话。那就不属于这一篇文章的目的了。j



发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表