星期三, 5月 27, 2009

Fixed Delphi 2009 TClientDataSet locate method (filter) at widestring problem

I have fixed "Clientdataset can't locate TWideStringField" problem!

I find then problem at TExprParser! You solve the problem Step by Step .

  • Add a new class inheritance from TClienDataSet

  • override Locate Method!

function TBearClientDataSet.Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean;
begin
 DoBeforeScroll;
 Result := LocateRecord2(KeyFields, KeyValues, Options, True);
 if Result then
 begin
  Resync([rmExact, rmCenter]);
  DoAfterScroll;
 end;
end;

  • Add private LocateRecord2--Copy From LocateRecord and Change TExprParser to TExprParser2
  • Write TExprParser2

Some Code..

function TFilterExpr2.PutConstant(Node: PExprNode): Integer;
begin
 Result := 0;
 case Node^.FDataType of
  ftString, ftFixedChar, ftGuid: Result := PutConstAnsiStr(AnsiString(Node^.FData));
  ftWideString, ftFixedWideChar: Result := PutConstUnicodeStr(UnicodeString(Node^.FData));
..
end.


function TFilterExpr2.PutConstAnsiStr(const Value: AnsiString): Integer;
var
Str: AnsiString;
Buffer: array[0..255] of Byte;
begin
 if Length(Value) >= SizeOf(Buffer) then Str := Copy(Value, 1, SizeOf(Buffer) - 1)
 else Str := Value;
 FDataSet.Translate(PAnsiChar(Str), PAnsiChar(@Buffer), True);
 Result := PutConstNode(ftString, @Buffer, Length(Str) + 1);
end;

function TFilterExpr2.PutConstUnicodeStr(const Value: UnicodeString): Integer;
var buffer: array of word; Len : Integer;
begin
  Len := Length(Value);
 SetLength(buffer, Len + 1);
 buffer[0] := Len * 2;
 if Value <> '' then Move(Value[1], Buffer[1], Len*2);
 Result := PutConstNode(TFieldType(ftUnknown), @buffer[0], (Len+1)*2);
 SetNodeOp(Result, 0, $1007);
end;

0 個意見: