Cool Owner Draw Engine

Environment: Windows 95, Visual C++ 6 SP2

Here I present a class that helps writing Owner Draw Controls with basic - although cute - text formatting capabilities.

The CCoolOwnerDrawEngine class is not a control class by its own, or even a CWnd derived class. As a matter of fact, its objects work as aggregateable members of Owner Draw Controls objects. By instantiating a CCoolOwnerDrawEngine as a member object, such a control can rely on delegation to let the engine taking care of the complex draw and format operations.

All we have to do is to redirect the control's DrawItem method to the engine's DrawItem, providing it with the draw data (DRAWITEMSTRUCT), and the item's tagged text string.

The tagged item's string describes both the text and the format, pretty much as other tagged syntaxes do. Of course it's not so powerful as HTML or Rich Text Format. But, for the basic stuff, it's pretty good.

Just to make it clear now, so I won't disappoint you later: at this version, it's not possible to mix different font typefaces or font sizes. However, you still can change the font color and any of its bold, italic or underline attributes.

For a glance, the text items in List 1, entered in the Cool Demo application, will produce the visual output of Figure 1 - you must enter line by line.


List 1


  <0><-><j><#1010>Table<10>
  <#1000><0><|><j>Group A<5><|><j>Group B<10><|>
  <#1000><0><|><-><j>Col X<1><|><-><j>Col Y<2><|><-><j>Col Z<5><|><-><j>Col W<6><|><-><j>Col T<10><|>
  <0><|> <i0> <20> Thales <1><|><j><j><#5>10 <#><2><|><#1><b10><#><5><|>---<6><|>---<10><|>
  <0><|> <i0><i1><i2> <20> Ricardo <1><|><j><j><#5>100 <#><2><|><#1><b100><#><5><|>---<6><|>---<10><|>
  <0><|> <i0> <20> Pacheco <1><|><j><j><#5>20 <#><2><|><#1><b20><#><5><|>---<6><|>---<10><|>
  <0><|> <i0><i1> <20> Eloy <1><|><j><j><#5>50 <#><2><|><#1><b50><#><5><|>---<6><|>---<10><|>
  <0><|> <i2> <20> Marcio <1><|><j><j><#5>3 <#><2><|><#1><b3><#><5><|>---<6><|>---<10><|>
  <0><|><1><|><2><|><5><|><6><|><10><|>
  <0><-><|><1><-><|><2><-><|><5><-><|><6><-><|><10><|>
  <0><-><|><#1000><j><j> Total<#> <1><-><j><j><-><#5>11111 <#><2><|>

Figure 1

Figure 1


The Cool Demo application uses the CCoolDemoListBox, which is a CCoolOwnerDrawEngine equipped MFC Owner Draw CListBox.


Tags Overview

Here is a description of each existing tag.

<#n> - Select Style

This tag selects the style n for the subsequent drawing, where n is a decimal identifier from 0 up to 4294967294. Each style has a text color and a font attribute (either bold, italic, underline or any combination of those). At this version (and probably this is the last one), it's not possible to change the font size, neither the font typeface.

Styles are independently configurable through the CCoolOwnerDrawEngine::SetStyle member function.

I designed it to use externally configurable styles, rather than putting direct tags to select font attributes and text colors, because I think styles are more abstract. Therefore, you can change one style properties and all the affected items will be changed automatically, without having to be reformatted and reinserted in the control.

The selected style won't persist from one item to other. Every time the engines starts drawing a new item, it resets to the default style.

If a style doesn't exist (it was not configured with CCoolOwnerDrawEngine::SetStyle), the engine keeps using the current style.

You can use sparse style IDs (e.g. 1015 and 3). Internally, the engine keeps them in an ordered CArray and uses binary search (which, for this particular purpose, has better performance than the CMap, for both memory and speed).

<#> - Select Default Style

The default style is basically the style of the DC that's provided for CCoolOwnerDrawEngine::DrawItem.

<n> - Tab Stop

This tag aligns the current draw position with the tab stop n, where n is a decimal identifier from 0 up to 4294967294.

Well, at first it's a normal tab stop, but there're three major differences:

- It has an ID. Therefore, you always know to which tab stop you're going to advance the drawing position. In an ID-less tab stop List Box, for instance, if the drawing position is already beyond the desired tab stop (the previous text was too long), it'll advance to the next tab stop - if any -, and the item will show unaligned.

- Again, it has an ID. Another advantage of labeled tab stops is they affect only the items that refer to them. Therefore, you might have different groups of items, each one using a separate group of tab stops, and one will not get in the way of the other.

- The engine automatically resizes them, so the distance between any two different tab stops is always enough to fit any text that happen to be between them. It makes the tag useful to create simple tables.

<j> or <J> - Justification

This tag changes the justification alignment from left to center, and from center to right, between two consecutive tab marks.

The engine stars aligning text to the left. If it finds this tag once, the subsequent output will be aligned to the center, and, if it finds this tag twice or more, the subsequent output will be aligned to the right.

For instance, List 2's items will produce Figure 2's output:

List 2


   Left <j> Center <j> Right
   Just Left
   <j> Just Center
   Left and... <j><j> Right

Figure 2

Figure 2


Since the output is once aligned to the right, extra Justification tags would have no effect. However, do note that the Tab Stop tag will reset the alignment back to the left.

<in> or <In> - Icon Tag

Yes, you can attach a CImageList to the engine and instruct it to draw icons, using this tag. Just give the icon index. By the way, there's a member function to attach the Image List.

<-> - Bottom Horizontal Border

This tag instructs the engine to draw a bottom border (a 1 pixel horizontal line) between the current tab stops, using the current style color.

<|> - Vertical Border

This tag instructs the engine to draw a vertical border (a 1 pixel vertical line) at the current drawing position.

<bw> or <Bw> - Bar

This tag instructs the engine to draw a bar w pixels wide. It advances the current drawing position of w pixels to the right. By the way, the bar is painted with the current style's text color.

<<> - Less Than Character

This tag draws the '<' character.

<>> - Greater Than Character

This tag draws the '>' character.


Cool Demo Application Features

The demo application is just a dialog box with an edit box and a list box. The list box's stamina is a CCoolOwnerDrawEngine object. The edit box is just for entering tagged items strings in the list. So, just type the text in the edit box and press <return>. You can also delete an item by selecting it and pressing <del>. The dialog box is resizeable.

In the demo application, I use the following style ID pattern: biuC

Where b, i and u are the flags for font attribute bold, italic and underline. These flags can be either 1 (on) or 0 (off). And C is the color index, being 0 black, 1 light red, 2 light green, 3 light blue, 4 dark red, 5 dark green, and 6 dark blue.

Therefore, such a tag as <#1003> will activate the blue bold font style.

But do note that you can program whatever combination you want.


I hope that some of you will find this engine useful and cute, and maybe you'll create some new Owner Draw Controls based on it. Perhaps, in the future, we'll see some of them here.

Downloads

Download demo application - 62 Kb
Download demo project - 19 Kb
Download source code - 6 Kb


Comments

  • What has this got over the HTML control

    Posted by Legacy on 07/30/2002 12:00am

    Originally posted by: Peter Ritchie

    Why would I use this control over an HTML control and have to learn a whole new set of tags (less-powerful, as you admit)?

    Reply
  • very sweet man

    Posted by Legacy on 06/14/2002 12:00am

    Originally posted by: code6

    very sweet indeed, this is quite bad ass. i'm extremely impressed by the screen shots. just gonna checkout all the drawing code, but props man, looks like you gotta hella kewl little framework going here

    Reply
  • Documentation!

    Posted by Legacy on 02/11/2000 12:00am

    Originally posted by: Philippe Lhoste

    Your engine is indeed cool!

    I like it, I think it can help a lot to easily make owner drawn controls. Thank you for such a great idea.

    Perhaps you put too much features in your tag language, but as long as it don't bloat your code... And I suppose that if you put them here, you needed them in your projects.

    Now, a little reproach. One I can make to most of the programmers publishing here:
    Please, put a doc. in your Zip files!

    Often, after download, I have to copy the CodeGuru page (HTML or text) and add it to the Zip file. I find this annoying, so if you can, please, put some doc. with the sources.
    It is direly needed here, as we lack a tag language reference with the source...

    Thank you for all.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: November 20, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Are you wanting to target two or more platforms such as iOS, Android, and/or Windows? You are not alone. 90% of enterprises today are targeting two or more platforms. Attend this eSeminar to discover how mobile app developers can rely on one IDE to create applications across platforms and approaches (web, native, and/or hybrid), saving time, money, and effort and introducing apps to market faster. You'll learn the trade-offs for gaining long …

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds