OWL 5.0

TDibDC Requires WING.DLL in 5.01
Previously TDibDC made use of either WinG (WING.DLL) or DIB.DRV "depending on which is available on the user's system." Since DIB.DRV is no longer supported and is not available free, TDibDC was modified to use WinG only. If you don't have the WinG DLL you can obtain it free from one the Microsoft web page or from any of the usual Microsoft sources on the internet.

Converting OWL 2.5 Apps to 5.0
There isn't a lot to converting OWL 2.5 apps to 5.0. The main thing that you must do is change all BOOL to bool, TRUE to true, and FALSE to false. This is because bool is an integral data type in 5.01 and not just a typedef'd int. Aside from that there is very little needed to convert.

There is also a scoping rule change in the C++ draft which was implemented in 5.0. You may get 'undefined symbol' errors when compiling your apps under 5.0 for the first time. The following code snippet is not longer legal:

for (int i=0;i<100;i++) {
  // do some stuff
}
int index = i;

The new rule states that 'i' has scope limited to the for statement. In order to get the above code to compile you would have to move the declaration for 'i' above the for statement.

Documentation Error in TSplashWindow
This is a problem that goes back to 5.0, actually. The documentation for TSplashWindow says,

The splash screen does not assume ownership of the DIB.

This is incorrect. TSplashWindow does take ownership of the TDib and deletes it when the splash window closes. Do not attempt to delete the TDib passed to TSplashWindow or a GPF will result.

Change in Behavior of TSplashWindow in 5.01
In BC++ 5.0 TSplashWindow closed itself using CloseWindow. This meant that the TSplashWindow did not get deleted when the app closed. In 5.01 TSplashWindow closes itself by sending a WM_CLOSE message. This adds the splash window to the TApplication object's condemned list and when the app closes the memory is reclaimed. If you had been using IdleAction() or some other means of deleting the TSplashWindow in 5.0 you need to remove that code so the splash window does not get deleted twice.


Dialogs and ToolTips Behave Oddly in 5.01
In some cases you may notice that tool tips or dialogs don't work properly the first time an app runs. When this happens it is necessary to click on the application's title bar or main window to give the main window focus before things will work properly. This is actually due to a bug in TControlBar that snuck into 5.01. There's no work around at present. Hopefully Borland will provide a small patch soon.

OWL Dialogs in DLL Throw Exception, Global Variable ::Module Not Initialized
(5.01 only) If you provide a DLLEntryPoint() for your DLL then ::Module does not get intitialized. In your DLLEntryPoint() call OWLInitUserDLL() to make sure the globals get set up properly. In LIBMAIN.CPP you'll find this line in DLLEntryPoint(): 

  return OWLInitUserDLL(hInstance, 0) ? 1 : 0;

Do the same in your DLLEntryPoint and ::Module will be initialized.

Brush Colors Appear to Change at Random
If you use a lot of brushes in your application and you keep those brushes around for the life of the application you may notice that the colors appear to change spontaneously. The reason is that OWL has a mechanism for caching brushes (and other GDI objects). The brush cache size is 8 and if OWL has to cache more than 8 brushes the oldest brush gets discarded to make room for the newest. To prevent this be sure that you are using your brushes at local scope where possible and keep the brushes used at the application level to an absolute minimum. Note that this only applies to solid color brushes. Pattern brushes are not chached.

TPropertySheet: Response Table Doesn't Function in Derived Classes
(5.01 Only) If you derive a class from TPropertySheet and attempt to catch messages via the response table you will probably find that it doesn't work. This is because OWL is not subclassing the property sheet common control. In order to have the response table work as it does for other classes you'll have to call EnableSubclass(true); for the property sheet prior to SetupWindow().

Getting OWL and STL to Work Together
OWL uses the cstring class (string) and STL also has a string class. Thus, there is a namespace conflict. Attempting to use STL in an OWL app results in compiler errors that are elusive and don't point to the real problem. You can use STL and OWL together in a project, though.

One method is to not use STL and OWL together in the same module. Although this will work, it is not very practical in a real-world situation. A more practical solution requires renaming the std::string class to std::_string. The following code fragment illustrates:

#include <owl\applicat.h>
#include <owl\framewin.h>
#pragma hdrstop
#define string _string
#include <vector>
#undef string
#define string _string
#include <string>
#undef string

using namespace std;
typedef vector<_string> array;

Now all references to std::string must be '_string' rather than plain 'string.' Notice in the above code the #pragma hdrstop is placed before the STL #includes. If you try to include the STL headers in the pre-compiled header you will get a warning, "Cannot create pre-compiled header - code in header." Stopping compilation of the .csm prior to including the STL headers eliminates the warning and allows use of pre-compiled headers.

GPF or 'Create Fail for Window' When Opening a Dialog
Running your program on a different machine or without the IDE and getting Create fail for Window or GPFs, when it runs sound as a bell on your development machine. A pound to a penny it is because you are not correctly loading BWCC.DLL. Simply add EnableBWCC() in your InitMainWindow() code - and ensure that BWCC.DLL is installed on any target machine.

We recommend that you don't use BWCC anymore, especially now that OWL 5 adds the TGlyphButton class for those great Delphi/BC5 IDE bitmap & text buttons.

GPF on TClipboard::SetClipboardData
Using TClipboard causes GPFs (especially on SetClipboardData). This is a CodeGuard bug not an OWL bug. Disabling CodeGuard (via the tools | CodeGuard Config) will cure the GPF.

TDialog::IdleAction() Uses 100% CPU
There is a bug in TDialog::IdleAction() (which is used for command enabling). The workaround is to derive a class from TDialog and override IdleAction() as follows:

bool MyDialog::IdleAction(long idleCount)
{
  TDialog::IdleAction(idleCount);
  return false;
}

I get a GPF trying to use a TPropertySheet with an MDI child.
As of right now you can't use a TPropertySheet as the client of a TMDIChild window. There is apparently some problem with the underlying Win95 control in this regard. Borland is aware of the problem and is reported to be looking into a fix. In the mean time (or in either case) you can use Steve Saxon's excellent TPropertyDialog (tabbed dialog class) which you can get by clicking here.

Can I add my own controls to a TPropertySheet?
The underlying property sheet control is somewhat unforgiving in this regard. You can add new controls below the property pages and to the right, but not above or to the left. This is because the tab control that manages the property pages is anchored to a specific location on the property sheet and cannot be easily moved.

I can't seem to use the ItemData in a TTreeWindow
The underlying tree view control is a little different. It requires you to declare that you will be using the ItemData when the control is created and prior to actuall using the ItemData. The following code illustrates:

TTreeNode node(*DirTree, hItem);
TTreeItem item;
item.SetItemData(0);
node.GetItem(&item);
item.SetItemData(someValue);

I can't get the text from a TTreeWindow item using TTreeItem::GetText().
In order to get the text from a TTreeWindow item you need to use both a TTreeNode and a TTreeItem. Still, once you've taken those steps just creating a TTreeItem with the default constructor and then using TTreeItem::GetText() will not work. You need to use the TTreeItem::TTreeItem(const char far*, int len = 0) form of the constructor. The following code illustrates:

TTreeNode node(*tree, hItem);
char buff[50];
TTreeItem item(buff, sizeof(buff));
node.GetItem(&item);
// 'buff' now contains the item text
MessageBox(buff, "Text in the item");

Why do I always get the OWL icon on my title bar rather than the icon I set?
In 32-bit apps you have to call SetIconSm()in addition to SetIcon() to set both the regular icon and the small icon that Windows uses on the title bar and the Win95 task bar.

TSplashWindow bitmap doesn't show until after the main window comes up.
Set the size of your splash window to be considerably larger than you need at startup, and give it a shrinktofit style. The problem occurs when the splash window is smaller than the dib. You may also want to call UpdateWindow() for the TSplashWindow to force a repaint sooner.

TGauge doesn't work when added to a dialog via Resource Workshop.
This appears to be a bug in TGauge. As a workaround, after creating the gauge in your dialog's constructor add the line:

gauge->SetLed(1,1);

The gauge will function after that.

BC++ 5.0 FAQ PageBC++ 5.0 Tips Page


Copyright 2002, Reisdorph Publishing. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Reisdorph Publishing is prohibited. All other product names and logos are trademarks or registered trademarks of their respective owners.