Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CustomDrawStateToPython return always all TCustomDrawState #478

Closed
shineworld opened this issue Jul 8, 2024 · 4 comments
Closed

CustomDrawStateToPython return always all TCustomDrawState #478

shineworld opened this issue Jul 8, 2024 · 4 comments

Comments

@shineworld
Copy link

The function CustomDrawStateToPython, in WrapVCLComCtrls.pas, instead to place the actual ACustomDrawState in the python object places all possible TCustomDrawStates.

@shineworld shineworld changed the title CustomDrawStateToPython return always all TCustomDrawState and not what passed CustomDrawStateToPython return always all TCustomDrawState Jul 8, 2024
@shineworld
Copy link
Author

shineworld commented Jul 8, 2024

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
Copy link
Author

shineworld commented Jul 8, 2024

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
Copy link
Owner

Can you check with the latest commit?

@shineworld
Copy link
Author

New commit solve the issue and WORKS perfectly !!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants