Jump to content

Lars Fosdal

Administrators
  • Content Count

    3504
  • Joined

  • Last visited

  • Days Won

    115

Everything posted by Lars Fosdal

  1. Lars Fosdal

    his control requires version 4.70 or great of COMCTL32.DLL

    What version is your comctl32.dll? Can an ancient version have snuck into your path somewhere?
  2. Lars Fosdal

    August 2019 Roadmap released

    10.4 has "language improvements". Some of the stuff I'd want to see here - although I expect only the two top ones to actually be candidates... - parameterless record constructors - nullable types - proper record constants that are treated as constants - generic support for nullable types - generic constraint for enumerated types so that you can for a Value:T use Ord(Value), Set of T, Value in Set, etc. - generic constraint for number, so that you can use mathematical operators on a value of T - generic record helpers - TArray<T> / record helper for TArray<T> - helper aggregation/overload/scoping so that one helper does not have to replace another - lambda expressions - ternary operator to shorten those lambdas
  3. Lars Fosdal

    August 2019 Roadmap released

    Infradestructure?
  4. Lars Fosdal

    New RoadMap Delphi 2019/2020

    Duplicate of
  5. Lars Fosdal

    TWebBrowser + dynamic JS question

    Are you certain that JS is enabled and triggered on page load? Have you tried the embedded Chrome browser to see if that makes any difference? https://github.com/salvadordf/CEF4Delphi I think your last sentence already is in effect for a large number of sites as it makes harder to crawl content tags and references if they are generated dynamically by JS.
  6. Lars Fosdal

    Relaxed JSON

    I prefer regular Json as defined by Ecmascript ES5 / https://json.org When exchanging data, I prefer rigid formats over flexible formats.
  7. I prefer using thread safe queues aka the mailslot principle. Normally I let my worker threads have an workqueue and a reference to the mainthread responsequeue. I post a task to the workqueue, getting a task ticket, and the background thread posts a response/result package to the responsequeue, marked with that task ticket. I can either poll the response queue with the ticket, or I can have the thread fire off a windows message to the main thread that basically says "check the queue for this task ticket" Benefits: 100% async and isolated. No concurrent access to data. All updates can happen at the leisure of the main thread.
  8. Lars Fosdal

    parsing Google search results

    Although DuckDuckGo does not offer a full cover API, it seems that their DOM is easier to parse which could give you easier access to the data you need - unless you are specifically looking for Google data? https://stackoverflow.com/questions/37012469/duckduckgo-api-getting-search-results It depends a lot on what data you are trying to gather.
  9. Lars Fosdal

    Datasnap server updating error image blob column

    Is there a particular reason that the params are numbered 0, 1, 10 ? On the server side - have you inspected the stream after you fill it from the request? Does the length of the stream match the size of the image?
  10. The admins are fast 🙂
  11. How many of these are spammers?
  12. Lars Fosdal

    FireDAC TFDMetaDataQuery default field value

    Which database? For SQL Server, there is this: https://stackoverflow.com/questions/3817885/sql-server-find-out-default-value-of-a-column-with-a-query
  13. Lars Fosdal

    How best to update from 10.3.1 to 10.3.2?

    If you installed 10.3.1 in your VM with the webinstaller, you can simply download the new webinstaller for 10.3.2 and run it. It will still automatically uninstall the previous version, but if you select to keep the configuration, it will remain configured for 10.3.2. If you installed 10.3.1 in your VM from the ISO image, I recommend uninstalling it before installing the 10.3.2 from either the new ISO image or the new webinstaller. Personally, I always use the webinstaller. /off-topic: Considering the number of new features in 10.3.2, I am a little miffed that you can't have both 10.3.1 and 10.3.2 installed at the same time.
  14. Lars Fosdal

    Generic Command Line Parser for Delphi 10.3.x

    Except for supporting multiple parameters per option, parameters with spaces, default values, as well as the implicit conversion of ints, floats and enumerated types? Help would require declaring each command-line option, and help could include short text, long text, as well as examples. I had to stop somewhere, and since my apps mostly are services or GUI apps, documenting the command line was low on the priority list. As for Version, I suppose there would be as many requirements for what to display (file version, product version, file name, product name, copyright, libs, attributions, etc,) as there are users of the code. Also - how would you handle those for a GUI app? Other extensions could be to say that an option was mandatory, and if it should be a secret parameter that should be included in the help or not. It would be trivial to create a specific TFileNameOption that checked that a filename only contained valid characters. How about a TDateTimeOption? Cross-option validation? All is possible, and you have the source code and permission to change and build on it.
  15. Lars Fosdal

    Generic Command Line Parser for Delphi 10.3.x

    Mine can also quite easily be extended with a short / long description per parameter.
  16. I have a feeling I've asked this question before, but here I go again? Is there a way to declare a constant of type rec that actually is constant? {$WRITEABLECONST OFF} type rec = record a: string; b: string; end; type TestAttribute = class(TCustomAttribute) public r: rec; constructor Create(const ar: rec); end; const rconst:rec = (a:'foo'; b:'bar'); type TTestClass = class private FProp: string; public [Test(rconst)] // [dcc32 Error] E2026 Constant expression expected property Prop: string read FProp write FProp; end;
  17. They are fragile in the respect that you may omit an attribute or enter a valid attribute that is not used by the class, i.e. not valid to use in the specific scope. A valid and appropriate attribute is not really fragile as such.
  18. I already have init code where stuff like decorators, formatters, secondary sorting etc. is set up, so I guess I have to move this here as well - or add another set of constructor overloads to the attribute 😕 or add an extra attribute or two. It would have been so nice being able to inline declare a record as a constant. That goes outside the use with attributes as well. type coordinate = record x,y: Double; end const cp = coordinate(x: 10; y:10); // an actual immutable constant Explicit var p: coordinate := (x: 10; y:10); Inferred: var p := coordinate(x: 10; y:10); p := (x:10; y:10); p := cp;
  19. Lars Fosdal

    VCL component issue

    A notion of a change to the control design interface between D7 and modern Delphi rustles in the back of my head, but I have not done component work in ages....
  20. @Stefan Glienke The snippet below is one more complex of a few hundred GridSets that I have, and I'd like to change the parameterization of every InitField attribute to a structure. How well suited is "the obvious and already proven to work fine solution" in this context? TDeliverySet = class(TGridSet) const DateFmt = 'dd.mm.yyyy'; type TOnHasExternal = reference to function(const aDeliveryId:Integer):Boolean; TFieldSortPosition = class(TFieldEnum<TPSDPositionInGroup>); TFieldPickMethod = class(TFieldEnum<TPSDCustomerOrderPickingMethod>); TFieldTPackPickMethod = class(TFieldEnum<TPSDCustomerOrderTPackPickingMethod>); TRouteKey = record Id: Integer; Count: Integer; end; private function GetRouteKey(const aIndex: Integer; var RouteEntry: TRouteEntry): Integer; function GetShowPickRoutes: Boolean; protected OnHasExternal: TOnHasExternal; PickTPacks: Boolean; Environment: TPSDEnviroment; RouteDictionary: TRouteDictionary; public [GridAutoSize, GridMultiSelect //, GridShowFilters ] [InitField(' ', 20), CustomField] Grouping: TFieldGrouping; [HiddenField, CustomField] SortPositionInRoute: TFieldSortPosition; [HiddenField, CustomField] SortPositionInPickGroup: TFieldSortPosition; [InitField(sfrmPSDExpeditionDGridHeadindRoute, 100), CustomField, DefaultSortField] DisplayRoute: TFieldString; [HiddenField] RouteNo: TFieldString; [HiddenField] RouteDepartureTime: TFieldDateTime; [InitField(sfrmPSDExpeditionDGridHeadindCustomer, 180), CustomField] DisplayCustName: TFieldString; [HiddenField] CustomerNo: TFieldString; [HiddenField] CustomerName: TFieldString; [HiddenField] RefCustomerNo: TFieldString; [HiddenField] RefOrderCustomerName: TFieldString; [InitField(sfrmPSDExpeditionDGridHeadindDelivery, 110)] DeliveryNo: TFieldString; [HiddenField] PickingFinishedTime: TFieldDateTime; [HiddenField] HasOnlyAutoPickedLaterLines: TFieldBoolean; [HiddenField] CompleteTPackCount: TFieldInteger; [HiddenField] LineCountWithSmallPick: TFieldInteger; [HiddenField] PickMethod: TFieldPickMethod; [HiddenField] TPackPickMethod: TFieldTPackPickMethod; [HiddenField] PartlyPickedLineCount: TFieldInteger; [HiddenField] PickedLineCount: TFieldInteger; [InitField(sfrmPSDExpeditionDGridHeadindPickRoute, 60), HiddenField, ToggleField] PickRoutes: TFieldString; [InitField(sfrmPSDExpeditionDGridHeadindRouteSequenceNo, 60)] RouteSequenceNo: TFieldInteger; [InitField(sfrmPSDExpeditionDGridHeadindOrderNo, 80)] OrderNo: TFieldString; [InitField(sfrmPSDExpeditionDGridHeadindLines, 60), CustomField] DisplayLineCount: TFieldString; [HiddenField] LineCount: TFieldInteger; [HiddenField] MissingDPackCount: TFieldInteger; [HiddenField] MissingLineCount: TFieldInteger; [InitField(sfrmPSDExpeditionDGridHeadindGroupe, 60), CustomField, HiddenField(True)] GP: TFieldString; [InitField(sfrmPSDExpeditionDGridHeadindColliPickTo, 80), HiddenField(True)] ColliPickTo: TFieldString; [InitField(sfrmPSDExpeditionDGridHeadindPickDeviationEmpty, 60), HiddenField(True),ToggleField] PickDeviationEmptyCount: TFieldInteger; [HiddenField] PrioritizedArticleDeviation: TFieldBoolean; [InitField(sfrmPSDExpeditionDGridHeadindPickDeviationPickLater, 80), HiddenField(True)] PickDeviationWillBePickedLaterCount: TFieldInteger; [InitField(sfrmPSDExpeditionDGridHeadindReportingErrors, 50), HiddenField(True)] ReportingStatusFailedCount: TFieldInteger; [InitField(sfrmPSDExpeditionDGridHeadindConfirmedCollicount, 70), CustomField, HiddenField,ToggleField] U: TFieldInteger; [HiddenField] ConfirmedColliCount: TFieldInteger; [InitField(sfrmPSDExpeditionDGridHeadindComments, 80), CustomField, HiddenField(True)] K: TFieldInteger; [HiddenField, CustomField] Comment: TFieldString; [HiddenField] PreComment: TFieldString; [HiddenField] PostComment: TFieldString; [InitField(sfrmPSDExpeditionDGridHeadindKPackCount, 40)] KPackCount: TFieldInteger; [InitField(sfrmPSDExpeditionDGridHeadindPrePick, 60), CustomField, HiddenField(True)] Prepick: TFieldString; [HiddenField] IsExport: TFieldBoolean; [HiddenField] RefOrder: TFieldString; [HiddenField] RefOrderRouteNo: TFieldString; [HiddenField] RefOrderRouteSequence: TFieldString; [InitField(sfrmPSDExpeditionDGridHeadindPickers, 60), HiddenField(True)] PickerUserName: TFieldString; [InitField(sfrmPSDExpeditionDGridHeadindEstimatedColliCount, 60), HiddenField(True)] EstimatedColliCount: TFieldDouble; [InitField(sfrmPSDExpeditionDGridHeadindUsedColliSummary, 60), HiddenField(True)] UsedColliSummary: TFieldString; [HiddenField, ToggleField] PickGroupId: TFieldInteger; [HiddenField, ToggleField] HasConsumers: TFieldBoolean; [HiddenField, ToggleField] CustomerOrderId: TFieldInteger; [HiddenField, CustomField] RouteKey: TFieldInteger; [UniqueField, HiddenField, ToggleField] DeliveryId: TFieldInteger; [InitField(sfrmPSDExpeditionDGridHeadindDeliverySummaryId, 'Id', 60), HiddenField, ToggleField] DeliverySummaryId: TFieldInteger; constructor Create; override; destructor Destroy; override; function GetEmptyImageIndex(const aIndex: Integer): Integer; function GetDeliveryNoImageIndex(const aIndex: Integer): Integer; function GetPickedLaterImageIndex(const aIndex: Integer): Integer; function RouteNoImageIndex(const aIndex: Integer): Integer; function GetReportingStatusImageIndex(const aIndex: Integer): Integer; function GetCommentImageIndex(const aIndex: Integer): Integer; function GetCommentHint(const aIndex: Integer):String; function GetDockImageIndex(const aIndex: Integer): Integer; function GetConsumerPickImageIndex(const aIndex:Integer): Integer; function DeliveryRowStyler(const aIndex, aCol: Integer; var Style: TCellStyle):Boolean; procedure DoAfterConvert(const rx: Integer); override; procedure FillRouteSet(const aRouteSet: TRouteSet); procedure UpdateFromDeliverySet(FullSet:TDeliverySet; SelectedRouteKeys: TArrayInteger); /// <summary> Assumes ReleasedTPack and ReleasedPick have been initialized </summary> procedure GetReleaseStates(const aIndex: Integer; out ReleasedTPack, ReleasedPick: TThreeChoices); property ShowPickRoutes:Boolean read GetShowPickRoutes; end;
  21. So many apps today no longer follows the Windows Theme color settings. That annoys me.
  22. That is a good idea, but also somewhat fragile as the Json can't be validated at compile time - or can it... Perhaps a preprocessor would do the trick. Thanks, that is worth looking at.
  23. Lars Fosdal

    Refer to Form Control without using the Form unit?

    TForm.QualifiedClassName would be an option, @Mike Torrettinni
  24. Lars Fosdal

    Restart the same App?

    IME, code doesn't need to be exemplary, as long as it does the job within its operating parameters. Besides, I can always trust you to point out the weaknesses.
  25. BDS doc has degenerated badly over the years, and it is often incomplete, inaccurate, or outdated. Logically, at least in my head, a type const declared with {$WRITEABLECONST OFF} is immutable and hence should be possible to use as any other const. If that is impossible - I should at least be able to follow the pattern of the following const _000000FF = Integer(255) s = String('C'); and declare const r = rec(a:'Foo'; b:'Bar'); but alas... Your workaround works, but presents two problems: - String constants as a reference are fragile. Renaming through the refactoring methods may very well break the link. - I use attributes to parameterize a large number of properties per class, and that would mean a lot of extra code. To me, it is the attribute Create that is the problem. It doesn't behave the same as other class Create ctors. There are probably compiler tech reasons - but valid or not - the behavior is frustrating. program Test; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; type rec = record a: string; b: string; class function Create(const aa,ab: string): rec; static; end; const crec: rec = (a:'X'; b:'Y'); type TTestClass = class private r: rec; public constructor Create(const arec: rec); procedure Test(const arec: rec); end; { TTestClass } constructor TTestClass.Create(const arec: rec); begin r:= aRec; end; procedure TTestClass.Test(const arec: rec); begin r := aRec; end; { rec } class function rec.Create(const aa, ab: string): rec; begin Result.a := aa; Result.b := ab; end; begin var TC := TTestClass.Create(crec); try try TC.Test(crec); // typed constant allowed TC.Test(rec.Create('X','Y')); TC.Test((a:'X'; b:'Y')); // BARF - IMO this needs to be supported TC.Test(rec:(a:'X'; b:'Y')); // BARF except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; finally TC.Free; Write('Press Enter'); Readln; end; end.
×