Jump to content

Anders Melander

Members
  • Content Count

    2561
  • Joined

  • Last visited

  • Days Won

    133

Everything posted by Anders Melander

  1. Anders Melander

    Use of inline variables..

    ...or without the temporary buffer: function ComputerName: string; begin var Size: Cardinal := 0; if (not GetComputerName(PChar(Result), Size)) and (GetLastError <> ERROR_BUFFER_OVERFLOW) then RaiseLastOSError; SetLength(Result, Size-1); if (not GetComputerName(PChar(Result), Size)) then RaiseLastOSError; end;
  2. Anders Melander

    Looking for a localization tool

    It's unavoidable. For instance if a resourcestring is deleted then the whole range of IDs above it must change their ID. With regard to Windows resources I don't think ordinal resource IDs (not just string IDs) were ever meant to be stable. Instead we were supposed to use .rc and .h files and symbolic names - which is basically what the drc file is.
  3. Anders Melander

    Looking for a localization tool

    Good point. Luckily it's just the numeric ID values that change and these values aren't even guaranteed to be stable across compiles within the same platform. This is why BTM (and I'm guessing Soluling too) use the resourcestring names instead of the ID values to identify the strings. The DRC file contains the mapping between name and ID value and this file is used when scanning the source application and when building the resource module DLL. So in order to build a resource module for a particular platform, you just point the build tool to the exe and drc of that platform and you will get a resource module that matches them.
  4. Anders Melander

    Looking for a localization tool

    Thanks for the kind words. Much appreciated. Yes, I made a conscious choice not to include any kind of form editor or preview, even though I have these features implemented locally, simply because they never work reliably. The main problem is that in case your forms contains 3rd party controls, then the viewer/editor will need to be able to load the runtime packages containing these controls, and the packages have to be the correct version, for the correct version of Delphi. etc. etc. It's a nightmare. For in-house translation, I think I came up with a better solution to providing context. With a few lines of code one can have BTM follow the focus of the target application. Start the target application, open a form in the application and BTM will automatically select the corresponding module. Click a control in the application and BTM will select the properties of that control. Of course with external translators providing the application, and all the dependencies it might have, might not be feasible (it isn't in our case). In that case a simple screenshot should do it. No need for that. The language modules, as @aehimself said, are just empty resource DLLs with no code. The same DLL stub is used for 32- and 64-bit. Sure there is; It's called a Stop List. You can configure properties or modules to ignore based on a plethora of different rules - or regex if everything else fails. Validation is performed live. In addition, you can validate the whole project via the ribbon: BTM validates a host of different properties such as leading and trailing space/colons/whatnot, delimiters, shortcuts, case (and type of casing), etc. etc. Many validation violations can be resolved automatically. Some are too risky to try and do automatically. I don't know what you mean by "interactive TM/MT/terms". If you mean automatic translation lookup and prompt, then BTM does that too. The UI sucks a bit though. Yes, these are Windows common controls and unfortunately, the VCL developers chose to persist them using their internal binary (and undocumented) stream format. If you look at the DFM file of a form containing one of these controls you will see what I mean. I guess I could write adapters specifically for these controls but so far I haven't had any requests for them.
  5. Anders Melander

    FireDAC performances

    Ditto. And ditto on your options. Before trying to solve this problem you should determine where your bottleneck is instead of guessing. Is it the DB server, the network, the middleware (FireDAC), or your own code? Examine the CPU, network usage, and DB server (using the activity monitor) during execution. Who's waiting on what? Profile your application or, if you don't know how to do that, just repeatedly pause your application in the debugger and examine the call stack. Chances are that the bottleneck will be somewhere in the call stack. It's a poor man's sampling profiler.
  6. Anders Melander

    Issue in copy and past

    You might not have started anything manually but there are always programs running in the background. This isn't DOS after all. I would suggest you run a virus scanner on that system ASAP. My guess is that "something" has hooked into the clipboard chain and is corrupting the clipboard. If the list contains CF_UNICODETEXT then it should also contain CF_TEXT because the clipboard internally synthesizes between the two formats automatically. It is impossible to only have one of them on the clipboard.
  7. Anders Melander

    Issue in copy and past

    I would start by examining what it is you put onto the clipboard. You can use a simple clipboard viewer for this but it needs to be able to display the data as hex to be of much use. The Drag and Drop Component Suite has a Drop Source Analyzer application that can do it. If you're brave you can use the one I have attached. SourceAnalyzer.zip
  8. Anders Melander

    Lazy loading progressbar dialog

    https://bitbucket.org/anders_melander/better-translation-manager/src/master/Source/amProgress.API.pas and another, slightly older, version of the same: https://bitbucket.org/anders_melander/dwscriptstudio/src/master/Source/amProgress.pas and even a DWScript wrapper (the second & third screenshots are actually from a DWScript): https://bitbucket.org/anders_melander/dwscriptstudio/src/master/Source/ScriptRTL/amScriptModuleUserInterfaceProgress.pas Displays a non-modal form with a progress bar, a status message, and an optional cancel button. Defer the initial display of the progress form (what you call lazy loading). Default delay is 500 mS. Limit rate of progress update to minimize UI overhead. Default is max 1 update per 100 mS. Selectively pumps message queue to avoid application freeze and enable user to move/cancel progress dialog during use. Progressive or marquee mode. The current implementation uses DevExpress label and button controls but these can just be replaced with regular VCL controls without any loss of functionality. Usage: var Progress := ShowProgress('Hello world', False); Progress.EnableAbort := True; Progress.Progress(psBegin, 0, 100, 'Charging flux capacitor...'); for var i := 0 to 100 do begin Sleep(100); Progress.AdvanceProgress; end; and in Marquee mode: var Progress := ShowProgress('Hello world', False); Progress.EnableAbort := True; Progress.Marquee := True; Progress.UpdateMessage('Charging flux capacitor...'); while (not Progress.Aborted) do begin Sleep(100); Progress.AdvanceProgress; end;
  9. Anders Melander

    function returning interface

    Thanks very much. Works in Delphi 11.0 too it seems. This was driving me absolutely crazy because I was so sure that it wasn't a problem anymore but I just couldn't get it working. Some of my projects are in Delphi 10.3 and some are in 11.0 so that explains the confusion. I'll bet that in a year or so I will be in this situation again but at least there's a chance I will find this thread then 🙂
  10. Anders Melander

    Change parameters when compiling using dcc32.exe

    Run the application in the debugger and when the dialog appears, pause the application in the debugger. You should then be able to examine the call stack in order to determine exactly where in the code the dialog is shown.
  11. Anders Melander

    32bit vs 64bit

    Sorry to hijack the topic but: Wow! I had completely forgotten about that gem of a library. There's a Double version to ease the transition: damath.pas Can someone explain the following from the readme for me: Why aren't they correctly rounded? I ask because it's an optimization technique I use a lot.
  12. Anders Melander

    The Delphi 11.2 release thread

    Fair enough; Then state that these platforms requires Windows 10.
  13. Anders Melander

    The Delphi 11.2 release thread

    Yes, we can't rule it out. My point was that they should be able to unless their developers are a bunch of cowboys.
  14. Anders Melander

    The Delphi 11.2 release thread

    I'm not sure I understand what you mean. Do you mean that there are dependencies which requires Windows 10? I could understand if they explicitly excluded support for Windows 8.x since it's probably impossible to find anyone running that of their own free will. I haven't installed 11.2 but I haven't had any problems with prior versions and I'm running Windows 7...
  15. Anders Melander

    The Delphi 11.2 release thread

    Because they know if they introduced new dependencies (at least they should know). And presumably they have beta testers using these environments.
  16. Anders Melander

    The Delphi 11.2 release thread

    Definitely. It's not that some of the things that are in the release isn't nice but given the fact that this major release is a year old today I guess I just expected something more. If there had been a roadmap I wouldn't have had these apparently unrealistic expectations. Anyway, it is what it is. No big deal - yet.
  17. Anders Melander

    The Delphi 11.2 release thread

    Remember back in the day when a new release made you go Wooo Hooo ? This release? Meh
  18. Anders Melander

    FireDAC array DML performance issue

    You could probably have used the MSSQL Server Profiler to determine what the server is doing when you run the query. With regard to transactions, I always use explicit transactions. BeginTransaction; try DoStuff; CommitTransaction; except RollbackTransaction; raise; end;
  19. Anders Melander

    Profiling Clipper2

    Um... Unicode, 64 bit, generics, anonymous methods, inlining, record methods....? Thanks. Halfway there 🙂 Unfortunately I don't think it's a realistic goal to beat C++ without rewriting the hotspots in assembler.
  20. Anders Melander

    Profiling Clipper2

    Why? I get it that there are people who are stuck on Delphi 7 and refuse to upgrade but do those people really need your library? You can move the assignment of nodeI outside the loop and increment it inside the loop. I doubt that it makes any difference in performance but at least it will not trigger my OCD. I'd be interested in seeing how the performance compares against C++ and C# at this point. Can you post the updated numbers, please?
  21. Anders Melander

    Profiling Clipper2

    Yes it should be but I think there might be too much register pressure here for the compiler to generate the code we want. Haven't tried it though. Also we need the pointer anyway after the iteration. Left as an exercise to the reader :-)
  22. Anders Melander

    Profiling Clipper2

    With Delphi 10.3 the benchmark is slower when compiled for 64-bit compared to 32-bit. Are you seeing something else? They make a pretty big difference on my system when compiled for 32-bit. I'd say around 20% improvement. I could be wrong because I'm working on my day job at the same time. I just tried using a pointer instead of the list getter inside the loop in ProcessIntersectList and that seems pay off: procedure TClipperBase.ProcessIntersectList; var ... node: PIntersectNode; node2ptr: ^PIntersectNode; ... begin ... for i := 0 to highI do begin node := UnsafeGet(FIntersectList, i); if not EdgesAdjacentInAEL(node) then begin j := i; node2ptr := @FIntersectList.List[j]; repeat inc(node2ptr); until EdgesAdjacentInAEL(node2ptr^); // now swap intersection order FIntersectList.List[i] := node2ptr^; node2ptr^ := node; end; ...
  23. Anders Melander

    Profiling Clipper2

    What Stefan wrote 🙂 I had my focus on the exact same three areas and had made almost the same changes. When you look at the profiling of the generated asm it becomes pretty clear what the bottlenecks are - down to the individual statements. In addition to Stefan's modifications I would try to see if it made any noticeable difference to test for (i = 0) last in IntersectListSort because presumably the two other conditions are met more often. It could eliminate one or two branches. I would also consider if quick sort is the best algorithm to use. For example if the list is already "almost sorted" (for example because a sorted list was modified), insertions sort might be a better choice.
  24. Anders Melander

    Profiling Clipper2

    I hadn't thought about using TLists.List so I would probably have tried avoiding TList altogether. Maybe TLists.List is good enough and it's certainly an easier fix that replacing TList. A new profile run would answer that. I only spent 5 minutes looking at the profile result yesterday so I can't give much details, but one thing I noticed is that you're iterating a list sequentially in ProcessIntersectList. Since TList is basically just a wrapper around a contiguous array, a sequential iteration can be done by just incrementing a pointer inside the loop thus bypassing the getter altogether. The profile results also hints that some things might be made slightly faster just by moving things around a bit. A better optimizer would have done that for us but alas we have to work with what we got. I will try to find time to look at this more closely this week end.
  25. Anders Melander

    XML viewer component

    Something like this? The above was done with a standard TTreeView using ownerdraw (and "a few" hacks). I've attached the source but it's part of a larger framework so it will have to be tweaked a bit in order to work standalone - Minor stuff. If I were to implement this today I would definitely use Virtual TreeView instead; L oad the XML into a DOM (e.g. MSXML/IXMLDocument), populate the treeview and ownerdraw the nodes. amResourceViewXML.pas amResourceViewXML.dfm amTreeView.pas
×