
------------------------------ QUIRKS.TXT ----------------------------------


This  file documents YACL's  known  quirks, bugs,  limitations and  the like
under the window systems   that it supports.  In  some cases, YACL  includes
necessary workarounds, and these are also documented here.


Author:          M. A. Sridhar
Last updated:    May 20th, 1996

----------------------------------------------------------------------------




                        G E N E R A L     I S S U E S




[Executable size.]
Currently YACL's makefiles do  not  include support for   building it  as  a
shared library (or DLL).  (The one exception is the Sun Solaris 2.5 platform
using GNU C++; in  this one case the  makefiles include support for building
shared   libraries.)  Consequently   much   of YACL   is   linked   into the
executable. So for the typical GUI demo,  the executable size is around 500K
(under Windows or OS/2).  This figure varies quite  a bit: Under Borland C++
4.0, it's about 700K, while under Watcom C++ with  OS/2 and Windows NT, it's
about 275K.  In any case, it will reduce drastically when YACL is built as a
shared library.  (I hope  to add support for  shared libraries under Windows
and OS/2, real soon now. :-)


[CompositeVObjects with menu bars.]
If a CompositeVObject has a MenuBar, then it increases  its height (over and
above the programmer-requested  height) by the  MenuBar's  height. This way,
the actual visible area of  the CompositeVObject equals the height requested
by   the   programmer.   In   order  to   implement  this  correctly,    the
CompositeVObject's CreateVisualElement method  (which is, of course,  called
before those of   any of its children)   calls each child's   AdjustPosition
method. The latter adjusts  the child's vertical  position by an amount that
is platform-specific and hard-wired into  the code. Note, however, that  the
Composite     calls AdjustPosition only     for  those  children that   have
non-negative view id's.   This is another  reason to ensure  that all simple
visual objects have non-negative view id's.

Note also that this  mechanism of position  adjustment will only work if you
create the MenuBar before the Composite's visual  element is created. If you
do things like creating menu bars on the fly, this adjustment will not work.
(Well, it does under  Windows and Unix,   for different reasons; it  doesn't
under OS/2.)


[Button groups.]
Positioning   buttons within a   button  group  is  very  hard to   do in  a
platform-independent manner. Under Motif, the group  looks best (with fairly
small fonts) if the top button in the group  is 15 pixels below the parent's
top border.   But this setting  is   unsatisfactory under Windows   with the
default font, because it obscures the button group's label. And it is barely
satisfactory under OS/2. You can't win 'em all. :-(


[Default push buttons.]
If you  run a dialog modally,  and designate one of its  push buttons as the
default push button, then  the modal execution  terminates if the  user hits
the enter key, with  the dialog pretending  that the default push button was
pressed. There is one   exception: the dialog  does  not terminate if  it is
itself the main window. This is because "termination" of  the main window is
not detected by the dialog but by the controller.


[Shared libraries/DLLs.]
I have had minimal  success with building YACL as  DLLs. Here's the  (short)
list of successes:

  -  Under    Linux 2.0 (with  ELF),  YACL  can be   built   as three shared
     libraries, libbase.so, libio.so and libui.so.  You can look in and edit
     the  file control/gnuc/linux.cfg    to  enable the  appropriate    make
     variables.   Michael  Martin   (martinm@mbmartin.bevc.blacksburg.va.us)
     contributed the ideas leading to Linux shared library support.

  -  YACL's base and io libraries can be built as  DLLs under Win32 and OS/2
     using Borland C++ (tested under BC 4.0).

And here's the list  of  failures (I  would  greatly appreciate any help  in
fixing these problems):

  -  Building the UI  library as a DLL  under Borland C++,  under both Win32
     and OS/2, causes the GUI  application to crash on  exit. I have no idea
     why.  I ascribe this to a gap in my knowledge of how to build a DLL.

  -  Under Win16, if any  of the library components  is built as a DLL,  the
     app doesn't seem to start at all. I.e., if  you double-click on the app
     from File Manager, it seems to exit immediately. Again, no idea why.

  -  Microsoft VC++ (version 4) does not support the use  of the _export (or
     the _declspec(dllexport) )    qualifier for class  templates.  So  YACL
     cannot be  built as a  DLL under VC++. (Correct  me if I'm wrong, or if
     you know of a workaround.)

  -  I couldn't get the Watcom compiler to link to the generated DLLs.



           

           C O M P I L E R      S P E C I F I C      I S S U E S


[SGI Delta C++.]
The memory leak checker reports a leak of  1024 bytes in some programs, when
there is no   leak. This is  because  the  SGI  Delta C++ iostream   classes
allocate memory  the first  time  it  is needed,  and  this memory  is  only
destroyed after the main program is finished. This is reported  as a leak by
the leak checker, because the leak checker exits when the main program does.

The template instantiation seems to be buggy.  Even with a -ptall flag, some
templates  -- CL_Sequence in particular --  were not  being instantiated.  I
forced  the instantiation using  a pragma, and  that seems to work. Look for
code surrounded by "#ifdef __SGI_DELTA_CC__" to find out about this.

I haven't yet been able to get YACL shared libraries to work under SGI IRIX,
mainly because  I don't know how to get static objects in the shared library
to initialize.


[Centerline C++ for Sun Solaris.]
This is a  cfront-based compiler with lots  of idiosyncracies about template
instantiation.  There's a  lot  of  code  surrounded  by "#ifdef __CFRONT__"
intended to      appease    this   compiler.   Thanks    to     Jody  Hagins
(gamecox@magicnet.net) for the help on this.


[Watcom C++.]
The template support in Watcom C++ 10.0a is  still buggy.  So if you attempt
to instantiate your own  templates using the YACL  containers, you might get
lots of syntax errors. This happens, for example,  if you try to instantiate
a Set of Points in ui/containr.cxx.   I don't know if  the latest release of
the compiler (the  10.5 version) fixes these  problems. The reason why 10.0a
compiles YACL now, and it  didn't before, is  just that I found a workaround
for its bugs and restructured the YACL code.

Generally, though,   Watcom   C++ seems   to produce  smaller   executables,
particularly under  OS/2.  I'd guess this  is  because of  the linker option
"eliminate" which doesn't seem to be available for other compilers.

Watcom  C++  sometimes  doesn't  do  type casts  properly.  For example, the
following statement

    (CL_Interval&) VScroller->Model() = CL_Interval(0, 0);

has to be parenthesized under Watcom:

    ((CL_Interval&) VScroller->Model()) = CL_Interval(0, 0);


[Watcom C++ under OS/2 and Windows NT.]
Under OS/2 and Windows NT, the Watcom linker  is unable to retrieve the main
program from the   UI library; don't know  why.   It complains that a  start
address  is   not found. This    does not happen  under   Windows,  which is
weird. The workaround I use is  to explicitly include ui/mainprog.obj in the
linker command. You  can see this in  uidemo/wtcappmk.ctl, which is included
by all the uidemo makefiles.


[Borland C++ 5.0.]
BC5  seems to issue some   spurious warnings about  variables being assigned
values that are never used. Also, BC5 instantiates a lot more templates than
does  BC4,  so the  library utility  (TLIB)  issues warnings about duplicate
symbols.


[Borland C++ 1.5 under OS/2 and the String class.]
It seems as if expressions involving Strings with concatenation, such as

                return s1 + s2 + s3 + s4;

as the arm of a switch statement cause the program to crash; for example the
CL_Date::PrintString method.  The exact same  code works fine under BC++ for
DOS/Windows and GNU C++.   I'd guess that  BCOS2 is generating bad code  for
this one    case.   The straightforward  workaround   is   to   use String's
AssignWithFormat method.


[GNU C++.]
I've  had some strange program crashes  if I compile  YACL with the optimize
(-O)    switch; the  crashes   go  away    if   I   recompile YACL   without
optimization. The trouble is that without optimization,  GCC doesn't seem to
generate inline   code for  methods declared   inline, so the   code is very
inefficient. You can't win.  :-( [EMX compiler  for OS/2.]  YACL  will *not*
compile under version  2.7.0 of EMX.  The  compiler crashes with an internal
compiler error. Version 2.6.3 works fine, however, as does version 2.7.2.


[EMX Compiler.]
Under OS/2, this  compiler produces very compact  executables;  the UI demos
are in the range of 300K. The only compiler that does better is Watcom.

There seems to be a connection (at least on my machine) between the speed of
the EMX compiler and the IBM Internet Access Kit package  that came with the
BonusPak (don't ask me why). If I have the SLIP drivers from the IAK package
loaded, EMX slows to a crawl: I clocked  it taking six  hours to compile all
the ui classes on my 486/66 with 28 MB main memory. But  if I don't have the
IAK loaded, the speed is acceptable; it takes  about 30 seconds (on average)
per file. Of course, your mileage may vary.

Also, if your machine has  8MB or  less of RAM,   then EMX takes  inordinate
amounts of time to  compile YACL -- as  much as a whole  day. This is mainly
because GNU C++ is a memory hog when compiling templates, and YACL uses lots
of  templates.   The   result is  that   EMX thrashes   badly  on low-memory
machines. But if  you have at least  16MB, then  EMX's speed is  acceptable,
with the whole compilation taking about 2 hours.

It seems that  GNU C++ (and consequently  the EMX compiler)  do not actually
inline functions   that have been  declared inline  unless  you  specify the
optimization switch (-O). But if you do specify the switch, the compile will
go much slower. Bear this in mind when you  choose to uncomment the OPTIMIZE
symbol definition in the file control/emxos2.ctl.

At least  one  of the UI demos    manifests a rather   peculiar problem with
EMX. The TextEditor demo (in the directory uidemo/txteditr) crashes when you
try    to  open  a  new    file (immediately  after     the file open dialog
completes). Here's the strange part. If you build this  demo using the debug
version  of   the EMX  makefile  (i.e.,  emxdebug.mak),   the demo will  not
crash. Nor will it   crash under any  other  compiler. So there's  something
wrong with  EMX's OMF setup. But   I can't find  out what  it is,  because I
cannot run gdb on executables built using the OMF utilities.


[Microsoft Visual C++ 2.1.]
Under VC++ 2.1, the iostream classes seem to allocate memory dynamically and
release it  when the program  terminates.  The result  is that the allocated
memory shows up as a leak in the memory leak checker's output, although very
likely it isn't a leak.

VC++ seems to generate improper  code for default  arguments to functions in
some circumstances.  I had to put in a workaround for this; look in the file
basedemo/format1.cxx for an example. Look also in apps/dlged/dlgedit.cxx.

The GUI demos have a peculiar problem: some SimpleVObjects (e.g., the Label,
ToggleButton  and   ExOrToggleButton),  when  created   as  children   of  a
CompositeVObject, show a grey background instead of a white one. This should
be the  default  behavior if  the  object is a   child  of a  Dialog, not  a
CompositeVObject. This phenomenon does  not occur under the other  compilers
(Borland and Watcom), so it  must be something  specific to the VC++ runtime
system.

VC++ does not include POSIX routines for  directory   handling. Consequently
the Directory class is not supported under that compiler.



[IBM Visual Age C++ 3.0 for OS/2.]
The  makefiles and patches  were contributed by Tom  Satter
(tsatter@purecode.com).  (Thanks, Tom!)  Here are some of its quirks:

    - The IBM compiler does not allow the WindowProc to be a (static)
      member function of the window class. The workaround is to make
      the WindowProc a friend. (blechh!)

    - Like the Watcom compiler, the IBM compiler does not like to have
      the main program in a library. So the main program file
      (mainprog.obj) is included explicitly in the makefiles  for the
      UI demos.

    - The compiler is rather slow. On my 486/66 with 28MB RAM, it
      needs 2 hours to compile YACL and 7 hours for the demos. (Compare
      that with 45 minutes under Borland C++ for compiling everything.)

    - The executables it generates are large, averaging about 250K for
      the base demos and 800K for the UI demos. Tom says, however,
      that using appropriate link switches might bring down the
      executable size.

    - The memory leak checker reports a leak of 1024 bytes in some
      programs,  when there  is  no  leak.   This is because   the
      VisualAge C++  iostream  classes allocate  memory the  first
      time it is  needed, and this  memory is only destroyed after
      the main program is finished. This is  reported as a leak by
      the leak checker,  because the leak  checker exits when  the
      main program does.

Also, I've  organized the makefiles to  support  manual instantiation rather
than automatic, because the latter caused undefined symbols. Maybe there's a
way to use automatic  instantiation; I'd be delighted  if you can contribute
makefiles for this.

Visual    Age  C++  does     not  include   POSIX   routines for   directory
handling.   Consequently the  Directory  class is   not supported under that
compiler.





                      X / M O T I F     P R O B L E M S

                          
[CompositeVObject's title bar and border.]
Currently,  the   CompositeVObject's    title  bar    manipulation   methods
ShowTitleBar  and  HideTitleBar,   and   the  border   manipulation  methods
ShowBorder and  HideBorder, only work  if called before the CompositeVObject
is displayed.  Effectively, that  means they  work if  either you call  them
immediately  after the  Composite  is created, or  you  derive a class  from
CompositeVObject and call them  in your derived class constructor. Otherwise
they don't  work. And, of course,  they  don't work  at  all if  your window
manager does not respect MWM hints. I know they work under MWM and FVWM, but
I don't  know  about   other  window managers.   Note  that   for non-sticky
composites, HideBorder/ShowBorder applies to the sizing border.

[CompositeVObject's Initialize method.]
YACL stipulates   that   a  VisualObject's   Initialize method   is   called
immediately after it  first becomes visible.   (The reason for this is  that
the derived classes might want to draw on the VisualObject in the Initialize
method.) This causes problems under  X, because there  does not seem to be a
reliable way to tell  when a widget becomes visible,  other than waiting for
the first Expose  event.  MapNotify doesn't meet this  need; for example, if
we try to use image operations in the Initialize method (such as the animate
demo does), the app crashes  with a BadMatch  error (particularly if the app
is run on  a remote machine)  unless Initialize is done  on the first Expose
event. So  YACL's Controller code  waits until the first  Expose event for a
CompositeVObject before calling its Initialize method. Bear in mind, though,
that this means that the CompositeVObject should not be initially invisible;
if it is, it won't be initialized until it becomes visible.

[Tabbing.]
Under Motif, tab stops are managed by the Motif  library. This is unlike the
OS/2 and Windows implementations, where tab stops are managed by YACL's code
(specifically the methods in CompositeVObject). This  means that the tabbing
behavior is  different under Motif from what  it is under  Windows and OS/2.
For  example, the left and  right arrow keys work under  Motif, but they are
currently unused (by YACL) under Windows and OS/2.

[StringViews.]
StringView is implemented not just as  a ScrolledList, but as a ScrolledList
which  is a child of  a  Frame.  This  is because  of the  following: If you
create a ScrolledList as a child of a BulletinBoard,  make it invisible, and
create other widgets  in the same  area, the other widgets remain  invisible
until the ScrolledList is made visible once  and then made invisible. Weird.
With the workaround,  the ScrolledList is a child  of a Frame, which in turn
is  child of the BulletinBoard  (CompositeVObject), so when MakeInvisible is
called on the StringView, I make the frame invisible by unmanaging it.


[Resources.]
You can use a resource file for setting individual resources of widgets. The
widget names are internally generated; if you want to assign your own names,
look  into  the InstanceName methods   on Application and  VisualObject. For
example, you can set foreground and background colors via command line using
the -fg and  -bg switches. Remember also  that under Motif, setting the font
resource via the  command line needs a  special syntax. For  example, if you
want say 9x15 to be the default font, you must invoke the app with a command
such as

           myapp -xrm "*fontList: 9x15"
           
for the font name to take effect.


[Standard dialogs.]
The parent  of a  StandardDialog *must*  be  a non-null, currently-displayed
window.  Otherwise   you   might  not  get   the  StandardDialog   displayed
properly. This is because the XmCreate...Dialog API calls require a non-null
widget as parent.

[Titles for standard dialogs (message boxes).]
Make sure you have the "decorateTransients"  (or equivalent) property set by
your  window manager.  Otherwise you  will not see  the titles on any of the
standard dialogs.

[Fonts for menus.]
Currently, you cannot  change the font of the  items of a  menu bar or popup
menu under program  control   (i.e., using the   Font()  method.) You   can,
however, set these fonts using the X resource mechanism.


[Checkable menu items.]
(Added May 19,   1996.)  Ideally, we would   want   to have any  menu   item
checkable. In  other words, the application should  be able to set or remove
the check mark  on a menu item at  any time. This is in  fact the case under
Windows and OS/2. But under Motif, the kind of visual  element created for a
MenuItem depends on whether or not  the item is checkable.  (Checkable items
need  ToggleButton  widgets,   while  non-checkable  ones   need  PushButton
widgets.) Therefore, YACL  imposes the restriction (at  least for those YACL
programs that must  run under  Motif) that if   you want  a MenuItem  to  be
checkable, you must set its state to either Checked or NotChecked before the
item's visual  element  is created. In other   words, after a  menu's visual
elements  have been  created, you cannot  change a  checkable MenuItem  to a
non-checkable one or  vice  versa.   (By default,  the  MenuItem's state  is
NotCheckable.)  This  is  not a serious restriction;  as  soon as you create
your Menu (via new), you simply need to invoke SetCheck  on those menu items
that you want to  be checkable.  See the demo  in uidemo/menu1 or the dialog
editor application in apps/dlged for examples illustrating this.


[Popup menus and right mouse buttons.]
If you create a CompositeVObject that has both a  PopupMenu and a PushButton
child, then right mouse clicks on the PushButton go to the CompositeVObject,
not to the PushButton.  Seems like  a Motif "feature"  because I tracked the
origin of the  event -- X seems  to give me the  widget id of the  Composite
rather than the PushButton. The problem does not arise if the Composite does
not have  a PopupMenu. (Thanks  to Holger Pfaff  (holger.pfaff@class.de) for
pointing this out.)


[String editors.]
Motif refuses to change  the cursor position  from within a callback. I have
worked  around this irritating  problem.  For the StringEditor's  FilterChar
method,  the workaround   is  to assign  explicitly  to  the  fields of  the
XmTextVerifyCallbackStruct (see  ui/stred.cxx).  For the Update  method, the
workaround  uses    a special event   (Event_StrEdChanged)   enqueued by the
callback function. This event is processed by the  Controller, in the method
UI_Controller::ProcessSoftEvents.

This change  points up the need  for cleaning up the  event  structure. At a
later date, I should  have each event type  represented by its own class, so
that user-defined events can be added.


[Arguments to Main.]
If the user types X-windows-specific parameters  as part of the command line
(e.g.,  -bg yellow   -fg blue),   they  don't show up  in   the arguments to
UI_Application :: Main. This is because they  are already eaten  up by the X
resource mechanism before Main is called.


[Dialog movement events.]
For some reason, I don't get the ConfigureNotify  event from X when the user
repositions a Dialog. The event comes through just fine for the main window;
I also get the event when the user resizes a Dialog.  There is, however, the
difficulty that X does not provide a  good way to distinguish between moving
and resizing. You'll see  a consequence of  this problem in the  window demo
(in the directory uidemo/window). In this demo, if  you resize the window by
dragging its top  left corner,  the new position   always  shows up  as  (0,
0).  I'm still trying to  figure out how to solve  these problems. As usual,
all suggestions are welcome.


[ScrollableWindow problems.]
The ScrollableWindow class  doesn't yet work  satisfactorily under Motif. If
you resize  the main  window, the scroll  bars  should be repositioned,  but
Motif doesn't  seem to get  this right. It seems as  if the only way out the
geometry  management problems under  X is  to  write a Composite widget that
allows arbitrary positioning without dictating geometry.  One of these days,
I'll probably do just that.


[Termination of modal dialogs.]
(Added Feb  18th, 1996.) The application  code should ensure  that the event
handler called in response to a modal dialog's  completion doesn't take very
long to execute. This is  because of the following:   if the user presses  a
button that terminates the dialog, the button will  appear to remain pressed
as long as    the  event handler   is   running.  See the comment    in  the
SelectionCallback code in ui/pushbtn.cxx for the reason why this is so.


[RLE-encoded MS Windows bitmaps.]
(Added Feb 18th, 1996.) The  YACL code  does not support  run-length-encoded
Windows bitmaps; if the application attempts to read such a bitmap, the code
(in ui/bitmap.cxx) issues an error message.


[VisualObject's Foreground and Background methods.]
(Added March 2, 1996.) The VisualObject  methods for setting and getting its
foreground and background colors don't work correctly under  X.  I'm not yet
certain that this is really an issue, because the user can always set widget
colors  explicitly  via the resource mechanism.  This  is why I haven't paid
attention to this question.


[ComboBox under Motif 2.0.]
(Added October 11, 1996.) I have not ported YACL to use Motif 2.0's combo box
instead of the  freeware  widget that YACL  relies on.   But if you  use this
freeware widget   with Motif   2.0,    Motif gives   a  warning  about    the
StringDirection resource.  Hopefully someone knowledgeable about the freeware
ComboBox will fix this.


[Bitmap buttons.]
If you  disable a bitmap  button under Windows or  OS/2, the button's bitmap
will be displayed with a  gray look to suggest  that it is disabled. This is
because YACL   does the painting  of  the  bitmaps. Under  Motif, the  Motif
library does the  bitmap management,  and  it doesn't  display the  disabled
button's bitmap any differently from when it is enabled.



                        O S / 2     P R O B L E M S

                   
[Message boxes and de-iconfication.]
If you try to put up a StandardDialog (i.e., MessageBox) in the handler of a
Deiconify event, the MessageBox will show  up, and then  your app will hang.
Looks like an OS/2 bug. In general, it's a bad idea to use standard  dialogs
in code that responds to any event that might cause screen repainting.


[Message box parent.]
Make sure you  specify a parent for   the StandardDialog under  OS/2. If you
don't, the  dialog becomes  non-modal, and  this   can result in  some  very
unexpected effects!


[General: view  id's.]
OS/2  is  very picky about  view  id's.  Make  sure that  all  children of a
Composite or Dialog have distinct view id's and that all  of them are in the
range 1 to 32700. (Remember that this includes any  menu items of menus used
by the Composite,   because  menu items  are  treated  as children   of  the
Composite in the view tree.) View  id's above 32700 seem  to be used by OS/2
internals (e.g., FID_MENU).  OS/2  Warp lets you have  long values (4 bytes)
for view id's, but OS/2 2.1 can only handle a short (2 bytes) as a view id.


[OS/2 2.1 specific stuff.]
Under OS/2 2.1, if you start up a  YACL PM application  from an OS/2 command
window, the  following happens: after  the YACL app terminates,  the command
window seems  completely unresponsive. But if you  then  click on some other
window (making the command  window lose focus), and  click back again on the
command window, it behaves ok. I have  no idea why  this happens; if you can
tell me why (and better  yet, give me  a workaround), I'd be delighted. This
does not happen under Warp. It also  does not happen  under 2.1 if you start
up  the YACL app  directly from the desktop  (e.g. by opening the folder via
the "drives" icon and starting up the app).


[Trouble with CompositeVObjects.]
Under both Windows and OS/2, if you create Composite B as  a sticky child of
Composite A, and  then  have a button   group as child  of  Composite B, the
interior of the button  group will not be repainted   correctly after it  is
temporarily obscured.


[Co-ordinate system.]
OS/2 reckons its co-ordinate system from the bottom left corner, not the top
left  corner.  The  result is that   if you  create  a Composite   with some
children, and then  resize  the  Composite,  the  children  appear  to  move
downwards, because their positions are tied to the bottom of the window, not
the top. This doesn't happen under X or MS Windows.


[Fonts for menus.]
You cannot change the font of a menu item or  menu bar under program control
(i.e., via  its Font()  method). The reason  for  this restriction  is  some
rather peculiar behaviour  I observed when  trying to change  the font  of a
menu while responding to its parent window's PAINT message.


[Bitmap buttons.]
Bitmap buttons are implemented  not via OS/2's  button class but by using  a
special window class registered by  YACL. This is  because I couldn't find a
way  to use OS/2's Button  class to implement both   the toggle and the push
button variety.  Bitmap buttons work ok, except  that their Disable() method
does nothing. This will be fixed later.

[The DateEditor class.]
Sometimes,  when the DateEditor gains focus,  it  sets itself into overwrite
mode rather than insert mode. (This is shown by a block  caret rather than a
thin i-beam caret.) The result is that typing into the DateEditor results in
no action  at all. Hit  the insert  key and put  it  into insert mode before
typing in, and that'll fix it. This is merely a temporary workaround until a
better way to ensure insert mode is added into YACL.


[Font problems.]
OS/2 seems to lie about font attributes sometimes.  For example, in the list
of fonts returned by GpiQueryFonts (in FontInfo::AvailableFonts --- see file
ui/font.cxx), when it  gives the face name as  Courier Bold Italic, it  only
sets the italic attribute in fsSelection, not the bold attribute. The result
is to make it seem as if the Font  demo doesn't work  right: clicking on the
Courier Bold Italic font  produces the system font  in italic mode. However,
if  you explicitly   select a  Courier Bold  Italic    font for use on  your
DisplaySurface, it works fine.


[Multi-color bitmaps.]
OS/2 absolutely  requires, when creating a Bitmap  from a file,  that before
you  call GpiCreateBitmap you  must have selected  the bitmap's palette into
the presentation  space  via GpiSelectPalette.  Discovered  this by lots  of
experimentation.  So the code for  UI_Bitmap::BuildFrom selects the palette,
creates the  bitmap and then deselects the  palette. Just before  painting a
bitmap, the   DisplaySurface::DrawBitmap  method actually  does  the palette
selection. The reason for  this setup is  that  the presentation space  is a
common  resource   on which the   application  might  want  to  draw several
different bitmaps, so we cannot have the Bitmap class dictating what palette
is selected on the DisplaySurface.


[The 3DLabel class.]
(Added March 4,  1996.) Under  OS/2, the 3DLabel   class does *not*  use  an
in-memory display surface, unlike  on  the other  platforms. THe  reason for
this  is the following.  If the 3DLabel did use  an in-memory DS, and if its
parent doesn't  create a  DisplaySurface  for itself when   a paint event is
received,  then   each  3DLabel   instance   will  create   and   destroy  a
DisplaySurface for  its parent on each paint  event. The result is that more
than one  WinGetPS  call  occurs for  the   parent window during  its  paint
event. OS/2 doesn't seem to like  that; it reacts in a  peculiar way --- the
label's font seems to shrink on each consecutive call.


[Multiple Document Interface.]
(Added March 4th, 1996.) MDI support under OS/2 is still somewhat flaky. The
MDI children get created, but don't  get added to the  menu bar or repainted
correctly. Also, tiling is not supported yet.


[The TextEditor class.]
The TextEditor class is realized using OS/2's MLE control, and the latter is
subject to a limit  of 4K on its  content  size. Therefore, under  OS/2, the
TextEditor class cannot handle a model size larger than 4K.

Also,  the MLE control  is peculiar in the  way it responds to queries about
its contents. It reckons hard line breaks as  single characters, even though
a hard line  break under OS/2 consists  of the two characters  CR and LF. So
the YACL  code asks the MLE  twice for each  position index, once  using the
MLM_QUERYTEXTLENGTH  message and   once  using the MLM_QUERYFORMATTEXTLENGTH
message.




           M I C R O S O F T    W I N D O W S    P R O B L E M S
           

[Trouble with CompositeVObjects.]
Under both Windows and OS/2, if you create Composite B as  a sticky child of
Composite  A, and then   have a button  group  as child of  Composite B, the
interior of  the button group  will not be repainted  correctly  after it is
temporarily obscured.


[Three-dimensional look.]
If you try to create  CompositeVObjects with the  3-D look, you'll find that
the  system menu for such  a window is not  displayed properly -- it will be
about 3  pixels below and to  the right of  where it should  be.  The window
positions will also be off by  a little, i.e., the values  your app will get
for  the  client area's position  and  size will  be about 3  pixels off the
correct value. Moral:  don't use the 3-D  look on CompositeVObjects. The 3-D
look works fine with Dialogs, though. I think that's because Dialogs are not
resizable.

Note  also that a  MenuBar  attached to  a  Dialog doesn't look right  under
Windows  with the 3-d look. Again,  I think this is  because of a CTL3D bug.


[Fonts for menus.]
Windows  does not include inherent  support for changing   the fonts of menu
bars and popup menus. YACL could include such  support, but at the moment it
doesn't. In other words, attempting to  use the Font() method  on a menu bar
has no effect.


[Arguments to Main.]
Under Windows, the argv[0] value of the parameters to UI_Application :: Main
is always the full path name of  the executable file,  never a relative path
name.  This   is because  it   is  obtained  via the  GetModuleFileName  API
call. The remaining argv values are the command line parameters, as is usual
on Unix and OS/2 systems.


[Bitmap buttons.]
Bitmap buttons are implemented not via Windows' button class  but by using a
special window class registered by YACL.  This is because  I couldn't find a
way  to use Windows' Button class to implement both the toggle  and the push
button variety.  Bitmap buttons work ok, except  that their Disable() method
does nothing. This will be fixed later.




         M I C R O S O F T    W I N D O W S   N T   P R O B L E M S
           

All the comments above about Windows also apply to Windows NT.









--------------------------- END OF QUIRKS.TXT ------------------------------

