Jump to content

Lars Fosdal

Administrators
  • Content Count

    3416
  • Joined

  • Last visited

  • Days Won

    113

Everything posted by Lars Fosdal

  1. Lars Fosdal

    How to manage defined list values

    I prefer record helpers, combined with the const arrays. I really wish I could make generic record helpers for arrays, though 😕 type TProjectType = (ptMain, ptSub, ptExternalDev, ptInternalDev); TProjectTypeHelper = record helper for TProjectType private const cProjDefValues: array[TProjectType] of string = ('main_proj', 'sub_proj', 'dev_ext', 'dev_int'); cProjCaptions: array[TProjectType] of string = ('Main Project', 'Sub Project', 'External Dev Project', 'Internal Dev Project'); public class function DefValueOf(const aProjectType: TProjectType): string; static; class function CaptionOf(const aProjectType: TProjectType): string; static; function DefValue: string; function Caption: string; end; implementation { TProjectTypeHelper } function TProjectTypeHelper.Caption: string; begin Result := CaptionOf(Self); end; class function TProjectTypeHelper.CaptionOf(const aProjectType: TProjectType): string; begin Result := cProjCaptions[aProjectType]; end; function TProjectTypeHelper.DefValue: string; begin Result := DefValueOf(Self); end; class function TProjectTypeHelper.DefValueOf(const aProjectType: TProjectType): string; begin Result := cProjDefValues[aProjectType]; end; The class functions could also be case statements - but the array[type] ensures you have values for all. The weak spot here is if you insert a value in the constant list, or reorder values - without doing the same for the strings. Or you can use class vars - which would make it easier to load up different languages at runtime, if so needed. type TProjectType = (ptMain, ptSub, ptExternalDev, ptInternalDev); TProjectTypeHelper = record helper for TProjectType private class var cProjDefValues: array[TProjectType] of string; cProjCaptions: array[TProjectType] of string; public class procedure InitHelper; static; class function DefValueOf(const aProjectType: TProjectType): string; static; class function CaptionOf(const aProjectType: TProjectType): string; static; function DefValue: string; function Caption: string; end; implementation { TProjectTypeHelper } function TProjectTypeHelper.Caption: string; begin Result := CaptionOf(Self); end; class function TProjectTypeHelper.CaptionOf(const aProjectType: TProjectType): string; begin Result := cProjCaptions[aProjectType]; end; function TProjectTypeHelper.DefValue: string; begin Result := DefValueOf(Self); end; class function TProjectTypeHelper.DefValueOf(const aProjectType: TProjectType): string; begin Result := cProjDefValues[aProjectType]; end; class procedure TProjectTypeHelper.InitHelper; begin cProjDefValues[ptMain] := 'main_proj'; cProjCaptions [ptMain] := 'Main Project'; cProjDefValues[ptSub] := 'sub_proj'; cProjCaptions [ptSub] := 'Sub Project'; cProjDefValues[ptExternalDev] := 'dev_ext'; cProjCaptions [ptExternalDev] := 'External Dev Project'; cProjDefValues[ptInternalDev] := 'dev_int'; cProjCaptions [ptInternalDev] := 'Internal Dev Project'; end;
  2. Lars Fosdal

    Delphi 5 to Delphi 10.1

    @Markus Kinzler - What I meant is that in UDP, there is no mechanism the ensures that the packet reaches its destination, nor is there a mechanism that allows the recipient to discover that a packet has gone missing. As you say, all of that would have to be implemented as a protocol on top of UDP. When it comes to the content, I actually don't know if UDP ensures that the content of a delivered package is guaranteed to be intact? I would tend to assume so, but I haven't actually checked.
  3. Lars Fosdal

    Delphi 5 to Delphi 10.1

    UDP is per definition not reliable.
  4. Lars Fosdal

    Firebird 3 and SP in Object Pascal

    We use a couple of C# assemblies - mostly for being able to break down stuff like bar code scan strings into AIs, or other forms of string analysis, validation (checksums) or manipulation. It is a bit cumbersome, tbh, but it is a lot more efficient than trying to do the same stuff in T-SQL.
  5. Lars Fosdal

    Delphi 5 to Delphi 10.1

    Are you using the appropriate code page for your ansistring? Can you give an example of what goes wrong, character-wise?
  6. Lars Fosdal

    Memo scrolling to the bottom ... sometimes

    ah no - dang - I missed that it was Android. Moved the post again.
  7. Lars Fosdal

    Memo scrolling to the bottom ... sometimes

    No worries. I moved it to VCL. What if you try: SendMessage(Memo1.Handle, EM_SCROLLCARET, 0, 0); instead of the goto/scrollto ?
  8. Lars Fosdal

    Memo scrolling to the bottom ... sometimes

    Is there any difference in behaviour if you SetFocus GoToTextBegin ScrollToTop instead? Can you reproduce the problem in a minimal app?
  9. Edit: I rewrote this on my blog: https://larsfosdal.blog/2019/10/31/demystifying-pointers-in-delphi/ Having a general understanding of how memory and addressing works, helps a bit for pointers. Learning assembler gives you that knowledge, but there are simpler ways to think about it. A pointer is a memory location that contains the address to the actual data you want Think of a street with houses. Make a list of the houses and their addresses. This is a list of pointers. Each pointer leads to the actual house it refers to. As you move through the list and follow each pointer, you can visit each house. Street of houses (i.e. your blocks of data, 1Kb each) 10k 11k 12k 13k 14K +------------+------------+------------+------------+------------+ |Apple |Pear | |Banana |Orange | | H1 | H2 | | H3 | H4 | | | | | | | +------------+------------+------------+------------+------------+ Your list of addresses (aka 4 byte pointers) is stored at memory address 100k var ptrlist: array[0..3] of pointer; assuming the list has been initialized with the correct addresses ptrlist[0] 100k contains 10k ptrlist[1] 100k+4 contains 11k ptrlist[2] 100k+8 contains 13k ptrlist[3] 100k+12 contains 14k for var ix := 0 to Length(ptrlist) - 1 do begin here, ptrlist[ix] = 10k,11k,13k,14k, and ptrlist[ix]^ = whatever value that is stored in the respective house the pointer addresses f.x. ptrlist[1] contains 11k (and that value is stored at 100k+4, and ptrlist[1]^ points to 'Pear', i.e. whatever is stored from address 11k Why the empty house? To exemplify that your list of pointers may be a consecutive array or linked list, but the data each pointer points to does not necessarily need to be consecutive. Now, if you address ptrlist[4] - you are out of bounds on the pointer list, and if you are so "lucky" that the address @ptrlist[4] (which is 100k+16) is not inaccesible, then ptrlist[4]^ will point you to whatever random value that pointer contains,, and most likely give you an access violation, or for sure - point you to data you are not meant to visit.
  10. I have a class type that I call a GridSet, and I use RTTI to match object prop names with DB field names (and attributes for overrides) for multi-row datasets, I build a list of property setters that are ordered the way the fields exist in the DB, for all the fields that exist both in the data set and the object and then I simply loop that list row by row when loading the dataset. I also have an attribute driven variation of filling a GridSet that builds the field definitions dynamically from the DataSet - so that I basically can fill the GridSet from any query, and display it in my GridView class, which attaches to a TAdvStringGrid and sets up the grid purely in code with the various event handlers for sorting and filtering. Hence I can show the result of any query in a grid with one line of code - no visual design required. The benefit of declaring the fields in a gridset, is that I can specify nicer titles, max widths, hints, etc.
  11. Consider this pseudo code uses Rest.Json; TDateClass = class private FHasDate: TDateTime; FNoDate: TDateTIme; public constructor Create; property HasDate: TDateTime read FHasDate write FHasDate; property NoDate: TDateTime read FNoDate write FNoDate; end; constructor TDateClass.Create; begin HasDate := Now; NoDate := 0; end; var Json: String; DateClass: TDateClass; begin DateClass := TDateClass.Create; Json := TJson.ObjectToJsonString(Self, [joIgnoreEmptyStrings, joIgnoreEmptyArrays, joDateIsUTC, joDateFormatISO8601]); which results in the Json string looking like { "HasDate":"2019-02-14T06:09:00.000Z", "NoDate":"1899-12-30T00:00:00.000Z", } while the ideal result would be { "HasDate":"2019-02-14T06:09:00.000Z", } Q:Is there a way to make TDateTime properties with a zero value be output as an empty string - and hence be stripped?
  12. I guess we've avoided the problem since we only have used Zulu timestamps. "departureDate":"2019-10-28T06:00:00.000Z", The problem is at the bottom of procedure DecodeISO8601Time in System.DateUtils- That is where the assumption is made that there will always be a time separator if there is a minutes section AHourOffset := StrToInt(LOffsetSign + GetNextDTComp(P, PE, InvOffset, TimeString, 2)); AMinuteOffset:= StrToInt(LOffsetSign + GetNextDTComp(P, PE, '00', STimeSeparator, True, True, InvOffset, TimeString, 2)); Please make a QP.
  13. @Attilla, from the theorist side if a time zome colon is mandatory in a ISO8601 date, then the problem is really that php API, isn't it? While if a colon is optional, the Delphi implementation of the conversion seems lacking, hence a QP would be a starting point. From the more practical side - Is using class based Json conversion out of the question? - Would pre-processing be an option to correct for the format deviation, f.x. by reg.exp searching for the dddd-dd-ddTdd:dd:dd+dddd and injecting the missing colon
  14. Lars Fosdal

    SetFocus issue

    Is it just me, or does it seem to be slightly different behavior for Focus and BringToFront in Windows 10 1809 and later? I've had several experiences with Application modal windows popping up behind the main window, and it has not only been my own Delphi apps. Starting a Delphi App in the IDE for debugging, would leave the app running behind the BDS now and then. I've had MSSQL Server Management Studio 17.x become unusable with a popup locked behind its main window when left running overnight, on several occasions.
  15. Lars Fosdal

    Parsing Google Search Results redux

    I've been wondering about those... Where do I download/install these? Can't see them in GetIt.
  16. Lars Fosdal

    HEIC library

    Sorry, no idea. This was courtesy of Google search, but judging from the description, it should be a reasonably standard plugin for WIC, so the indentifiers should be discoverable through the WIC interfacees.
  17. Lars Fosdal

    HEIC library

    https://www.copytrans.net/copytransheic/ installs a driver for Windows Imaging Component that allows conversion with WIC and is, as far as I can tell, free.
  18. Lars Fosdal

    LiveBinding at runtime

    We already had something else doing the job for us, so we had no need to transition to it. The fragile bit can be only be eliminated when we get a NameOf compiler magic function.
  19. Lars Fosdal

    Interesting article about dying languages

    Jack of all trades, master of none - seems to be my modus operandi, which is more or less the same as sucking equally at everything 😉
  20. Lars Fosdal

    LiveBinding at runtime

    Live bindings were dead to me after a short test. Fragile and slow was not a winning combo.
  21. It probably disappeared when they introduced TListHelper. GetList returns arrayofT(FListHelper.FItems);
  22. Lars Fosdal

    Azure Key Vault support

    Feel free to vote for https://quality.embarcadero.com/browse/RSP-26400 if you need Azure Key Vault support for your Delphi/C++Builder projects.
  23. Lars Fosdal

    How to get Linux installed?

    It is truly tragic that Linux is not available for the Pro SKU. It should even have been in the Community version IMO. Imagine the potential plethora of code coming from open source projects.
  24. Lars Fosdal

    Interesting article about dying languages

    https://larsfosdal.blog/2019/10/10/most-popular-programming-languages-1965-2019/ Stumbled on a nice video showing the rise and fall of Pascal and Delphi. That said, like Cobol, Delphi will take a looong time disappearing.
  25. Lars Fosdal

    Add a system-menu item to all applications?

    Adulthood is overrated.
×