| Frequently Answered Questions [Remove Frame]

Questions

Why does FOX look so much like Windows?
Has FOX been ported to the Apple Macintosh?
Which Systems are supported by FOX?
Is FOX `64-bit clean'?
How do I write portable code?
Why do I get an `illegal icon specified' message when I change some Widget's icon?
Compiling FOX as a DLL under VC++ gives me a unresolved external symbol.?
When do I call flush(), forceRefresh(), refresh() and update() after a change?
How does layout work, exactly?
When I construct a window at the beginning it works but when I construct it later it doesn't.
About numbering Message ID's.
Why support GIF?
Failing to delete menu panes in owner's destructor.
How does FXStream serialize an FXObject?
Why did FOX choose the message-map based callback paradigm?
Why does a AUTOGRAY disable, but not enable the Button?
I get compiler errors in Visual C++ when inclusing FXArray or FXElement.
My Motif application complains with messages about failing to allocate colors.
File fxpngio.cpp does not compile on IRIX 6.5.
Developing FOX Applications under Windows.
Why are there various flavors of running an event loop?
Why do I need to declare a default contructor in my classes?
Which FOX objects do I need to delete to avoid memory leaks?
What's the difference between detach and delete?
Can I use multiple threads in my FOX application?
Can I cross compile FOX on Linux for Windows?
Can I have other colors besides black and white for my cursor?
Why is the SEL_DELETED message sent before the actual deletion?
How do I perform double buffered drawing?
How do I make sure drawing is flicker-free?
Why does the border style not follow what I specify?
What's the deal with default buttons?
Shouldn't fx.h include fxkeys.h?
I have this great idea, but you will need to rewrite all of the FOX library and applications.
How do I monitor activity on sockets?
What do the different version numbers for FOX mean?
Why didn't you fix the problem of the last pixel of a line not being drawn on MS-Windows?
Why doesn't FOX use ASSERTs to check API arguments?
Why can I not paste clipboard data out of a deleted window?
What is valgrind?
When is a member function virtual or not?
Why does a toplevel window have different decorations than I specified?
Why do none of the FXScrollArea derived widgets have a frame?
What is the Legal Status of FOX since your departure from CFD Research?
What is all this stuff with FXSelector and so on?
How do I add an icon for Windows Explorer?
The TextField stops updating while the cursor is in it.
Building and using DLL's with FOX under Windows.
Creating an MDI application.
MS-Windows GDI handle limits.

Why does FOX look so much like Windows?

FOX looks much like Windows in part because of historical reasons, and in part because it is intentional. Having FOX look similar to Windows means the users of a FOX application will be able to bring to bear their prior experience on Windows, and therefore they will be able to be productive much quicker.
But let there be no mistake about it:- for software developers, FOX looks very differently internally.

Has FOX been ported to the Apple Macintosh?

Please refer to The fifthplanet Macintosh Wiki. Basically, if you have installed XFree or Apple's own X Server, FOX can be compiled and run on OS-X. Only a few environment variables need to be modified (the usual bunch, see INSTALL for more detailed information).

A native port running on top of OS-X w/o the need of an X Server is possible. However, the author currently does not own a Macintosh, nor has access too one. Therefore, unless some hardware is donated to the FOX Project for this purpose, chances are small that a software port will happen any time soon, esp. since Apple's own X-Server already solves the problem.

Which Systems are supported by FOX?

There are two main ports of FOX:- UNIX/X11 and MS-Windows. Specifically, FOX is known to work on the following systems:

- Linux. Any version of Linux should work, on any hardware. FOX is being developed on LINUX.

- FreeBSD. FreeBSD is reported to work.

- SGI IRIX. SGI systems with IRIX 5.3 and up. It can be compiled with GCC or SGI's MIPS Pro C++ compiler.

- SunOS/Solaris. Either Solaris or SunOS. Compiled with GCC or Sun Workshop C++.

- HP-UX. Tested with GCC under HP-UX 9.x and 10.x.

- IBM AIX. Tested with GCC under AIX 4.2.

- DEC Alpha/COMPAQ Tru64. Tested with GCC under Digital Unix 4.0.

- Other UNIX Systems. If you have a reasonable C++ compiler, UNIX, X11, chances are very good you can get FOX to work.

- Microsoft Windows 2000, Windows NT 4.0, Windows 95, Windows 98. Compile either with Visual C++ 6.0, Borland C++ Builder, CYGWIN32, MINGWIN32, and IBM VisualAge C++ for Windows. Older versions of Visual C++ will work, but you must create your own projects in that case.

These are the systems we know about. Since FOX uses GNU autoconfigure, chances are good that most UNIX/X11 combinations can be made to work. If you're running FOX under a system not mentioned above, please drop me a line so we can add it to the list.

Is FOX `64-bit clean'?

With the arrival of 64-bit PC's, this is a pertinent question. The answer is yes. FOX is currently being compiled on several 64-bit architectures, such as HP/Compaq/DEC Alpha, HP-PA, SUN UltraSparc, and SGI MIPS R10000. More recently, porting to Intel Itanium and AMD Opteron has been performed. We have reports from people who have compiled on Windows-XP 64.

While coding of FOX itself has been prepared for the coming 64-bit era, the same may not be true for your own application code. A few guidelines:

- Most systems (except Microsoft) follow the ILP32 vs LP64 model, i.e. in 32-bit mode integers, longs, and pointers are 32-bits, and in 64-bit mode longs and pointers become 64-bits while integers stay 32-bit. Microsoft seems to continue with long equal to 32-bit even for 64-bit CPU's.

  If you use the FOX types like FXlong and FXint the sizes are going to be typedef-ed properly according to the LP64 model.

- On some 64-bit compilers, a double-cast may be needed for casting pointers to an int via long. For this purpose, FOX defines a signed and unsigned integer type whose size is big enough to fit a pointer.

  These types are called FXival and FXuval. Note that FXival and FXuval are defined to be the size of a pointer, and so these are not fixed-size types to be used for streaming!

  For portable code you will need to cast void* to FXint by way of FXival or FXuval, as in:

      intval=(FXint)(FXival)ptr;

  Conversely, its a good idea to cast from FXint to void* by way of FXival or FXuval to get predictable zero-extended or sign-extended results:

      ptr=(void*)(FXuval)intval;

- You should use the FXint, FXlong, etc. types when serializing data using FXStream. The types FXint, FXlong, etc. are defined to be a certain size and are the same on all architectures; otherwise binary data will not be compatible between platforms.

Of course all the usual caveats apply, like using sizeof() instead of hard-coded assumptions about sizes; the best practice of developing portable code is to develop it on a number different platforms from the very beginning.

How do I write portable code?

FOX is a platform-independent toolkit (currently, it supports many architectures and compilers), but a few caveats still apply if your own code is going to have to be ported.
A few guidelines which I found useful in my own development practices can make the process very painless:

- Don't include any platform-dependent libraries (e.g. no "Windows.h" or "X11.h". Just your regular stdio, stdlib and so on (those are C/C++-language standard libraries, and pretty much the same on most machines except for some minor nitty gritty stuff.

- Of course, you will use FOX, and while your own code isn't platform dependent, FOX itself is. So you *will* have to link your application with various platform-dependent libraries that FOX itself uses.

- You can safely assume sizes of FXchar, FXshort, FXint, FXlong, FXfloat and FXdouble to be the same on all platforms. However, int, long, etc. are NOT guaranteed to be a certain size. This is important when saving loading binary data files (e.g. using FOX's FXStream class). Also, there is byte-order. This is also platform-dependent. FXStream allows for byte swapping during I/O. The symbol FOX_BIGENDIAN is set 1 on big-endian machines (e.g. SGI, PPC) and 0 for little-endian machines (Intel, Alpha).

- To be 64-bit future-proof, you *must* use double-cast to- and from pointers. see above. Just to be sure.

- Try avoid very sophisticated C++ features (this means most of STL). Code that does a lot of STL doesn't port one iota's worth, at best it compiles with thousands of warnings [some people are going to flame me for this, but its true!].

- Use FOX macros like FXMALLOC(), FXFREE() and so on. They are implemented to behave EXACTLY the same on all systems (even though underlying malloc() and realloc() library functions don't always treat the corner cases properly.

- Use FXTRACE(()) for debugging; use FXASSERT for asserts. Use fxwarning fxerror() and fxmessage() for messages to the console (on Windows, you don't have a console, and printf() will crash!!). These functions "do the right thing" on the various platforms.

- Don't try to do your own filename manipulation routines. Use the functions in the FXFile namespace. These functions properly handle drive letters, Windows Uniform Naming Convention, and so on. They also know about forward and backward slashes and such stuff. Use the PATHSEP, ISPATHSEP etc. macros to check for path separation characters.

- Do not assume characters are signed or unsigned; FXuchar is always unsigned, however, FXchar may be either.

- When opening a binary file, don't forget fopen("name","rb") instead of fopen("name","r"). On UNIX there is no difference, but on Windows, forgetting the "b" will cause "\r\n" to be translated to "\n", corrupting the data stream.

Why do I get an `illegal icon specified' message when I change some Widget's icon?

Basically, an Icon [Widget, Image, Font, etc] comprises a part which lives in your program [the client-side], and a part which lives in the X-Server or GDI subsystem [the server-side].

The C++ CTOR only builds the part in the client side. The server side part of the Icon [Widget, Image, etc] is realized when you call create() on it. For convenience, all reachable resources may be created with a single call to FXApp::create(). The call to FXApp::create() traverses the entire Widget tree and creates all Windows, Icons, and other resources that are needed to realize that Widget tree on the screen.

The reasons for all this are:

- Since all FOX classes may be subclassed, it cannot be assumed that after an object's ctor has run that the object has been fully constructed; after all, you may have subclassed it.

- It will also be important later on when the GUI itself will be subject to serialization. As we can not serialize server-resident resources, we need a two-step process of construction [via deserialization] and creation [from a single call to FXApp::create()].

Because of this, when you construct an FXIcon later on, then you need to call FXIcon::create() manually, as the icon was not a part of the Widget tree at the time the Widget tree was first realized.

Compiling FOX as a DLL under VC++ gives me a unresolved external symbol?

If you build a project under VC++ to compile a FOX application, do not forget to specify -DFOXDLL on the compiler command line. Without it, you will get an error like: error LNK2001: unresolved external symbol "public: static struct FXMetaClass const FXApp::metaClass" (?metaClass@FXApp@@2UFXMetaClass@@B). Or words to that effect.

Of course, you can also build FOX as a static library, in which case there is no problem.

When do I call flush(), forceRefresh(), refresh() and update() after a change?

Under normal circumstances, the display on the screen is kept up-to-date automatically. However, FOX uses a lazy screen refreshing technique. The lazy technique allows your callback routine to make lots of changes in the GUI, then update the screen in one fell swoop. This obviates the need that some other toolkits have for freeze/thaw API's.

There are several aspects to this: repainting the screen, i.e. processing expose or repaint events, performing layout computations, and performing GUI updating.

- Repaint Events are piled up until there are no further events to be processed. In fact, repaint events are not simply saved but are conglomerated into larger and larger rectangles, so as to minimize the number of times that repainting is actually done (it actually also minimizes the area which is repainted).

- Layout Reconciliation is also delayed. No layout is performed until returning to the event loop, in fact. Like repainting, layout is delayed until no more events are available.

- GUI Updating is also delayed until there are no more events in the queue.

The order in which these are performed are repaints, layout, and gui-updates. Contrary to intuition, delaying the expensive operations such as repainting instead of doing them right away is actually faster.

Sometimes, you want to force the display to refresh without returning from a callback; this can be effected with the following routines:

- FXApp::flush() will flush all drawing commands to the display. In other words, it will cause all drawing commands to be executed eventually. Note that flush() is moderately expensive as it causes synchronization between the display and the program.

- FXApp::forceRefresh() will perform a layout reconciliation, followed by a GUI update. Since this may lead to more expose events, you typically follow a call to forceRefresh() with a call to flush(). Note that forceRefresh() is a very expensive operation.

- FXApp::refresh() is similar to forceRefresh() in that it causes a layout and a GUI update to be performed. The difference is that refresh() will not actually perform the operation but simply cause the system to perform layout/gui-update later, after returning to the event loop. The call to refresh() is very cheap.

- FXWindow::update() marks the window, or part of the window as dirty. This causes the window to receive an expose event at some point in the future. The rectangles marked with update() as dirty may be conglomerated into a few big rectangles. No repainting is actually performed until returning to the event loop or calling flush(). Since no drawing is performed, a call to update() is fairly cheap.

- FXWindow::repaint() performs the opposite of update(). It paints the window, or part of the window by issuing SEL_PAINT messages if necessary. It works by first pulls all outstanding expose events from the X server, compositing the dirty rectangles. Then, it processes all dirty rectangles pertaining to the given window; if a rectangle is passed, it only processes the dirty rectangles overlapping with the given rectangle. Note that repaint() should NOT be called while performing a painting operation as it would lead to multiple locks of the device context FXDCWindow.

- FXApp::repaint(), does the same as FXWindow::repaint(), except FXApp::repaint() causes ALL windows to process their backlogged SEL_PAINT messages.

- FXWindow::recalc() marks the widget, and all of its parents, as dirty, i.e. in need of layout. Under normal circumstances, layout is only called when the size of a widget has changed; however, there are often other reasons why layout is needed. In such cases, calling recalc() will ultimately cause a layout to happen also. The entire chain from the widget to its top most parent must be marked this way, otherwise (as there may have been no size changes), the layout process will stop. A few widgets will overload recalc() to cause additional layout computations to happen (e.g. computing content size inside a scrolled view of a list).

How does layout work, exactly?

Automatic layout is a very usuful feature in FOX. It allows automatic placement of widgets in the desired arrangement without explicitly placing each widget in terms of position and size. Thus, changes in widget's contents, font, and language binding can be accomodated with ease.

But automatic placement takes a bit of getting used to, especially for Windows developers who are not accustomed to the concept (many UNIX GUI systems such as Xt and Motif have similar layout facilities so UNIX programmers tend to be more familiar with the idea).

Composite widgets may contain one or more child widgets. These child widgets could be simple controls, like Buttons, but also other Composite widgets. Thus, layout is inherently a recursive process.
Layout of a widget tree is determined by the following:

- The arrangement pattern. For example, a Matrix layout manager arranges the children in rows and columns; a HorizontalFrame arranges its children side by side, and a Packer arranges them against the sides of the interior.
- The packing flags. A layout manager has certain flags which apply to the layout of all of its children. For example the flag PACK_UNIFORM_WIDTH causes each child to be made the same width.
- The layout hints. Each child has certain layout flags which affect the way the layout manager places that child; an example is the LAYOUT_FIX_WIDTH flag which tells the layout manager of that child that the child wants to keep its initially assigned width instead of its minimum (default) width.
  Not all layout hints are observed by the layout manager; certain arrangements interpret certain hints, and ignore others. For instance the Switcher layout manager places all children on top of each other, and makes them all the same size.
- Other information, such as the interior padding between the edges of the layout manager and its children, spacing between children, and other information like the number of rows and columns in a Matrix layout manager, or which child is on top in a Switcher layout manager, and so on.

Layout is a recursive process, proceeding from the top down. A layout recalculation is needed under the following circumstances:

- The widget's size has changed in response to position() or resize().
- The widget has been marked as dirty by means of recalc().
- In a few cases, layout() is called directly.

Because layout involves a lot of calculations, its quite expensive; we therefore try to perform it as infrequently as possible, and to stop the layout recursion as soon as we can. The former is implemented by performing the layout only when there's nothing better to do, during idle time when there are no events demanding our immediate attention. The latter is done by stopping the recursion when we hit a widget that already has the right size and is not marked as dirty.
This makes layout pretty fast (close to real-time when interactively resizing windows).

Only a handful of API's are responsible for the whole layout process:

- getDefaultWidth() and getDefaultHeight(). These API's measure the minimum size of the widget. For simple controls such as Buttons the implementation consists of simply adding up the size of the icon, caption, and surrounding borders.
  For layout managers however, it is more complex:- the size of the layout manager depends on the arrangement, and the size of the children, and needs to take into account the packing flags and layout hints as well.
- getWidthForHeight() and getHeightForWidth(). These measure the width of a widget in terms of its height, and the height of a widget given its width, respectively. In order for getWidthForHeight() to work, the height has to be known in advance.
  Because of these restrictions, these functions are basically only called from top level windows, as top level windows are given a size directly by the user and therefore the required information is known.
- position(). This API physcally moves a child's to its new location, and if the child's size was changed or the child was marked as dirty, recursively invokes layout() on the child.
- layout(). This is the workhorse of the layout system. The typical implementation in a layout manager loops over all the children, applying each child's layout hints and default size as computed by getDefaultWidth() and getDefaultHeight(), and then placing each child accordingly by calling position(). Note that by calling position(), the child's layout() may in turn be called!

When I construct a window at the beginning it works but when I construct it later it doesn't

When you construct a window before calling FXApp::create(), the window will be created when all windows are created. If however you construct a window later on, then you need to call window->create() yourself.

Please refer to the section about creating icons for a more detailed explanation.

About numbering Message ID's.

When deriving classes from FOX Widgets such as FXDialogBox, make sure you're messages are numbered so as to not conflict with those of the base classes. The most simple way is to continue numbering from where the base class left of; I suggest the following C++ trick:

    class MyDialog : public FXDialogBox {
      ...
      enum{
        ID_CLICKED_YES=FXDialogBox::ID_LAST,
        ID_CLICKED_NO,
        ID_CLICKED_OK,
        ID_CLICKED_CANCEL,
        ID_CLICKED_QUIT,
        ID_CLICKED_SAVE,
        ID_LAST
        };
      ...
      };

As you see, the implementor of the base class can insert additional message ID's but the numbering is automatically kept straight by the compiler. Also, if you're own class is being derived from then this derived class can start counting from MyDialog::ID_LAST and not worry about any messages being inserted into MyDialog.

Why Support GIF!

The compression technique in GIF was patented by UNISYS. In 2003, this patent expires and using GIFs no longer presents a problem; until that time FOX does not support compressed output, only decompression.

From what I've read, LZW decompression is not subject to the patent [hence ability gzip support for the old ``compressed'' files].

I feel that there is therefore no need to remove the FOX support for GIF icons/images, and therefore any existing investment should you have in large icon collections would be protected.

Should you still harbor any qualms about using GIF's in your project, you could of course always use BMP icons. However, GIF icons appear to be typically about half the size of BMP icons.

Note that the LZW patent will expire soon, and so compressed GIF support will therefore be reinstated.

Nevertheless, software patents are very bad for software developers, particularly since so many completely trivial ideas seem to slip through the patent system, see The Case Against Software Patents.

Failing to delete menu panes in owner's destructor.

When you create a MenuPane, the pointer passed in to MenuPane is the owner of that MenuPane, which is typically a MainWindow or DialogBox. This causes the MenuPane to stay on top of the owner window.

When adding a MenuCommand in a MenuPane, the MenuCommand will obtain the owner of the MenuPane and install its accelerator in the owner's accelerator table. This is necessary, as the accelerator is to be effective without the MenuPane being having been popped up.

When the MenuCommand is destroyed, it tries to remove this accelerator again by obtaining the MenuPane's owner and removing the accelerator from the owner's accelerator table. Should it be the case that the owner of the MenuPane had already been deleted, an access to a non-existing memory location (segmentation fault) will likely occur.

Thus, it is necessary for the owner of a MenuPane to be still in existence when the MenuPane itself is destroyed. So when the owner of a MenuPane is destroyed, it must make sure the MenuPane is destroyed before its destructor completes:- otherwise, the MenuPane would refer to a non-existent owner.

As a general rule, shared resources such as Icons, Fonts, Cursors, Bitmaps, and also MenuPanes, must be explicitly deleted by the widgets that owns them.

How does FXStream serialize an FXObject?

When you serialize a pointer to an object, like for example:

      // Declarations
      FXStream    stream;
      FXDocument *document;

      // Serialize
      stream.open(FXStreamSave);
      stream << document;
      stream.close();

      // Deserialize
      stream.open(FXStreamLoad);
      stream >> document;
      stream.close();

What really happens when you serialize a pointer to an object is the following:

- stream checks an internal hash table to see if document has been serialized before.
- if it has been serialized before we just save a reference number into the stream, and we're done.
- if document was not encountered before, stream saves the classname.
- then, the document->save(stream) is called to save the object's contents [member data] into the stream.

When you deserialize an object is:

- stream loads an item from the stream.
- if the item represents a reference number, then we must have loaded the document previously; using an internal lookup table, stream maps reference number to the memory address where document was loaded, and returns this address.
- if the item is a classname, then stream calls FXMetaClass::getMetaClassFromName(classname) to obtain the metaclass, and calls metaclass->makeInstance() to properly manufacture an object.
- then, stream calls document->load(stream) to pull in the object's contents.

Sometimes, a special container object is referred by other objects, but should not itself be serialized. In this case, you may want to use the constructor:

      FXStream    stream(container);

instead. This will add the pointer container to the internal table of stream, so that any subsequent encounter of the same pointer value will generate a reference number only.

Why did FOX choose the message-map based callback paradigm

There are several different mechanisms to connect Widgets, the sources of events, and their targets, or the application code that you write.
I have evaluated several different callback mechanisms, each have their different strengths and weaknesses.

- Function pointer [Motif, Xt].

- Very dissatisfying for C++ programs, as it is not object-oriented.
- Extra callback parameter [call_data] is not type safe.
- This is mostly interesting for procedural programming styles, e.g. using C.
- Hard to serialize (or save to file) the connectivity.

- Message handling with fixed routing [Microsoft Foundation Classes, Borland C++ Builder].

- Can bind source and target together at run time.
- Need fixed message routing scheme, since there is no specific target.
- Need to keep the messages globally unique (because of the fixed message routing scheme).
- Message-delegation [forwarding of messages to another party] is easy.
- GUI widgets can not receive messages, only sent them (because of a fixed message routine scheme).
- May be not type-safe.
- Easy to serialize the connectivity.

- Signal/Slot [Qt (Preprocessor), C++ templates (Gtk--, I believe)].

- A special preprocessor does not seem very elegant to me [Qt].
- A template-based signal/slot system is elegant from a theoretical point of view.
- Templates are instantiated at compile time. This means it's going to be difficult to hook up objects which are only known at run time [like e.g. loading a custom control from a DLL].
- To connect a message source and a target, you actually construct a connector object that is parameterized by the target; you can not do this unless you know the type of the target [This is because pointer-to-member-of-class types can only be downcast!].
- Hard to serialize, because a pointer-to-member-of-class contains a function-pointer when the member is not a virtual.

- Message handling with specific target [FOX, NeXTSTEP (using Objective-C of course)].

- You can connect at run-time, because connectivity does not involve compile-time code generation like with a signal-slot mechanism. Run-time connectivity is needed because you may load objects dynamically from a DLL, from deserialization, or you may want to write an GUI-Builder which interactively connects things up.
- There is no need for a globally unique list of message ID's. The message is addressed to a specific target, and the same message-ID can be reused by another target for another purpose.
- Widgets may receive messages as well as send them. This is very important for component-based programming paradigms. It is also important to note that this allows for ``glue-less'' programming; for example, a message ID_HIDE to any Control will hide the Control.
- No special preprocessor is needed. The compiler automatically keeps the message-ID's straight [see above].
- It is not type safe, in the sense that if you do need to interpret the void*, you would need to cast. Note however that in the vast majority of cases, the void* argument is not used; when it is used, the use is pretty consistent:- what do you think the void* refers to when the message-id is ID_SETINTVALUE?
- In the case of NeXTSTEP, the argument signature was a part of the message, which means that for an object to implement the message, the signature had to match up; this was type-safe while at the same time very flexible.
  Alas, FOX was written in C++, not Objective-C.
- You connect things simply by passing the target-pointer in the constructor when you create a widget.
- FOX supports message delegation very easily.
- You can actually turn FOX into a type of template-based signal/slot system of you make FXObject-derived connectors!

As you see, FOX's message handling system may not be type safe, but it is very compact, allows for run-time connectivity, is serializable, and favors component-oriented development.
Were FOX written in Objective-C, one could achieve the goal of type-safety as well; C++ clearly limits our choices.

Why does a AUTOGRAY disable, but not enable the Button?

AUTOGRAY and AUTOHIDE are very useful features when messages are being delegated around, like for example in an Multiple Document Interface [MDI] application. In an MDI application, the target which actually ends up handling the message may be different from one moment to the next. When no target handles the message (e.g. when all FXMDIChild windows have been deleted), an FXButton which is set to BUTTON_AUTOGRAY will be disabled automatically. When there is a target, this target should enable or disable the button as appropriate. The FXButton does not automatically enable itself when there is a target that handles the message, as it is not necessarily the case that the button should be enabled when it does.

I get compiler errors in Visual C++ when inclusing FXArray or FXElement

FOX uses the placement version of the C++ new operator. Declarations for this operator may be made available to your program by:

      #include < new >

just before including FXArray and FXElement. FXArray and FXElement are not automatically included into fx.h because these files rely on a proper template implementation of your compiler; also, FOX widgets do not need these headers.

My Motif application complains with messages about failing to allocate colors

This typically happens on PseudoColor systems, i.e. systems which use a colormap or color palette. Even many high end SGI systems run the Motif GUI in PseudoColor mode [these systems support multiple hardware colormaps]. FOX normally allocates about half of the available colormap [125 colors, to be exact]. Under normal circumstances, this leaves plenty of colors for other applications. However, sometimes of course it can happen that other X11 applications require more colors than are available. Fortunately, FOX can be told to use a different number of colors. There are several ways to do this:

- The simplest way is to specify the maximum number of colors on the command line, with the parameter -maxcolors n. The number n should be between 2 and 256. Setting the parameter causes FOX to allocate no more than the indicated number of colors. FOX will attempt to allocate a block of colors such that nRed x nGreen x nBlue is not larged than n; it will favor slightly more resolution in the green and red than in blue, because the eye is more sensitive to these colors.

- If you find yourself passing this parameter regularly, you may consider specifying the number of colors using the Registry mechanism instead; this way, FOX applications will automatically pick this up. The most easy way to do this is to load the file $HOME/.foxrc/Desktop into your editor, and adding the following to the [SETTINGS] group:

      [SETTINGS]
      maxcolors = 64

  Of course you may specify any number you like.

- The last method is to specify the maximum number of colors programmatically. In case you're developing e.g. a data-entry application, you may not need many colors and you can simply set the value to a fairly low value, like 27:

      FXVisual *vis = application->getDefaultVisual();
      vis->setMaxColors(27);

  Of course you will need to do this prior to a call to application->create().

On some machines, you may be able to switch the video hardware into a higher color resolution, and if this is possible, it may be by far the best solution.

File fxpngio.cpp does not compile on IRIX 6.5

FOX uses GNU autoconfigure to determine the whereabouts of various files. It so happens that IRIX 6.5 ships with an older release of the PNG library. You can do two things:

- Re-run configure as configure --disable-png to disable PNG image file support. FOX will be fully functional, except that PNG image file support is stubbed out.

- Obtain the PNG library libpng version 1.05 or better, and install this on your machine.
  You can find PNG on: http://www.libpng.org/pub/png/.

If you choose the latter, you will of course have to make sure the configure script is able to locate the new library; how this is done depends on where it is installed.

Developing FOX Applications under Windows.

Developing FOX applications under Windows warrants a lot of extra information. You can find this here.

Why are there various flavors of running an event loop?

FOX applications are event driven applications. All FOX applications therefore spend almost all their time in an event loop, waiting for events [such as keyboard and mouse events] from a user. Depending on the situation, there are several types of event loops possible:

- FXApp::run(). This is the main event loop and it is entered when you start your program, and does not exit until you call FXApp::exit(), or the application object receives the ID_QUIT message. Typically, after returning from FXApp::run() your program will exit.

- FXApp::runModalFor(window). You enter this event loop to run a modal dialog. A modal dialog is a dialog which will block any interaction with any other window of the program except for the indicated dialog window, until the modal event loop is exited.
  FXApp::runModalFor() is a recursive invocation of the event loop, and it will not return until FXApp::stopModal(window,code) is called. The return code is passed along and will be returned by FXApp::runModalFor().

- FXApp::runModalWhileShown(window). This routine is a variant of FXApp::runModalFor() which returns as soon as the window is no longer visible, or until terminated by FXApp::stopModal().

- FXApp::runUntil(condition). This routine enters a recursive event loop, passing all events normally. The event loop returns as soon as the variable condition is set no a non-zero value.

- FXApp::runWhileEvents(). This routine enters a recursive event loop, but returns as soon as no current events are outstanding in the event queue. This can be used to catch up with the event stream during processing of some long computation, and then resume the computation as soon as all events have been processed.

- FXApp::runOneEvent(). This function processes one single event and then returns.

- FXApp::peekEvent(). This tests if any events are present on the event queue, and returns immediately with TRUE if there are, or FALSE otherwise.

Recursive invocations of the event loop are very useful, because they allow you to temporarily resume processing of events without returning from your message handler.
The runModalFor() is especially useful if your message handler needs to display a temporary dialog box, acquire some information from a user, and then continue processing the user input all without returning to the main event loop.

Why do I need to declare a default contructor in my classes?

The FXObject-derived classes need to have the FXDECLARE() macro in the header (.h) file and the FXIMPLEMENT() macro in the implementation (.cpp) file. The FXDECLARE macro declares a static const member variable called metaClass, which is a table describing this class. It provides some form of runtime type information. It also declares a virtual function getMetaClass() which can be used to obtain a pointer to an objects metaclass variable; this way, one can interrogate the type of an object. In addition, it declares a static member function called manufacture() which will construct an object of this class using the default constructor. Finally, it declares two convenience functions for serialization of pointers to objects of this class.
The FXIMPLEMENT macro is used to define and fill-in the table declared using FXDECLARE. It defines the static member function manufacture(), the virtual member function getMetaClass(), and fills in the static member variable metaClass. If the object handles messages, it also fills in a pointer to the message table.

A default constructor needs to be defined in your class because the manufacture() function needs to use the default contructor to create a properly initialized object of this type. This is needed by the deserialization system so that it can allocate and initialize an object prior to loading values for the persistent member variables.

Which FOX objects do I need to delete to avoid memory leaks?

Most FOX Widgets are automatically deleted by their parent Widget. However there are some resources which are sharable, and these resources must be deleted explicitly by the program in order to avoid memory leaks or other problems.

Cursors, Fonts, Images, Icons, Bitmaps, and Visuals are sharable resources which must be cleaned up explicitly. Because several Widgets may refer to the same icon or font, these resources are not automatically deleted by the Widget as they may be used in another Widget. A number of resources, such as the default cursors, the default font, and the default visual, are automatically created by the Application object, and the Application object also assumes responsibility to destroy these when the Application object itself is being destroyed.

Menu panes usually refer to the Widget that owns them, and because dangling references to a deleted owner object are not allowed, the owner Widget must make sure the Menu panes are deleted when the owner Widget itself is. Failing to do this will leave the Menu pane in existence while their owner is already deleted, and this will cause problems.

Ordinary Widgets, like Buttons, Sliders, and so on, are automatically deleted by their parent Widget; therefore it is not necessary for your application to keep track of them explicitly

What's the difference between detach and delete?

Many FOX objects, like widgets and icons and fonts and so on, have resources which are resident in the X-Server (or GDI in the case of Windows). The existence of these X-Server resident resources is manipulated through the member functions create() and destroy().
When a program's GUI is realized, all the X-Server resident resources are automatically created by recursively working through the entire widget tree and calling create() for every reachable object.
When a widget is deleted, the X-Server resident resources are released by recursing through the widget tree and calling destroy().
However, destroy() is only called for those objects which not shared; shared resources like icons and fonts are not destroyed because they may still be referenced from other places.
On UNIX systems, it is possible to fork() a process, which creates a child process which has initially all the same data as the parent. This includes the handles to the X-Server resident resources. Of course, these resources really belong to the parent process, and should not be references by the child process after the fork.
To clean up, a child process forked off from a parent process needs to call detach(). The call to detach() will recursively work down the widget tree and detach all reachable objects (widgets as well as sharable resources like icons and fonts) from their X-Server resident representations. After having been detached, the objects can then be destroyed without generating a call to destroy() along the way, so the child will not accidentally release any resources which the parent process still needs.

Can I use multiple threads in my FOX application?

FOX assumes one single thread to be responsible for the User Interface related tasks. This is because certain FOX resources are not thread-safe; also, because on MS-Windows message queues from a window are tied to the thread that created that window, it is very important for portability reasons that it is always the same thread performing the User Interface tasks.

You can however use any number of threads in your application, as long as they are worker bees, i.e. they do not perform User Interface functions.

Synchronization between the User Interface thread and the worker threads can be performed using a synchronization object, a pipe (UNIX/LINUX) or an event object (MS-Windows).

The synchronization object is passed to FXApp::addInput() so that the User Interface thread is awakened when the worker thread turns the synchronization object into a signalled state.

Can I cross compile FOX on Linux for Windows?

Yes. Markus Fleck writes:

      FROM: Markus Fleck
      DATE: 04/10/2001 09:42:55
      SUBJECT:  [Foxgui-users]Convenient cross-compiling for Win32 on Linux

      Hi!

      Below are some experiences that I thought I'd share; they're mostly of
      interest if you're a UNIX developer at heart and are forced to create Win32
      versions of your applications as well (using FOX for the GUI part, of
      course :-).

      I'm currently using FOX for cross-platform development (Linux and Win32),
      and have been using Cygwin under Windows for some time to create binaries
      for Win32. Unfortunately, Cygwin under Windows is quite slow, and tends to
      crash rather often (at least for me.)

      Recently, I came across a patched GCC cross-compiler for Win32:

        http://www.libsdl.org/Xmingw32/

      A Linux binary build of the cross-compiler can be downloaded from that site,
      or you can use the script at

        http://www.libsdl.org/extras/win32/cross/build-cross.sh

      to automatically download, configure and build the cross-compiler from
      sources for your platform.

      The cross-compiler works like a charm; I am now able to create Win32 .EXE
      binaries in a fraction of the time that Cygwin used to require running under
      native Windows.

      Using the cross-configure.sh/cross-make.sh scripts as a starting point, even
      "configure" and "make" can be run on Linux, even though you're generating
      target code for the Win32 platform.

      I have also started to make use of "Wine" (the Linux/FreeBSD-based execution
      environment for Win32 EXE/DLL code) instead of booting into Windows for the
      purpose of testing my application; I had to uncomment (or "#if 0") the call
      to "TrackMouseEvent" in FOX's src/FXApp.cpp, though, because apparently Wine
      doesn't implement that function and aborts when it encounters a call to it.

      I also had to disable (or actually, comment out using "dnl") the invocation
      of autoconf's "AC_C_BIGENDIAN" macro in configure.in (and invoke "autoconf"
      to rebuild the "configure" script); it appears that "AC_C_BIGENDIAN" doesn't
      (yet) accept a default endianness value to use when cross-compiling, so that
      effectively the "AC_C_BIGENDIAN" test cannot be used when cross-compiling
      (yet). So in order to better support cross-compiling, configure.in should
      probably test for "ac_cv_prog_cc_cross=yes" and/or shortcut the endianness
      test if Win32 is the target platform.

      In a nutshell, I can only recommend using the GCC cross-compiler to build
      Win32 executables; it's much faster than Cygwin and much more convenient if
      you prefer to do development on a UNIX-type system. If you're using Linux
      or FreeBSD, "Wine" can give you some additional convenience when it comes
      to testing you application.

So cross compiling is not only possible, but it works very well and may be faster than working natively. One note on the AC_C_BIGENDIAN thing:- you can simply pass -DFOX_BIGENDIAN=0 on the compiler command line to override it.

Can I have other colors besides black and white for my cursor?

As of FOX 1.1.45, yes! Under X11, you will need the Xcursor extension, which means you must have a recent X server such as XFree 4.3 or later. On Windows, it should be OK in all cases.

Why is the SEL_DELETED message sent before the actual deletion?

SEL_DELETED is sent so as to afford the target of the message a chance to save the text that existed prior to the removal; this is useful for the purpose of maintaining undo list.
Since the SEL_DELETED message contains the information about the to-be-deleted stuff, its a small matter to determine what the state of the widget will be after the deletion, should it be necessary.

How do I perform double buffered drawing?

You can perform double buffered drawing by using an FXImage. First, create an off-screen FXImage, which will be the target of the drawing operations. Then, set the FXDCWindow to draw on the FXImage. Finally, whenever the widget needs to be repainted, BLIT the contents, or part of the contents of the FXImage to the Widget.
In code:

      picture=new FXBMPImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,500,500);
      ...
      picture->create();
      ...
      FXDCWindow dc(picture);
      dc.setBackground(FXRGB(255,255,255));
      dc.drawRectangle(0,0,500,500);        // Erase it!
      ...
      ... drawing commands ...
      ...

    And in onPaint:

      FXDCWindow dc(this,(FXEvent*)ptr);
      ...
      dc.drawImage(picture,0,0);
      ...

Some details are omitted here; most likely, the drawing of the FXImage and the repainting are not both done in onPaint(); because the FXImage is off-screen, its not "clobbered" by other programs so there's no need to redraw it unless the widget changed size or if the content data was changed.

How do I make sure drawing is flicker-free?

The following tricks have been proven to be very helpful in reducing visual flicker while redrawing widgets:

- Limit drawing to the dirty area. Use FXDCWindow dc(this,event), because that will clip all drawing commands to the event's dirty rectangle. Drawing takes more time that almost anything else; so it is worth a lot of work to limit the amount of drawing. I refer to FXTable to give you an idea. Drawing the table seems simple enough, but initially it was very slow. I've since then expended a lot of code to determine which cells of the table were clobbered, and for each cell set clipping rectangles so as to not erase the grid lines. Now the table is virtually flicker free, and draws a whole lot faster.

- Try to avoid erasing the background of the entire widget. Instead, paint background around the content area, then paint the content over. This is done in most FOX widgets, particularly FXTable.

- If you have to erase the background, try and erase it little bits at a time. For example, in the FXList widget, instead of erasing the entire widget and then painting the icons over it, I erase and paint over each item individually. While is is actually a bit slower, it is visually much more acceptable because at no time is the entire widget completely erased.

- Flush the command buffer prior to the erase, and after the last drawing command which paints over the erased background. Drawing commands are buffered, and the buffer is flushed when it is full. However, you don't want to have the situation where the last command sent is the erase, as in that case the window will stay white for the entire duration while the command buffer is filled up with commands to paint over the background. You want the erase command and the paint command to be in the same batch, if possible, so that they get executed by the X server right after each other.

- Perform double-buffered drawing, using an FXImage as noted above.

Why does the border style not follow what I specify?

Under Windows, you should essentially get what was specified. Some decorations under Windows are tied, for example it is not possible get DECOR_MINIMIZE and DECOR_MAXIMIZE without also getting the System Menu. Also, the Close button is tied to the Menu.

Under X11, the decorations are mere Hints to the Window Manager. Different Window Managers may or may not observe the hints properly. As the Window Manager is a program written by other people, I have little influence over their correctness in observing the decoration hints.

However, I have had fairly good luck with Motif, KDE 2.2, and other Window Managers like WindowMaker, Sawmill, BlackBox, and Enlightenment.

The Free Desktop Project is trying to standardize various aspects of client and Window Manager interaction, and FOX will try to take advantage of this where it makes sense.

What's the deal with default buttons?

Certain buttons in a dialog box may be designated as default buttons. If the focus moves onto a default button, a RETURN key will be dispatched to this button. The way to make a button be a default button is to pass BUTTON_DEFAULT.

One single button in the dialog box may be designated as the initial default button. The initial default button is the one that will become the default button whenever the focus moves to a widget which can not itself be the default widget and which does not handle the RETURN key. Passing BUTTON_INITIAL will make it the initial default. BUTTON_DEFAULT means that if the focus lands on this button, it will become the one to respond to RETURN key.

To programmatically set BUTTON_DEFAULT, use setButtonStyle(BUTTON_DEFAULT). Calling setDefault(TRUE) will MAKE the button the default; this is different from ALLOWING it to be the default, which is what BUTTON_DEFAULT does.

Recommendations:

- Only buttons normally terminating a dialog should have BUTTON_DEFAULT. For example, the "Accept" and "Cancel" buttons at the bottom of the dialog.
- Only one single button should have BUTTON_INITIAL. This should correspond to the choice that would be the most often chosen one, e.g. "Accept". If the dialog does something dangerous, like "Erase All files" then make "Cancel" your default choice:- hitting RETURN is a reflex and in some cases its better for the easy path to lead to safety rather than to danger!
- If you write custom widgets and your custom widget handles the RETURN key, your overload of setFocus() and killFocus() should call setDefault(TRUE) and setDefault(MAYBE), respectively.

  Calling setDefault(TRUE) means the current default button will no longer be default one because your widget now deals with the RETURN key. Calling setDefault(MAYBE) when your widget looses the focus means the default button will revert to the initial default button (unless of course the focus lands on another widget which can handle the RETURN key!).

Shouldn't fx.h include fxkeys.h?

The header file fxkeys.h is rarely used, basically only by programs which catch keyboard messages directly. The vast number of programs will use the widgets and rely on the regular callbacks from these widgets.

To make programs compile faster, the file fxkeys.h, which contains a very large number of definitions, is therefore not normally included.

I have this great idea, but you will need to rewrite all of the FOX library and applications.

No!

How do I monitor activity on sockets?

When you are running a GUI, you can monitor sockets in two ways:- first, you can of course dedicate a worker thread to the socket activity, and leave GUI work to the GUI thread.

Another approach is to use the addInput() facility of FXApp. The addInput() call registers a callback message, and target object, to be invoked when the event on the file descriptor occurs. For example, adding:

            app->addInput(fd,INPUT_READ|INPUT_WRITE,myobject,MyClass::ID_FD);

Will send a message ID_FD of type SEL_IO_READ when new data is available on fd to be read, and a message ID_FD of type SEL_IO_WRITE when the buffer is ready to accept more data to be written. In either case the void* ptr refers to the file descriptor fd, permitting you to use the same handler for multiple file descriptors.

On MS-Windows, instead of a POSIX file descriptor, you must use a handle. Thus, under MS-Windows, the addInput() API can be used to wait on a great variety of kernel objects, ranging from event objects (which is what you need to use for sockets), to process and thread handles, and so on. Please consult the MSDN documentation on Winsock2 for details.

What do the different version numbers for FOX mean?

Starting with the FOX 1.0.0 release, FOX library releases will have a version number of the form major.minor.patch. When the minor version number is odd, this indicates that it's a development version of FOX; when it's even, this indicates a stable release version.

The intent is for even-numbered releases to keep the header files untouched, to guarantee DLL or shared library compatibility. If bugs are fixed, the patch number will be increased. Thus, applications should be able to link to shared library versions of FOX with confidence. For odd-numbered releases, everything may be changed from one patch level to the next, so one would have to recompile applications (that's the nature of it being a development version!).

Why didn't you fix the problem of the last pixel of a line not being drawn on MS-Windows?

I have received many such suggestions. Here's why the suggestions received so far do not work:

- You may draw thicker lines; adding a pixel with thin lines (1 pixel wide) is possible, but with thick lines it gets kind of complicated.

- You may be drawing with stipple style. The stipple algorithm is closely tied to the DDA and to draw the end-point properly you must know the state of stippling algorithm in order to decide what color to give the final pixel.

- Drawing with patterns and various BLIT modes. There are ways to draw with hatched brushes, and you can use many different BLIT modes to combine foreground, background, and hatch patterns with the background. So it gets even more complicated....

- Even if you can solve the problem of doing all the above, there is one problem left which you CAN NOT SOLVE. You can not solve it because of the mathematics of rational numbers:

         Y

         5
         4            oo@
         3         ooo
         2      ooo
         1   ooo
         0ooo
          0123456789012345  X

  Suppose you draw the line above, but you want to include @. You'd think its a matter of specifying a slightly different end point P, such that @ is touched in the DDA algorithm.
  However, this is impossible, because the line shown has a slope of 3:1, and this hypothetical endpoint would be at at (15,4 1/3) and of course that's not an integer coordinate. The next best thing would be either (15,4) or (15,5), but that will give you a different slope line (and totally different pixelization) altogether. In effect, rather than having a tiny problem at the end of a line segment, you now have many problems along the entire line.

The moral of the story is that we're basically better off NOT trying to fix this problem, but simply organize code so as to (a) minimize the reliance on line drawing, and use rectangle fills instead, and (b) whenever we do need to draw lines, try to make sure this effect is hidden, and finally (c) if all else fails, there is #ifdef style conditional compilation.

As it happens, I have been able to make do with (a) and (b) in almost all cases, and had to resort to (c) only once or twice.

Why doesn't FOX use ASSERTs to check API arguments?

The philosophy of error checking is like this:

- As a library, FOX is installed and used by many programs, and so under normal circumstances it is compiled with optimization flags, and so assertions and such are normally removed.

- Application developers may compile their own code with debugging enabled, but usually link against a pre-installed copy of the library.

- Thus, errors in arguments and such need to be checked by means other than assertions.

- If you're working on additional FOX widgets, or perhaps suspect a bug in the FOX library, then the library can be compiled for debug mode. In this case, we're interested to uncover bugs and inconsistencies in the library itself, so assertions and tracing and so on must be turned on.

- The assertions in the library itself should however NEVER be triggered, even if the application program is ill-behaved or the library is used in the wrong way:- because the assertions are there to verify the correctness of the library itself, and the standpoint is that other checks should catch bad parameters to API's and other abuses.

All this checking introduces some overhead, of course. But lets not forget that its a GUI library, and so the speed of many operations is not so critical, because 99% of the time the application is simply waiting for the user to do something; also, the dominant amount of CPU is actually spent on drawing, which is not slowed down at all. The payoff of all this checking is that various kinds of programming problems are (hopefully) discovered sooner.

Why can I not paste clipboard data out of a deleted window?

Deferring the generation of the clipboard data until a request is received from another application has a number of advantages:

- A cut or copy operation can be nearly instantaneous, even for very large data, as no actual data are being transferred.
- It is more open-ended in terms of clipboard data types, since not all data formats need to be generated up front.
- It allows for some optimizations; for example, if the requestor and the source are in fact the same application, no inter-process communication needs to be performed at all; data can be exchanged directly in memory.

The alternative would be to generate all clipboard-types up front; imagine what this would mean if we had 10 image formats and you clipped an image to the clipboard:- you'd have to place the same image on the clipboard in all 10 image formats just on the off-chance that one of them may be requested!

The source of the clipboard data is the widget from which the data was clipped to the clipboard; that widget is the one which owns the clipboard, and that widget is the one that will be asked to generate a specific representation of the data for a specific clipboard type when it is asked by another application. Only that particular widget has the methods and knowledge for generating the requested representation of the clipped data.

While this allows for a lot of flexibility in the clipboard data types, it does have a downside:- when the owner of the clipboard is deleted, so does the clipped data.

What is valgrind?

Valgrind is a tool for detecting various memory problems in your code, such as:

- Use of uninitialised memory;
- Reading/writing memory after it has been freed;
- Reading/writing off the end of malloc'd blocks;
- Reading/writing inappropriate areas on the stack;
- Memory leaks -- where pointers to malloc'd blocks are lost forever;
- Passing of uninitialised and/or unaddressible memory to system calls;
- Mismatched use of malloc/new/new [] vs free/delete/delete [];
- Some misuses of the POSIX pthreads API.

Valgrind works on Linux/x86 only (on Windows, consider tools such as Purify or BoundsChecked; there may be other tools).

Valgrind translates x86 instructions into instrumented code, basically inserting various checks on memory references. Because its still not completely aware of all sorts of x86 instruction set extensions like 3DNow and SSE, you should probably compile your code in "vanilla" pentium mode.

If your code links against OpenGL libraries from NVidia then you can disable the OpenGL library's use of 3DNow and SSE by setting:

      export __GL_FORCE_GENERIC_CPU=1

on recent releases of the OpenGL library.

If you care about software quality, you owe it to yourself to try valgrind out as it can catch a great many bugs; some memory bugs are like "time-bombs" and may linger in the code for a long time; valgrind can ferret them out.

When is a member function virtual or not?

There are often questions about why certain member functions of FOX classes are not virtual. The point below attempt to explain the reasoning behind the decisions.

1. Functions which need to be virtual are. Examples of these are functions like getDefaultWidth() and layout().
2. Certain functions which may be overloaded in derived classes are; for instance expandTree() is virtual because it allows a derived class to know when a subtree is unfolded.
3. Message handlers are never virtual. You can just add the same message handler in the derived class's message map, which is faster anyway.
4. Functions which should not be overloaded (e.g because it could break the abstraction, like for example getNext() and getPrev()), are never virtual either.
5. Other than the above 4 rules, non-virtual may have been chosen without good reason. On such cases, I'm open to suggestions.

Obviously the full scope of widget subclassing is not really known until people try; because of rule (4) chosing non-virtual is a better way to enforce the integrity of the abstraction.

Why does a toplevel window have different decorations than I specified?

The toplevel windows (anything derived from FXTopWindow) can have various decoration hints, such as DECOR_TITLE, DECOR_BORDER, and so on. FXTopWindow passes these hints to the underlying system. On X11, a separate program called a Window Manager is responsible for interpreting these hints and applying the appropriate borders, title bar, close buttons, minimize and maximize buttons and so on. On Microsoft Windows, this is done by the GDI layer. Either way, the decorations specified from within the FOX program are just hints:- the interpretation of these hints depends on the underlying system, and is therefore out of our jurisdiction.

There are many Window Managers under X11, such as KDE, WindowMaker, FVWM, Motif Window Manager (MWM), and so on. The ICCCM document details a few common conventions that Window Managers are supposed to adhere to; unfortunately, decoration styles are not part of this document. Because of its historic popularity, many Window Managers have opted to follow the Motif Window Manager hints.

There is also some effort under way to define some more modern standards, the Free Desktop Organization. FOX adheres to many of the Free Desktop's standards, insofar as it does not conflict with Motif Window Manager standards (since FOX needs to work reliably under Motif for some time to come).

Under MS-Windows, the part that is responsible for the title and border drawing is implemented in the Windows DLL's that FOX needs to link to. The non-client drawing is handled by these libraries, ensuring that FOX's toplevel windows look and behave according to the particular version of Windows your FOX program runs on.

Since the behaviour of the decoration hints depends on the underlying system, FOX programmers must perform some testing under various systems to ensure that the particular combinations of hints they have chosen work as expected; the FOX library itself uses very conservative settings which are known to work properly on most Window Managers.

Why do none of the FXScrollArea derived widgets have a frame?

The short answer is that FXScrollArea is derived from FXComposite, and FXComposite does not support a frame.

The longer and more accurate answer is a bit more complicated. The FXScrollArea widget, and its derivatives, present a small view of a larger content. The content may be a drawing, but sometimes also other widgets are involved, for example in the case of FXIconList. It is necessary to clip all drawing to the visible viewport of the FXScrollArea. This is made possible by making sure the FXScrollArea's scroll bars and scroll corners are always the topmost three children, and positioned so as to leave a simple rectangular viewport area in which the content is shown.

If FXScrollArea would draw borders or padding around itself, this would necessarily not be covered by the scroll bars and scroll corner; however that would present a problem as any content or sub-windows of the content would be drawn on top of the FXScrollArea's borders.

Thus, FXScrollArea does not support borders. If you need a sunken border around a scrolling widget, simply create a FXVerticalFrame with no padding as the immediate parent.

What is the Legal Status of FOX since your departure from CFD Research?

CFD Research has been very nice to work out an arrangement for the legal status of FOX which is acceptable to all parties. The issues were the continued availability of the FOX Library to CFD Research, and the acknowledgement of copyrights to its author and contributors.

The arrangement is as follows:

1. CFD Research disclaims all Copyright Interests to the FOX Library.
2. CFD Research will continue to be able to use the FOX Library under the Lesser GPL license.

What is all this stuff with FXSelector and so on?

When a target receives a message from a widget, it may want to know several things:

- From which widget did the target receive the message? This is determined by FXObject *sender argument of the message handler.

- What happened? The answer to this question is in the type-part of the FXSelector sel argument of the message handler. You can obtain the message type by means of the macro: FXSELTYPE(sel).

- The identity of the widget from which the message was received. This is answered by the id-part of the FXSelector sel argument of the message handler. You can obtain the message id by means of the macro: FXSELID(sel).

- Any other pertinent data. This data depends on the type of widget, the message type which was received, and is found in the void* ptr argument of the message handler. You must typically cast this to the appropriate type.

Sometimes, a handler may have to send messages back to the sender, for example, in response to a SEL_COMMAND message a message handler may want to obtain the value of the sending widget by sending it a message of type SEL_COMMAND, and message id ID_GETINTVALUE. To build a message out of the type and id parts, you can use the macro: FXSEL(type,id).

For historical reasons, the data type used for the message-id, message-type, as well as the combined selector is FXSelector.

How do I add an icon for Windows Explorer?

You need to create a file, call it "myapp.rc", and then put into it:

      0 ICON DISCARDABLE "myapp16.ico"
      1 ICON DISCARDABLE "myapp32.ico"

Where, obviously, myapp16.ico and myapp32.ico are the icons you want to be associated with your application.

You will also need to convince your resource compiler to compile that, of course.

The TextField stops updating while the cursor is in it?

While a Control is being manipulated by the user, the GUI update (the process by which the widget updates itself from the application state) is turned off.
For most simple controls like Sliders this is done only during the time the mouse has grabbed the slider head.
However, for TextFields the updating is turned off while the TextField is being edited. There is no easy way to detect when the user is "done" with the TextField; but it is clear that the TextField can be updated again when:

- You've moved the focus to another Control, or
- You've hit RETURN in the Text Field to accept the typed input.

Building and using DLL's with FOX under Windows.

When you compile something, the header files can be parsed two ways on Windows. When compiling the FOX library itself as a DLL, the FXAPI macro should be set to FXEXPORT, which itself is set to __declspec(dllexport), (or possibly as something else depending on the compiler and linkage ideosyncracies). When you're compiling your own code which uses the FOX DLL, then FXAPI is defined as FXIMPORT which is then typically set to __declspec(dllimport).

There are two layers of macros so for your own DLL and EXE building you won't have to remember what to do for export or import, you can use the FXEXPORT and FXIMPORT macros. Now, you can NOT use FXAPI. When you build your own library, that library is a importer of the FOX API but an exporter of its own API!

For example, in FXChart new symbol FXCHARTAPI is defined so that when it is compiled it could be import symbols from FOX yet at the same time export its own symbols.

So in a nutshell:

- Compile FOX with -DFOXDLL and -DFOXDLL_EXPORTS.

- Compile programs which use FOX with -DFOXDLL and nothing else.

- Compile your own DLL's which use FOX with -DFOXDLL and -DYOURDLL_EXPORTS [see FXChart for example]. Your own FOX-based DLL's export ONLY their own symbols but import the core library's symbols.

Creating an MDI application.

When you build an MDI application, messages should be routed via the FXMDIClient to an FXMDIChild, and from there, to either FXMDIChild's content window and the FXMDIChild's target. The FXMDIChild's target is typically a document object of some kind.

So, GUI controls basically have FXMDIClient as their target. The FXMDIClient is a kind of delegator, in the sense that when it does not understand a message, it forwards it to its currently active FXMDIChild; if there is no such child, then control is returned to the calling widget with the "unhandled" message return code.

The FXMDIChild similarly does a delegation. It tries the content window first, then its target "document" object.

Since we do not know which FXMDIChild is going to be active, it is important to ensure that all message ID's are unique if you have different types of FXMDIChild widgets.

For example, an application may have a 3D viewer in one FXMDIChild and a text view in another FXMDIChild. We don't want messages intended for a 3D viewer to be connected to a wrong handler when the text view FXMDIChild is active.

So, I recommend a common base class for your various FXMDIChild subclasses, and to define all message ID's in there. Then various subclasses of this base class map whatever ID's they need to specific handlers.

If you also have a Document class as target of the FXMDIChild windows, then number the messages the Document deals with starting from the ID_LAST of the FXMDIChild base class widget in your application. See below:

      // MDI Child base class
      class MyMDIChildBase : public FXMDIChild {
      ...
      enum {
        ID_FIRST=3000,      // High number away from any ID's defined in widgets
        ...
        messages defined for all subclasses of MyMDIChildBase
        ...
        ID_LAST
        };
      ...
      };

      // Custom document class
      class MyDocument : public FXObjecvt {
      ...
      enum {
        ID_FIRST=MyMDIChildBase::ID_LAST,
        ...
        ID_LAST
        };
      ...
      };

This is convenient. For example, a "Cut Selection" message could have radically different implementations in the various subclasses, yet be invoked from the same single menu.

When a particular FXMDIChild is active, some message ID's will be mapped to a handler, and some will not be.

FOX can take advantage of this fact by allowing you to specify the AUTOGRAY or AUTOHIDE flags on certain controls. For example, if you were to specify BUTTON_AUTOGRAY on a toolbar button, the button is automatically grayed out when no corresponding handler is found in the currently active FXMDIChild, or when there is no open document at all.

BUTTON_AUTOHIDE works similarly, except that in this case the button will be hidden instead of simply grayed out.

When you use BUTTON_AUTOGRAY, it is of course going to be necessary to implement the SEL_UPDATE handler as well as the usual SEL_COMMAND handler, so that you can enable the button. You can enable the button by means of a message, so that your handler won't have to know what kind of widget the sender was.

Example:

      // Undo last command
      long MyDocument::onCmdUndo(FXObject*,FXSelector,void*){
        /// perform the command for undo
        return 1;
        }

      // Sensitize undo widget; the ID_ENABLE message
      // enables the sender [presumably a widget of some sort]
      // We don't need to know what kind of widget the sender is,
      // so we can actually use this handler for sensitizing toolbar
      // buttons as well as the corresponding pulldown menu commands.
      long MyDocument::onUpdUndo(FXObject* sender,FXSelector,void*){
        sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL);
        return 1;
        }

      // Example: pulldown menu command
      new FXMenuCommand(editmenu,"&Undo",undoicon,clientarea,MyDocument::ID_UNDO,MENU_AUTOGRAY);

      // Example: toolbar command
      new FXButton(maintoolbar,"\tUndo",undoicon,clientarea,MyDocument::ID_UNDO,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED);

Of course there may be a few cases where you may need to perform a wholesale update of the user interface when the user switches FXMDIChild windows or documents. Some major widgets with lots of content should probably not be updated using the SEL_UPDATE mechanism.

There are two ways; first is the SEL_CHANGED from FXMDIClient; a better way, and the recommended one, is to catch the SEL_SELECTED and SEL_DESELECTED messages from FXMDIChild:

      // Switched to new active document
      long MyDocument::onChildActivate(FXObject*,FXSelector,void* ptr){
        if(!ptr || ((FXMDIChild*)ptr)->getTarget()!=this) activateDocument();
        return 1;
        }

      // Switched from old active documents
      long MyDocument::onChildDeactivate(FXObject*,FXSelector,void* ptr){
        if(!ptr || ((FXMDIChild*)ptr)->getTarget()!=this) deactivateDocument();
        return 1;
        }

The void* in these messages reflects the OLD FXMDIChild window that was active before the switch. The code above takes care of the case where there are multiple FXMDIChild windows which may have a common document, and we would of course only want to update the GUI controls when we switch documents, not when we switch between FXMDIChild windows of the same document.

The implementation of activateDocument() will be responsible for setting up the GUI controls with data pertaining to the document. Likewise, deactivateDocument() should tear down the user interface and leave widgets in their pristine state [as if there were no document].

MS-Windows GDI handle limits.

MS-Windows has finite limits on GDI handles; the maximum number of HWND handles in the entire system is determined by 16-bit handle values. There is also a maximum number of bitmap handles.

These limits manifest themselves when calls to create() are failing by throwing an exception.
Windows NT, 2K, and XP probably have higher limits than Windows 95, Windows 98, and Windows ME.

It is therefore important to make sure that resources are deleted as soon as they're no longer needed. Since its pretty fast to create resources, its best to delay creation of windows and icons until they're actually needed.

In particular, dialogs should "own" their icons, and delete them in the dialog's destructor. Try to construct dialogs only when they're actually brought on-screen, and try to delete them when the interaction with them is done.

Note that un-created() icons and images do not use any handles in the system, so refrain from calling create() on icons or images if all you want to do is load and manipulate the image's pixel data. You only need to call create() when images are to be drawn into or used as sources for drawing (like e.g. drawing onto widgets).

Copyright © 1997-2005 Jeroen van der Zijp