More Delphi 7 DBCtrlGrid Legacy tricks - lookup

 09 08 06

posted earlier on dbctrlgrid's paintpanel event to show/hide (draw/notdraw) components.

Today, I further developed a workaround for the dbctrlgrid, because I needed a lookup combobox (dblookupcombobox) on the grid.

If you place one normally, you cannot assign the ListSource design-time. Logically, you cannot then assign KeyField or ListField. ("Operation not allowedDBCtrlGrid"). Trying to override this run-time may be possible, but I haven't tried.

Adding a lookupfield field to the underlying dataset (adoquery in my case) also does not help (in my case) since the key is an ID (int) looking up a string (person name). The lookup field will not allow correct assigning, neither with a combobox or a dblookupcombobox.

The trick is, again, to use the painpanel event, this time to draw a control (the lookup control in this case) that was placed outside the dbctrlgrid on the correct spot in the dbctrlgrid. You can use the Index in-event variable against the panelindex property to make sure you only "draw" (position) in the selected canvas. You may need a dummy version of the dynamically draw-positioned control on the non-selected rows / panels. (Depends on your application).

The paintpanel code:

 

procedure TFPVA2.DBCtrlGrid1PaintPanel(DBCtrlGrid: TDBCtrlGrid;

  Index: Integer);

begin

  try

    DBCtrlGrid1.Canvas.Lock;

    if index = dbctrlgrid1.PanelIndex then  begin

      dblookupcombobox1.Top:=DBCombobox2.Top+ dbctrlgrid1.Top+dbctrlgrid1.PanelIndex*dbctrlgrid1.PanelHeight;

      dblookupcombobox1.Left:=65;

    end;

    DBCtrlGrid1.Canvas.Unlock;

  except end;

end;

The Canvas.Lock and Unlock may not be needed for your app. The 'try except end' statement was used because Delphi throws "Canvas does not allow drawing" errors that actually do not block the code or it's functionality.

 

 

DBCtrlGrid: visible controls per panel in D7

 09 04 15

Borland Delphi 7 has a control called the DBCtrlGrid. (Its counterpart in ASP.NET is the Repeater control).

In D7, at least, this control is rather limited. It will only allow a very limited range of other controls on its panels. Another rather harsh restriction is the programmer’s influence on the look per-panel: all controls on all panels must have the same look and setting properties (say, for one checkbox) in the repeater means setting that property for ALL controls in the Grid.

In a set of legacy applications I’m currently developing, a DBCtrlGrid is however the most light-weight and easily implemented solution.

One could extend the control, or purchase a commercial version, but as D7 is a legacy IDE for us, that’s not really an option.

A fortunate exception to the limitations above is the option to paint on each panel’s Canvas through the DBCtrlGrid’s PaintPanel event. Normally used to change the looks of the selected row, today I found a way to fake the visibility property of static controls, as least. It’s done through drawing images of those controls to the canvas. Using this work-around would be really bitter and ugly for anything other than images – but I’m in luck, as it’s images I want to toggle.

I want to toggle the visibility of three different images based on the presence of a character in a string field in my Query (Fields[6]) the DBCtrlGrid’s based on. Here’s the code:

procedure Form1.DBCtrlGrid1PaintPanel(DBCtrlGrid: TDBCtrlGrid; Index: Integer);
begin

if StrUtils.AnsiContainsStr(ADOQuery1.Fields.Fields[6].AsString, 'K') then DBCtrlGrid1.Canvas.Draw(804,6,imageK_template.Picture.Graphic);  

if StrUtils.AnsiContainsStr(ADOQuery1.Fields.Fields[6].AsString, 'A') then DBCtrlGrid1.Canvas.Draw(804,15,imageA_template.Picture.Graphic);  

if StrUtils.AnsiContainsStr(ADOQuery1.Fields.Fields[6].AsString, 'M') thenDBCtrlGrid1.Canvas.Draw(804,24,imageM_template.Picture.Graphic);

end;

I use AnsiContainsStr from StrUtils to check for the character. If I find it, I draw the graphic onto the canvas based on a (non-visible) picture I’ve placed on the form as well.

Note that I do not need to iterate over the query myself as the panel paint event steps through the rows itself, so I can just read the query value and it will automatically be the correct row.

The result (first row has KA in the string, the others just have A):

kam_dbctrlgrid

Part of this method was inspired by Eric Harmon’s book: “Delphi/Kylix Database Development” – one of the few sources anywhere about solid information (at least concerning DBCtrlGrid: I haven’t perused it further).

Animated Gif in Delphi 7 without flicker using RxLib

 09 04 08

There are several options for animated gif's in Borland Delphi 7.

Here's one: 

The most obvious option is using the JvGifAnimator from the JVCL library - however, you may experience flicker when you play your GIF (I do, for certain gif's).

Instead, consider using the RxGIFAnimator. I do, and it works well for me. I believe RxLib has been incorporated in builds of JVCL, but people have had issues (the Jedi installer is great, but conversion of projects sometimes does give minor headaches).

You can go to the RxLib sourceforge page to try to find it but you'll see that project has been discontinued. See this devexpress community forum post about frustration regarding RxLib.

To solve your problems (if you want to use RxLib in D7): I believe I got an update for D7 (the latest legacy version of Delphi in use at Muldis) at twm's homepage, but I cannot recall this for sure at this time (what I have works, don't have time to go back in the time machine). The twm homepage was still updating as of early 2009, so hopefully it will stay active. If the twm stuff doesn't work, ask me and I'll check what versions I have lying around and whether you can get your hands on it as well.

Powered by BlogEngine.NET 1.5.0.7 - Old School Theme by n3o Web Designers &
Tobias op den Brouw.