Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. RichTextBox and ITextHost

RichTextBox and ITextHost

Scheduled Pinned Locked Moved C#
c++csharpphpcomhelp
7 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Michael Wolski
    wrote on last edited by
    #1

    I am trying to draw RTF text in my custom UserControl without actually having a RichTextBox window. I have seen a couple articles on the web about creating a windowless RichTextBox by supplying it with a custom ITextHost interface (see http://www.codeguru.com/Cpp/controls/richedit/windowless/article.php/c5367). The problem is, these examples are for c++ and I am wondering how one could go about doing this from C#. Is there a way to somehow import the ITextHost interface from the control? Does anybody have any clue to point me in the right direction? (and no, I am not above using unmanaged code to get this to work). Or is there a better way to accomplish this? Thanks in advance! Michael Developer, Author, Chef

    H 1 Reply Last reply
    0
    • M Michael Wolski

      I am trying to draw RTF text in my custom UserControl without actually having a RichTextBox window. I have seen a couple articles on the web about creating a windowless RichTextBox by supplying it with a custom ITextHost interface (see http://www.codeguru.com/Cpp/controls/richedit/windowless/article.php/c5367). The problem is, these examples are for c++ and I am wondering how one could go about doing this from C#. Is there a way to somehow import the ITextHost interface from the control? Does anybody have any clue to point me in the right direction? (and no, I am not above using unmanaged code to get this to work). Or is there a better way to accomplish this? Thanks in advance! Michael Developer, Author, Chef

      H Offline
      H Offline
      Heath Stewart
      wrote on last edited by
      #2

      .NET is a natural progression from COM, and can easily interop with COM. Read Interoperating with Unmanaged Code[^] in the .NET Framework SDK for basic information on these concepts. Also, be sure to read Windowless Rich Edit Controls[^] in the Platform SDK for details information, not just examples. First, you should consider encapsulating both the CreateTextServices API as well as the implementation of ITextHost in a class to make it easy to use. You then need to declare the ITextHost and, optionally (though recommended), ITextServices interfaces in C#. An example of (part, since it's so long) of ITextHost host looks like this (methods must be in order since this interface inherits from IUnknown and methods must be in the proper VTBL order):

      [Guid("c5bdd8d0-d26e-11ce-a89d-00aa006cadc5")]
      [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      public interface ITextHost
      {
      IntPtr TxGetDC();
      IntPtr TxReleaseDC(IntPtr hdc);
      bool TxShowScrollBar(IntPtr fnBar, bool fShow);
      // ...
      }

      Be sure you know the conversion from unmanaged to managed data types. For example, many of the methods use INT, which is not necessarily 32 bits. It is system dependent, just like IntPtr. You can also use a Int64 (long) and use MarshalAs(UnmanagedType.SysInt) which would make it easier and should work well for many, many years (since 64-bit processors are just starting to hit main-stream on the x86 platform supported by current CLI implementations). The CreateTextServices factory function would look like this:

      [DllImport("riched20.dll")]
      private static extern int CreateTextServices(
      [MarshalAs(UnmanagedType.IUnknown)] object punkOuter,
      ITextHost pITextHost,
      [MarshalAs(UnmanagedType.IUnknown), Out] out object ppUnk);

      You could also use IntPtr instead of object and then use appropriate methods from the

      M 1 Reply Last reply
      0
      • H Heath Stewart

        .NET is a natural progression from COM, and can easily interop with COM. Read Interoperating with Unmanaged Code[^] in the .NET Framework SDK for basic information on these concepts. Also, be sure to read Windowless Rich Edit Controls[^] in the Platform SDK for details information, not just examples. First, you should consider encapsulating both the CreateTextServices API as well as the implementation of ITextHost in a class to make it easy to use. You then need to declare the ITextHost and, optionally (though recommended), ITextServices interfaces in C#. An example of (part, since it's so long) of ITextHost host looks like this (methods must be in order since this interface inherits from IUnknown and methods must be in the proper VTBL order):

        [Guid("c5bdd8d0-d26e-11ce-a89d-00aa006cadc5")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface ITextHost
        {
        IntPtr TxGetDC();
        IntPtr TxReleaseDC(IntPtr hdc);
        bool TxShowScrollBar(IntPtr fnBar, bool fShow);
        // ...
        }

        Be sure you know the conversion from unmanaged to managed data types. For example, many of the methods use INT, which is not necessarily 32 bits. It is system dependent, just like IntPtr. You can also use a Int64 (long) and use MarshalAs(UnmanagedType.SysInt) which would make it easier and should work well for many, many years (since 64-bit processors are just starting to hit main-stream on the x86 platform supported by current CLI implementations). The CreateTextServices factory function would look like this:

        [DllImport("riched20.dll")]
        private static extern int CreateTextServices(
        [MarshalAs(UnmanagedType.IUnknown)] object punkOuter,
        ITextHost pITextHost,
        [MarshalAs(UnmanagedType.IUnknown), Out] out object ppUnk);

        You could also use IntPtr instead of object and then use appropriate methods from the

        M Offline
        M Offline
        Michael Wolski
        wrote on last edited by
        #3

        Heath, You had 49 minutes (since I posted) to think about and write a response and that is all you could manage? ;) Seriously, many many many many thanks for the tips and pointers. I will be looking into this as you suggest. If I manage to get this working well, I will share the info in the form of an article. Again, thanks thanks thanks for setting me down the right path! Michael Developer, Author, Chef

        H 1 Reply Last reply
        0
        • M Michael Wolski

          Heath, You had 49 minutes (since I posted) to think about and write a response and that is all you could manage? ;) Seriously, many many many many thanks for the tips and pointers. I will be looking into this as you suggest. If I manage to get this working well, I will share the info in the form of an article. Again, thanks thanks thanks for setting me down the right path! Michael Developer, Author, Chef

          H Offline
          H Offline
          Heath Stewart
          wrote on last edited by
          #4

          Actually, I replied to the other message below first that I hadn't gotten to yet since yesterday (or that could've used some additional attention). Much of what I posted I already knew (I strive to learn all I can, and in-depth). I had to check the headers, though, to make sure I was giving you correct method declarations and it took some time to find the GUID for the ITextHost interface, since in the header it's extern'd. :mad: Sorry it took so long! :-O Mwolski wrote: Developer, Author, Chef Same here! My friends and family are always making me cook whenever I can and I like exploring and creating new recipies. I'm thinking "chef" would make a nice mid-life crisis career path! :)

          Microsoft MVP, Visual C# My Articles

          N M 2 Replies Last reply
          0
          • H Heath Stewart

            Actually, I replied to the other message below first that I hadn't gotten to yet since yesterday (or that could've used some additional attention). Much of what I posted I already knew (I strive to learn all I can, and in-depth). I had to check the headers, though, to make sure I was giving you correct method declarations and it took some time to find the GUID for the ITextHost interface, since in the header it's extern'd. :mad: Sorry it took so long! :-O Mwolski wrote: Developer, Author, Chef Same here! My friends and family are always making me cook whenever I can and I like exploring and creating new recipies. I'm thinking "chef" would make a nice mid-life crisis career path! :)

            Microsoft MVP, Visual C# My Articles

            N Offline
            N Offline
            Nick Parker
            wrote on last edited by
            #5

            Heath Stewart wrote: Sorry it took so long! Practice makes perfect! ;P - Nick Parker
            My Blog | My Articles

            1 Reply Last reply
            0
            • H Heath Stewart

              Actually, I replied to the other message below first that I hadn't gotten to yet since yesterday (or that could've used some additional attention). Much of what I posted I already knew (I strive to learn all I can, and in-depth). I had to check the headers, though, to make sure I was giving you correct method declarations and it took some time to find the GUID for the ITextHost interface, since in the header it's extern'd. :mad: Sorry it took so long! :-O Mwolski wrote: Developer, Author, Chef Same here! My friends and family are always making me cook whenever I can and I like exploring and creating new recipies. I'm thinking "chef" would make a nice mid-life crisis career path! :)

              Microsoft MVP, Visual C# My Articles

              M Offline
              M Offline
              Michael Wolski
              wrote on last edited by
              #6

              Heath, 1) Just wanted to let you know that I was successful in taking the second route you outlined. I initially spent about 2 hours trying to get everything defined in C#. This was a bit of a nightmare as you suggested. Then I spent about 10 minutes doing it as a mixed-mode MC++ class library, and exposing the routines I needed. Works like a charm! In the future, I plan revisit the c# way (to eliminate the mc++ dll and learn what I was doing wrong), but for now this is completely workable. Thanks for the previous advice. 2) 5 Years ago I was lucky enough to take a 1 year sabbatical. What did I do? Since I was about to turn 30 I decided I wanted to see the world, but learn something as well. Since I have always cooked, I decided to go to Paris and attend culinary school at Le Cordon Bleu. I heartily reccommend it for burned-out developers! Amazing time, amazing people, amazing food, and an amazing amount of work. The only problem: Software pays way too much to let it go completely! So I heartily applaud the mid-life career change, but I warn you that you will find it hard to let go of your current one. Thanks again! Michael Developer, Author, Chef

              H 1 Reply Last reply
              0
              • M Michael Wolski

                Heath, 1) Just wanted to let you know that I was successful in taking the second route you outlined. I initially spent about 2 hours trying to get everything defined in C#. This was a bit of a nightmare as you suggested. Then I spent about 10 minutes doing it as a mixed-mode MC++ class library, and exposing the routines I needed. Works like a charm! In the future, I plan revisit the c# way (to eliminate the mc++ dll and learn what I was doing wrong), but for now this is completely workable. Thanks for the previous advice. 2) 5 Years ago I was lucky enough to take a 1 year sabbatical. What did I do? Since I was about to turn 30 I decided I wanted to see the world, but learn something as well. Since I have always cooked, I decided to go to Paris and attend culinary school at Le Cordon Bleu. I heartily reccommend it for burned-out developers! Amazing time, amazing people, amazing food, and an amazing amount of work. The only problem: Software pays way too much to let it go completely! So I heartily applaud the mid-life career change, but I warn you that you will find it hard to let go of your current one. Thanks again! Michael Developer, Author, Chef

                H Offline
                H Offline
                Heath Stewart
                wrote on last edited by
                #7

                Mwolski wrote: ...but I warn you that you will find it hard to let go of your current one I don't think I'll have any problems letting go of the chest pains, irregular heart beat, headaches, stiff joints, tendenitous, and stress. Money is a slight factor, but hopefully these stock options pay-out. :)

                Microsoft MVP, Visual C# My Articles

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups