El 02/11/15 a les 11:56, Luca Olivetti ha escrit:
Show quoted text 34 lines
El 02/11/15 a les 11:12, Luca Olivetti ha escrit:
> 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 (FEditornil) 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.
Bug created:
http://bugs.freepascal.org/view.php?id=28944As I said in the bug report I just discovered
http://www.freepascal.org/~michael/articles/grids/grids.pdf (published in 2008!) describing how to correctly implement a custom editor (so the method from the wiki I originally used is wrong, I also added a note to the wiki).
*However* the component described by Michaël only works with a StringGrid, not with a DBGrid: when you change cell the grids sends the GM_SETVALUE message *before* the GM_GETVALUE one, so the edited value is lost and a semi-random one is used instead.
To make it work one has to override the Change method (as it is done in grids.pas):
procedure TStringCellEditor.Change;
begin
{$IfDef DbgGrid} DebugLn('TStringCellEditor.Change INIT
text=',Text);{$ENDIF}
inherited Change;
if (FGridnil) and Visible then begin
FGrid.EditorTextChanged(FCol, FRow, Text);
end;
{$IfDef DbgGrid} DebugLn('TStringCellEditor.Change END');{$ENDIF}
end;
*but* the EditorTextChanged method is protected, so an additional cracker class (ugly) has to be used, e.g.
TMyGrid = class(TCustomGrid)
procedure EditorTextChanged(const aCol, aRow: Integer; const aText:
string); override;
end;
procedure TMyGrid.EditorTextChanged(const aCol, aRow: Integer;
const aText: string);
begin
inherited EditorTextChanged(aCol, aRow, aText);
end;
procedure TMyEditor.Change;
begin
if (FGridnil) and Visible then begin
TMyGrid(FGrid).EditorTextChanged(FCol, FRow, Text);
end;
Maybe EditorTextChanged (and others methods to be used in custom editors) should be public?
Comments?
Is there something else that I'm missing?
Bye
Luca Olivetti
Wetron Automation Technology
http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007