-
Content Count
2561 -
Joined
-
Last visited
-
Days Won
133
Everything posted by Anders Melander
-
Trap TFDConnection error on data module create etc?
Anders Melander replied to Chris1701's topic in Databases
...and the ability to not corrupt the database if the application crashes. -
You (mostly) just need to derive your class from TComponent: type TFruit = class(TComponent) private FColor: string; protected public constructor Create(AOwner: TComponent); override; published property Color: string read FColor write FColor; end; ...and then you also need to register your component: procedure Register; begin RegisterComponents('Cool Stuff', [TFruit]); end; I suggest you read the documentation.
-
[Delphi] Looking for a Delphi Profiler in 2023
Anders Melander replied to Willicious's topic in Delphi IDE and APIs
That isn't really a profiler. -
Trap TFDConnection error on data module create etc?
Anders Melander replied to Chris1701's topic in Databases
Create the TFDConnection in code (e.g. in the DM constructor). Open the connection after the DM has been created. For complex applications, I use a design where the application startup is divided into stages. The stage progression is centrally controlled and broadcast to all interested parties. Something like this: // The following could be in the .dpr file type TRunStageBoot = bsInit..bsReady; TRunStageShutdown = bsShutdown..bsShutdown; begin // Broadcast startup progression for var Stage := Low(TRunStageBoot) to High(TRunStageBoot) do RunStageNotify(Stage); Application.Run; // Broadcast shutdown progression for var Stage := Low(TRunStageShutdown) to High(TRunStageShutdown) do RunStageNotify(Stage); end. ...and the run stage management: type TRunStage = ( bsInit, // Whatever needs to run before the DMs are created. E.g. load config. bsCreateModules, // Create DMs bsConnectDatabase, // Connect to database bsLoadDatabaseSchema, // Validate and update database schema bsLogin, // Perform application login bsInitUI, // Create main UI (e.g. mainform) bsReady, // Show UI bsShutdown // Application shutdown ); IRunStageSubscriber = interface {...GUID...} procedure RunStageNotify(Stage: TRunStage); end; TRunStageDelegate = reference to procedure(Stage: TRunStage); procedure RunStageNotify(Stage: TRunStage); procedure RegisterRunStageHandler(Delegate: TRunStageDelegate); overload; procedure RegisterRunStageHandler(const Subscriber: IRunStageSubscriber); overload; // ...similar for unsubscribe... implementation var // Create on demand in RegisterRunStageHandler. Free in finalization. RunStageSubscribers: TList<IRunStageSubscriber>; RunStageDelegates: TList<TRunStageDelegate>; procedure RegisterRunStageHandler(Delegate: TRunStageDelegate); begin RunStageDelegates.Add(Delegate); end; procedure RegisterRunStageHandler(const Subscriber: IRunStageSubscriber); begin RunStageSubscribers.Add(Subscriber); end; procedure RunStageNotify(Stage: TRunStage); begin for var Subscriber in RunStageSubscribers do Subscriber.RunStageNotify(Stage); for var Delegate in RunStageDelegates do Delegate(Stage); end; ... ...and the DM with the connection would then look something like this: type TDataModuleDatabase = class(TDataModule, IRunStageSubscriber) private FConnection: TFDConnection; private // IRunStageSubscriber procedure RunStageNotify(Stage: TRunStage); public constructor Create(AOwner: TComponent); override; end; var DataModuleDatabase: TDataModuleDatabase; implementation constructor TDataModuleDatabase.Create(AOwner: TComponent); begin inherited; FConnection := TFDConnection.Create(Self); // Setup params on connection ... // Register so we will be notified when the connection should be opened RegisterRunStageHandler(Self); end; procedure TDataModuleDatabase.RunStageNotify(Stage: TRunStage); begin case Stage of bsConnectDatabase: FConnection.Open; end; end; procedure RunStageNotify(Stage: TRunStage); begin case Stage of bsCreateModules: DataModuleDatabase := TDataModuleDatabase.Create(Application); end; end; initialization // Register so we will be notified when the DM should be created RegisterRunStageHandler(RunStageNotify); end; -
Did you read the page linked to? First paragraph states: [edit] I guess you don't know what the PDB file is for. The PDB file is used by the profiler to map the addresses in the application being profiled to source files, function names, and line numbers. Without that information, the profiler would only be able to show you the raw addresses. Download and install VTune. Download map2pdb, extract the exe, and save it somewhere of your choice. For example c:\tools\map2pdb\map2pdb.exe Add a menu item in the Delphi IDE via Tools -> Configure Tools... The parameters in the above are: -debug -v -pause -bind:$EXENAME $PATH($EXENAME)$NAMEONLY($EXENAME).map -include:0001 Make sure the compiler are generating a full map file: Compile your project. Execute the map2pdb tool action. Launch VTune and create a profiler project for your exe. Profile the project in VTune. Profit!
-
VCL Handling of dpi changes - poor performance
Anders Melander replied to Vincent Parrett's topic in VCL
At least you no longer have this problem... Eh? -
Problem writing to memo on main form from thread
Anders Melander replied to Jud's topic in General Help
Replace application.processmessages with form1.TestMemo.Update ...and then Google "avoid application.processmessages", "never use application.processmessages", "don't use application.processmessages", etc. -
The trigger is the presence of the "⁄" character anywhere in the text. It's the Unicode "Fraction Slash". It can be reproduced with the GDI ExtTextOut function, which is how I accidentally discovered it. I suspect that this is actually a bug in GDI because as far as I can tell there's nothing in the font tables that should require that character to be present before ligatures are applied. It could also be a bug in the font that triggers a bug in GDI; There are a lot of bugs in Cascadia and Fira. Normally, in an OpenType shaper, the fraction slash triggers hardcoded logic ("hardcoded" as in "logic not defined in the OpenType tables") that converts numeric fractions from the form 1/2 to ½ but that requires the 'frac' feature to be enabled which it isn't by default.
-
Unless you've discovered the magic key to unlock it:
-
Marketing. I don't think they originally intended it as such but since it at best doesn't hurt performance, that's what it became. Yes, it does. Maybe now would be a good time to read up on what virtual memory is. You don't have to allocate beyond physical memory before virtual memory comes into play. You just have to allocate beyond the process' working set. The working set is the part of your process' virtual memory that is backed by physical memory. The working set can grow and shrink depending on memory access and global resource pressure but there's always an upper and lower limit. Of course, it's a bit more complicated than that (there are more layers than what I have described) but that's the basic overview. In general, I would recommend that one doesn't try to outsmart things one doesn't fully understand. Be it threading, memory management, or women 🙂
-
combining two characters to a string switches them
Anders Melander replied to dummzeuch's topic in RTL and Delphi Object Pascal
No. The order is undefined. For example, if you evaluate the expression (A and B and C ) the evaluation order might very well be BCA. Only boolean short circuit evaluation has a defined order. -
I'm writing a shaper for complex text layout and for that, I need to do Unicode decomposition and composition (NFD and NFC normalization). Does anyone know of a Pascal library that can do this? I have the following basic requirements: Open source with a workable license (i.e. not GPL). Cross platform (i.e. not tied to Windows or whatever). Operate on UFC4/UTF-32 strings. Based on the standard Unicode data tables. Must have the ability to update tables when new Unicode tables are published. Must support both NFD decomposition and NFC composition. So far I have found the following candidates: Delphi Unicode libraries PUCU Pascal UniCode Utils Libary 🔵 Origin: Benjamin Rosseaux. ✅ Maintained: Yes. ✅ Maintained by author: Yes. ✅ License: Zlib. ⛔ Readability: Poor. Very bad formatting. ✅ Performance: The native string format is UCS4 (32-bit). ✅ Features: Supports decomposition and composition. ✅ Dependencies: None. ✅ Data source: Unicode tables are generated from official Unicode data files. Source for converter provided. ⛔ Table format: Generated inline arrays and code. ✅ Completeness: All Unicode tables are available. ✅ Hangul decomposition: Yes. ✅ Customizable: Required data and structures are exposed. ✅ Unicode level: Currently at Unicode v15. ⛔ Unicode normalization test suite: Fail/Crash FreePascal RTL 🔵 Origin: Based on code by Inoussa Ouedrago. ✅ Maintained: Yes. 🔵 Maintained by author: No. 🔵 License: GPL with linking exception. ✅ Readability: Good. Code is clean. ✅ Performance: Code appears efficient. ⛔ Features: Only supports decomposition. Not composition. ✅ Dependencies: None. ✅ Data source: Unicode tables are generated from official Unicode data files. Source for converter provided. ✅ Table format: Generated arrays in include files. ⛔ Completeness: Only some Unicode tables are available. ⛔ Hangul decomposition: No. ⛔ Customizable: Required data and structures are private. ✅ Unicode level: Currently at Unicode v14. ⛔ Unicode normalization test suite: N/A; Composition not supported. JEDI jcl 🔵 Origin: Based on Mike Lischke's Unicode library. 🔵 Maintained: Sporadically. 🔵 Maintained by author: No. ✅ License: MPL. ✅ Readability: Good. Code is clean. ⛔ Performance: Very inefficient. String reallocations. The native string format is UCS4 (32-bit). ✅ Features: Supports decomposition and composition. ⛔ Dependencies: Has dependencies on a plethora of other JEDI units. ✅ Data source: Unicode tables are generated from official Unicode data files. Source for converter provided. ✅ Table format: Generated resource files. 🔵 Unicode level: Currently at Unicode v13. ✅ Completeness: All Unicode tables are available. ✅ Hangul decomposition: Yes. ⛔ Customizable: Required data and structures are private. ⛔ Other: Requires installation (to generate the JEDI.inc file). 🔵 Unicode normalization test suite: Unknown The FPC implementation has had the composition part removed so that immediately disqualifies it and the JEDI implementation, while based on an originally nice and clean implementation, has gotten the usual JEDI treatment so it pulls in the rest of the JEDI jcl as dependencies. I could clean that up but it would amount to a fork of the code and I would prefer not to have to also maintain that piece of code. That leaves the PUCU library and I currently have that integrated and working - or so I thought... Unfortunately, I have now found a number of severe defects in it and that has prompted me to search for alternatives again. Here's the project I need it for: https://gitlab.com/anders.bo.melander/pascaltype2
-
In the end, I had to abandon PUCU as the author never bothered to react to my bug reports. Instead, I tried to adapt the JEDI implementation: I removed all dependencies and fixed the worst bugs and performance issues. Finally, I ran the code against my unit tests. The result was a big disappointment; While it didn't crash like PUCU, it failed even more of the test cases. The test suite uses the 19,000 NFC (compose) and NFD (decompose) normalization test cases published by the Unicode consortium. So back to square one again. Comparing the algorithms used by the JEDI library against countless (I've looked at over a hundred) other Unicode libraries didn't reveal the cause. They all used the same algorithms. Blogs and articles that described the algorithm also matched what was being done. I was beginning to suspect that Unicode's own test cases were wrong, but then I finally got around to reading the actual Unicode specification where the rules and algorithms are described, and guess what - Apart from Unicode's own reference library and a few others, they're all doing it wrong. I have now implemented the normalization functions from scratch based on the Unicode v15 specs and all tests now pass. The functions can be found here, in case anyone needs them: https://gitlab.com/anders.bo.melander/pascaltype2/-/blob/master/Source/PascalType.Unicode.pas#L258 Note that while the functions implement both canonical (NFC/NFD) and compatible (NFKC/NFKD) normalization, only the canonical variants have been tested as they are the only ones I need.
-
Paste image from clipboard : RGB becomes BGR on IOS 64 bits ?
Anders Melander replied to FabDev's topic in FMX
The bitmap in that issue is a version 1 BMP in BI_RGB format so the problem I mentioned does not apply. Issue RSP-37651 might be related. According to that issue, it's fixed in 11.2 but as far as I can tell from looking at the source in 11.2 it hasn't been fixed. At least not in the way suggested by the reporter. -
Paste image from clipboard : RGB becomes BGR on IOS 64 bits ?
Anders Melander replied to FabDev's topic in FMX
I don't have time to look at the source but if the bitmap being pasted is a 16 or 32-bit BMP bitmap with BI_BITFIELDS encoding then the problem can be that Delphi's TBitmap doesn't really support the nuances of that format. The BI_BITFIELDS format uses 3 (or 4, depending on the BMP version) mask values that specify the layout of the RGB channels in the pixel values and AFAIR TBitmap ignores the mask values and instead assumes a certain layout. -
Localization of constant arrays - best practice?
Anders Melander replied to Fr0sT.Brutal's topic in General Help
If only someone had already solved all those problems... I haven't tried it but I would just compile for Linux and see what it produces. -
My TStringList custom SORTing, trying to mimic Windows Explorer way
Anders Melander replied to programmerdelphi2k's topic in Algorithms, Data Structures and Class Design
It's called "Natural" sort order. Explorer probably uses StrCmpLogicalW but there's also CompareStringEx with SORT_DIGITSASNUMBERS? See also: Sorting for Humans : Natural Sort Order- 5 replies
-
- tstinglist
- sort
-
(and 2 more)
Tagged with:
-
Localization of constant arrays - best practice?
Anders Melander replied to Fr0sT.Brutal's topic in General Help
Like this: https://bitbucket.org/anders_melander/better-translation-manager/src/f96e7dcdba22667560178d32aebb5137484107f0/Source/amLocalization.Model.pas?at=master#lines-578 // ----------------------------------------------------------------------------- // // Strings // // ----------------------------------------------------------------------------- resourcestring sTranslationValidationWarningEmptyness = 'Source or translation is empty and the other is not'; sTranslationValidationWarningAccelerator = 'Accelerator count mismatch'; sTranslationValidationWarningFormatSpecifier = 'Format specifier count mismatch'; sTranslationValidationWarningLineBreak = 'Linebreak count mismatch'; sTranslationValidationWarningLeadSpace = 'Leading space count mismatch'; sTranslationValidationWarningTrailSpace = 'Trailing space count mismatch'; sTranslationValidationWarningTerminator = 'Translation is terminated differently than source'; sTranslationValidationWarningPipe = 'Pipe character count mismatch'; sTranslationValidationWarningSurround = 'Surround character mismatch'; const // Note: Must use PResStringRec or values will be of the language active at the time System._InitResStrings was called, // which means that the user language selection will not affect the values as it should. sTranslationValidationWarnings: array[TTranslationWarning] of PResStringRec = ( @sTranslationValidationWarningEmptyness, @sTranslationValidationWarningAccelerator, @sTranslationValidationWarningFormatSpecifier, @sTranslationValidationWarningLineBreak, @sTranslationValidationWarningLeadSpace, @sTranslationValidationWarningTrailSpace, @sTranslationValidationWarningTerminator, @sTranslationValidationWarningPipe, @sTranslationValidationWarningSurround); and then use the strings like this: https://bitbucket.org/anders_melander/better-translation-manager/src/f96e7dcdba22667560178d32aebb5137484107f0/Source/amLocalization.Dialog.Main.pas?at=master#amLocalization.Dialog.Main.pas-2600 Item.Caption := LoadResString(sTranslationValidationWarnings[Warning]); FWIW, I believe this is also the way the VCL/RTL itself does it. -
The problem with docking is that most users don't understand how to use it. I mean, if they have problems with maximized MDI forms, docking isn't going to be easy to understand. That said, one could use docking with manual docking disabled. That way it's just used to organize the forms into a fixed layout.
-
I used to work on a project that allowed the user to switch between SDI and MDI. We used DevExpress, FWIW. As far as I can see from the code, all I did to make it work was set Visible=False on the child form before changing FormStyle and set Visible=True after. You'll also need to adjust the size/position and maybe also the BorderIcons; In our application, we hid the Maximize button in MDI mode because the maximized form would hide the MDI icons (the buttons representing the other, minimized, MDI children) and the user would get confused. As far as I recall we also manually managed the layout of child-forms in MDI mode. Also, and I'm working from 6-7 year old memory here, I believe you need to have Formstyle=fsMDIForm on the main form and keep it that way. MDI child forms are made visible in their constructor (TCustomForm.Create probably) or when FormStyle is set. To avoid that, in the child form constructor, you need to Include(FFormState, fsCreating) before setting FormStyle, set FormStyle and then Exclude(FFormState, fsCreating). You also need to Exclude(FFormState, fsVisible) to avoid the form being shown when the constructor exits.
-
SvCom - Services 64bit on Delphi 11.3
Anders Melander replied to FPessina's topic in Delphi Third-Party
I've written many, many Windows services and never encountered anything that couldn't be satisfied with the standard Delphi service classes. I'm curious; Why is it that you need to use SvCom at all? -
Please support Stack Overflow moderators strike against AI content policy
Anders Melander replied to Dalija Prasnikar's topic in Tips / Blogs / Tutorials / Videos
Wow. Excellent article (but a bit long). Thanks. I particularly liked this one at the end: -
Please support Stack Overflow moderators strike against AI content policy
Anders Melander replied to Dalija Prasnikar's topic in Tips / Blogs / Tutorials / Videos
It's like watching a slow-motion car crash. Pretty fascinating, really. -
More specifically here: http://melander.dk/delphi/gifimage/#faq_2 Sorry for the completely broken site (when using https). As should be evident I really don't update it anymore.