欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

richtextbox控件插入链接代码分享

程序员文章站 2024-02-23 22:13:16
复制代码 代码如下:using system;using system.componentmodel;using system.drawing;using system.w...

复制代码 代码如下:

using system;
using system.componentmodel;
using system.drawing;
using system.windows.forms;
using system.runtime.interopservices;

namespace richtextboxlinks
{
 public class richtextboxex : richtextbox
 {
  #region interop-defines
  [ structlayout( layoutkind.sequential )]
  private struct charformat2_struct
  {
   public uint32 cbsize;
   public uint32   dwmask;
   public uint32   dweffects;
   public int32    yheight;
   public int32    yoffset;
   public int32 crtextcolor;
   public byte     bcharset;
   public byte     bpitchandfamily;
   [marshalas(unmanagedtype.byvalarray, sizeconst=32)]
   public char[]   szfacename;
   public uint16 wweight;
   public uint16 sspacing;
   public int  crbackcolor; // color.toargb() -> int
   public int  lcid;
   public int  dwreserved;
   public int16 sstyle;
   public int16 wkerning;
   public byte  bunderlinetype;
   public byte  banimation;
   public byte  brevauthor;
   public byte  breserved1;
  }

  [dllimport("user32.dll", charset=charset.auto)]
  private static extern intptr sendmessage(intptr hwnd, int msg, intptr wparam, intptr lparam);

  private const int wm_user    = 0x0400;
  private const int em_getcharformat  = wm_user+58;
  private const int em_setcharformat  = wm_user+68;

  private const int scf_selection = 0x0001;
  private const int scf_word  = 0x0002;
  private const int scf_all  = 0x0004;

  #region charformat2 flags
  private const uint32 cfe_bold  = 0x0001;
  private const uint32 cfe_italic  = 0x0002;
  private const uint32 cfe_underline = 0x0004;
  private const uint32 cfe_strikeout = 0x0008;
  private const uint32 cfe_protected = 0x0010;
  private const uint32 cfe_link  = 0x0020;
  private const uint32 cfe_autocolor = 0x40000000;
  private const uint32 cfe_subscript = 0x00010000;  /* superscript and subscript are */
  private const uint32 cfe_superscript= 0x00020000;  /*  mutually exclusive    */

  private const int cfm_smallcaps  = 0x0040;   /* (*) */
  private const int cfm_allcaps  = 0x0080;   /* displayed by 3.0 */
  private const int cfm_hidden  = 0x0100;   /* hidden by 3.0 */
  private const int cfm_outline  = 0x0200;   /* (*) */
  private const int cfm_shadow  = 0x0400;   /* (*) */
  private const int cfm_emboss  = 0x0800;   /* (*) */
  private const int cfm_imprint  = 0x1000;   /* (*) */
  private const int cfm_disabled  = 0x2000;
  private const int cfm_revised  = 0x4000;

  private const int cfm_backcolor  = 0x04000000;
  private const int cfm_lcid   = 0x02000000;
  private const int cfm_underlinetype = 0x00800000;  /* many displayed by 3.0 */
  private const int cfm_weight  = 0x00400000;
  private const int cfm_spacing  = 0x00200000;  /* displayed by 3.0 */
  private const int cfm_kerning  = 0x00100000;  /* (*) */
  private const int cfm_style   = 0x00080000;  /* (*) */
  private const int cfm_animation  = 0x00040000;  /* (*) */
  private const int cfm_revauthor  = 0x00008000;


  private const uint32 cfm_bold  = 0x00000001;
  private const uint32 cfm_italic  = 0x00000002;
  private const uint32 cfm_underline = 0x00000004;
  private const uint32 cfm_strikeout = 0x00000008;
  private const uint32 cfm_protected = 0x00000010;
  private const uint32 cfm_link  = 0x00000020;
  private const uint32 cfm_size  = 0x80000000;
  private const uint32 cfm_color  = 0x40000000;
  private const uint32 cfm_face  = 0x20000000;
  private const uint32 cfm_offset  = 0x10000000;
  private const uint32 cfm_charset = 0x08000000;
  private const uint32 cfm_subscript = cfe_subscript | cfe_superscript;
  private const uint32 cfm_superscript= cfm_subscript;

  private const byte cfu_underlinenone  = 0x00000000;
  private const byte cfu_underline   = 0x00000001;
  private const byte cfu_underlineword  = 0x00000002; /* (*) displayed as ordinary underline */
  private const byte cfu_underlinedouble  = 0x00000003; /* (*) displayed as ordinary underline */
  private const byte cfu_underlinedotted  = 0x00000004;
  private const byte cfu_underlinedash  = 0x00000005;
  private const byte cfu_underlinedashdot  = 0x00000006;
  private const byte cfu_underlinedashdotdot = 0x00000007;
  private const byte cfu_underlinewave  = 0x00000008;
  private const byte cfu_underlinethick  = 0x00000009;
  private const byte cfu_underlinehairline = 0x0000000a; /* (*) displayed as ordinary underline */

  #endregion

  #endregion

  public richtextboxex()
  {
   // otherwise, non-standard links get lost when user starts typing
   // next to a non-standard link
   this.detecturls = false;
  }

  [defaultvalue(false)]
  public new bool detecturls
  {
   get { return base.detecturls; }
   set { base.detecturls = value; }
  }

  /// <summary>
  /// insert a given text as a link into the richtextbox at the current insert position.
  /// </summary>
  /// <param name="text">text to be inserted</param>
  public void insertlink(string text)
  {
   insertlink(text, this.selectionstart);
  }

  /// <summary>
  /// insert a given text at a given position as a link.
  /// </summary>
  /// <param name="text">text to be inserted</param>
  /// <param name="position">insert position</param>
  public void insertlink(string text, int position)
  {
   if (position < 0 || position > this.text.length)
    throw new argumentoutofrangeexception("position");

   this.selectionstart = position;
   this.selectedtext = text;
   this.select(position, text.length);
   this.setselectionlink(true);
   this.select(position + text.length, 0);
  }

  /// <summary>
  /// insert a given text at at the current input position as a link.
  /// the link text is followed by a hash (#) and the given hyperlink text, both of
  /// them invisible.
  /// when clicked on, the whole link text and hyperlink string are given in the
  /// linkclickedeventargs.
  /// </summary>
  /// <param name="text">text to be inserted</param>
  /// <param name="hyperlink">invisible hyperlink string to be inserted</param>
  public void insertlink(string text, string hyperlink)
  {
   insertlink(text, hyperlink, this.selectionstart);
  }

  /// <summary>
  /// insert a given text at a given position as a link. the link text is followed by
  /// a hash (#) and the given hyperlink text, both of them invisible.
  /// when clicked on, the whole link text and hyperlink string are given in the
  /// linkclickedeventargs.
  /// </summary>
  /// <param name="text">text to be inserted</param>
  /// <param name="hyperlink">invisible hyperlink string to be inserted</param>
  /// <param name="position">insert position</param>
  public void insertlink(string text, string hyperlink, int position)
  {
   if (position < 0 || position > this.text.length)
    throw new argumentoutofrangeexception("position");

   this.selectionstart = position;
   this.selectedrtf = @"{\rtf1\ansi "+text+@"\v #"+hyperlink+@"\v0}";
   this.select(position, text.length + hyperlink.length + 1);
   this.setselectionlink(true);
   this.select(position + text.length + hyperlink.length + 1, 0);
  }

  /// <summary>
  /// set the current selection's link style
  /// </summary>
  /// <param name="link">true: set link style, false: clear link style</param>
  public void setselectionlink(bool link)
  {
   setselectionstyle(cfm_link, link ? cfe_link : 0);
  }
  /// <summary>
  /// get the link style for the current selection
  /// </summary>
  /// <returns>0: link style not set, 1: link style set, -1: mixed</returns>
  public int getselectionlink()
  {
   return getselectionstyle(cfm_link, cfe_link);
  }


  private void setselectionstyle(uint32 mask, uint32 effect)
  {
   charformat2_struct cf = new charformat2_struct();
   cf.cbsize = (uint32)marshal.sizeof(cf);
   cf.dwmask = mask;
   cf.dweffects = effect;

   intptr wpar = new intptr(scf_selection);
   intptr lpar = marshal.alloccotaskmem( marshal.sizeof( cf ) );
   marshal.structuretoptr(cf, lpar, false);

   intptr res = sendmessage(handle, em_setcharformat, wpar, lpar);

   marshal.freecotaskmem(lpar);
  }

  private int getselectionstyle(uint32 mask, uint32 effect)
  {
   charformat2_struct cf = new charformat2_struct();
   cf.cbsize = (uint32)marshal.sizeof(cf);
   cf.szfacename = new char[32];

   intptr wpar = new intptr(scf_selection);
   intptr lpar =  marshal.alloccotaskmem( marshal.sizeof( cf ) );
   marshal.structuretoptr(cf, lpar, false);

   intptr res = sendmessage(handle, em_getcharformat, wpar, lpar);

   cf = (charformat2_struct)marshal.ptrtostructure(lpar, typeof(charformat2_struct));

   int state;
   // dwmask holds the information which properties are consistent throughout the selection:
   if ((cf.dwmask & mask) == mask)
   {
    if ((cf.dweffects & effect) == effect)
     state = 1;
    else
     state = 0;
   }
   else
   {
    state = -1;
   }

   marshal.freecotaskmem(lpar);
   return state;
  }
 }
}