FAKEIT.ZIP

(C)1993 Honor Oak Systems, All Rights Reserved

This is provided as an example for you to play with. I do
not accept any responsibilty for bugs and errors, you are
on your own. Feel free to include it in your own
applications.

That being said, any comments and suggestions are welcome
to CIS is 100111,421. Large donations of money are never
turned away!

Overview

FAKEIT.ZIP is a demonstration program which shows how to
build a window that appears to be a dialog screen when a
large number of controls are needed. It provides a
solution that allows for almost unlimited numbers of
controls and reasonable screen painting times.

Windows has limits on the number of children allowed in a
window, and also there are limits because each window
takes 50-70 bytes of the 64k segment for all
applications.

The principle of FAKEIT is that controls are complex
pieces of code that one would want to avoid writing, but
when not in use it is easy to paint something that looks
like a control.

FAKEIT uses a BIDS array to store the fake controls,
which are constructed in a very similar way to normal OWL
controls. A special manager window is created to
encapsulate the behaviour of the control painting, and a
special version of TApplication is derived to look after
intercepting dialog keystrokes.

A demonstration project is included, a standard dialog
with 2000 controls on it, (check the program manager
About box for resource usage).

It is not intended to be a complete application solution,
but should provide a demonstration of the techniques
sufficient for you to build your own solutions.

Acknowledgements

The principle of FAKEIT is in part taken from the ONEEDIT
program provided by Microsoft available in CompuServe
forum MSL. However, this is an original work and the code
and methods used are my own.

For comparison with a standard program, I have based the
example on the EDITTEST Borland C++ OWL example.

Thanks to Paul Andre LeBlanc who pointed me in the right
direction on handling push buttons and to all the co-
habitees of BCPPWIN who have helped be on my way with
Windows programming..

Building the Example

To keep the download small, I have not included any
.EXEs. The project file should build o.k. if in a
directory directly off your BORLANDC (or equivalent)
directory, otherwise you'll need to change the directory
entries, (options|directories).

There is only one known bug that you might trip over. In
arrays.h there is an error which results in an Unable to
find constructor for AbstractArray error. I have fixed
this to suit my compiler, but there seem to be people
who's version acts up in a different way. If you get a
strange compile error try this :

remove the #define <abstarry.h> in the first line of
fakeit.h and it should compile alright, the fix is to get
arrays.h to be the first thing included.

Class Overviews

TManageApp

This is derived from TApplication. The only change is to
ProcessAppMsg which I have hacked out the dialog
processing etc. and left a PreprocessMessage in its
place. This intercepts all WM_KEYDOWN messages for the
application, and if they are for child windows of the
main window turns them into user messages for the
TManageWindow to handle. Note that this technique avoids
getting into message hooks, but would not work for
intercepting a true dialog's keystrokes as they are
handled internally by Windows.


TManageWindow

This acts as a main window, containing all the keyboard
management, the control list and the painting. It
supports scrolling through the standard TScroller method,
and optimises the painting of fake controls.

The SetupWindow() function initialises the "dialog"
details, finding the first tab stopped control, checks
for buttons and default push buttons. Using the control
list it provides hit testing the mouse and requesting the
moving of fake controls. It provides a notification
response for the real control for a xxKillFocus. This
allows the TManageWindow to know when control has passed
to a real control via a mouse click.

The dialog management is customised to manage both real
and fake controls. As it is not a dialog, the application
intercepts the WM_KEYDOWN VK_TAB and VK_RETURN and passes
these to TManageWindow as user messages. It uses the
order of the control list to interpret the window order
of tabbing and back tabbing
It will interogate the current control, if real, to see
if it is a button that needs to respond to the enter key,
and if not checks for a default push button and triggers
than if necessary. This version does not implement the
ALT-key accelerators.


ControlDisplay

The important class. This contains the controls to be
displayed. They can be real controls (derived from
TControl for which a constructor is provided, no other
action is required), or fake controls whose behaviour is
coded in derivatives of ControlDisplay.

Fake controls need to provide three functions:
-    DisplayControl,     which provides the function of
how to draw the fake control.
-    SetAttributes       which sets up the real control
with the specific behaviour required for the
ControlDisplay instance, and the moving of the real
control.
-    GetAttributes       which stores the real control
information into the ControlDisplay instance.
Further to this, any extra behaviour required can be
coded into the derivative class, (for instance see the
DisplayEdit class for setting and getting text).

StaticDisplay

This class replaces TStatics. Note it assumes that the
static control will not be updated. It does not require a
real control to manage user input. If a static were
required to be updated a function like
EditDisplay::SetText could be implemented.

EditDisplay

This class provides basic edit control functionality.
Further attributes could be added, such as font setting,
edit styles, colours etc.


Tailoring the FAKEIT system, some thoughts and
suggestions

I wrote the example as classes to be derived from. Note
that the dialog handling is very incomplete, though
sufficient for basic control. Also note that the example
only works for a main window, a scheme such as
EnableKBHandler to identify a child window as a dialog
handler might be needed.

The FAKEIT system provides the key element for data entry
of a large number of edit controls. Having established
the principle it is easy to add further functionality for
the edit controls. Owner draw buttons and Borland buttons
should not provide too much difficulty, though I was
pondering the best way to provide "not in focus" pushing.
I thought that rather than moving controls around it
would be best to entirely draw them - which then leads to
the question of whether it is worth using a real control
at all. This is the slippery slope of re-writing Windows!

My basic thinking was that for data processing
applications, the number of graphic controls would be
limited and the reduction in numbers of static & edit controls 
would allow for the more complicated controls not to be
replaced. Rather than providing a complete solution, the
developer can add in the specific functions in a way that
suits.

For instance, for complete Windows compatability, each
edit control would need the ability to support its own
font. However, in most applications, having all the edit
controls with the same font would be satisfactory. With
sharing one font, this could be created in the main
window and accessed as required. To allow every edit
control to be different, the fonts would need to be
created and destroyed as used where a large number of
fonts were used to avoid a GDI overflow. For a reasonable
number of fonts, a cache of fonts might be useful. The
method would be determined by the application
requirements.

List boxes should be straightforward to implement in
terms of drawing, though large lists being cleared and
loaded might not give satistfactory performance (though
it is suprising what gives acceptable results). Here a
compromise might be sought where small lists would be
faked, and large lists provided with their own controls.

Drop down combo boxes should be easy, with the same
proviso as list boxes, they don't drop down when not
in focus, so the drawing ought to be easy.

Fake Control Response Functions

With OWL, the tailored activities of an application are
provided through response functions. In the FAKETEST
example, based on the EDITTEST example, a standard
control provides the function. It may be desired to
provide responses for individual fake controls. The
easiest way to implement this is with a change to the
stand in controls' id based function. This could call a
virtual function in a derived DisplayControl. Similarly
where responses to particular messages were required,
e.g. WM_KEYDOWN, then a derived OWL control could be used
to call virtual function to manage the WM_KEYDOWN for
particular instances. This would be better than
hardcoding responses in derived controls.

It might be nice to add some focus following logic. This
would be fairly easy to add into the TEdit control as a
derivative, adding code around a WM_SETFOCUS, though to
cover for the other controls might mean deriving your own
version of each control you require. (Further hint, TScroller
::IsVisible).

Any road up, this is just provided as an example and
building block. The main point is that this does provide
a solution that can be programmed in an OOP, or at least
OWL way.

A note on using the demo program.

The demo program uses a standard button response to copy text
from the first to the second edit control. You can press this
button by the usual methods, and as a default button you can
also press it by keying enter when in any control. Aside from
a large number of irrelevant edit controls and associated text
the operation is the same as EDITTEST OWL example. It is worth
comparing the two examples for the differences in coding.


Enjoy!?

Ian Spencer
Honor Oak Systems
231 Lichfield Road
Rushall
Walsall
ENGLAND WS4 1EA

CIS id : 100111,421
