Category : Pascal Source Code
Archive   : TMWIND.ZIP

Output of file : TMWINDOW.DOC contained in archive : TMWIND.ZIP
{Window applications of Object professional.

Last updated 18-SEP-90

(C) Tim Mackinnon
Cad Graphic Design Ltd.
206 Guigues Ave.
Ottawa On.
K1N 5J2

613 233-7246

Compuserve [72230,3101]


I am not the greatest at documentation, so bear with me on this one, as I
try to explain to you what I have done.

I have embraced object oriented programming and have developped the following
window objects in my (large) library out of frustration with what was around
me. This of course is the power of OOPS, if you don't like it, OVERRIDE it!
I welcome you to do the same here.

Coming from CARLETON University, where OOP is a way of life, and unless you
do it in Smalltalk you'll never get your honors project completed, I have
tried to make the most of Object TP, and have found that it can be made to
function very much like Smalltalk, even excelling it in some places (Try
using grep to find a lost method in Smalltalk!).

The text file device driver encapsulation used here, is used in many more
of my libraries, which I am polishing up. While I don't mind if you use my
routines, if they do get used a lot, please send a donation to a
starving student, who's getting sick of Kraft dinner.

Anyway, here is what this library can provide you!

1) PlainWindow:

Command windows are great, if you take the time to get all the pieces
right. I like to get them up FAST, and with little fuss. PLAINWINDOW
does this by creating the commandprocessor for you, and setting up
default window attributes that I use all of the time.

2) MsgWindow:

This is what you are here for! I hate having to use Long2Str, and
converting everything to a string to write it in a window. Furthermore, I
can never get everything to line up correctly in the window. This one
does it all for you. I have encapsulated a Text File device driver so that
you can simple say:

writeln(,25,' Bottles',^A,' of beer on the wall!');

It will wrap, and support the flex attribute convention of Turbo power.

3) ScrollingMsgWindow:

I haven't played with this one too much, so it hasn't been field tested
too much. The idea is to be able to write to a large window and let the
user pan around it. Its built on top of MsgWindow and so has the same
text file device driver capabilities.

4) Button:

This one gets used for my buttonSelector objects (which use entryScreen,
who's fields must be command window derivatives, and so this is why it
is here!). When I get the docs for that one completed, I'll upload it

The hierarchy I have used is this:

|- PlainWindow
| |
| |- MsgWindow
| |
| |- ScrollingMsgWindow
|- Button

Here is a brief summary of the methods I have used and how they might be of
use to you:

tmUseShadows : boolean = true; {change to false to disallow shadows}

tmDefWindowOptions : longint = wClear+wSaveContents+wResizeable+wStoreContents+wBordered;

I use these, as I hate the defualt of no wBordered in oPro (why they did this
only they know). Sometimes I don't use shadows, (usually I do), so
tmUseShadows is a painless quick way of doing that.

procedure plainWindowStream(sPtr : idStreamPtr);

This is a procedure for registering in streams. It can be used both by
plainWindow and commandWindow (which does'nt introduce anything too new).

constructor initCustom(x1,y1,x2,y2 : byte; title : string;
var colors : colorSet; options : longint);

constructor init(x1,y1,x2,y2 : byte; title : string);
constructor load(var S : idStream); {load an existing instance from a stream}

destructor done; virtual;
procedure store(var S : idStream);

The above all explain themselves, as they are similar to Opro.

procedure initCp; virtual;

Sometimes its nice to add more commands to the commandProcessor. All my
objects have this method, so that you can easily add commands when
deriving a new object, and not have to retype out all of the parameters
for init (I hate that).

procedure processSelf; virtual;
procedure erase; virtual;

The above are the same, except that erase, will use eraseHidden if it is
not active.


I won't go in to how the text file device driver works, the TP manual is
pretty good about it. The idea is that there is just enough extra room
in a TFDD to store self in there so that write and writeln, can direct
a string to the correct instance of an object.

textPtr = ^text;

Originally I needed the above for objects that didn't directly inherit from
msgWindow. I hated having to use writeln(^,'Hello'); so I did
get around it (You will see this in my other libraries, when I upload them).

msgWindowPtr = ^msgWindow;
msgWindow = object(plainWindow)

win : text; {the text file device that you use!!!}
flexAttr : char; {private, leave it alone!}

Win is the one you USE! Its really very simple, if you have a msgWindow
instance called "myWin", then you would use:

write(,'Hello world');

Very simple, very painless! You can even embed ^A,^B and ^C to have
attribute control (see flexWrite in opro for more of a description).
While I do a bit of checking on this string. If you jam enough of these
onto one line, I'm sure you can get the wrapping to mess up (as wordWrap
in opString, does not take into account these extra characters) and I
do my best to adjust for it, without getting out of control. If you don't
understand wordWrap, refer to it in opString.

NOTE: there is one caveat with word wrapping. A text file device has a
defualt buffer of 128 bytes. I left this alone so as not to waste space
by allocating a bigger buffer. Conceivably one can keep using write(ln),
forever, with the buffer being flushed every 128 bytes. If you use it
past 128 bytes, be warned that you can get a word broken in two, because
my write method does not get the other half until it is too late (and the
first 128 bytes have been wrapped). You can avoid this by using lots of
short write's and writeln's, or just terminating them you see that you
have a problem. If it really annoys you, override my object and allocate
yourself a bigger text buffer. Its only caught me off guard a few times,
so I just watch out for it.

constructor initCustom(x1,y1,x2,y2 : byte; title : string;
var colors : colorSet; options : longint);

constructor init(x1,y1,x2,y2 : byte; title : string);
destructor done; virtual;

The above are normal.

procedure clear; virtual;

procedure write(s : string); virtual;
procedure writeln(s : string);

procedure flexAttributes(VAR fAttrs : flexAttrs); virtual;
procedure maintainAttribute(s1 : string; VAR s2 : string);

Clear was changed so that it clears the current flex attribute to the
text attribute of the window. Write and writeln get called by the TFDD,
so its not much fun calling them yourself, but you can if you want. Note:
I had to add special logic to ensure that when a line is wrapped, the
current attribute is still used (this is what maintainAttribute is for).
If you are going to override anything, OVERRIDE flexAttributes. These are
my favorite colours, they may not be yours!

function window : textPtr;
function winP : textPtr;

For historical reasons (and pointer freaks), you can reference win, by using
one of these pointers to it.

I'm getting tired of this, so use this one as best your can, I'll point out
the important things!

constructor initCustom(x1,y1,x2,y2 : byte; wid,hgt : word; title : string;
var colors : colorSet; options : longint);

constructor init(x1,y1,x2,y2 : byte; wid,hgt : word; title : string);
destructor done; virtual;

function winWidth : byte;
function width : word;
function winHeight : byte;
function height : word;

procedure updateContents; virtual;
procedure clear; virtual;

procedure activate;
procedure deactivate;

As with the normal scrolling window, call activate before you write, and
deactivate when you are done. As I inherited from commandWindow, I had
to pass these calls to the internal VS. (Where is multiple inheritance
when you need it).

procedure write(s : string); virtual;
procedure writeln(s : string); virtual;

procedure processCmd; virtual;
procedure processself; virtual;

Use write and writeln as you would normally for msgWindow (but inside
activate and deactivate). Process cmd is where I interpret clicks on
the scroll bar etc. I like to leave process self quite short, so I can
easily see what gets me out of the process loop. Override processCmd
to add more functions, but remember to call it in your code if your
still want to let the user move around.

{A button object will wait until the command key is pressed. The
command key is specified in msg with the ^ character (ie. ^Ok).

I will leave buttons alone. Lets just say they become child windows in
an entry screen so you can click on them. I will get to these another day.


Well this about sums it up. I would like to thank the guys at Turbo Power
for putting up with me, while I got some of this stuff to work!

Whats next on my list?

Well how about a TFDD for reports? (Its done and just needs some tuning).
The idea is that you do writeln(myRep.header,''); writeln(myRep.footer,'');
and then keep doing writeln(myRep.body,''); and watch your report just
magically come out, nicely formatted with the ability to group objects
together so that they can stay on a page. I don't know what opForm was all
about, but its not how I write reports.

A database object, that implements all of the Filer routines (its done, but
does not have lan, or vRec support yet). Would like to add autoCompression

Please stay tunded!

And once again, If you really like this library, find it usefull and want me
to get these other ones done:

Send $10 (or whatever you think its worth, if only a postcard) to

Tim Mackinnon
CAD Graphic Design Ltd.
206 Guigues Ave.
Ottawa, ON
K1N 5J2

  3 Responses to “Category : Pascal Source Code
Archive   : TMWIND.ZIP

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: