Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by aehimself

  1. aehimself

    Form no longer repaints after WM_SETREDRAW

    @PeterBelow, @Anders Melander Good point, I tend to forget about this. However in this case the handle seems to be the same, even when during the destructor.
  2. aehimself

    jpg validation

    My 2 cents are... not releasing write lock / not closing file, or improper flushing to disk. I personally never had any issues with TJPEGImage like this. @dkprojektai If you really want to make sure, try reloading the saved file with the same, TJPEGImage object and catch any exceptions. As I stated above though, I would be surprised if there would be any. I think @Remy Lebeau is on the right track here and the DLL is not handling the file correctly. At the end of the day it might be a special requirement in the header / pattern what we don't know about.
  3. aehimself

    Add aย system-menu item to all applications?

    Come on. Let us to have some fun, life is not only strict and serious work. After all, there are people who always try to put some humor into their writing.
  4. aehimself

    Add aย system-menu item to all applications?

    Nice, I actually laughed on this ๐Ÿ™‚
  5. aehimself

    JSON as a way to save information in Firebird

    @Arnaud Bouchez I guess it all comes down to personal preference and possibility. There are cases when you are not allowed to choose the DB engine for your application, and there are cases when your application has to support some / most of them. My situation was exactly like this - someone decided to go with ONE DB engine only, and the whole software was built to use the engine-specific features. You don't necessarily have to agree with the design choices but you can only cook from what you have. As for preference I like the strict typing more but I can see the pros and opportunities of weak types (JSON is still the best for REST-like channels and local application settings store). I'll rather add a column to a database than to verify before each data access if the value exists, if it is a known (and accepted) type and if it has the information which I need. Especially if the user has the freedom or the possibility to access / change these objects (in my consideration if the software is running on their systems, they do). If you have the freedom and do not plan your database to grow too large - go for it. All I'm saying is that I already burned myself with this and therefore quickly became a no-go in future designs.
  6. This. I remember having a similar issue a couple of years ago calling .DLL exported functions when I switched from D7 to D10.2. The issue was memory allocation for a string (* SizeOf(Char) was not included) which lead to a nice and beautiful memory corruption. The application always crashed several functions later so it was a pain in the butt to find it. Anyways, memory corruption would indeed be my guess in this case, too.
  7. aehimself

    Best components for creating windows service apps

    POWEREVENT, TIMECHANGE ๐Ÿ™‚ I already had to make workarounds for these. Good to know, thank you very much!
  8. aehimself

    Best components for creating windows service apps

    I never had to do anything fancy - reply to stop, start, pause, resume and shutdown events. Just out of my own curiosity and education - what are these features?
  9. Ouch. Why I always tend to overcomplicate things? ๐Ÿ™‚ This is the correct solution.
  10. if Num > 999999999 then raise Exception.Create('Can''t express more than 999,999,999 in words'); This made me giggle ๐Ÿ™‚ Seriously though, ours is somewhat similar. It's not this sophisticated though.
  11. We did something like this in a commercial application: it only handles numbers up to 9999 but in multiple languages if I'm not mistaken. To be completely honest, it's quicker just to write your own from scratch which will satisfy your needs rather than to look for one. The code I was talking about is about 50-100 lines in Delphi... Due to it's commercial nature I'll not be able to share sniplets, but it's basically these rules in lots of "if" statements ๐Ÿ™‚
  12. aehimself

    Best components for creating windows service apps

    Agreed, this is a possibility in most cases; I just don't see a reasonable chance when it comes to Windows Services. Even if Embarcadero would decide to re-write the logic, they'd probably keep the event handlers and the class name so it stays backwards compatible... I hope ๐Ÿ™‚ if not, most of us will be in a big trouble ๐Ÿ™‚
  13. aehimself

    Application blocking (suspended)

    When my applications stop processing Windows messages it's always a very long processing in the VCL thread. Like reconnecting to a database, refreshing a huge dataset or I simply messed something up and my code got in an endless loop ๐Ÿ™‚ This is when correct logging can save your life: I'm usually logging when an action starts and when it ends. When the application freezes just check which action started, which did not report back as finished.
  14. Hello, I will be honest I don't understand the question correctly, but if you'd like to identify if the received string is a JSON or an XML, you can use this: Uses System.JSON; [...] Var x: TJSONValue; begin x := TJSONObject.ParseJSONValue('this is the received file'); If x = nil Then Begin // File is NOT JSON -> it is XML (or other webserver generated error page) End Else Begin // File is JSON, values can now be accessed by object "x" End; end; In the x = nil branch you could make an XML-to-object parsing to confirm if it's XML and simply stop processing if not. I never worked with XMLs from my codes so I have no knowledge on how to do that, though ๐Ÿ˜ž
  15. aehimself

    Best components for creating windows service apps

    I personally never used SvCom but even if it's unsupported I would not worry about it. The way Windows handles services (service control messages) did not and could not change as it would break backwards compatibility (you wouldn't be able to install / start a service on Windows 2003, only on 2019 - never seen that, unless it was an API dependency in the business logic). A component to create a service application mostly contains a code to handle these SCMs, which are the same since Windows 2000.
  16. aehimself

    Best components for creating windows service apps

    I wrote all of my Windows service applications based on Delphi's TService and I did not find any showstoppers which made me want to change it. It's robust, small and gets the job done quite well. A small tip though. Since service applications are hard to debug, I started to implement the whole business logic as a simple Class which is being created and destroyed based on what is happening with the service. Change the .DPR like this: If Not FindCmdLineSwitch('console', True) Then Begin If Not Application.DelayInitialize Or Application.Installing Then Application.Initialize; Application.CreateForm(TService1, Service1); Application.Run; End Else StartWithConsole(TMyServiceClass); ...where StartWithConsole is just a small procedure which creates a console window with AllocConsole, creates the service class, redirects the logging output to StdOut and handles the console handlers (like Ctrl-C, etc). This way there's only one executable, which can be started as a command line application for easy debugging and as a Windows Service as well. P.s.: don't forget about creating a custom message pump, some components rely on Windows Messages to work properly!
  17. aehimself

    Setting Environment Variables

    I just checked my old codes and yes - they do take effect after the broadcast was sent. Must have mistaken it with setting it somewhere else in Windows...?
  18. aehimself

    Setting Environment Variables

    Also please note that in Windows several environmental variables requires a logoff-logon for the changes to take affect (like %PATH%).
  19. Hello, I was just wondering if this is "normal" or just an anomaly on my side. Consider the following code: Set a breakpoint on sl.Add and execute. When the execution stops, press F8. However the Except block executes, the Delphi debugger does not continue the step-by-step debugging. I know, you can put a breakpoint on On E:Exception but it would be a lot nicer to see how the exception is flowing (especially through 5-10 units until it reaches the final handler). Is there a way to achieve this or it's just a limitation of the debugger? Cheers!
  20. aehimself

    Step-by-step debugging exceptions

    Shift-F8 will return at the end of the calling method, in this case the OnClick handler. It will NOT put you inside the Except block in any case. As for TStringList, I just chose something random, you can even put Raise Exception.Create('hello world'); instead. Also, I believe that when you try to access an uninitialized object it does not matter where it comes from, as it does not exist... I am afraid that @Fr0sT.Brutal will be right, and this - too - is going to be a limitation of the IDE. Too bad ๐Ÿ™‚
  21. aehimself

    JSON as a way to save information in Firebird

    Based on experience I am against this type of data storage for several reasons: - Some database engines can not search in BLOB fields. Now it might not be an issue in the beginning but it makes investigating data corruption / debugging processing issues a living nightmare - Downloading blob fields are slow, no matter what. Especially over the network. In our production databases I can select hundreds of thousands of rows with 150+ columns but only a fraction of that 2 fields: an ID and a BLOB storing an XML - Database engines are robust, they were built for having columns. While it can be hard / intimidating to see the relations at first time, they have no issues handling a larger number of columns - Unless the DB engine has built-in JSON support, you'll not be able to query and compare a specific value on database side, you'll always have to download and compare from code, increasing memory, network and CPU usage of your program. Considering a well-fed metal (our slang for a server with enough resource + overhead) running the database, this will always be significantly slower than letting the DB engine to take care of these The only reasonable case when storing a JSON / XML in a database I can see is if you receive that from an external source (like a REST server or a 3rd party sending your software some information) and you want to keep those chunks for auditing purposes. Sooner or later you'll face one of the issues I mentioned, though ๐Ÿ™‚ We did the same about 8 years ago (only with XMLs) and now we are looking into opportunities to undo it...
  22. aehimself

    VCL component issue

    A quick and dirty way of adding this component in design time is to switch the platform back to Win32, drop the component and then switch back (even completely remove the Win32 platform). I usually have to do this with my 64bit applications using database access components.
  23. Hello, Of course, this information is included in the update file and (except for the download link) are published by the thread object as properties. For simplicity's sake I decided not to include them, but here you go ๐Ÿ™‚
  24. A thread with local variables was always my solution as well. When my application starts it launches a background thread which downloads the update definition file and notifies the main form to show the "Updates are available". Everything until here is not locking the UI. When the update form is shown and the user clicked "Yes" the main form calls a .Update method in the thread which downloads the update file, verifies it etc. and returns a simple bool if it was successful or not. This way no global variables were defined, no complex types were passed between threads and most of the work was done without locking the UI. Threads are a good thing.
  25. aehimself

    JSON string value

    I am using Delphi 10.2.3 and wow, I wish I knew about this before I started my first project... now I have to go back and correct them all ๐Ÿ˜„ I can confirm that s.ToJSON is producing the exact same output as it was originally requested: s.ToString with the replacements produces "\"value\\with\n{strange}chars/\"" s.ToJSON produces "\"value\\with\r\n{strange}chars\/\"" Lesson learned. Do not try to reinvent the wheel, just realize if I messed up the implementation. (I wonder why it has a .ToString if it is not producing a correct syntax though...)