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
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;