-
Content Count
3416 -
Joined
-
Last visited
-
Days Won
113
Everything posted by Lars Fosdal
-
How to manage defined list values
Lars Fosdal replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
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; -
@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.
-
UDP is per definition not reliable.
-
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.
-
Are you using the appropriate code page for your ansistring? Can you give an example of what goes wrong, character-wise?
-
ah no - dang - I missed that it was Android. Moved the post again.
-
No worries. I moved it to VCL. What if you try: SendMessage(Memo1.Handle, EM_SCROLLCARET, 0, 0); instead of the goto/scrollto ?
-
Is there any difference in behaviour if you SetFocus GoToTextBegin ScrollToTop instead? Can you reproduce the problem in a minimal app?
-
Pointers... loops...
Lars Fosdal replied to Sonjli's topic in Algorithms, Data Structures and Class Design
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. -
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.
-
TJson - Strip TDateTime property where value is 0?
Lars Fosdal posted a topic in Network, Cloud and Web
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? -
TJson - Strip TDateTime property where value is 0?
Lars Fosdal replied to Lars Fosdal's topic in Network, Cloud and Web
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. -
TJson - Strip TDateTime property where value is 0?
Lars Fosdal replied to Lars Fosdal's topic in Network, Cloud and Web
@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 -
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.
-
Parsing Google Search Results redux
Lars Fosdal replied to David Schwartz's topic in Network, Cloud and Web
I've been wondering about those... Where do I download/install these? Can't see them in GetIt. -
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.
-
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.
-
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.
-
Interesting article about dying languages
Lars Fosdal replied to David Schwartz's topic in General Help
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 😉 -
Live bindings were dead to me after a short test. Fragile and slow was not a winning combo.
-
TArray vs TList with VirtualStringTree
Lars Fosdal replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
It probably disappeared when they introduced TListHelper. GetList returns arrayofT(FListHelper.FItems); -
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.
-
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.
-
Interesting article about dying languages
Lars Fosdal replied to David Schwartz's topic in General Help
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. -
Add a system-menu item to all applications?
Lars Fosdal replied to PeterPanettone's topic in Windows API
Adulthood is overrated.