CodeRage XI, the online event from Embarcadero for Delphi and C++Builder developers, with dozens of technical sessions by Embarcadero speakers, MVPs, and tech partners. Bruno Fierens (founder TMS software), Wagner Landgraf (TMS Business product manager) & Roman Yankovsky (TMS FixInsight product manager) brought sessions covering our latest technologies FNC, myCloudData, Aurelius, FixInsight developed at TMS software. If you missed one of these sessions last week, you can now watch them via our Youtube channel. New video's published at tmssoftwareTV:
|
Drop a TAdvRichEditor and TAdvRichEditorHTMLIO instance on the form and add the code: var s:string; begin // set the richeditor content from a HTML formatted string s := '<i>Hello</i> <b>world</b>'; AdvRichEditorHTMLIO1.LoadHTML(s); // return the richeditor content as HTML formatted string s := AdvRichEditor1.ContentAsHTML(); ShowMessage(s); end; |
This is an example of a recursive function that adds all files and folders including sub files and subfolders to a TListView control: Storage.GetDriveInfo(); FillListView(ListView1, Storage.Drive); procedure FillListView(AListView: TListView; Folder: TCloudItems); var li: TListItem; i: integer; begin for i := 0 to Folder.Count - 1 do begin li := AListView.Items.Add(); li.Caption := Folder.Items[i].FileName; li.Data := Folder.Items[i]; if (Folder.Items[i].ItemType = ciFolder) and Assigned(Folder.Items[i].Folder) then FillListView(AListView, Folder.Items[i].Folder); end; end; |
What's wrong with the KIS principle to store application settings in an INI file? The risk that someone is tampering with the INI file is an often heard reason for not using them. Not being able to store private or secret information another one. Both issues are solved with the introduced TEncryptedIniFile class. It descends from TMemIniFile and is as such a drop-in replacement and will deal only in app memory with decrypted data. In the file itself, the data is at all times encrypted. To build TEncryptedIniFile, we internally use AES 256bit encryption offered by the TAESEncryption class in TMS Cryptography Pack. The code to use TEncryptedIniFile becomes something like: const aeskey = 'anijd54dee1c3e87e1de1d6e4d4e1de3'; var mi: TEncryptedIniFile; begin try mi := TEncryptedIniFile.Create('.settings.cfg', aeskey); try FTPUserNameEdit.Text := mi.ReadString('FTP','USER',''); FTPPasswordNameEdit.Text := mi.ReadString('FTP','PWD',''); FTPPortSpin.Value := mi.ReadInteger('FTP','PORT',21); mi.WriteDateTime('SETTINGS','LASTUSE',Now); mi.UpdateFile; finally mi.Free; end; except ShowMessage('Error in encrypted file. Someone tampered with the file?'); end; end;Of course, the weakness now is that the AES key is in the EXE file and as such, it won't stop seasoned hackers to extract it from the EXE and use it directly to decrypt/encrypt the settings file and tamper with it this way. Extra steps could be taken to use an AES key that is a combination of a unique machine ID and a part that is encrypted with a Ed25519 generated public key and decrypt the encrypted part of the AES key on the fly in the app with the Ed25519 private key and then use it in combination with the machine ID to encrypt/decrypt the INI file. That should make the effort to hack the settings file already a lot more difficult. To start using this TEncryptedIniFile you can get TMS Cryptography Pack and you can download the TEncryptedIniFile class source here. |
In this sample code, whenever a new cell value is entered longer than 3 characters, a messagebox is shown to ask to confirm this value or restore the original value: TForm1 = class(TForm) AdvStringGrid1: TAdvStringGrid; procedure FormCreate(Sender: TObject); procedure AdvStringGrid1CellValidate(Sender: TObject; ACol, ARow: Integer; var Value: string; var Valid: Boolean); procedure AdvStringGrid1EditCellDone(Sender: TObject; ACol, ARow: Integer); private { Private declarations } public { Public declarations } isvalid: boolean; origvalue: string; newvalue: string; end; procedure TForm1.AdvStringGrid1CellValidate(Sender: TObject; ACol, ARow: Integer; var Value: string; var Valid: Boolean); begin isvalid := length(value) <= 3; newvalue := value; origvalue := advstringgrid1.OriginalCellValue; end; procedure TForm1.AdvStringGrid1EditCellDone(Sender: TObject; ACol, ARow: Integer); begin if not isvalid then begin if MessageDlg('new value ' + newvalue +' is not valid, restore old value '+ origvalue + ' ?', mtConfirmation, [mbYes, mbNo], 0 ) = mrYes then begin AdvStringGrid1.Cells[acol,arow] := origvalue; end; end; end; procedure TForm1.FormCreate(Sender: TObject); begin AdvStringGrid1.Options := AdvStringGrid1.Options + [goEditing]; AdvStringGrid1.RandomFill(True); end; |
Following sample code snippet shows how you can retrieve results: begin AdvMultiInputQueryDialog1.QueryValues.Clear; AdvMultiInputQueryDialog1.QueryValues.Add; AdvMultiInputQueryDialog1.QueryValues.Add; AdvMultiInputQueryDialog1.QueryValues[0].&Label := 'Value 1'; AdvMultiInputQueryDialog1.QueryValues[1].&Label := 'Value 2'; if AdvMultiInputQueryDialog1.Execute = mrOK then begin listbox1.Items.add(AdvMultiInputQueryDialog1.QueryValues[0].ResultValue); listbox1.Items.add(AdvMultiInputQueryDialog1.QueryValues[1].ResultValue); end; end; The listbox is filled in this example with the input values entered in the dialog. |
One question we get asked from time to time is if FlexCel has a method like “DumpDataset” or “CopyFromRecordset” (which is the actual name in OLE Automation). This method should take a dataset and dump it into a sheet. And the answer is no, we don’t include such a method because we find it too limiting: Normally you will have to customize some way how the cells are written, and you can’t do it with a single method that does the whole export in one piece. So instead, we provide 2 other different solutions to the problem. 1)FlexCel has reports, which you can use to dump a dataset “as is”, mostly as a DumpDataSet would, but it also lets you do the formatting. What is more, it allows you to easily modify the resulting sheets without modifying the code at all, so even the final user can do it. Say for example the logo of the company changes, you can update the logo in the Excel template, and the code stays exactly the same. Or if you prefer you can embed the templates in your exe file, and they won’t be editable by the final user. Your choice. From reports, the most similar thing to "DumpDataset" is to create an empty file, write "<#mydataset.*> on it, save it, and then run the report against your dataset. You can find an example of this in the demos: <flexcel install folder>\TMSSoftware\FlexCelVCLNT\Demo\Delphi\Modules\20.Reports\88.Generic Reports and <flexcel install folder>\TMSSoftware\FlexCelVCLNT\Demo\Delphi\Modules\20.Reports\89.Generic Reports 2 Of course those 2 demos focus in “generic” datasets which you don’t know beforehand. If you know what data you are outputting, then you can just write <#dataset.field> in the cells where you want that field written, and format each field as you want. Reports are designed specifically to deal with the problem of exporting datasets into Excel, but allowing formatting. 2)The reports in FlexCel work exclusively by calling the FlexCel API, so anything you can do in a report, you can do it directly with the API. So if for any reason you can’t or don’t want to use reports, you can use a method like this: uses System.SysUtils, Windows, DB, DBClient, VCL.FlexCel.Core, FlexCel.XlsAdapter; procedure DumpDataSet(const ds: TDataSet); var xls: TXlsFile; Row, Col: integer; Fmt: TFlxFormat; DateXF, DateTimeXF: integer; begin xls := TXlsFile.Create(1, true); try Fmt := xls.GetDefaultFormat; Fmt.Format := 'dd/mm/yyyy hh:mm'; DateTimeXF := xls.AddFormat(Fmt); Fmt := xls.GetDefaultFormat; Fmt.Format := 'dd/mm/yyyy'; DateXF := xls.AddFormat(Fmt); ds.First; row := 1; while not ds.Eof do begin for col := 1 to ds.FieldCount do begin case ds.Fields[col - 1].DataType of TFieldType.ftDateTime: begin xls.SetCellValue(Row, Col, ds.Fields[col - 1].AsDateTime, DateTimeXF); end; TFieldType.ftDate: begin xls.SetCellValue(Row, Col, ds.Fields[col - 1].AsDateTime, DateXF); end; else begin xls.SetCellValue(Row, Col, ds.Fields[col - 1].Value); end; end; end; ds.Next; Inc(row); end; xls.Save('r:\test.xls'); finally xls.Free; end; end; |
In FixInsight Settings dialog you can use file masks to exclude certain units. Furthermore you can exclude an entire folder using a mask like this "C:\FolderToExclude\*.pas". This will make FixInsight to ignore all units in the specified folder. |
Analytics library allows easily evaluation of math expressions and symbolic derivative calculation. Another feature of the library is that it provides a mechanism for checking syntax of math expression before calculation. Moreover, it is possible to show user the exact error and where it is in the expression. Analytics library uses exceptions to provide information about syntax (and other) errors (see page 20 of developer guide). Then exception handling must be used in any code when checking errors. The example of code for function calculation with syntax checking: procedure TFormSyntaxErrorHighlight.ButtonCheckSyntaxClick(Sender: TObject); var f: string; formula: TFormula; v: TValue; s: string; begin f:=LabeledEditF.Text; try if FTranslator.CheckSyntax(f) then begin formula:=FTranslator.BuildFormula(f); v:=formula.Calculate(); s:=TUtilities.SafeToString(v); end; except on es: ESyntax do begin HighlightSyntaxError(es); exit; end; on ex: Exception do begin ShowException(ex); exit; end; end; MessageDlg('Syntax is OK.'+#13+'F='+s, TMsgDlgType.mtInformation, [TMsgDlgBtn.mbOK], 0); end; The syntax check is made by CheckSyntax function of TTranslator class. This function returns true if an expression is syntactically correct and throws an exception if not. The exception is always inherited from base ESyntax class. This class contains information about the syntax error and position of the wrong part of the expression. And it makes easy to highlight the error for user. Code for highlighting: procedure TFormSyntaxErrorHighlight.HighlightSyntaxError(es: ESyntax); var err: TSyntaxError; p1: Integer; p2: Integer; begin err:=es.Error; p1:= err.Position1; p2:= err.Position2; LabeledEditF.SelStart:=p1-1; LabeledEditF.SelLength:=p2-p1+1; ShowException(es); end; procedure TFormSyntaxErrorHighlight.ShowException(ex: Exception); begin MessageDlg(ex.Message, TMsgDlgType.mtError, [TMsgDlgBtn.mbOK], 0); end; The code above selects the wrong part of the expression in the edit. The information for selecting text extracted from generated exception. Some result of syntax errors highlighting presented below. As can be seen from the pictures, wrong expression parts selected in the edit box and description of the errors shown in message boxes. Full source code of the example application (VCL) can be downloaded here. |
If you are, like us, excited about Internet of Things, embedded software development, DIY projects, controlling electronics from your code, ... we have for you a free & open-source bundle of hardware access components for Raspberry Pi. You can download full source code via following git repository: https://tmssoftware@bitbucket.org/tmssoftware/tms-lcl-hw-pack-for-raspberry-pi.git We also welcome you to contribute to this open-source package. Contact us with your suggestions, feedback, contributions. |
As always, we thank all users for the numerous inputs, feedback, comments and suggestions. This is an invaluable help to steer our developments here at TMS software. We continue to look forward to all your further communications to direct our team to provide you better tools and components for your needs.
Kind regards,
TMS software team
Email:
info@tmssoftware.com
Web: http://www.tmssoftware.com
Support, FAQ & Manuals: http://www.tmssoftware.com/site/support.asp