shineworld 73 Posted July 8 I found an oddity in the "state" field of the OnCustomDrawItem event. Basically instead of reporting the states of the VCL control passed by the related event all possible states are passed there: 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; 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 Append(Result, GetEnumName(LCompType, LState)); // <-- all enums are always set to state python attribute end; In my TreeView, when a node is selected, I've to change to white the font color otherwise text is hard to be sight: Either I completely misunderstood the functionality of that function or there was an oversight. Unfortunately Vcl.ComCtrls TCustomDrawItem is defined as a set with direct enumerators in the set so I didn't find a direct method to do: if CAST_TO_ENUM(LState) in TCustomDrawState then but with a forcing and a pointer you still get something working: 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; I'm not so smart in these things so if some Delphi guru has a better solution I'm ready to fix the code. Best regards. Share this post Link to post
pyscripter 689 Posted July 8 A fix has been applied to P4D. Please check. 1 Share this post Link to post
Remy Lebeau 1392 Posted July 8 4 hours ago, shineworld said: Unfortunately Vcl.ComCtrls TCustomDrawItem is defined as a set with direct enumerators in the set so I didn't find a direct method to do: if CAST_TO_ENUM(LState) in TCustomDrawState then FYI, in Delphi 12 Athens, TCustomDrawState now uses a new enum type TCustomDrawStateItem, so you can cast the values to that type, eg: for LState := LMin to LMax do begin if TCustomDrawStateItem(LState) in ACustomDrawState then Append(Result, GetEnumName(TypeInfo(TCustomDrawStateItem), LState)); end; Share this post Link to post
shineworld 73 Posted July 9 (edited) 14 hours ago, pyscripter said: A fix has been applied to P4D. Please check. New commit fixes the issue and works perfectly. Edited July 9 by shineworld Share this post Link to post