Leaderboard
Popular Content
Showing content with the highest reputation on 03/28/19 in all areas
-
What to do with unsupported components?
Edwin Yip replied to Mike Torrettinni's topic in General Help
DLL seems to be the way to go. This reminds me the now on going discussion about not to buy a library without source in the other thread which announced a new commercial SVG library library. -
What to do with unsupported components?
Remy Lebeau replied to Mike Torrettinni's topic in General Help
You could always embed the DLL in the EXE's resources and then extract it at runtime before using its functions. That way, the DLL does not have to be deployed separately. -
What to do with unsupported components?
dummzeuch replied to Mike Torrettinni's topic in General Help
Embedding a DLL can be done without extracting it (at least for some DLLs for 32 bit Windows programs). But I am not sure whether this would work with that DLL. My dzlib contains a unit for that: u_dzRessourceDllLoader. -
TJson - Strip TDateTime property where value is 0?
Lars Fosdal replied to Lars Fosdal's topic in Network, Cloud and Web
I wonder when we will get nullable types. That will be awesome for DB related code. -
What to do with unsupported components?
Mike Torrettinni replied to Mike Torrettinni's topic in General Help
I think they are realizing the dll option is not that bad. -
A Curious Inheritance Problem... what pattern solves it?
Remy Lebeau replied to David Schwartz's topic in RTL and Delphi Object Pascal
I would suggest having the wrapper expose access to the actual TStrings object for the SQL, instead of getting/setting the SQL as just a String. It is usually beneficial to be able to build up SQL queries, especially long/complex queries, in multiple pieces, which can be tricky/inefficient as a single string. type TxQuery<T: TDataSet> = class abstract private FiQuery: T; protected function GetSQL: TStrings; virtual; abstract; function GetDataSet: TDataSet; virtual; abstract; property iQuery: T read FiQuery write FiQuery; public procedure Execute; virtual; abstract; property SQL: TStrings read GetSQL; property DataSet: TDataSet read GetDataSet; end TxQueryClass = class of TxQuery; TxOraQuery = class TxQuery<TOracleDataset> protected function GetSQL: TStrings; override; function GetDataSet: TDataSet; override; end; TxPgQuery = class TxQuery<TPgQuery> protected function GetSQL: string; override; function GetDataSet: TDataSet; override; end; function TxOraQuery.GetSQL: TStrings; begin Result := iQuery.SQL; end; function TxOraQuery.GetDataSet: TDataSet; begin Result := iQuery.DataSet; end; function TxPgQuery.GetSQL: TStrings; begin Result := iQuery.SQL; end; function TxPgQuery.GetDataSet: TDataSet; begin Result := iQuery.DataSet; end; type TForm1 = class(TForm) var QryClass: TxQueryClass; procedure FormCreate; procedure TestQuery(aQuery: TxQuery; aSQL: string); end; procedure TForm1.FormCreate; begin if Config = Pg then QryClass := TxPgQuery else QryClass := TxOraQuery; end; procedure TForm1.TestQuery; var Qry: TxQuery; SQL: string; begin Qry := QryClass.Create; Proc1(Qry, aSQL); end; procedure TForm1.Proc1(aQuery: TxQuery; aSQL: string); begin aQuery.DataSet.Close; aQuery.SQL.Text := aSQL; aQuery.DataSet.Open; ... end; -
TJson - Strip TDateTime property where value is 0?
Uwe Raabe replied to Lars Fosdal's topic in Network, Cloud and Web
Indeed, when you ask for the date you will get 0 even when the DB field is NULL: function TDateTimeField.GetAsDateTime: TDateTime; begin if not GetValue(Result) then Result := 0; end; Unfortunately you cannot distinguish that from a valid date (unless you narrow the range for those). I would prefer when the above function would actually return a non-valid date in that case, but I guess that would break compatibility. Meanwhile, the trick is not to ask for a date in the first place when the field is NULL. To store such an invalid date into a TDateTime field the NullDate approach is quite valid. Actually any value below -DateDelta ( = 693594) would do, as it results in a non-positive Date part of a TTimeStamp and makes DecodeDateFully return false. The chosen value of NullDate = -700000 ist just a bit easier to remember. -
Remote Desktop with ICS
Remy Lebeau replied to jbWishmaster's topic in ICS - Internet Component Suite
Just curious, why are you converting from Indy to ICS? Are you having a problem with Indy? -
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 -
What to do with unsupported components?
Bill Meyer replied to Mike Torrettinni's topic in General Help
In my case, it was worse. All evidence suggested that we had no source because we (probably) had no license. -
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. -
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. -
A Curious Inheritance Problem... what pattern solves it?
Lars Fosdal replied to David Schwartz's topic in RTL and Delphi Object Pascal
We chose to do wrapper classes that further abstract the actual database types away from our code. Hence, in our code, there is no difference between running a BDE wrapped ADO connection and a FireDAC connection. Those classes use old school encapsulation to hide such differences from our code with very little overhead. -
OK, so what I originally wrote was basically correct: Fork the original repository to create your own copy of it on GitHub Create a local clone of your own fork using e.g. GitHub Desktop Make the change. Commit it Push it to GitHub On the repository's website create a pull request. I just did that, let's see what happens. https://github.com/project-jedi/jvcl/pull/74 Thanks everybody who helped. The crucial step is to first *fork* the original repository on GitHub rather than clone it. (OK, maybe I am not to stupid to use git after all.)
-
Having worked in Delphi since D1, and twice having had to deal with the issue of components without source, I would say that the value without source is essentially zero, as the risk factor is not worth any benefits in the short term. So I would suggest that the question as you ask it is simply wrong.
-
I have wanted this feature until long time ago. Thanks for advance.
-
Lockfree approach on a Single reader, Multiple Writer queue
Primož Gabrijelčič replied to kokoslolos's topic in Algorithms, Data Structures and Class Design
BTW, OmniThreadLibrary's TOmniBoundedQueue was implemented in 2008. Then we needed about a year to find few weird boundary conditions where the code would crash and fix them. After that the queue was working perfectly until 2018, when I found a race condition which caused the queue to say "sorry, can't add an item, the queue is full", when the queue has actually just become empty. Nobody noticed the problem in the meantime, we all thought the code is perfect, and the unit/stress test did not test for this specific scenario ... Writing lock-free structures is harder than you think. (Applies to me, too.) -
Lockfree approach on a Single reader, Multiple Writer queue
Primož Gabrijelčič replied to kokoslolos's topic in Algorithms, Data Structures and Class Design
There's a Delphi version, too: http://deadlockempire.4delphi.com/delphi/ -
What is the fastest way to check if a file exists?
KodeZwerg replied to dummzeuch's topic in Windows API
uses ActiveX, Shlobj, IOUtils; function TestFileExists( Filename: String ): Boolean; begin Result := FileExists( Filename ); end; type TParseDisplayName = function(pszPath: PWideChar; pbc: IBindCtx; var pidl: PItemIDList; sfgaoIn: ULong; var psfgaoOut: ULong): HResult; stdcall; var SHParseDisplayName: TParseDisplayName; SHELL32DLLHandle : THandle; function TestPIDL( Filename: String ): PItemIdList; var PIDL: PItemIdList; Attrs: DWORD; begin Result := nil; try CoInitialize(nil); if ( SHParseDisplayName( PChar( Filename ), nil, PIDL, 0, Attrs ) = S_OK ) then if Assigned( PIDL ) then Result := PIDL; finally CoUnInitialize(); end; end; function TestCreateFile( Filename: String ): Boolean; var hFile : THandle; begin Result := False; hFile := CreateFile(PChar( Filename ), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if hFile <> INVALID_HANDLE_VALUE then begin Result := True; CloseHandle(hFile); end; end; function TestGetFileAtrributes( Filename: String ): Boolean; var i: Cardinal; begin Result := False; i := GetFileAttributes( PChar( Filename ) ); if i <> INVALID_FILE_ATTRIBUTES then begin Result := True; end; end; function TestFileAge( Filename: String ): Boolean; var DT: TDateTime; begin Result := False; if FileAge( Filename, DT ) then begin Result := True; end; end; function TestFileGetAttr( Filename: String ): Boolean; begin Result := False; if FileGetAttr( Filename ) <> 0 then begin Result := True; end; end; function TestTFile( Filename: String ): Boolean; begin Result := False; if TFile.Exists( Filename ) then begin Result := True; end; end; function TestFindFirst( Filename: String ): Boolean; var sr: TSearchRec; begin Result := False; if FindFirst( Filename, faAnyFile, sr ) = 0 then begin Result := True; end; FindClose(sr); end; procedure TForm1.btnDoJobClick(Sender: TObject); var Start, Stop, Frequency: Int64; Filename: String; i: Integer; Max: Integer; begin Filename := edFilename.Text; try Max := StrToInt( edLoops.Text ); except Max := 1000; edLoops.Text := IntToStr( Max ); end; Memo1.Clear; (* if FileExists( Filename ) then Memo1.Lines.Add( 'File located/cached, begin testing.' ) else begin Memo1.Lines.Add( 'File not found. Test canceled.' ); Exit; end; *) Memo1.Lines.Add( 'Begin Test #1: FileExists (' + IntToStr( Max ) + ' repeats)' ); QueryPerformanceFrequency(Frequency); QueryPerformanceCounter(Start); for i := 0 to Max do if TestFileExists( Filename ) then else begin Memo1.Lines.Add( 'File not found. Test canceled.' ); Break; end; QueryPerformanceCounter(Stop); Memo1.Lines.Add( 'Results for ' + IntToStr( Max ) + ' repeats: ' + FormatFloat('0.00', ( Stop - Start ) * 1000 / Frequency) + ' Milliseconds' ); Memo1.Lines.Add( 'Begin Test #2: PIDL (' + IntToStr( Max ) + ' repeats)' ); QueryPerformanceFrequency(Frequency); QueryPerformanceCounter(Start); for i := 0 to Max do if ( TestPIDL( Filename ) <> nil ) then else begin Memo1.Lines.Add( 'File not found. Test canceled.' ); Break; end; QueryPerformanceCounter(Stop); Memo1.Lines.Add( 'Results for ' + IntToStr( Max ) + ' repeats: ' + FormatFloat('0.00', ( Stop - Start ) * 1000 / Frequency) + ' Milliseconds' ); Memo1.Lines.Add( 'Begin Test #3: CreateFile (' + IntToStr( Max ) + ' repeats)' ); QueryPerformanceFrequency(Frequency); QueryPerformanceCounter(Start); for i := 0 to Max do if TestCreateFile( Filename ) then else begin Memo1.Lines.Add( 'File not found. Test canceled.' ); Break; end; QueryPerformanceCounter(Stop); Memo1.Lines.Add( 'Results for ' + IntToStr( Max ) + ' repeats: ' + FormatFloat('0.00', ( Stop - Start ) * 1000 / Frequency) + ' Milliseconds' ); Memo1.Lines.Add( 'Begin Test #4: GetFileAtrributes (' + IntToStr( Max ) + ' repeats)' ); QueryPerformanceFrequency(Frequency); QueryPerformanceCounter(Start); for i := 0 to Max do if TestGetFileAtrributes( Filename ) then else begin Memo1.Lines.Add( 'File not found. Test canceled.' ); Break; end; QueryPerformanceCounter(Stop); Memo1.Lines.Add( 'Results for ' + IntToStr( Max ) + ' repeats: ' + FormatFloat('0.00', ( Stop - Start ) * 1000 / Frequency) + ' Milliseconds' ); Memo1.Lines.Add( 'Begin Test #5: FileAge (' + IntToStr( Max ) + ' repeats)' ); QueryPerformanceFrequency(Frequency); QueryPerformanceCounter(Start); for i := 0 to Max do if TestFileAge( Filename ) then else begin Memo1.Lines.Add( 'File not found. Test canceled.' ); Break; end; QueryPerformanceCounter(Stop); Memo1.Lines.Add( 'Results for ' + IntToStr( Max ) + ' repeats: ' + FormatFloat('0.00', ( Stop - Start ) * 1000 / Frequency) + ' Milliseconds' ); Memo1.Lines.Add( 'Begin Test #6: FileGetAttr (' + IntToStr( Max ) + ' repeats)' ); QueryPerformanceFrequency(Frequency); QueryPerformanceCounter(Start); for i := 0 to Max do if TestFileGetAttr( Filename ) then else begin Memo1.Lines.Add( 'File not found. Test canceled.' ); Break; end; QueryPerformanceCounter(Stop); Memo1.Lines.Add( 'Results for ' + IntToStr( Max ) + ' repeats: ' + FormatFloat('0.00', ( Stop - Start ) * 1000 / Frequency) + ' Milliseconds' ); Memo1.Lines.Add( 'Begin Test #7: TFile (' + IntToStr( Max ) + ' repeats)' ); QueryPerformanceFrequency(Frequency); QueryPerformanceCounter(Start); for i := 0 to Max do if TestTFile( Filename ) then else begin Memo1.Lines.Add( 'File not found. Test canceled.' ); Break; end; QueryPerformanceCounter(Stop); Memo1.Lines.Add( 'Results for ' + IntToStr( Max ) + ' repeats: ' + FormatFloat('0.00', ( Stop - Start ) * 1000 / Frequency) + ' Milliseconds' ); Memo1.Lines.Add( 'Begin Test #8: FindFirst (' + IntToStr( Max ) + ' repeats)' ); QueryPerformanceFrequency(Frequency); QueryPerformanceCounter(Start); for i := 0 to Max do if TestFindFirst( Filename ) then else begin Memo1.Lines.Add( 'File not found. Test canceled.' ); Break; end; QueryPerformanceCounter(Stop); Memo1.Lines.Add( 'Results for ' + IntToStr( Max ) + ' repeats: ' + FormatFloat('0.00', ( Stop - Start ) * 1000 / Frequency) + ' Milliseconds' ); Memo1.Lines.Add( '' ); Memo1.Lines.Add( 'Job Done.' ); end; I build a small quick bencher, to me GetFileAttributes() is the winner and PItemIdList is by far biggest looser (if i implemented correct way.....) FindFile.7z