Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 01/27/23 in all areas

  1. vfbb

    ANN: Skia4Delphi v4.0.0

    v4.1.0 Added new parameters to SkCanvas.SaveLayer; API Added functions ComputeFastBounds and CanComputeFastBounds to SkImageFilter; API Added the properties ApproximateOpCount and ApproximateBytesUsed to SkPicture; API Added ShaderButton demo in VCL & FMX (presented at the Embarcadero Brazil Conference 2022); Samples Added virtual methods to TSkLabel; #182 Controls Added support for beta versions of RAD Studio; Setup Improved codecs load; Render Fixed support for iOS Simulator ARM64; #186 Library Fixed invalid float point operation in texts; Render Fixed trimming issue in TTextLayout; #192 Render Fixed Skia's codecs color type on mobile with Skia's render disabled; #197 Render Fixed ISkPath.IsRect results; API Fixed read of Metal view; Render Fixed cursor in TSkLabel of VCL; Controls Fixed text attributes; Render Fixed controls inside TSkCustomAnimatedControl in VCL; Controls Fixed TextLayout before 10.2 Tokyo; Render Fixed iOS certificate issues in main demo; Samples Fixed NavigationBar color on Android12+ in main demo; Samples Fixed and improved unit tests; Tests Minor improvements. Skia version: 107.1.0 New ShaderButton demo (VCL & FMX) ShaderButton.MP4
  2. FPiette

    Need a "Delphi programming guideline"

    I have this document : http://wiki.overbyte.be/arch/IcsMidwareCodingStyle.pdf It partially answer your request.
  3. Lars Fosdal

    Need a "Delphi programming guideline"

    Another good read is https://www.oreilly.com/library/view/framework-design-guidelines/9780135896457/ It is not Delphi specific, but the advice is sound and actively applied to C#/.NET code by Microsoft. Also - the book I wish I had read during my education days. https://www.oreilly.com/library/view/code-complete-2nd/0735619670/
  4. haentschman

    Need a "Delphi programming guideline"

    Hi... Sorry, but it is not the right company. That's where the developers get in their own way. Uniform styles are important to understand all "developers" and their code. The management must set the standard! Try to talk to the others about a simple standard (prefixes for components, meaningful variable names, begin/end styles - separate lines or not, CTRL+D for all...). What is the total number of lines of source code? Do you have a trainee for the implementation of the styleguide in the old code? no matter what you do... ...that is the problem! another one... PDF 😉 ...great work! Manual_on_Object_Pascal_Style_Guide.pdf
  5. Darian Miller

    Need a "Delphi programming guideline"

    Here's one I started: https://github.com/radprogrammer/radteam/wiki/RADProgrammer-Style-Guide
  6. We are using the built-in TEdgeBrowser which is sufficient for our needs. I am guilty of taking the quick & dirty way out of Edge blocking local files by default. In one of our projects where we needed it, I simply have: Win32Check( SetEnvironmentVariable( 'WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS', '--allow-file-access-from-files' ) ); right in the DPR file. Above it is some kind of //TODO: Patch Vcl.Edge.pas so this is no longer necessary. Overall, I'm rather happy with the Edge Browser. We are using it to play videos, display and annotate PDFs, display web content and using rich HTML content editors like SunEditor.
  7. programmerdelphi2k

    Need a "Delphi programming guideline"

    about the nomenclatures, really, only the programmer can define it. But the IDE provides some internal tools that can help in the quest to produce better coding or even improve the look (for better readability). Tools->Language->Formatter: reformating you code with CTRL+D (I love this) on unit or for all project: Project-> Format Project Sources you can create your "way" ( as you named all procedure/functions/vars/objects/etc.. ), then, the "formatter" will use as your "pattern" to fix all next occurrences -> it's great helper! the main idea, it's create the first occurrences (names) then the "formatter" will use it! in Project->QA Metrics, QA Audits -> you will have some info about your project with some tips about your coding in Project -> Method Toxicity Metrcis -> you will know "how is it?" a general idea of how your code is doing, with respect to complexity (which can affect performance) But nothing will save you from a sloppy project manager! If the boss doesn't care, who needs that boss!
  8. I'm targeting Windows 8+ 64-bit with Delphi 11 and was wondering if anyone is using the Edge browser control in production and which one you are using ? I've spotted the following 4 options: TEdgeBrowser which is part of Delphi 11 installation. It doesn't seem to provide support for custom options such as --disable-web-security to load local files TMSFNCWebBrowser from TMS Software. It doesn't seem to handle --disable-web-security either WebView4Delphi from Salvador Díaz Fau which supports that option, but needs a few tricks to work properly: use a timer for initialization and listen to parent form's MOVE messages to resize properly. This looks a bit weird compared to other components but not a show stopper CEF4Delphi also from Salvador Díaz Fau which I've discarded as being far too large to be distributed with my application It looks like only WebView4Delphi could work for my use case as it is the only one supporting --disable-web-security and I was wondering if anyone had feedback about using these in production or if you have any other recommendations?
  9. My current company does not follow any Delphi programming guideline. You know the document that recommends to use short function, long variable names, use of try/finally, etc. I never needed one, because in the previous companies everybody was doing good code "by default". But in this company..... every programmer does whatever it wants (function that have 2000 lines of code, as strings are named s, k or i, etc). I expected to find such a guideline on Emba's website. But cannot find it. Anyone can point to such document or if you wrote one, upload it somewhere? My colleagues refuse to read Delphi books (they don't know how to make classes), and our boss is not a technical guy. He only looks in the scrum if for the GUI DoD (definition of done) if the task is ready or not.
  10. Hi guys! Nowadays I see lot's of applications where a regular desktop app pops up a browser-like window where the end-user can enter his xxxxx@gmail.com email address and password and grant access to Google email or Google calendar, etc. etc. I have the DevExpress suite ( and D11 ) and my end goal is to sync the DevExpress calendar with the TcxScheduler. There is an DevExpress demo example but it's too complicated for me ( for now) and the end-user. Their example works with client-id and client-secret. And creating them takes 15 clicks in the console.google.cloud . This way too complicated for an end-user..... Is there a way ( which I don't see now ) how to get ( OAuth?!?) easy access by just entering email and password? Any help would be nice! Best regards, Emile
  11. Anders Melander

    Convert Png To ico fmx delphi

    Actually, IME, the PNG sub-format is the least troublesome; It just has a PNG file instead of the regular BMP pixel data. No, it's the non-alpha formats, and in particular, the 1 bpp format, that is the worst. If the task here is to convert a PNG to an ICO I would just create an ICO header with a single 32bpp PNG sub-image and then simply use the PNG as-is for the sub-image. Something like this (not tested): const RES_ICON = 1; RES_CURSOR = 2; type TIconDirectoryHeader = packed record Reserved: Word; // Reserved; must be zero. ResType: Word; // Specifies the resource type. This member must // have one of the following values: // RES_ICON Icon resource type. // RES_CURSOR Cursor resource type. ResCount: Word; // Specifies the number of icon or cursor // components in the resource group. end; TIconDirectoryEntry = packed record Width: Byte; Height: Byte; ColorCount: Byte; Reserved: Byte; ResInfo: packed record case byte of RES_ICON: ( IconPlanes: Word; IconBitCount: Word); RES_CURSOR: ( CursorHotspotX: Word; CursorHotspotY: Word); end; BytesInRes: DWORD; ImageOffset: DWORD; end; TColorDepth = 1..32; // Bits per pixel. Not bits per plane. function ColorDepthToColors(ColorDepth: TColorDepth): cardinal; begin Result := 1; while (ColorDepth > 0) do begin Result := Result shl 1; dec(ColorDepth); end; end; // PngStream: A stream containing the PNG // IcoStream: The outout stream // AWidth: Width of the PNG // AHeight: Height of the PNG // AColorDepth: Color depth of the PNG procedure SavePngStreamToIcoStream(PngStream, IcoStream: TStream; AWidth, AHeight: integer; AColorDepth: TColorDepth = 32); begin var IconDirectoryHeader: TIconDirectoryHeader := Default(TIconDirectoryHeader); var IconDirectoryEntry: TIconDirectoryEntry := Default(TIconDirectoryEntry); IconDirectoryHeader.ResType := RES_ICON; IconDirectoryHeader.ResCount := 1; IcoStream.Write(IconDirectoryHeader, SizeOf(IconDirectoryHeader)); // Note : 256x256 icon sets Width&Height to 0 (according to docs) or to 255 (according to .NET) IconDirectoryEntry.Width := AWidth and $FF; IconDirectoryEntry.Height := AHeight and $FF; var BitCount := 0; var ColorCount := 0; case AColorDepth of 1, 4: ColorCount := ColorDepthToColors(AColorDepth); else BitCount := AColorDepth; end; IconDirectoryEntry.BytesInRes := PngStream.Size; IconDirectoryEntry.ImageOffset := SizeOf(IconDirectoryHeader) + SizeOf(IconDirectoryEntry); IconDirectoryEntry.ResInfo.IconPlanes := 1; IconDirectoryEntry.ResInfo.IconBitCount := BitCount; IconDirectoryEntry.ColorCount := ColorCount; IcoStream.Write(IconDirectoryEntry, SizeOf(IconDirectoryEntry)); IcoStream.CopyFrom(PngStream, 0); end;
  12. Anders Melander

    Convert Png To ico fmx delphi

    I'm guessing you've never had to write code that can read and write icons in all of the supported formats 🙂
  13. Sherlock

    Need a "Delphi programming guideline"

    That sounds dismal. What struck me though is this: How does this make any form of version management possible? If every developer has their own style they might be tempted to reformat code as they work on it, causing a multitude of changes and in essence a merging nightmare.
  14. Sherlock

    IEC 62304 Medical software standard

    @Rollo62 HA! Nice! Johner Institute is my helper to get through this tedious process I can really recommend them.
  15. Rollo62

    IEC 62304 Medical software standard

    I think the kind of language is the least problem you will face. Here is a short summary of the current changes, unfortunately in German, but I think it might help anyway. You will have to do a lot of documentation, tests and verifications around the code, where the "safety" of a language is mostly defined by how you organize and implement your apps and workflows.
  16. Sherlock

    IEC 62304 Medical software standard

    There are plenty of applications created with Delphi, that are conform with 62304. My own application for example. 62304 does not demand the use of certain languages, it does however require extensive documentation. Documentation you should have anyway... Have you read anything concerning this standard? Wikipedia grants us a small glance at the implications: https://en.wikipedia.org/wiki/IEC_62304 I would suggest to consult more in depth literature and courses however. The subject is not trivial, especially the risk based decision model, that should be used in almost all aspects of the software life cycle. Auditors or accreditors as you call them, will not read your source code, as that is proprietary to you and your company. They will however read the entire technical documentation. Most important is the market you want to sell your product, if it is Europe, you will need more that IEC 62304. You will need to adhere to the medical device regulation (MDR 2017/745) and that means you'll need to establish a company wide quality management system such as the ISO 13485. And you'll need certification before selling anything. All in all this will swallow up a ton of money before you can even start thinking about generating any revenue.
  17. Stefan Glienke

    Delphi 11.2 Linker eliminating symbols

    No, just pray the issue gets fixed in your lifetime
  18. Der schöne Günther

    Need a "Delphi programming guideline"

    There is a "style guide" which focuses on Delphi-relative conventions like that weird "F" prefix for field names and such: Delphi’s Object Pascal Style Guide - RAD Studio (embarcadero.com) Embarcadero does not provide official guidelines on how to write good and re-usable code in general. At some point, probably most of us have dealt with with ancient Pascal spaghetti code that is almost impossible to understand. I feel your pain. If your colleagues are stuck one or two decades ago and refuse to study further, I doubt an "official" guide from the vendor of your IDE is going to change much.
  19. MMX Code explorer (now free and maintained by Uwe Raabe) has a class browser that might be useful within a file. MMX – speed up your Delphi development (mmx-delphi.de)
  20. David Heffernan

    A book about Object Pascal Style Guide

    I have to say that I have never understood why args get prefixed with A and why local variables get prefixed with L. Upper or lower case. I just don't see the benefit.
  21. Done. Also, there was a problem with the last update where I failed to upload a recent change in Img32.pas which caused problems in Img32.Layers. That's now fixed too. I've also made a minor update to the Layers301 sample application. https://sourceforge.net/projects/image32/files/
  22. sh17

    Sending email and compose via Outlook

    Not very different TMailOutlook = class(TObject) private const olMailItem = $00000000; private class function HaveActiveOleObject(const ClassName: string): boolean; public class procedure Execute(const _To,_ToCC,_ToBCC,_Subject,_Body,_Attachment : String); end; { TMailOutlook } class procedure TMailOutlook.Execute(const _To, _ToCC, _ToBCC, _Subject, _Body,_Attachment: String); var Outlook: OleVariant; MailV: Variant; begin if not HaveActiveOleObject('Outlook.Application') then Outlook := CreateOleObject('Outlook.Application') else Outlook:= GetActiveOleObject('Outlook.Application'); MailV := Outlook.CreateItem(olMailItem); if (_To <> '') then MailV.To := _To; if (_ToBCC <> '') then MailV.BCC:= _ToBCC; if (_ToCC <> '') then MailV.CC:= _ToCC; MailV.Subject := _Subject; MailV.Body := _Body; if _Attachment <> '' then if FileExists(_Attachment) then MailV.Attachments.Add(_Attachment); MailV.Display; end; //// Want to Bypass exception so we check this without using the activex unit class function TMailOutlook.HaveActiveOleObject( const ClassName: string): boolean; var ClassID: TCLSID; Unknown: IUnknown; oleresult: HResult; begin ClassID := ProgIDToClassID(ClassName); oleResult:= GetActiveObject(ClassID, nil, Unknown); result:= Succeeded(oleResult); end;
  23. Given a large directory tree with many files and sub directories and a depth of about 5 located on a Samba server share which must be fully traversed: What is more efficient: Depth First Search: Recursive FindFirst/Next which immediately handles each sub directory when it is encountered. Breadth First Search: Iterative FindFirst/Next which maintains a list of directories to process and appends sub directories to this list when they are encountered to be processed later. I have so far implemented DFS, simply because it was the easiest. It takes a very long time (about 60 seconds in my test scenario). Before I try to implement BFS: Has anybody ever compared the performance of these approaches on Windows + network shares? I googled, but could not find anything definitive (which really surprised me), maybe my google fu has let me down again.
  24. Conclusion: It doesn't matter whether I use Breadth First or Depth First Search, the performance is the same. Switching from SysUtils.FindFirst/FindNext to Windows.FindFirstFileEx/FindNextFile with only basic file information and the flag FIND_FIRST_EX_LARGE_FETCH brought me a performance gain of about 25% which is not too bad. I found no way to benefit from using TDirectory. The only test I made got worse performance than FindFirst/Next. Test environment: Windows 8.1 client accessing a share on a Samba server over 1 GBit Ethernet with minimal traffic (it's a weekend). The computer is a reasonably fast Intel Xeon E3 with 3.4 GHz with 8 cores and 16 GByte RAM. The Server has an Intel Core I9-9940X processor with 16 cores and with 64 GBytes of RAM. The share is stored on a 2 TB Intel M2 NVMe SSD. It's running Ubuntu 18.04.4 LTS and Samba 4.7.6-Ubuntu. The test program was compiled with Delphi 10.4. There was a no noticable difference between building with Debug and Release config. The directory tree is 4 levels deep and contains only a few directories on the first 3 levels but a total of 898 directories on the deepest level. Each of these directories on the deepest level contain from several hundred up to several thousand jpeg files. The purpose of the code is to find all directories on any level containing at least one jpeg file but no subdirectories. All tests were run several times in varying order to prevent any caching effects to distort the result.
  25. My tests show no performance difference at all between DFS und BFS using FindFirst/FindNext. Both take nearly exactly 60 seconds on my test machine traversing the same directory tree on a Samba server. Trying to use TDirectory did not result in any improvement. It takes about twice as long. DFS code: var DirsWithJpg: TArray<string>; procedure CheckDirectory(const _Dir: string); var DirBs: string; sr: TSearchRec; ContainsFiles: boolean; ContainsSubdirs: boolean; begin ContainsFiles := False; ContainsSubdirs := False; DirBs := IncludeTrailingPathDelimiter(_Dir); if FindFirst(DirBs + '*.*', faAnyFile, sr) = 0 then begin try repeat if (sr.Name = '.') or (sr.Name = '..') then begin // ignore end else if (sr.Attr and faDirectory) <> 0 then begin // directory ContainsSubdirs := true; // recursive Depth First Search CheckDirectory(DirBs + sr.Name); end else if sr.Attr and (faHidden or faSysFile or faSymLink) = 0 then begin // regular file if not ContainsFiles then begin if SameText(ExtractFileExt(sr.Name), '.jpg') then begin ContainsFiles := true; end; end; end else begin // ignore special files end; until FindNext(sr) <> 0; finally FindClose(sr); end; end; if ContainsFiles then begin if ContainsSubdirs then begin m_Result.Lines.Add(Format('Directory %s contains files and subdirectories, ignoring it.', [_Dir])); end else begin DirsWithJpg := DirsWithJpg + [_Dir]; end; end; end; var Stopwatch: TStopwatch; begin Stopwatch.Reset; Stopwatch.Start; CheckDirectory('\\server\share\dir'); Stopwatch.Stop; m_Result.Lines.Add(Format('FindFirst/Next DBF: Found %d dirs in %.3f seconds', [Length(DirsWithJpg), Stopwatch.Elapsed.TotalSeconds])); end; BFS code: var DirsWithJpg: TArray<string>; DirsToSearch: TStringList; procedure CheckDirectory(const _Dir: string); var DirBs: string; sr: TSearchRec; ContainsFiles: boolean; ContainsSubdirs: boolean; begin ContainsFiles := False; ContainsSubdirs := False; DirBs := IncludeTrailingPathDelimiter(_Dir); if FindFirst(DirBs + '*.*', faAnyFile, sr) = 0 then begin try repeat if (sr.Name = '.') or (sr.Name = '..') then begin // ignore end else if (sr.Attr and faDirectory) <> 0 then begin // directory ContainsSubdirs := true; // add to list for later processing DirsToSearch.Add(DirBs + sr.Name); end else if sr.Attr and (faHidden or faSysFile or faSymLink) = 0 then begin // regular file if not ContainsFiles then begin if SameText(ExtractFileExt(sr.Name), '.jpg') then begin ContainsFiles := true; end; end; end else begin // ignore special files end; until FindNext(sr) <> 0; finally FindClose(sr); end; end; if ContainsFiles then begin if ContainsSubdirs then begin m_Result.Lines.Add(Format('Directory %s contains files and subdirectories, ignoring it.', [_Dir])); end else begin DirsWithJpg := DirsWithJpg + [_Dir]; end; end; end; var Stopwatch: TStopwatch; begin Stopwatch.Reset; Stopwatch.Start; DirsToSearch := TStringList.Create; try DirsToSearch.Add('\\server\share\dir'); while DirsToSearch.count > 0 do begin CheckDirectory(DirsToSearch[0]); DirsToSearch.Delete(0); end; finally FreeAndNil(DirsToSearch); end; Stopwatch.Stop; m_Result.Lines.Add(Format('FindFirst/Next BFS: Found %d dirs in %.3f seconds', [Length(DirsWithJpg), Stopwatch.Elapsed.TotalSeconds])); end; The naive approach using TDirectory takes about twice as long because of the calls to .GetFiles and .GetDirectories each call FindFirst/FindNext per directory. (It also finds 2 less directories containing jpg files, so there is probably a bug somewhere, but I didn't investigate this any further.) var DirsWithJpg: TArray<string>; procedure CheckDirectory(const _Dir: string); var Files: TArray<string>; Dirs: TArray<string>; i: Integer; begin Files := TDirectory.GetFiles(_Dir, '*.jpg'); Dirs := TDirectory.GetDirectories(_Dir); if Length(Files) > 0 then begin if Length(Dirs) > 0 then begin m_Result.Lines.Add(Format('Directory %s contains files and subdirectories, ignoring it.', [_Dir])); end else DirsWithJpg := DirsWithJpg + [_Dir]; end else begin for i := Low(Dirs) to High(Dirs) do CheckDirectory(Dirs[i]); end; end; var Stopwatch: TStopwatch; begin Stopwatch.Reset; Stopwatch.Start; CheckDirectory('\\server\share\dir'); Stopwatch.Stop; m_Result.Lines.Add(Format('DirGetFiles: Found %d dirs in %.3f seconds', [Length(DirsWithJpg), Stopwatch.Elapsed.TotalSeconds])); end; I thought about using TDirectory.FileSystemEntries instead but could not think of a simple way to implement this. It's probably possible using a Predicate but that's not really any simpler than directly using FindFirst/FindNext. There is probably still some space for improvements and the code is not really clean, e.g. accessing variables of the outer procedure. So, now I'll have a look at calling Windows.FindFirstFileEx instead of FindFirst, but I don't have much hope that this will help much.
×