Valhalla Legends Forums Archive | General Programming | Windows Rich Text Control Development

AuthorMessageTime
Myndfyr
Hey all --

I've been giving some thought as to how I might be able to develop a very custom rich text control.  It wouldn't be a control people actually type in -- it'd be meant for output only.  Here are my tentative specs:
[list]
[*]Fully object-oriented
[*]Text items are stored in nodes that are linked together in a forward list
[*]Scrolling should be set line-by-line, top, bottom, or any variable number.
[*]Scrolling should either be smooth that is, each time text *should move* a pixel, it does), or clipped (text isn't redrawn until a scroll bar is released), based on the Windows Show Window Contents while Dragging setting
[/list]

Anyone have any ideas?
November 18, 2004, 6:42 AM
Skywing
I would be highly interested in working on this -- however, the work is definitely going to be non-trivial.

In addition to what you have specified above, the primary feature requirements I have that I can recall off the top of my head are:

The most important thing is automatic font linking for glyphs not present in the selected font (e.g. truly Unicode enabled).  This is the primary reason why I haven't written my own control so far -- Uniscribe/MLang are a major pain to use and the documentation isn't that great.  Any control that's used for chat needs to have font linking so that blocks aren't displayed for characters not supported by the current/default font.

Other things:

- It should be easy to disable scrolling, e.g. so that a user can scroll up and select something without having the client area scrolled out from under them.
- The insertion position should be distinct and separate from the user's text selection for copy/paste.
- Formatting support (this probably doesn't need to be as extravagent as RTF, but it should support stuff like drawing text with different colors or font attributes within the same control).
- Easy to use from languages that don't have intrinsic support for COM (including non-CLR languages).  Preferably implemented as a standard Windows custom control would be.
November 18, 2004, 7:37 AM
Myndfyr
You've piqued my curiousity.  However, there are some areas I'm not sure about:

[quote author=Skywing link=topic=9595.msg89228#msg89228 date=1100763454]
The most important thing is automatic font linking for glyphs not present in the selected font (e.g. truly Unicode enabled).  This is the primary reason why I haven't written my own control so far -- Uniscribe/MLang are a major pain to use and the documentation isn't that great.  Any control that's used for chat needs to have font linking so that blocks aren't displayed for characters not supported by the current/default font.
[/quote]
I haven't dealt with much multi-language support in my travels; are the "blocks" that you refer to those annoying rectangle things that pop up when Windows doesn't know what character to display?  I'm not particularly familiar with using Unicode (other than that I know NT natively supports it as does Java and .NET).

[quote author=Skywing link=topic=9595.msg89228#msg89228 date=1100763454]
- It should be easy to disable scrolling, e.g. so that a user can scroll up and select something without having the client area scrolled out from under them.
[/quote]
I hadn't considered automatic scrolling -- which seems like a distinct possiblity -- but you make a good point.  I just assumed that the client hosting the control would scroll.
[quote author=Skywing link=topic=9595.msg89228#msg89228 date=1100763454]
- Formatting support (this probably doesn't need to be as extravagent as RTF, but it should support stuff like drawing text with different colors or font attributes within the same control).
[/quote]
One of my thoughts about this was that each text node in the list would contain font and color information.
[quote author=Skywing link=topic=9595.msg89228#msg89228 date=1100763454]
- Easy to use from languages that don't have intrinsic support for COM (including non-CLR languages).  Preferably implemented as a standard Windows custom control would be.
[/quote]
For me, that was assumed.  Implementing it in COM or .NET would limit the accessibility and generalizability of the control.  However, it would be nice to provide a wrapper for those environments to access it.
November 18, 2004, 2:14 PM
Arta
It would be nice to have a control that supported margins as well: In other words, instead of:

[code]
<user> this text is
wrapping
[/code]

You would have

[code]
<user> this text is
          wrapping
[/code]

I think that would look great and make things easier to read
November 18, 2004, 4:51 PM
Myndfyr
It occurs to me that the ability to add images in various formats may also be useful.
November 18, 2004, 6:19 PM
kamakazie
One thing I liked about using a WebBrowser control to display chat, updates, etc. is that I can link a stylesheet to it to allow the user to custom define the colors.  It also is nice for showing/hiding timestamps since you just update the css file to set that particular element to hidden.  The only bad thing was the bloat.
November 18, 2004, 8:48 PM
Myndfyr
[quote author=dxoigmn link=topic=9595.msg89283#msg89283 date=1100810904]
The only bad thing was the bloat.
[/quote]

That was the WORST thing.  It used at least an additional 30 or so mb of memory.  Bloat nothing.
November 18, 2004, 10:17 PM
kamakazie
[quote author=MyndFyre link=topic=9595.msg89288#msg89288 date=1100816240]
[quote author=dxoigmn link=topic=9595.msg89283#msg89283 date=1100810904]
The only bad thing was the bloat.
[/quote]

That was the WORST thing.  It used at least an additional 30 or so mb of memory.  Bloat nothing.
[/quote]

And if you could develop a control that has similar functionality without the bloat, you'd do everyone a good service.
November 18, 2004, 10:42 PM
St0rm.iD
How about we all band together and write a kickass text rendering engine for it, slap on a HTML parser, and call it an ultralite browser.
November 19, 2004, 12:25 AM
UserLoser.
[quote author=Arta[vL] link=topic=9595.msg89260#msg89260 date=1100796691]
It would be nice to have a control that supported margins as well: In other words, instead of:

[code]
<user> this text is
wrapping
[/code]

You would have

[code]
<user> this text is
          wrapping
[/code]

I think that would look great and make things easier to read
[/quote]

Note: That's already possible with the current RichEdit20.dll.  See PARAFORMAT and EM_SETPARAFORMAT - My old client supported this.
November 19, 2004, 3:05 AM
Myndfyr
[quote author=Banana fanna fo fanna link=topic=9595.msg89307#msg89307 date=1100823918]
How about we all band together and write a kickass text rendering engine for it, slap on a HTML parser, and call it an ultralite browser.
[/quote]

That was something I was considering.  If we could develop a decent way of putting together a nice base class for text rendering, making an HTML node inherit from it shouldn't be too much of a stretch.  But I'd rather focus on one thing at a time, bearing in mind design goals such as generalizability, reuse, and extensibility, instead of having a load of feature creep.
November 19, 2004, 3:07 AM
Arta
[quote author=UserLoser link=topic=9595.msg89326#msg89326 date=1100833511]
Note: That's already possible with the current RichEdit20.dll.  See PARAFORMAT and EM_SETPARAFORMAT - My old client supported this.
[/quote]

Neat, I'll have to look into that.
November 19, 2004, 1:56 PM
Grok
Support embedded DIBs?
November 19, 2004, 9:37 PM
Myndfyr
[quote author=Grok link=topic=9595.msg89400#msg89400 date=1100900245]
Support embedded DIBs?
[/quote]

I'm not sure that I want this to create "documents" per se.  At least, that wasn't what I'd envisioned.  :-)
November 19, 2004, 10:06 PM
Myndfyr
So, although I haven't given this TOO much thought, I was working through some ideas and I wanted to share a little bit of the header that I started dabbling with:

RichDisplay.h
[code]
#ifdef RICHDISPLAY_EXPORTS
#define RICHDISPLAY_API __declspec(dllexport)
#else
#define RICHDISPLAY_API __declspec(dllimport)
#endif

// Handle to a text segment with individual information for text, font name, and color.
typedef HANDLE HTEXTSEG;

// This class is exported from the RichDisplay.dll
class RICHDISPLAY_API CRichDisplay {
public:
CRichDisplay(void);
~CRichDisplay(void);

};

// This class describes segments of text.  Describes text, font name and color.
class RICHDISPLAY_API CTextSegment
{
private:
BOOLEAN m_selected;
LPWSTR m_text;
LPWSTR m_font;
DWORD m_color;
HTEXTSEG m_handle;

public:
CTextSegment(void);
~CTextSegment(void);

DWORD GetSelected(OUT BOOLEAN &fSelected);
DWORD SetSelected(IN BOOLEAN fSelected);

DWORD GetText(OUT LPWSTR szBuffer, IN DWORD nMaxLength, OUT DWORD nTextLength);
DWORD SetText(IN LPCWSTR szBuffer, IN DWORD nTextLength);

DWORD GetFontName(OUT LPWSTR szBuffer, IN DWORD nMaxLength, OUT DWORD nLength);
DWORD SetFontName(IN LPCWSTR szBuffer, IN DWORD nNameLength);

DWORD GetColor(OUT DWORD &nColor);
DWORD SetColor(DWORD nColor);

HTEXTSEG GetHandle();
}

// Creates a new CTextSegment instance and retrieves its handle so that it can be used in languages that do not support
// use of C++ classes.
RICHTEXTDISPLAY_API HTEXTSEG CreateTextSegment(LPCWSTR szText, DWORD nTextLength, LPCWSTR szFontName, DWORD nFontNameLength, DWORD nColor);
[/code]

So essentially, I want C++ users to be able to use classes, but I also want other language libraries to be able to interact with the library through handles.

Any thoughts?
December 16, 2004, 9:46 PM
Kp
It may be preferable for memory-usage reasons not to store the font name within the control, but rather to save an object which holds a reference count and a font handle.  Then all the segments drawn in a single font share one FontContainer, which is freed when they're all erased.  For example:

class FontContainer {
    HANDLE hFont;
    unsigned count;
    LPWSTR wszName;
  public:
    static FontContainer *getFont(LPWSTR font_name); // return an existing FontContainer if one is available, otherwise load the named font and return it in a new container
};

With regard to selection support, it looks like your present scheme has a selection granularity of one text segment.  This could be annoying if you wanted to select part of a line, as could happen if you were selecting a URL from someone saying "This site rocks: protocol://someplace.net/".
December 16, 2004, 10:10 PM
Myndfyr
[quote author=Kp link=topic=9595.msg92633#msg92633 date=1103235005]
With regard to selection support, it looks like your present scheme has a selection granularity of one text segment.  This could be annoying if you wanted to select part of a line, as could happen if you were selecting a URL from someone saying "This site rocks: protocol://someplace.net/".
[/quote]

Yes, I've considered that much.  We can create two integral values that have the beginning and ending of the selection text for zero-based indices; it shouldn't be too much trouble.  What I was going for in this case was more the general idea behind the way I think the library should work, more than the general object set.

As far as font objects -- good idea!  I hadn't thought of that.

[edit]Skywing: I found an MSDN article describing the process of laying out and drawing text using Uniscribe.  Wow.  Yes, you were definitely right: it looks like a major pain in the behind.  Thanks for the heads-up.
December 16, 2004, 10:16 PM

Search