Devoloper notes about Report Manager

TClientDataset and BCD types, why Delphi 5 enterprise version at least need

TRpDataset (rpdataset.pas) is a TClientDataset to buffer all the datasets passed to the engine that can feature grouping, so the main dataset go forward only (support for unidirectional datasets like SQLExpress), but the engine can remember at least two records to do grouping. Somebody said me last version of some reporting engines does not allow grouping if the dataset is unidirectional...

The method to implement TRpDataset is duplicate fields of new Dataset to a newly created TClientDataset (rpdataset)

Then assign fields and post the record in memory...

for i:=0 to fieldcount-1 do

It's a bit more complex because needs freeing memory (garbage old records)

This worked fine inclusive passing opened datasets to the engine until I updated to Delphi 7, where blob fields assignements are broken, I added the function AssignField(Source,Destination), and a compiler define, active for Delphi 7 (BLOBSTREAMBUG) so assignement for blobfields are patched in this function.

If you find an assignment fails using a particular type (like BCD) you can patch the assignment there, send me the bugfix so I will add a compiler define for the bug and add to the main tree.

BCD is a problematic type, see for example FormatVariant function in rptypes.pas.

Borland changes in TFiler in Delphi 6 and up

Borland have changed the way it stores WideStrings because Utf8 support.
(TFiler,TWriter,TReader) since Delphi 6, so because the engine can be compiled with any version of Delphi/Builder/Kylix, WideStrings properties are written in a custom way, really they are written in the Delphi 4/5 way.
WideString properties are TRpLabel text, Font names, etc.

From classes.pas

procedure TWriter.WriteWideString(const Value: WideString);
L: Integer;
Utf8Str: UTF8String;
Utf8Str := Utf8Encode(Value);
if Length(Utf8Str) < (Length(Value) * SizeOf(WideChar)) then
WriteMinStr(Value, Utf8Str)
L := Length(Value);
Write(L, SizeOf(Integer));
Write(Pointer(Value)^, L * 2);

This causes a incompatibility with earlier versions of Delphi.

The workaround is a to store all the widestring properties as
special properties defined in DefineProperties of each report
streamable component, and write and read the widestrings using the
old Delphi 5 method.

This problem was fixed in 1.2 version.

The horrible bug in Delphi 7 about TComboBox (VCL) empty items

Delphi 7 has a horrible bug, when you place a TCombobox in a form, with a empty selectable item (csDropDownList), at run time, selecting this item the application will crash (Win9x), or raise an exception in ntdll (WinNT) or work correctly (WinXP).

A patch for this issue is expected in a service pack, but for now all the empty selectable items of comboboxes are replaced with a a space (' ') to solve this issue. For your convenience the engine also includes a patch unit (D7GetComboBoxStringsPatch.pas) for your projects

The Open/Save dialog Windows CLX bug since Delphi 7

Delphi 7 has another horrible bug in CLX Open/Save Dialogs, a 'Drive C: not found' exception is raised if you try to select a file that is not in the root dir, but only in Win9x systems, in WinNT/XP works ok. Because for windows a pure VCL version is provided (repmandxp.exe) I don't worry about this issue but if you find a workaround feel free to send me it. You can reproduce it compiling repmand.exe for Windows and saving files in Windows 9x OS.

BiDi Support

Bidi support is now implemented allowing each label to have a diffetent value for each language, here are the comments about the user introducing the main idea.



I think that you should not bother yourself too much with providing
full BiDi support within RepMan. Instead, you should do what Delphi
controls do - let Windows API do the work. I'll explain in a little
more detail.

There are many small details surrounding BiDi, but all of them can be
grouped into two major problems: BiDi layout, and BiDi text input/output.


The layout problem is a bit complicated, becuase everything has to be
calculated in reverse. For example, when you create a right-to-left
(RTL) drop down field, you need to:
1. Place the field label to the right of the input box.
2. Place any drop down icon to the left of the field.
3. Draw the drop-down box aligned to the right of the input box.

However, BiDi layout is NOT IMPORTANT for printed reports. Reports are
mostly made of text objects and the positioning of is easily
determined at design time.

Of course that having full BiDi layout support is nice, and my guess
is that it will not be very difficult to implement. But even without
it, most users will be able to create right-aligned reports quite easily.


The other BiDi problem is correct input and output of text. We can
ignore the input, becuase report objects are for output only.

Fortunately, this should be VERY easy to solve, becuase you can
duplicate Delphi's text output methods. Actually Delphi only calls the
Windows API with the required parameters, and Windows does the work.


I think that adding BiDi text output should be really easy. Probably
all you need to do is:

1. Add BiDiMode and ParentBiDiMode properties (and some related
methods) to the report objects. You can look at an example in Delphi
source code for TControl in unit Controls.

2. Duplicate the way Delphi controls call DrawText - I think that you
only need to add a flag depending on the BiDiMode property. You can
look at an example in Delphi source code for TLabel in unit StdCtrls.

Another approach can require more work now, but may be better in the
long run: make RepMan objects descendants of Delphi controls, such as
TLabel, and use their output methods. This way your code will benefit
from future improvements to Delphi, like Unicode support.


The only remaining issue is compatability between Windows and Linux.

As I mentioned, Delphi uses the underlying OS (or graphics library)
for BiDi text input and output. The VCL libraries call the Windows API
which has full BiDi capabilities.

Unfortunately the QT library does not support BiDi, so at the moment
Delphi-CLX (and Kylix) don't support BiDi. (The most recent versions
of QT do have BiDi, but Delphi's CLX is built on older versions.)

So CLX/Kylix compatability is not relevant at the moment, because
there's no way to create BiDi applications at all with QT, so there's
no point to worry about the reports...


Out of two major issues, the big one (BiDi layout) is not really a
problem for reports, and the smaller one (BiDi text output) can be
solved easily.

I do hope very much that you decide to enable BiDi, and I will be glad
to test it for you and help you make it work. If indeed RepMan will
support BiDi, then I intend to purchase a copy, and I will also help
you add further features such as Hebrew translation, BiDi layout, etc.