Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/VCL/Type Info    [ Add a report in this area ]  
Report #:  29907   Status: Closed
SetPropValue on an enumeration fails with varOleStr variant
Project:  Delphi Build #:  9.0.1882.30496
Version:    9.0 Submitted By:   Piotr Szturmaj
Report Type:  Crash / Data loss / Total failure Date Reported:  6/7/2006 2:52:27 PM
Severity:    Commonly encountered problem Last Updated: 3/20/2012 2:24:39 AM
Platform:    All platforms Internal Tracking #:   240469
Resolution: Fixed (Resolution Comments) Resolved in Build: : 11.0.2565.3426
Duplicate of:  None
Voting and Rating
Overall Rating: (3 Total Ratings)
5.00 out of 5
Total Votes: None
Description
Calling SetPropValue with WideString as Value fails on enumerated properties; See Steps
Steps to Reproduce:
Open, build and run the attached project
Press Button labeled "String"
No error
Press Button labeled "WideString"
Error occurs
The only differenece between a and b is that one is a string and the other is a widestring

<sysop>
Original Steps:
</sysop>
1. Add TMemo and TButton to form
2. Add TypInfo to uses clause
3. Call SetPropValue(Memo1, 'Align', WideString('alClient')); in Button1Click

exp: should set align to alClient
act:

---------------------------
Debugger Exception Notification
---------------------------
Project Project2.exe raised exception class EVariantTypeCastError with message 'Could not convert variant of type (OleStr) into type (Double)'.
---------------------------
Break   Continue   Help  
---------------------------
Workarounds
1. Open TypInfo.pas and find procedure:

procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);

around line 675 there is:

tkEnumeration:
  if VarType(Value) = varString then

should be:

tkEnumeration:
  if VarIsStr(Value) then
  // checks for varString and varOleStr(widestrings)

Alternatively use this helper method:

procedure SetPropValue(Instance: TObject; const PropName: string;
  const Value: Variant);
begin
  if PropIsType(Instance, PropName, tkEnumeration) and
    (VarType(Value) = varOleStr) then
    TypInfo.SetPropValue(Instance, PropName, AnsiString(Value))
  else
    TypInfo.SetPropValue(Instance, PropName, Value);
end;
Attachment
qc29907.zip
Comments

Sebastian Modersohn at 6/7/2006 3:03:06 PM -
I can reproduce this with BDS2006 Upd 2. I've slightly modified your steps to mention the actual error message etc.

Piotr Szturmaj at 6/7/2006 3:11:35 PM -
Thanks, I'm using this helper procedure to avoid this bug:

procedure SetPropValue(Instance: TObject; const PropName: string;
  const Value: Variant);
begin
  if PropIsType(Instance, PropName, tkEnumeration) and
    (VarType(Value) = varOleStr) then
    TypInfo.SetPropValue(Instance, PropName, AnsiString(Value))
  else
    TypInfo.SetPropValue(Instance, PropName, Value);
end;

Sebastian Modersohn at 6/8/2006 3:51:31 AM -
I've added your helper method to the workaround.

David Dean at 7/17/2006 12:10:02 PM -
I have uploaded a new project to demonstrate this report.
It should better explain why this isn't a Test Case error

Server Response from: ETNACODE01