问题
Moving on from this question: Setting a "nullable" property on a .NET object
Thanks to Olivier for his help so far. I am now using this import for the .NET type library: https://github.com/DelphiWorlds/MiscStuff/blob/master/Test/mscorlib_TLB.pas which is based on v4 of the CLR, as opposed to the antiquated version I was using.
..and I now have this code:
procedure TDotNetObject.SetEnumProperty(const APropertyName: string; const AValue: OleVariant; const ATypeName: string; const AIndex: Integer = -1);
var
LRes: HRESULT;
LEnumType, LPropertyType: _Type;
LInvokeFlags: TOleEnum;
LArgs: PSafeArray;
LConvertedValue: OleVariant;
LPropertyInfo: _PropertyInfo;
LIndex: PSafeArray;
LName: WideString;
LResHex: string;
begin
LPropertyType := nil;
LRes := FType.GetProperty(APropertyName, BindingFlags_Instance or BindingFlags_Public or BindingFlags_NonPublic, LPropertyInfo);
if Succeeded(LRes) then
begin
if ATypeName.IsEmpty then
LPropertyInfo.GetType(LPropertyType)
else
LPropertyType := MTDataClr.GetType(ATypeName); // This is a workaround since for obtaining the underlying type
end;
if LPropertyType <> nil then
begin
// Convert the value to the correct type
LEnumType := MTDataClr.GetCoreType('System.Enum');
LInvokeFlags := BindingFlags_InvokeMethod or BindingFlags_Public or BindingFlags_Static;
LArgs := VariantToPSafeArray(VarArrayOf([LPropertyType, AValue]));
if Succeeded(LEnumType.InvokeMember_2('ToObject', LInvokeFlags, nil, Null, LArgs, nil, LConvertedValue)) then
begin
if AIndex >= 0 then
LIndex := VariantToPSafeArray(VarArrayOf([AIndex]))
else
LIndex := nil;
LRes := LPropertyInfo.SetValue(FTarget, LConvertedValue, LIndex);
if not Succeeded(LRes) then
begin
LResHex := IntToHex(LRes);
Sleep(0);
end;
end;
end;
end;
Everything works up until SetValue. LResHex is '80070057' which apparently equates to ERROR_INVALID_PARAMETER.
Any clues as to where I have gone wrong?
来源:https://stackoverflow.com/questions/61514990/setting-an-enum-property-on-a-net-object