在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