Recent Posts

Pages: [1] 2 3 ... 10
Just one more word on the auto-sizing (including align and all else)...

And it also depends on the parent having "AutoSize = True" or not.

Autosizing, aligning, positioning, .... are all always done immediately. You change the parent => autosize, you change the Top or Height => Autosize (of all others that may depend), you change anchors, or align ....

Unless you use DisableAutoSizing.

So when you have
Code: Pascal  [Select][+][-]
  1.   Self.Parent := AOwner as TWinControl;
  2.   Self.Align := alTop;
  3.   Self.Top := DTop; //High(SmallInt);

And say the Parent has "AutoSize = True"

Setting the parent, will set Top/Left = 0 => because an autosizing parent makes space...

Setting alTop, then makes this the topmost alTop (because Top=0). Actually it could also be the 2nd alTop from the top, as 2 controls would have "Top := 0".
The other panels will got down

"Self.Top = high(smallint)" should however work.... Good question. Though: assuming it is "visible = true". Not sure what happens if it is hidden. Might be skipped.

Though, again, I am not sure what happens with "top := " if align is already set. Yet, if you set it before it depends on the Parent.Autosize.

Beware, above is from distant memory. I probably got some details wrong. But it may be giving some ideas at what to pay attention....
Beginners / Re: ReadFileToString 'raises an exception' - but it doesn't?
« Last post by dsiders on Today at 01:30:00 am »
Code: Text  [Select][+][-]
  1. ... contains a n expanded value ...
Tiny typo: "a n" --> "an"

I noticed that. Already fixed. Thanks.
General / Re: Scaling a "skewed polygon"
« Last post by alpine on Today at 01:26:10 am »
See the attached picture.
My question is should the compiler be accepting "Absolute A" instead of the correct A[index] or
 should this produce an "Error" instead
in addition to what Jamie and Martin already said, the argument of "absolute" is a memory reference and "A" _is_ a memory reference, specifically it is where the array is located in memory, therefore it is _not_ an error.

As long as "absolute" is given a memory reference there is no problem.  You can even use the name of _typed_ constant (because a typed constant is actually a variable, thus a memory reference.)

Not necessary related to your issue, but how many such sub-panels are you talking about?

Because if it is in the hundreds, you might get Windows to freak out. I did once a test with a plain form (non LCL, directly created via Windows API, so everything was Windows API only). I did put around 300 or 400 buttons or panels on that form.  And at some point Windows froze... It' long aga, but IIRC it froze completely (my entire Desktop) for maybe 10 secs. (That was Windows 10, not sure if other Versions do that do, or if it is still like that at all)... I don't recall the exact details, but Windows does have limits...
Code: Pascal  [Select][+][-]
  1.  Self.Align := alTop;
  2.   Self.Top := DTop; //High(SmallInt);

Have you tried swapping those 2 lines?

Having multiple alTop is always a bit dangerous. Afaik/IIRC, They are sorted by whatever "top" position they have before the alTop overrides the position, but then I don't know, if the next one is sorted according to the new Top of the already aligned one.... So you may have to set value to Top that are further out than expected.

The other thing to do is to do a DisableAllAutosing on the parent container before setting them.
Otherwise, if you do more than one, they will keep adjusting while you still are adjusting them => and that ain't no good.

Though I wonder, when you used/tried AnchorSide.Control... Did you remove the alTop then? Because if you didn't, then the alTop may take precedence. Otherwise the AnchorSide would force position (you then need to set the parent control as AnchorSide for Left/Right to have the width being done.

Having seen you access parent.controls[parent.controlcount-1] => Just the obvious remainder: You don't use any "BringToFront" or similar on the panels? Because afaik that changes there order in the list of Controls. (But again, not sure)
"Absolute" is not type safe. And it isn't meant to be afaik.  In fact it is often used as a way to access on variable as something of another type.

Often time, those "type translations" are such that they could be done by typecase (maybe pointer to TObject), but that isn't necessary.

You could have a record "TPoint = record x,y: integer; end". And if you know that "x" is the first thing in memory, and it is right at the start of the record, then you could have an integer variable "absolute" at an variable of type TPoint.

In other words, it just takes the address, and gets whatever is in memory.
so it would then do the same as
Code: Pascal  [Select][+][-]
  1. PInteger(@MyPoint)^

It does the same in your case.

You have a static array, and a static array is not a pointer, it is straight there in memory, like a record would be. So the address of the array "A" and the entry "A[1]" are the same.

Hence it works.
(It wouldn't work with a dynamic array)
General / Re: How can I list all Properties in a Component?
« Last post by Aruna on Today at 12:57:54 am »
Use unit 'TypInfo' and maybe (when it's ready) 'Rtti'.
and then something like this:
Code: Pascal  [Select][+][-]
  1. var
  2.   Cnt,Lp: ptrint;
  3.   OrdVal: ptrint;
  4.   StrName,StrVal: String;
  5.   FloatVal: Extended;
  6.   PropInfos: PPropList;
  7.   PropInfo: PPropInfo;
  8. begin
  9.   { Find out how many properties we'll be considering and get them }
  10.   Cnt := GetPropList(PTypeInfo(Self.ClassInfo),PropInfos);
  11.   try
  12.     for Lp:= 0 to Cnt - 1 do begin { Loop through all the selected properties }
  13.       PropInfo:= PropInfos^[Lp];
  14.       StrName:= PropInfo^.Name;
  15.       { Check the general type of the property and read/write it in an appropriate way }
  16.       case PropInfo^.PropType^.Kind of
  17.         tkInt64,tkInteger,tkChar,tkEnumeration,tkBool,tkQWord,
  18.         tkSet,tkClass,tkWChar: begin
  19.                                  OrdVal:= GetOrdProp(Self,PropInfo);
  20.                                  Ini.WriteInt64('General',StrName,OrdVal);
  21.                                end; { ordinal types }
  22.         tkFloat:               begin
  23.                                  FloatVal:= GetFloatProp(Self,PropInfo);
  24.                                  Ini.WriteFloat('General',StrName,FloatVal);
  25.                                end; { floating point types }
  26.         tkWString,tkLString,tkAString,
  27.         tkString:              begin
  28.                                  { Avoid copying 'Name' - components must have unique names }
  29. //                                 if UpperCase(PropInfo^.Name) = 'NAME' then Continue;
  30.                                  StrVal:= GetStrProp(Self,PropInfo);
  31.                                  Ini.WriteString('General',StrName,StrVal);
  32.                                end; { string types }
  33.         else ;
  34.       end;
  35.     end;
  36.   finally
  37.     FreeMem(PropInfos,Cnt*sizeof(pointer)); { typinfo allocates like this: getmem(PropList,result*sizeof(pointer)); }
  38.   end;
  39.   Ini.UpdateFile; { persist to disk }
  40.   Result:= true;;
  41. end;
The above example, writes the properties to an ini-file, but I think you'll get the gist of it...
Regards Benny
Thank you very much Benny. The code was way over my head right now. So I plugged it into chatGPT and asked for a breakdown. I was quite pleasantly surprised by the result. See below for what chatGPT broke down the code into. I would still like to see some code that does not use self and does not write to a ini file but simply gets the properties then lists them in a memoedit if possible. I am includinmg the breakdown from chatGPT because I sincerely think it can help other newbies understand somewhat what the code does. I was quite frankly lost until I asked chatGPT for help  :D

Breakdown of the Code:

    Variable Declarations:
        Cnt, Lp: ptrint;: Variables to hold counts and loop indices.
        OrdVal: ptrint;: Holds integer/ordinal property values.
        StrName, StrVal: String;: Hold property names and string values.
        FloatVal: Extended;: Holds floating-point property values.
        PropInfos: PPropList;: Pointer to an array of PPropInfo.
        PropInfo: PPropInfo;: Pointer to a TPropInfo structure.

    Getting Property Information:
        Cnt := GetPropList(PTypeInfo(Self.ClassInfo), PropInfos);:
            Retrieves a list of properties (PropInfos) for the current object (Self).
            Self.ClassInfo provides type information about the class of Self.
            GetPropList fills PropInfos with pointers to TPropInfo structures.
            Cnt holds the number of properties found.

    Iterating through Properties:
        for Lp := 0 to Cnt - 1 do begin ... end;:
            Iterates through each property in PropInfos.

    Processing Each Property:
        PropInfo := PropInfos^[Lp];: Gets the TPropInfo structure for the current property.
        StrName := PropInfo^.Name;: Retrieves the name of the property.

    Switch Statement (case):
        case PropInfo^.PropType^.Kind of ... end;:
            Checks the type (Kind) of the property.

    Handling Different Property Types:

        Ordinal Types (tkInt64, tkInteger, tkChar, tkEnumeration, tkBool, tkQWord, tkSet, tkClass, tkWChar):
            Uses GetOrdProp to retrieve the ordinal value (OrdVal) and writes it to an INI file section ('General') using Ini.WriteInt64.

        Floating Point Types (tkFloat):
            Uses GetFloatProp to retrieve the floating-point value (FloatVal) and writes it to the INI file section ('General') using Ini.WriteFloat.

        String Types (tkWString, tkLString, tkAString, tkString):
            Uses GetStrProp to retrieve the string value (StrVal) and writes it to the INI file section ('General') using Ini.WriteString.

    Memory Management:
        FreeMem(PropInfos, Cnt * SizeOf(Pointer));:
            Frees memory allocated for PropInfos after processing all properties.

            Persists changes made to the INI file (Ini) to disk.

    Return Value:
        Result := True;: Returns True indicating successful processing.


    TypInfo Unit: The TypInfo unit provides functions (GetPropList, GetOrdProp, GetFloatProp, GetStrProp) for inspecting and manipulating properties of objects at runtime.
    INI File Handling: The code assumes the use of an Ini object (presumably TIniFile or similar) to read from and write to an INI file for persistence.
    Property Types: Different types of properties (ordinal, floating-point, string) are handled differently based on their kind (tk*) using type information retrieved from TPropInfo.
    Error Handling: Error handling (e.g., checking for nil values, ensuring proper property names) is not explicitly shown in this snippet and should be considered for production code.

This code snippet showcases how to dynamically read and write object properties to an INI file based on their type, demonstrating the flexibility of Object Pascal in handling runtime reflection and data persistence tasks. Adjustments can be made based on specific application requirements and property types involved.
LazUtils / Re: LazLogger not writing to file until program exits
« Last post by Martin_fr on Today at 12:52:09 am »
It's probably missing a flush somewhere. You could report this as a bug.

In the meantime, there is a property CloseLogFileBetweenWrites. But it's not on the baseclass, only on the class TLazLoggerFile used in the LazLogger unit.

So if you use the LazLoggerBase unit, to switch off logging, then that does not compile.
what is not correct?

Looks like it's working correctly.

Why would you think otherwise? Maybe it's a different language you come across that does that.

Pages: [1] 2 3 ... 10

TinyPortal © 2005-2018