[Lazarus] Increasingly frustrated with DbGrids

Tony Whyman tony.whyman at mccallumwhyman.com
Mon Nov 2 11:24:20 CET 2015


Intercept classes are a very useful technique for overcoming this 
problem. I recently wanted to have a specialised TComboBox as a 
TStringGrid Editor and defined an intercept class for this as:

TComboBox = class(stdctrls.TComboBox)
     FGrid: TCustomGrid;
     FCol,FRow: Integer;
     procedure WndProc(var TheMessage : TLMessage); override;
     procedure CloseUp; override;
     procedure KeyDown(var Key : Word; Shift : TShiftState); override;
     procedure Loaded; override;
     procedure msg_GetValue(var Msg: TGridMessage); message GM_GETVALUE;
     procedure msg_SetGrid(var Msg: TGridMessage); message GM_SETGRID;
     procedure msg_SetValue(var Msg: TGridMessage); message GM_SETVALUE;
     procedure msg_SetPos(var Msg: TGridMessage); message GM_SETPOS;
     procedure msg_GetGrid(var Msg: TGridMessage); message GM_GETGRID;
     procedure EditingDone; override;
     property BorderStyle;
     property OnEditingDone;

The result was a specialist editor for the stringgrid (and which handles 
TGridMessage) but which could be placed on the form and edited as a 
TComboBox.    The TStringFrid "OnSelectEditor " event is then used to 
return the combobox as an editor.

Intercept classes can be used to customise just about any component. 
Just ensure that your intercept class is defined after the parent class.

Tony Whyman

On 02/11/15 10:12, Luca Olivetti wrote:
> Hello,
> I constantly stumble with the behaviour of the TDBGrid.
> I understand that it's a complex component, but every time I find an 
> issue an Luiz fixes it, two more pop up (or an older one resurfaces).
> The latest episode of the saga is the futility of using a custom 
> editor (with OnSelectEditor), since the grids then sets the value of 
> the field using this snippet of code
>   if (FEditor<>nil) and FEditor.Visible then begin
>     Msg.LclMsg.msg:=GM_GETVALUE;
>     Msg.grid:=Self;
>     Msg.Col:=FCol;
>     Msg.Row:=FRow;
>     Msg.Value:=GetCells(FCol, FRow);
>     FEditor.Dispatch(Msg);
>     SetEditText(Msg.Col, Msg.Row, Msg.Value);
>   end;
> and this only works with the editors defined in Grids.pas, the only 
> ones managing the GM_GETVALUE message.
> For other kinds of editors the result depends on how you move in the 
> grid: it could either maintain the value the editor set or reset it to 
> an empty string.
> I think I will file a bug once I can create a simple project, but in 
> the meantime if somebody has an idea on how to solve it, it would be 
> appreciated.
> Oh, and a custom editor has no way of adapting if the dbgrid is 
> scrolled, a column is resized, etc. Again, this only work for the 
> editors defined in Grids.pas.
> Bye

More information about the Lazarus mailing list