注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

分享,态度 ·~~

—— 十年太长,五年;如果可以回到五年前,你最想对那时候的自己说什么?

 
 
 

日志

 
 

带记忆功能的地址栏(下拉菜单)  

2009-11-24 12:53:29|  分类: DotNet |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

概述:
本文描述了如何建立一个简单的、常用的用户控件――地址栏。
相信只要上网的朋友,都知道IE里面有一个提供大家输入你想去的网站的输入框。在该输入框中,你只需要输入部分字符,它在其下拉列表框中,就显示出来与你所输入相关的内

容(记忆功能)。
如果只要求输入字符串就可以的话。那么,我们可以直接使用TextBox等控件完成输入框。但如果你要让你的输入框有记忆功能的话。那么,我们所需要的就是要求能把以前所输入

的内容读取出来。
好了,废话说了半天了。那么,我们从下面开始讲解如何让我们的地址栏有记忆功能的。

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

建立自己的地址栏:
首先,我们要分两步走。
第一步,我们首先要明白,我们IE地址栏的历史记忆内容是从哪来的。因为只有知道它是从哪来的,我们才能明白我们的数据嘛。
那么,我们先看一下,IE在regedit(注册表)里面都有些什么内容。因为regeidt是Windows里面一个非常不错的数据库('),它可以把整台机子相关的一些东西都存放在里面。
我们要的是“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、  生成解决方案。
---------------------------------------------------------------------------------------------
最后:
好了,你也可以自己试着做一个自己的、个性化的浏览器了。如果还想再加其他功能的话。那就不属于这一篇文章的目的了。

【from http://doc.hot-open.com/article/adp/2/content12422.html

带记忆功能的地址栏(下拉菜单) - 乂乂 - 一个人,一支烟  ·~~
  评论这张
 
阅读(1917)| 评论(2)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017