CustomDrawStateToPython return always all TCustomDrawState
shineworld opened this issue · 4 comments
shineworld commented
The function CustomDrawStateToPython, in WrapVCLComCtrls.pas, instead to place the actual ACustomDrawState in the python object places all possible TCustomDrawStates.
shineworld commented
To solve it I had to do a "cobbler" since the TCustomDrawState set is built directly with enumerators and I don't know how else to do it.
function CustomDrawStateToPython(const ACustomDrawState: TCustomDrawState): PPyObject;
procedure Append(const AList: PPyObject; const AString: string);
var
LItem: PPyObject;
begin
with GetPythonEngine do begin
LItem := PyUnicodeFromString(AString);
PyList_Append(AList, LItem);
Py_XDecRef(LItem);
end;
end;
var
LCompType: PTypeInfo;
LMin: integer;
LMax: integer;
LState: integer;
type
TCustomDrawStateEnums = (
cdsSelected, cdsGrayed, cdsDisabled, cdsChecked,
cdsFocused, cdsDefault, cdsHot, cdsMarked, cdsIndeterminate,
cdsShowKeyboardCues, cdsNearHot, cdsOtherSideHot, cdsDropHilited
);
TCustomDrawStateSet = set of TCustomDrawStateEnums;
begin
Result := GetPythonEngine().PyList_New(0);
LCompType := GetTypeData(TypeInfo(TCustomDrawState)).CompType^;
LMin := LCompType^.TypeData^.MinValue;
LMax := LCompType^.TypeData^.MaxValue;
for LState := LMin to LMax do
begin
if TCustomDrawStateEnums(LState) in TCustomDrawStateSet(ACustomDrawState) then
Append(Result, GetEnumName(LCompType, LState));
end;
end;
I ask help to Delphi guru...
shineworld commented
Another, I think, very "bad" solution which does not require a re-definition of enum and set could be:
function CustomDrawStateToPython(const ACustomDrawState: TCustomDrawState): PPyObject;
procedure Append(const AList: PPyObject; const AString: string);
var
LItem: PPyObject;
begin
with GetPythonEngine do begin
LItem := PyUnicodeFromString(AString);
PyList_Append(AList, LItem);
Py_XDecRef(LItem);
end;
end;
function IsBitSet(Index: Integer; State: TCustomDrawState): Boolean;
var
P: PByte;
begin
if (Index < 0) or (Index >= SizeOf(TCustomDrawState) * 8) then Exit(False);
P := @State;
Result := (P^ and (1 shl Index)) <> 0;
end;
var
LCompType: PTypeInfo;
LMin: integer;
LMax: integer;
LState: integer;
begin
Result := GetPythonEngine().PyList_New(0);
LCompType := GetTypeData(TypeInfo(TCustomDrawState)).CompType^;
LMin := LCompType^.TypeData^.MinValue;
LMax := LCompType^.TypeData^.MaxValue;
for LState := LMin to LMax do
begin
if IsBitSet(LState, ACustomDrawState) then
Append(Result, GetEnumName(LCompType, LState));
end;
end;
Unfortunately in Vcl.ComCtrls TCustomDrawItem is defined as:
TCustomDrawState = set of (cdsSelected, cdsGrayed, cdsDisabled, cdsChecked,
cdsFocused, cdsDefault, cdsHot, cdsMarked, cdsIndeterminate,
cdsShowKeyboardCues, cdsNearHot, cdsOtherSideHot, cdsDropHilited);
and not as:
TCustomDrawStateEnum = set of (cdsSelected, cdsGrayed, cdsDisabled, cdsChecked,
cdsFocused, cdsDefault, cdsHot, cdsMarked, cdsIndeterminate,
cdsShowKeyboardCues, cdsNearHot, cdsOtherSideHot, cdsDropHilited);
TCustomDrawState = set TCustomDrawStateEnum,
which do not permits a simple:
for LState := LMin to LMax do
begin
if TCustomDrawItemEnum(LState) in ACustomDrawState then
Append(Result, GetEnumName(LCompType, LState));
end;
pyscripter commented
Can you check with the latest commit?
shineworld commented
New commit solve the issue and WORKS perfectly !!!!