Category : Pascal Source Code
Archive   : BININT.ZIP
Filename : BININT.DOC

 
Output of file : BININT.DOC contained in archive : BININT.ZIP

BININT
Accessing BINED Internal Information in Event Handlers
Version 1.0
Kim Kokkonen

Overview
------------------------------------------------------------------------------
BININT is a small unit that may be used in programs based on the binary
editor, BINED, from Borland's Editor Toolbox. It removes a drawback of BINED,
which is that accurate information about the cursor position (within the
current line and text buffer) is not available to event handlers. As such,
event handlers are limited in what they can do.

When accurate information is available to a BINED event handler, new
horizons open up for using the binary editor. We developed this unit in
order to add limited mouse support to BINED, which required knowing the
cursor position relative to the overall file size. Another popular request
is to add word-wrap to BINED -- knowing the information provided by BININT, an
event handler could be written to add word wrap.

BININT is a dirty little unit, peeking into the BINED code segment to read
certain offsets of data items that it needs to compute accurate information
for use by an event handler. Even so, BININT is very careful to assure that
the information it uses is correct. If BININT can't find the appropriate
offsets, it will fail gracefully, but in this case an event handler won't
have the information it needs. So far this isn't much of a concern since to
our knowledge Borland has released only a single version of BINED. BININT is
designed to adjust itself automatically whenever possible, even if BINED is
changed in the future.

In the following, we assume you know what is meant by a BINED "event handler".
See Borland's documentation, or the supplied example TEST.PAS, for background.


Using BININT
------------------------------------------------------------------------------
Just add BININT to your USES list, after BINED itself. (BININT depends on
BINED.) Then your application can call any of the following procedures and
functions.

procedure FindInternals(EdData : EdCB; var E : EdIntRec);

Call FindInternals any time after calling Borland's InitBinaryEditor
routine, but before calling UseBinaryEditor. This routine initializes the
record parameter E to hold information needed to track the specified edit
window EdData. The program must declare a global variable of type EdIntRec
to store the binary editor internals information for use by the event
handler. Note that you will need a separate EdIntRec variable for each
BINED edit window.

If for some reason BININT cannot find the appropriate locations in BINED, it
will return all fields of the EdIntRec set to zero. This may be considered
a critical error for any program using BININT even though the rest of
BININT's functions are designed to return safe values in this case. You can
test for correct operation of FindInternals with the following statement:

if E.EditSeg = 0 then
{Critical error, unknown BINED version} ;

The remaining BININT functions are intended for use within an event handler.
Each of them requires a parameter of type EdIntRec, previously initialized by
a call to FindInternals.

function CurrLineOfs(var E : EdIntRec) : Word;

This routine returns the byte offset within BinEd's text buffer of the first
character on the current line. For example, if the cursor is on the first
line of a text file, CurrLineOfs will return 0. If the first line has 10
characters (counting CR and LF), then CurrLineOfs will return 10 when the
cursor is on the second line of the file. When the cursor is moved to the
end of the file, CurrLineOfs returns the same value as EdData.EOtext. If the
EdIntRec was not correctly initialized, CurrLineOfs returns $FFFF.

Note that CurrLineOfs does not vary when the cursor is moved within a given
line. The LinePos function provides that information.

function CurrChar(var E : EdIntRec) : Char;

CurrChar returns the ASCII character associated with the current cursor
position in the file. If the cursor is beyond the end of the current line,
CurrChar returns a blank (#32). CurrChar will not return a CR (#13), LF
(#10), or EOF (#26) unless the text file is corrupt. If the EdIntRec was not
correctly initialized, CurrChar returns #255.

function LinePos(var E : EdIntRec) : Byte;

LinePos returns the position of the cursor in the current line. It returns 1
for the first character in the line. The highest value normally returned
will be 249. If the EdIntRec was not correctly initialized, LinePos returns
255.

Note that you can't add LinePos to CurrLineOfs and obtain an offset that
means anything. BINED copies the current line to a separate buffer for
editing and recopies it to the main text buffer only when the cursor leaves
the line. Hence, the contents of the text buffer beyond CurrLineOfs are not
guaranteed to be up to date. Use the CurrLine function to get the contents
of the current text line.

function LineLen(var E : EdIntRec) : Byte;

Returns the length of the current line. The length is defined as the number
of characters up to and including the last non-blank character in the line.
Note that the cursor is allowed to move beyond this position, and thus you
will have situations where LinePos > LineLen. If the EdIntRec was not
correctly initialized, LineLen returns 255.

function CurrLine(var E : EdIntRec) : string;

Returns the current text line as a string. There's no need to call LineLen
if you call CurrLine since the length of the returned string equals LineLen.
If the EdIntRec was not correctly initialized, CurrLine returns an empty
string.

function EditOptions(var E : EdIntRec) : Byte;

Returns the current value of the editor options (which may have been changed
by the user since the edit session started). See the constants near the top
of BINED.PAS (EdOptInsert and so on) for masks to decode this bit-mapped
byte.


Note that BININT is not designed to let you _modify_ any of the data that it
provides. Within an event handler, it is not safe to change the cursor
position, or directly modify the line buffer.

If modification of the text stream is desired (as would be the case when
adding word wrap to BINED), the appropriate action is to poke characters into
the keyboard buffer. For this reason, BININT provides two more procedures:

procedure ClearKbd(var E : EdIntRec);

Before poking a character, it is best to call this routine. ClearKbd clears
not only the BIOS keyboard buffer, but also an internal single byte buffer
used by BINED to hold extended keystrokes.

procedure StuffKey(W : Word);

This stuffs one character (ASCII value with scan code) into the keyboard
buffer. If the character is not extended (like or ) it is alright
to call StuffKey as follows:

StuffKey(Ord(CharToStuff));

For example

StuffKey(Ord(^M));

puts a carriage return into the keyboard buffer, to be acted upon by BINED
when the event handler returns.

For an extended character, pass the appropriate word value. For example

StuffKey($4B00);

stuffs a arrow into the keyboard buffer.

Remember that the keyboard buffer normally holds only 16 characters. If the
buffer is full when StuffKey is called, it does nothing.


Examples
------------------------------------------------------------------------------
The supplied program TEST1.PAS is a tiny example of using BININT. It allows
you to browse through a file while continuously showing a status report of the
information offered by BININT. Just compile TEST1.PAS and run it by specifying
a text file to browse on the command line:

TEST1 FileToBrowse

Press ^KD to quit. No changes will be saved.

TEST2 is a frivolous example of modifying the text stream by stuffing
characters into the keyboard buffer. Compile and run it just like TEST1. In
TEST2, whenever the cursor is positioned over a space within a text line, the
event handler breaks the text onto the next line, leading to a
semi-interactive "one word per line" filter. If the editor is in overwrite
mode, the event handler does nothing. Like TEST1, TEST2 does not allow you to
save the resulting file.


Disclaimer
------------------------------------------------------------------------------
The BININT unit was written by Kim Kokkonen of TurboPower Software. It is
hereby released to the public domain. We accept no liability for the use of
this software, and make no guarantees as to its performance. Good luck! We'd
like to hear from the first person to develop a word-wrapping event handler
for BINED.