-
Content Count
380 -
Joined
-
Last visited
-
Days Won
4
Everything posted by Clément
-
Grant lifetime subscription to Andreas Hausladen (IDE Fix Pack creator)
Clément replied to santiago's topic in Delphi IDE and APIs
But Andreas Hausladen has his way to find and fix the IDE. Who's to tell how to boost the IDE? EMB is focused on quality, stability and performance, but they have deadlines and investors to deal with. When an IDE fix is required, EMB would take months to test everything (as it should), but Andreas can do it over a free weekend. If Andreas has the time (and is willing )to patch the IDE, let him patch it. And later EMB can implement / fix such features. The same goes with FastCode project. Today most of that work is integrated. But who's to say there's nothing more to optimize? ( I really miss the ASM newsgroup and their fight over bits, bytes, cycles and benchmarks!) Anyway, I would vote for Andreas own copy/subscriptions. IDEs from D7 up to Tokyo are still using it! (BTW if someone is not using IDE Fix pack from those older IDEs: You are wasting time... Literally ) -
Grant lifetime subscription to Andreas Hausladen (IDE Fix Pack creator)
Clément replied to santiago's topic in Delphi IDE and APIs
Hard to tell. Marco said they've implemented the "safest" IDE Fix pack features in the IDE. -
Do you consider this type construct to be a smelly code?
Clément posted a topic in Algorithms, Data Structures and Class Design
Hi, I always tried to use the right type for the job, but there's a certain type construction that when used properly is just great. Since this type construct uses pointers, I'm afraid it might die as pointers are evil (by some, I just can't imagine coding without them) and might get removed at some point. Is there a better way to handle this construct? function DoSomething( const Data; const DataSize : Cardinal ) : TBytes; type PUInt64Array = ^TUInt64Array; TUInt64Array = array[0..MaxInt div 16] of UInt64; var {...}; begin {.. some code ..} n := HashBlockSize div SizeOf(UInt64); for i := 0 to n-1 do begin PUInt64Array(@oString[0])[i] := PUInt64Array(@oString[0])[i] xor UInt64($5c5c5c5c5c5c5c5c); PUInt64Array(@iString[0])[i] := PUInt64Array(@iString[0])[i] xor UInt64($3636363636363636); end; {.. some more code .. } end; I'm using such construct as a helper for a HMAC_SHA256 implementation, and it works great. Do you consider it a smelly code? Is there a better way to reproduce without pointers? TIA, Clément -
What options do I have to control custom releases?
Clément replied to Mike Torrettinni's topic in General Help
Hi, There are a few options. Depending on your project, one might be a better choice than the other. (no particular order) 1) Use IFDEF. If you have a centralized unit where all those options are assigned, you can create in project manager a Release Customer A, Release Customer B,... , etc. In each project configuration option, you should add a conditional define such as __CUSTOMER_A__, __CUSTOMER_B__, ...etc. Your unit(s) will get a bunch of $IFDEFs : // control Main Menus {$IFDEF __CUSTOMER_A_} EnableVisioMenu := false;{$ENDIF} // Customer A {$IFDEF __CUSTOMER_B_} EnableDrawingMenu := false;{$ENDIF} // Customer B // control PopupMenu options EnableCntxt_ImportFromVision := {$IFNDEF __CUSTOMER_C} false {$ELSE} true{$ENDIF}; // ??? ... As you can see, the more customers you get, the more difficult it will be to maintain such spaghetti, but it gets the job done. 2) Use an encrypted external configuration file The file gets constructed according to each customer, the executable remains the same. The only difference is the config file. When you deliver your application, this file goes together. If you absolutely need to keep things in one file, you might consider generating a resource file (.RC) that will be included with your executable. Be aware that some anti-virus might show false positives. The file itself can be very simple, such as an INI file. As long as it's encrypted, it will do it's job. 3) More sophisticated license manager that will allow to handle properly many customers. -
Given the scenario, wouldn't it be better to skip 10.3.2 and go straight to 10.4? I suppose the necessary workforce spent to release an updated such as 10.3.2, could be used to make 10.4 time to market shorter. I guess most of us understand the difficulties Delphi is trying to get out of (a lot of bugs and bugossaurs must be dealt with while keeping up with a very dynamic market). I wouldn't mind skipping 10.3.2 if that would allow a more stable and anticipated 10.4 release. To be honest, if both releases are so close to each other, I would probably wait to install 10.4 anyway, since I need at least a week to proper test a Delphi version before migration.
-
TSslHttpCli in multithreading environment
Clément replied to Mark Lobanov's topic in ICS - Internet Component Suite
Hi Mark, Have you to set USE_SSL and NOFORMS in your project conditional defines? -
In fact we need more stablity/perfomance/quality. I use Delphi Rio and the IDE is slow, not as stable as prior versions, I have to fight the debugger most of the time I'm debugging, especially with win64 projects but also there's far more features in Rio than any prior IDE. Not to mention a lot more compilers / platforms / bitness combination factor. EMB code is getting more and more organized, there's a lot of serious work done and I guess that Rio will improve much more with the next update. Your question don't have a direct answer. Each will report a different IDE (as you saw). What saved most of the "older" IDE is IDEFixPack. An amazing job that changed the experience and impressions of older IDEs. If you think delphi XE is stable, using it with IDEFixpack will make the IDE faster and more stable. That's true with almost every IDE that came before Rio.
-
Do you consider this type construct to be a smelly code?
Clément replied to Clément's topic in Algorithms, Data Structures and Class Design
Thanks I'll have a look. -
Do you consider this type construct to be a smelly code?
Clément replied to Clément's topic in Algorithms, Data Structures and Class Design
For this project I must use Delphi XE. Unfortunately most free implementation are not fast enough and/or depends on DLLs. -
@Georgge and @mjustin Thanks for the direction. I'm checking a few (including Stripe) and I will include BlueSnap too. There are a lot of options! Clément
-
I always used Indy and ICS. Both are great, but both requires extra DLL (OpenSSL) if you need to use https. Each version might required a different OpenSSL DLL version, so mixing both (indy and ICS) will lead to a bucket of inconsistent smelly stuff. In my latest project I was asked to implement a REST client that must access HTTPS URL. I used TNetHTTPClient very successfully. It is very fast and works https without extra DLL. All I had to do was to assign the proper header and voilá! POST, GET, PUT et al with https support. A single component to the rescue.! I tried the TRestClient component family but they seemed to be over complicated ( I just ruled them out )
-
A Curious Inheritance Problem... what pattern solves it?
Clément replied to David Schwartz's topic in RTL and Delphi Object Pascal
If I may..... Can you use an Interface instead? For example: type IHasSQLSupport = Interface ['{E38C927E-019E-423C-A0C3-5C65A836D0C7}'] procedure AssignSQL( const aSQL : string ); End; TOracleDataset = class (...., IHasSQLSupport) // implements IHasSQLSupport procedure AssignSQL( const aSQL : string ); end; TPgQuery = class ( ..., IHasSQLSupport ) // implements IHasSQLSupport procedure AssignSQL( const aSQL : string ); end; TForm72 = class(TForm) private { Private declarations } procedure Myfunc( aQry : IHasSQLSupport ); public { Public declarations } end; implementation procedure TForm72.Myfunc(aQry: IHasSQLSupport; const aSQL : string); begin aQry.AssignSQL(aSQL); end; As long as SomeDataset is TOracleDataset or TpgQuery, you can call it as MyFunc( SomeDataset, aSQL ); SomeDataset.Open; This way you could also implement transaction support, autoinc support etc... -
Yeap. It's happening also here.
-
Hands-On Design Patterns with Delphi
Clément replied to Primož Gabrijelčič's topic in Tips / Blogs / Tutorials / Videos
Got mine too! Nice -
Hello, I just hit a wall in my "Delphi Rio .1" project. I'm placing a few objects (TImage) on a Surface (TPaintBox) and when the mouse is over a TImage I wrote a routine to create a panel, move the TImage to this panel, send a Perform(WM_SYS_COMMAND, $F012, 0 ) and all is working beautifully! But I need to place Guidlines, similar to those in paint applications where an horizontal line and vertical line meet at the cursor position. Those guidelines will help the user align the controls in the surface. Once the perform message is sent ($F012), I no longer found a way to track the mouse position to display my guidelines. The lines just vanish for the duration of the drag and reappear when the drag is done. To illustrate I attached 3 images. The first one is the arrival, the second is just before dragging and the third is dragging. Is there anyway to solve this issue using $F012, or should I find another way to drag without any flicker TIA
-
Hi, $F012 is undocumented constant for SC_DRAG.
-
Thanks Peter, I'll try to use SetWindowsHookEx.
-
ICS V8.60 adds several new components
Clément replied to Angus Robertson's topic in ICS - Internet Component Suite
Great news!! ICS is amazing Clément Brazil -
If you still haven't installed IDE FixPack, do it! Highly recommended! http://www.delphifeeds.com/go/s/146660
-
Hi, I installed 10.3.1 without any problems. My machine is old and I still have Delphi XE, Berlin, Tokyo and Rio installed. I mostly use Tokyo, but I'm confident and I'm migrating my projects to Rio Update 1. I use the migration tool to export my settings from 10.3 to a file. (Very important step!!!) Used the feature install ( Tools -> Manage platform is present ). Emb. should change the way to distinguish between one and another. Messing up a delphi installation by using the wrong installer would cost at day or two to reinstall everything. Selected "NO" since I WANT TO KEEP MY REGISTRY settings. Please consider change this too. Instead of YES or NO, please use something like: "Keep your settings" / "New installation". Selected all the features I want installed Waited for an hour Clicked "Start working" and voilá(*) *I was almost ready. Some components where there, but other no. Especially my Library path. This is why you need the migration tool. Import the file and you're done! The 10.3.1 IDE is more stable than 10.3. This week I will migrate more projects and I will be able to compare against 10.2, but it seems 10.3.1 is a LOT better than 10.2 I'm working on a Win64 project (Multithreaded TCP/UDP communication with InterThread messaging). With 10.3 I had 4 or 5 crashes a day. With 10.3.1 NONE ( so far ). With 10.2 I had to use IDE Fix pack (No crashes at all for days). So far I'm not using IDE fix pack in 10.3.1 and I don't feel like I need it.
-
How to pass an unknown record to a function as argument
Clément replied to John Kouraklis's topic in RTL and Delphi Object Pascal
Hi, I wrote this code using XE. It might help you. type TMyRecord = Record item1: string; item2: Integer; Item3: Currency End; TForm68 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } function GetProperties( aTypeInfo : PTypeInfo; var aRec ) : String; end; implementation {$R *.dfm} procedure TForm68.FormCreate(Sender: TObject); var R : TMyRecord; begin Caption := GetProperties( TypeInfo(TMyRecord), R ); end; function TForm68.GetProperties(aTypeInfo: PTypeInfo; var aRec): String; var rtc : TRttiContext; lTyp: TRttiType; lFld : TRttiField; begin rtc := TRttiContext.Create; lTyp := rtc.GetType(aTypeInfo); for lFld in lTyp.GetFields do Result := Result + ' '+ lFld.Name; end; As you can see, all you need is Typeinfo. You can pass aRec as pointer if you need an instance to assign values. The result is obviously: Item1 item2 item3 Hope this helps, -
Is this method good to delete last character?
Clément replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Hi, The fastest way to delete the last character is to not add it. Compare the two following routines: procedure TForm61.Button1Click(Sender: TObject); var i : integer; lList : TStringlist; lResult : String; begin lList := TStringList.Create; lList.Add('Item1'); lList.Add('Item2'); lList.Add('Item3'); lList.Add('Item4'); try lResult := ''; for i := 0 to lList.Count-1 do lResult := lResult+ lList[i]+','; SetLength(lResult, Length(lResult) - 1 ); // Here I must delete the last char finally lList.Free; end; end; procedure TForm61.Button2Click(Sender: TObject); var i : integer; lList : TStringlist; lResult : String; begin lList := TStringList.Create; lList.Add('Item1'); lList.Add('Item2'); lList.Add('Item3'); lList.Add('Item4'); try if lList.Count>0 then begin lResult := lList[0]; for i := 1 to lList.Count-1 do lResult := lResult+','+ lList[i]; end; finally lList.Free; end; end; Every time I get the chance I use the second routine. It's faster and requires less memory reallocation. -
Let's say you receive a string with null chars in several places separating information. For instance: delphipraxis#0pointers are dangerous#0but worth the risk#0000#000#000000#0 How can you quickly process the information, check if they are valid and answer to that request. You have to return a modified string to the client. In that example you have to answer: delphipraxis#0pointers are dangerous#0but worth the risk#0101#022#014995#0 Of course the trick here is to avoid copying string over and over. Allocating and deallocating classes or complex structures to process the input information. With a simple array of pointers I can use this very same memory spot pointing to the beginning of each string without allocating or copying information. The alternative would be to create a class (TStringList for example), set some properties, use "DelimitedText", have a copy of each string , allocate another "Answer string" and at the end deallocating everything ->defragmentation nightmare. (The input string length varies!) Just picture this example in a network with hundred (or thousands) of devices sending requests of 10k bytes ( strings just like the above one but with 10k null separated values), and you get your performance example. Fragmentation is kept to a minimum and a service running for months without any problem. Is it even possible to improve the compiler as much?
-
Pointers are part of the package. I use them for performance and low memory footprint especially when dealing with low level code (bytes, records or low level TCP communication). The gain pointers bring to the table is worth the risk.
-
Serialize/Deserialize a TObjectDictionary with JSON example
Clément replied to David Schwartz's topic in RTL and Delphi Object Pascal
Hi. I also ended up writing my own JSON serializer/deserializer based on delphi TJsonObject. (Using another JSON class created incompatibilities with RTL). It works on generics (TDictionary<>, TObjectDictionary<>, Tlist<>, etc), Tdataset, TStringList, enum and nested classes. Quite fast. I needed a special TDataset handling (speed wise) that none of the library I tried solved. Anyway, sometimes it's worth reinventing the wheel!