Leaderboard
Popular Content
Showing content with the highest reputation on 03/27/19 in all areas
-
What to do with unsupported components?
dummzeuch replied to Mike Torrettinni's topic in General Help
I think you found all options. There are no others. I would Kick the person who bought this component without source. (Who was / is an idiot, nobody did that even back when Delphi 7 was new.) Suggest not updating to Delphi 10.3 but 10.2 (which will be rejected) Go with the DLL solution. -
TJson - Strip TDateTime property where value is 0?
Uwe Raabe replied to Lars Fosdal's topic in Network, Cloud and Web
There is a possibility, but it would be difficult to apply that behavior on any TDateTime field to be converted, which could as well be a pretty unwanted side effect. Instead you can put an attribute to each field being treated this way. What you need here are two classes (well, one would do, but the second one simplifies things a lot). The first one is the interceptor: type TSuppressZeroDateInterceptor = class(TJSONInterceptor) public function StringConverter(Data: TObject; Field: string): string; override; procedure StringReverter(Data: TObject; Field: string; Arg: string); override; end; function TSuppressZeroDateInterceptor.StringConverter(Data: TObject; Field: string): string; var ctx: TRTTIContext; date: TDateTime; begin date := ctx.GetType(Data.ClassType).GetField(Field).GetValue(Data).AsType<TDateTime>; if date = 0 then begin result := EmptyStr; end else begin result := DateToISO8601(date, True); end; end; procedure TSuppressZeroDateInterceptor.StringReverter(Data: TObject; Field, Arg: string); var ctx: TRTTIContext; date: TDateTime; begin if Arg.IsEmpty then begin date := 0; end else begin date := ISO8601ToDate(Arg, True); end; ctx.GetType(Data.ClassType).GetField(Field).SetValue(Data, date); end; The second one is a special attribute: type SuppressZeroAttribute = class(JsonReflectAttribute) public constructor Create; end; constructor SuppressZeroAttribute.Create; begin inherited Create(ctString, rtString, TSuppressZeroDateInterceptor); end; Now you can decorate your class fields like this: type TDateClass = class private [SuppressZero] FHasDate: TDateTime; [SuppressZero] FNoDate: TDateTime; public constructor Create; property HasDate: TDateTime read FHasDate write FHasDate; property NoDate: TDateTime read FNoDate write FNoDate; end; As I mentioned earlier, you can omit the new attribute and use the JsonReflectAttribute directly, but that is a bit cumbersome: type TDateClass = class private [JsonReflect(ctString, rtString, TSuppressZeroDateInterceptor)] FHasDate: TDateTime; [JsonReflect(ctString, rtString, TSuppressZeroDateInterceptor)] FNoDate: TDateTime; public constructor Create; property HasDate: TDateTime read FHasDate write FHasDate; property NoDate: TDateTime read FNoDate write FNoDate; end; -
Named pipe failure, multithreading and asynchronous I/O
FPiette replied to FPiette's topic in Windows API
I have done an intensive debug session and found the issue although I don't understand why it works with older Delphi versions. At line 2710, where the server hang, we have the code: Result := GetOverlappedResult(FPipe, FOlapRead, FRcvRead, TRUE); I simply changed the last argument by FALSE like this: Result := GetOverlappedResult(FPipe, FOlapRead, FRcvRead, FALSE); And now it works! That last argument when TRUE tells GetOverlappedResult to wait until completion. If FALSE, it returns immediately with whatever data is available, setting FRcvRead variable with actual number of bytes read. Since we only go to that code line when data is available, because of WaitForMultipleObjects called at line 2939, we can safely don't wait for more data. I will do more testing with the actual - real world - application using that code. In case the issue persist, I will report it here. Thanks to all having participated in this conversation. -- François Piette Embarcadero MVP -
A Curious Inheritance Problem... what pattern solves it?
PeterBelow replied to David Schwartz's topic in RTL and Delphi Object Pascal
Dmitry gave you a possible solution for the specific problem you posted (TDataset descendents). I think this is generally a case for the facade pattern: you extract the functionality the method needs to access to an interface type (or a wrapper base class) and make your divergent descendents implement this interface or provide a factory method for a suitable derived wrapper class instance. The method parameter is then typed as the interface or wrapper base class type. -
Guys, while pulling updates from a remote repo is part of git (e.g. git pull from the command line for example), a "pull request" is not something intrinsically part of git, but something that github institutes, or that we agree between ourselves as developers. It literally is saying to someone else "Please {git} pull from me as I've got something you might want to review/use." It follows that in order for someone else to "pull" changes from you, that you must have some accessible place for them to pull from. Obviously users on the internet won't have access to your local repo on your developer PC, so they cannot pull from there. Nor would you normally be able to push to their repo (or their github repo) if that is where you originally pulled from (unless you're one of the project administrators/owners of course.) There therefore needs to some other repo, that must belong to you and is accessible so that someone else can pull from, that you can also first push to. (Just like there needs to be a shared SVN server, say, if you want another dev to get some changes you've made and are using subversion.) And this is where github comes in. It provides an easy to access place where you can fork and create your own remote repositories (from others) that are therefore just as easily accessible by others too. All that background is to help you understand the following: The normal process for working on github, if you want to contribute changes, is to 1.) Fork the repo of the project you want to contribute to in your github account. This creates a cheap remote repo (think "my own SVN server at github" if that helps) that belongs to you, than you can push to. 2.) Clone this fork (your own copy of this github repo) to your local PC. 3.) Do your work, commit locally. Once totally happy, git push, which obviously goes to your own remote repo (from the fork.) 4.) Now you're a few revisions ahead of the original repo, and you can then tell the original upstream repo maintainers that you'd like them to pull from your repo as you've got changes to fix some issue or whatever. In github, you do this by simply clicking "New Pull request" button in github. Hope that helps! Edit: By the by, if you've previously pulled from someone else's project directly, made some changes and now want to push this somewhere else, it's quite easy to fork the project "after the fact" and then tell git/update that "remote"/"upstream" is now else, to e.g "push" to your fork instead. (It's also possible to have multiple remotes if you want, but I digress...)
-
A Curious Inheritance Problem... what pattern solves it?
David Schwartz replied to David Schwartz's topic in RTL and Delphi Object Pascal
@Lars Fosdal that's great! I'm chuckling because you're using the TxQueryClass as the discriminant. I had not thought of that. Otherwise it's very straightforward. Sweet! -
A Curious Inheritance Problem... what pattern solves it?
Remy Lebeau replied to David Schwartz's topic in RTL and Delphi Object Pascal
If checking for a common interface, like Dmitry showed, and creating wrappers, like Lars mentioned, do not work for you and/or are not options in your case, you can use RTTI instead: uses ..., System.Rtti; procedure Form1.Proc1( aQry : TDataset ); var Ctx: TRttiContext; SQL: TStrings; begin ... aQry.Close; SQL := TStrings(Ctx.GetType(aQry.ClassType).GetProperty('SQL').GetValue(aQry).AsObject); SQL.Text := 'select * from xyz'; aQry.Open; ... end; -
TJson - Strip TDateTime property where value is 0?
RussellW replied to Lars Fosdal's topic in Network, Cloud and Web
Slightly off topic. Using a Date of 0 is fine in certain circumstances but sometimes you might need that actual date rather than meaning that no date is set. Developer Express have a NullDate constant which is -700000 ... very useful -
What to do with unsupported components?
Uwe Raabe replied to Mike Torrettinni's topic in General Help
That is somewhat against the introducing condition ruling that option out in the first place. -
What to do with unsupported components?
Bill Meyer replied to Mike Torrettinni's topic in General Help
Been there, went with a DLL. The component was unsupported, the vendor gone, and no source. As it was an encryption tool, and not easily reverse engineered because of compatibility issues, we had no real choice. Comparable components using the "same" algorithm delivered quite different results. -
TJson - Strip TDateTime property where value is 0?
Uwe Raabe replied to Lars Fosdal's topic in Network, Cloud and Web
You can, but only when creating the TJSONMarshal instance yourself. The convenient class methods ObjectToJsonString and ObjectToJsonObject abstract this away, so by using these methods you lose the flexibility. Actually I prefer registering converters per instance instead of globally, so I think in principle it is done right. It definitely lacks documentation and sometimes I wish they had avoided private methods in favor of protected virtual ones. -
A Curious Inheritance Problem... what pattern solves it?
Dmitry Arefiev replied to David Schwartz's topic in RTL and Delphi Object Pascal
You can do, when both conditions are met: * TOracleDataSet and TgQuery both are inherited from TDataSet * and properly implement IProviderSupport methods: procedure Form1.Proc1( aQry : TDataSet ); begin ... aQry.Close; (aQry as IProviderSupport).PSSetCommandText('select * from xyz'); aQry.Open; ... end; -
I ended up using the following code: constructor Tf_MyForm.Create(_Owner: TComponent); begin inherited; WindowState := wsMinimized; ShowWindow(Handle, SW_SHOWNOACTIVATE); end; So far it seems to work fine.
-
HELP: Decoding of data stored in array of char - RFID tag's
Remy Lebeau replied to CRO_Tomislav's topic in VCL
Remember that PChar is PWideChar in Delphi 2009+, but the DSFIDAndUID data is returning an array of bytes, not characters, so the function should be declared as using PByte, not PChar, for that parameter: Function Inventory(var ComAdr : Byte; var State : Byte; var AFI : Byte; DSFIDAndUID : PByte; var CardNum : Byte; frmComPortindex : Integer): LongInt; stdcall; external 'RR3036.dll'; I would recommend this approach as well. However, do note that the function declaration would have to be changed to accommodate this, eg: Function Inventory(var ComAdr : Byte; var State : Byte; var AFI : Byte; var DSFIDAndUID : TTagBuffer; var CardNum : Byte; frmComPortindex : Integer): LongInt; stdcall; external 'RR3036.dll'; Otherwise, you would have to type-cast the DSFIDAndUID variable when passing it: var DSFIDAndUID : TTagBuffer; Get_UID_RFID_Tag_Data_Status := Inventory(fComAdr, State, AFI, PChar(@DSFIDAndUID), CardNum, frmcomportindex); -
HELP: Decoding of data stored in array of char - RFID tag's
PeterBelow replied to CRO_Tomislav's topic in VCL
From your description the data you get back are not characters, so do not use an array of char, use an array of byte. In fact you should be able to use something like this: type TTagResult = packed record DFSID: byte; case boolean of false: (UIDasBytes: array [0..7] of byte); true: (UID: Uint64); end; TagBuffer = packed array [0..15] of TTagResult; type the DSFIDAndUID parameter of the Inventory function as var DSFIDAndUID : TTagBuffer and you should be able to just pass a variable of type TTagBuffer and get the result back in a digested format.