Thema: Prism RTB und manuelle LInks

Einzelnen Beitrag anzeigen

Benutzerbild von Taladan
Taladan

Registriert seit: 5. Aug 2003
Ort: Osnabrück
505 Beiträge
 
Delphi 2005 Professional
 
#5

Re: RTB und manuelle LInks

  Alt 12. Jul 2005, 20:38
Hier der C# Code

Code:
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;
      }
   }
}
Marco
Wer Rechtschreibfehler findet, der darf sie behalten

Carpe Diem - Nutze den Tag (und zwar den ganzen!)
  Mit Zitat antworten Zitat