日新阁

取日三省之意,记生活珠玑,每日清新,谓日新阁.

 

C# 有记忆功能的地址栏控件

今天在做搜索引擎的资料准备,无意见到了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 = 0object arg2 = ""object arg3 = ""object arg4 = "";
                axWebBrowser1.Navigate(urlComboBox1.Text,
ref arg1,ref arg2, ref arg3, ref arg4);
              }

            
finally 
            
{
                Cursor.Current 
= currentCursor;

              }


        }

运行,测试就可以了.
到此,你也可以自己试着做一个自己的、个性化的浏览器了。

posted on 2007-03-24 16:14  flashicp  阅读(1700)  评论(0编辑  收藏  举报

导航