Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

More Problems with DBCtrlGrid

708 views
Skip to first unread message

imac-dc

unread,
Jun 18, 2002, 12:02:46 PM6/18/02
to
A couple of weeks ago I wrote the following:

. . Delphi 6 seems to have introduced a new quirk in the use of a
DBLookupComboBox in a DBCtrlGrid. After migrating from Delphi 4, I can no
longer click on the arrow next to the DBLookupComboBox to get the drop down
list. The message is "Operation Not Allowed in DBCtrlGrid". I have no
problem using the shift + down arrow to get the first value in the lookup
field but Alt + down arrow or the mouse click will no longer provide the
drop down. This would not be the first time that Borland has changed
something that worked fine under a previous version but needs to be changed
somehow in a later one. Does anyone have a clue as to what now needs to be
done to migrate a DBLookupComboBox in a DBCtrlGrid from Delphi 4 to 6? Thank
you. . ."

I received an answer from Mr. Fomine at Quasidata which located the error
message linked to TDBLookupControl.CheckNotLookup in the VCL. The calls to
this procedure are identical in Delphi 4 and 6. I could not find why this
doesn't work until I tried to re-configure the DBLookupComboBox on the
DBCtrlGrid by removing the lookup reference field and using the KeyField,
ListField, ListSource etc., properties of the DBLookupComboBox. At
design time, I received the same message "Operation Not Allowed in
DBCtrlGrid", when I tried to assign a ListSource to the control. Thus, it
appears that this is simply not allowed at this time. Does Team B or anyone
know why Borland has decided to no longer allow DBLookupComboBox's in
DBCtrlGrid's? This is a major inconvenience. Should I report this as a
bug? Thank you.

Rick W.

Quasidata

unread,
Jun 18, 2002, 1:54:21 PM6/18/02
to
Hello Rick,

What database? What dataset class?

--
Andrei Fomine.
DbAltGrid - multi-line layout, RTF and graphics of any kind in DBGrid.
Transfer@once - full-blown clipboard and drag-and-drop transfer in native
MS Office formats to/from any control.
www.quasidata.com


"imac-dc" <ima...@msn.com> wrote in message news:3d0f59ca$1_1@dnews...

imac-dc

unread,
Jun 18, 2002, 2:04:42 PM6/18/02
to
Andrei,

The database is Paradox/Standard using a TTable. Nothing fancy, strickly
simple stuff. Not networked. Thanks

Rick W.

"Quasidata" <quasidataATquasidataDOTcom> wrote in message
news:3d0f73e6_1@dnews...

Quasidata

unread,
Jun 18, 2002, 3:43:14 PM6/18/02
to
Hello Rick,

Could you create a simple sample project? You will need it anyway if you
are going to report a bug to Borland. Separate the issue from other stuff
in your project. You can send it to borland.public.attachments to let us
look into it.

--
Andrei Fomine.
DbAltGrid - multi-line layout, RTF and graphics of any kind in DBGrid.
Transfer@once - full-blown clipboard and drag-and-drop transfer in native
MS Office formats to/from any control.
www.quasidata.com


"imac-dc" <ima...@msn.com> wrote in message news:3d0f765e$1_2@dnews...

imac-dc

unread,
Jun 18, 2002, 4:03:52 PM6/18/02
to
Andrei,

I'll put together something by tomorrow. Thanks.

Rick W.

"Quasidata" <quasidataATquasidataDOTcom> wrote in message

news:3d0f8d6f_1@dnews...

Quasidata

unread,
Jun 19, 2002, 4:27:12 AM6/19/02
to
Hello Rick,

I have played with the sample projects you posted and here are some
thoughts.

There is a property which entirely controls placement of data-aware
controls into DBCtrlGrid, namely TDataLink.DataSourceFixed. If you
searched its occurence in the VCL sources, you can see that it is tested
in many data-aware controls, but is assigned only within
TDBCtrlGrid.UpdateDataLinks. The developers surely wanted it to be True
for a control placed on the grid.

And they surely wanted to avoid use of TDBLookupComboBox with the grid,
because they placed the line
if FDataLink.DataSourceFixed then DatabaseError(SDataSourceFixed);
in TDBLookupControl.CheckNotLookup (TDBLookupComboBox is a
TDBLookupControl descendant.)

But they failed to prevent it. There is some mess with the DataLink
implementation in TDBLookupComboBox in Delphi 4. For unclear reason the
control returns a wrong address of the datalink to the grid. The grid
misses the datalink and DataSourceFixed of the original datalink remains
False. It passes the test in CheckNotLookup and you are lucky.

Later, they fixed the datalink in TDBLookupComboBox in Delphi 6 (maybe
even in Delphi 5, I haven't checked there). An indirect evidence of that
work is that they added the protected DataLink property in
TDBLookupControl (before there was only single private FDataLink field)
and moved CMGetDataLink from TDBLookupComboBox to TDBLookupControl. So it
works correctly now and you become unlucky.

I am unable to dig deeper into the issue in Delphi 4, because the debugger
displays ambiguous values for the FDataLink field. So, if I place a
breakpoint within TDBLookupControl.Create, it displays different values in
the Watches window and in the tooltip window. I have given up with the
debugger.

Thus, they at Borland may say TDBLookupComboBox wasn't initially designed
to work within DBCtrlGrid and that was a bug it did in Delphi 4. I cannot
comment this.

--
Andrei Fomine.
DbAltGrid - multi-line layout, RTF and graphics of any kind in DBGrid.
Transfer@once - full-blown clipboard and drag-and-drop transfer in native
MS Office formats to/from any control.
www.quasidata.com


"imac-dc" <ima...@msn.com> wrote in message news:3d0f924d$1_2@dnews...

Marco Klemm

unread,
Jun 19, 2002, 5:12:57 AM6/19/02
to
Hi Rick,

imac-dc wrote:
>
> A couple of weeks ago I wrote the following:
>
> . . Delphi 6 seems to have introduced a new quirk in the use of a
> DBLookupComboBox in a DBCtrlGrid. After migrating from Delphi 4, I can no
> longer click on the arrow next to the DBLookupComboBox to get the drop down
> list. The message is "Operation Not Allowed in DBCtrlGrid".

You are lucky that you posted this question also to b.p.attachments,
since I do not read b.p.d.d.desktop normally :-)

For some time, we have found a workaround for this bug in a German
newsgroup. [1]
You have to patch the dbcgrids.pas with the following modification:

procedure TDBLookupControl.CMGetDataLink(var Message: TMessage);
begin
// BugFix1 Delphi 6.0, 6.1: DBLookupComboBox in DBCtrlGrid

Message.Result := Integer(nil);
// Message.Result := Integer(FDataLink);

// BugFix1 End
end;

The component will work in D6 as in D4 without limitations.

I try to explain the reason for this bug and workaround (in short,
since I'm running out of time), assuming that you understand the
"CMGetDataLink" logic.

TDBLookupControl has two relevant descendants:

TDBLookupComboBox = class(TDBLookupComboBox)
TPopupDataList = class(TDBLookupListBox) (= class(TDBLookupControl))

(TPopupDataList is the Dropdown-List of TDBLookupComboBox.)
The overriden TDBLookupControl.CMGetDataLink is correct for
TDBLookupComboBox and TDBLookupListBox, both have to be "fixed"
to the DBCtrlGrid and its corresponding DataSource.

Th problem of TPopupDataList is that TPopupDataList.FDataLink refers to
the lookup datasource - that is of course not TDBCtrlGrid.DataSource.

Regards,
Marco

[1]
<http://groups.google.com/groups?hl=en&lr=&frame=right&th=87e2853641b19&seekm=pn0ovtksoqtbs204pro44lsahqg9i1kf4s%404ax.com#link13>

Quasidata

unread,
Jun 19, 2002, 7:33:12 AM6/19/02
to
Marco,

Well done! Thanks to you, I changed my mind. It worked in D4 well, and
rather has been broken in D6. Rick, I'm sorry, I missed that FDataList in
code.

--
Andrei Fomine.
DbAltGrid - multi-line layout, RTF and graphics of any kind in DBGrid.
Transfer@once - full-blown clipboard and drag-and-drop transfer in native
MS Office formats to/from any control.
www.quasidata.com


"Marco Klemm" <DonL...@gmx.net> wrote in message
news:3D104B19...@gmx.net...

imac-dc

unread,
Jun 19, 2002, 10:49:15 AM6/19/02
to
Thanks to Marco and Andrei for their assistance. I've re-copied the VCL
Unit to a new folder and added the changed code to the library path, but it
is not taking it. Is there a different way to modify the VCL and include it
in the project? Thanks.

Rick W.

"Quasidata" <quasidataATquasidataDOTcom> wrote in message

news:3d106c1a$1_1@dnews...

Quasidata

unread,
Jun 19, 2002, 12:07:33 PM6/19/02
to
Hello Rick,

Copy DBCtrls.pas from $(DELPHI)\Source\Vcl to another directory. To keep
things easy, you could place it into your project's main directory. In the
main menu select Project | Options (Shift+Ctrl+F11),
Directories/Conditionals, and add the directory to the Search path. So the
compiler should find your changed unit before the original one.

Rename temporary the DBCtrls.dcu units in $(DELPHI)\Lib,
$(DELPHI)\Lib\Debug, and in $(DELPHI)\Source\Vcl if any. Otherwise, since
the original unit is unchanged, the compiler can think that the unit has
already been successfully compiled and link the old DCU file. Change and
restore back something in one of your units to force rebuild. Otherwise
the compiler will not check units to recompile. To make sure the compiler
finds the new unit, you even can add it to the project, though that is
redundant. Place the cursor on the unit name in the uses clause in the
Code Editor, right-click it and select Open File At Cursor (Ctrl+Enter).
The unit will be opened and the path to the unit will be displayed in the
Editor caption. Make sure it is correct. Change code and run the project.
I hope you will be lucky again.

Be careful, if you select the Use Debug DCUs checkbox under the Compiler
tab in the Project Options dialog, the IDE adds the $(DELPHI)\Lib\Debug
string in front of the Search path, so, if the old DCU file isn't renamed,
the compiler can use the old unit. Change the search order manually.

--
Andrei Fomine.
DbAltGrid - multi-line layout, RTF and graphics of any kind in DBGrid.
Transfer@once - full-blown clipboard and drag-and-drop transfer in native
MS Office formats to/from any control.
www.quasidata.com

"imac-dc" <ima...@msn.com> wrote in message news:3d109a0f$1_2@dnews...

imac-dc

unread,
Jun 19, 2002, 12:32:10 PM6/19/02
to
Andrei,

This worked fine, however, I had to uncheck 'build with runtime packages'.
Can I rebuild the package needed or does borland not allow that? Thanks.

Rick W.

"Quasidata" <quasidataATquasidataDOTcom> wrote in message

news:3d10ac65$1_1@dnews...

Marco Klemm

unread,
Jun 19, 2002, 12:34:37 PM6/19/02
to
Rick,

imac-dc wrote:
>
> Thanks to Marco and Andrei for their assistance. I've re-copied the VCL
> Unit to a new folder and added the changed code to the library path, but it
> is not taking it. Is there a different way to modify the VCL and include it
> in the project? Thanks.

I follow the recommendation of Dan Miser:
http://distribucon.com/midasbug/

It's quite easy.

Regards,
Marco

imac-dc

unread,
Jun 19, 2002, 12:39:24 PM6/19/02
to
Andrei/Marco,

This worked fine, however, I had to uncheck 'build with runtime packages'.
Can I rebuild the package needed or does borland not allow that? Thanks.

Rick W.

"Marco Klemm" <DonL...@gmx.net> wrote in message
news:3D10B29D...@gmx.net...

Quasidata

unread,
Jun 19, 2002, 2:16:22 PM6/19/02
to
Hello Rick,

The source files of the runtime packages do not come with Delphi, thus you
are unable to rebuild them. As another workaround to the issue I suggest
to intercept the CM_GETDATALINK message right in your form without
changing the original DBCtrls.pas file, but this is not a trivial thing.

--
Andrei Fomine.
DbAltGrid - multi-line layout, RTF and graphics of any kind in DBGrid.
Transfer@once - full-blown clipboard and drag-and-drop transfer in native
MS Office formats to/from any control.
www.quasidata.com


"imac-dc" <ima...@msn.com> wrote in message news:3d10b22f$1_1@dnews...

imac-dc

unread,
Jun 19, 2002, 2:57:46 PM6/19/02
to
Dear Andrei,

Thanks again for yours and Marco's help. I think I'll take a pass on
trapping for the message and close this chapter. If you ever have any
questions on qbe or local sql let me know, I'm pretty good at it (I think).

Rick W.

"Quasidata" <quasidataATquasidataDOTcom> wrote in message

news:3d10ca92$1_1@dnews...

imac-dc

unread,
Jun 19, 2002, 3:05:47 PM6/19/02
to
Dear Andrei,

Thanks again for yours and Marco's help. I think I'll take a pass on
trapping for the message and close this chapter. If you ever have any
questions on qbe or local sql let me know, I'm pretty good at it (I think).

Rick W.

"Quasidata" <quasidataATquasidataDOTcom> wrote in message

news:3d1040a2$1_1@dnews...

Marco Klemm

unread,
Jun 19, 2002, 7:13:25 PM6/19/02
to
Hi Andrei,

Quasidata wrote:
>
> The source files of the runtime packages do not come with Delphi, thus you
> are unable to rebuild them. As another workaround to the issue I suggest
> to intercept the CM_GETDATALINK message right in your form without
> changing the original DBCtrls.pas file, but this is not a trivial thing.

Even though I wouldn't do that, I'm interested in this idea.
How would you prevent the call to
AControl.Perform(CM_GetDataLink, 0, 0)
of the DBCtrlGrid? I don't see any possibility.

Regards,
Marco

Quasidata

unread,
Jun 20, 2002, 4:40:46 AM6/20/02
to
Hello Marco and Rick,

I figured out how to work around the issue. Here is a sample. It assumes
that the combobox is placed on the grid at design-time, not runtime. So at
the moment the event handler is executing, the controls have been streamed
successfully from the DFM and links already established. Though one should
test in a real project.

procedure TForm1.FormCreate(Sender: TObject);
var
I: Integer;
MyDataLink: TDataLink;
begin
for I := 0 to DBLookupComboBox1.ControlCount - 1 do
if DBLookupComboBox1.Controls[I] is TPopupDataList then
begin
MyDataLink :=
TDataLink(DBLookupComboBox1.Controls[I].Perform(CM_GETDATALINK, 0, 0));
if MyDataLink <> nil then
MyDataLink.DataSourceFixed := False;
MyDataLink.DataSource := nil;
end;
end;

Marco Klemm

unread,
Jun 20, 2002, 10:53:23 AM6/20/02
to
Hi Andrei,

Quasidata wrote:
>
> I figured out how to work around the issue. Here is a sample. [...]


>
> procedure TForm1.FormCreate(Sender: TObject);
> var
> I: Integer;
> MyDataLink: TDataLink;
> begin
> for I := 0 to DBLookupComboBox1.ControlCount - 1 do
> if DBLookupComboBox1.Controls[I] is TPopupDataList then
> begin
> MyDataLink :=
> TDataLink(DBLookupComboBox1.Controls[I].Perform(CM_GETDATALINK, 0, 0));
> if MyDataLink <> nil then
> MyDataLink.DataSourceFixed := False;
> MyDataLink.DataSource := nil;
> end;
> end;

Well done.
(Borland should reconsider the information hiding concepts :-)

Regards,
Marco

imac-dc

unread,
Jun 20, 2002, 3:16:01 PM6/20/02
to
Hello Andrei,

Well down times two. The workaround code works perfectly in my project. I
repeat Marco's comment about Borland. I've stumbled across too many bugs in
the past (especially in other LookUp situations) where some additional work
on their part could have avoided sloppy results. Thanks again.

Rick W.
ima...@msn.com

"Marco Klemm" <DonL...@gmx.net> wrote in message

news:3D11EC63...@gmx.net...

0 new messages