Jump to content

aehimself

Members
  • Content Count

    1030
  • Joined

  • Last visited

  • Days Won

    22

Everything posted by aehimself

  1. aehimself

    One more memory leak and FastMM4

    We are getting close to the next release so time is not that much to spare, but I managed to run my test. DeLeaker shows about the same results with 1, 2 and 5 copies of "s". I am no expert with memory leak detection in Delphi, but can someone explain this to me? No leaks, however (on a Unicode Delphi) this used up twice as much space as it was reserved. Fine, it's not a leak (as it is properly released), it's corruption. But why StrPCopy(pc, s + s); already pops up as leak in this case?
  2. aehimself

    Regex Validate string

    Ummm.... Why make a string? Why not getting rid of Allowed and setting Result directly? Why going through character by character if Regex can validate the whole string at once? If I'm not mistaken you'll achieve the same with this one line: Result := Regexs.IsMatch(svalue.Trim, '^[ء-يA-Za-z0-9$&+=?@#~<>.^*()%!\s]+$');
  3. aehimself

    tiny computer for Delphi apps

    According to the initial specs it has an USB - which can host both. But this immediately adds a USB hub / USB NIC / serial to USB to the price in a real-world application. I don't know how well USB handles dusty, hot and or moist environments though to call this reliable.
  4. aehimself

    tiny computer for Delphi apps

    A kiosk is - usually - a larger hardware, allowing the manufacturer to stuff in standard PC / laptop parts. In case something goes bad, they can swap it without changing the whole thing. This allows less downtime, cheaper and quicker repairs - probably happier customers. There is always a way, we have way too many (not that ethical) ethical hackers and hardware nerds (and I say that in the most positive meaning); it's only a matter of time when one of them decides to do it. Win10 IoT Core seems to be installable on an Rpi: https://www.techrepublic.com/article/windows-10-on-the-raspberry-pi-what-you-need-to-know/ I never used an Rpi (I'm more of an Arduino person), so it's possible that it's outdated or not working anymore. Take it with a grain of salt, this was just the first Google hit. Now I don't want to start anything in this topic, but even I received officially purchased hardware, coming with the software on an unlabeled CD-R with a readme file stating "Execute the ... application in the \Crack folder". I have absolutely no experience with Chuwi per se, so I might be damn wrong and in that case I immediately apologize for assuming. All I'm saying, they are located where most of the AliExpress sellers are 🙂 It's called IoT. It exists. The difference is, they have dedicated hardware for one specific task. This makes production cheaper, devices sucking less power. For comparison: Arduino is running a standard ATMega chip. An Arduino can be connected to the TCP/IP network. With a bit of soldering, you can "build" your own Arduino and upload your projects on a single chip (on 8 Mhz, for 16 Mhz you need a crystal and two capacitors, too). If you do power management right, those beasts are using picowatts, allowing them to be able to run on batteries. Specialized hardware will beat general hardware in price, space and parts required and power consumption. I'm not going to quote the whole "car" thing, I'll just say "bluetooth". Most cars already have it, or can have it with a really cheap adapter. And why on Earth I would want to be able to read my E-mails in my car?! I should keep my eyes on the road and I already spend too much time "connected" - if you know what I mean. Reading this post back I admit that it sounds offensive, but believe me - there's none. I'm just saying these overminimized PCs are usually good for one thing: thin clients. Cheap, no clutter on your desk, the unbeatable processing power comes from a server room from 3 racks. I'll never buy something like this, but I'd be glad to play around with it if I'd get one for free. I'm a tech geek after all 🙂
  5. aehimself

    tiny computer for Delphi apps

    I am fond of mini PCs. Love them. But - as always - it always comes down to the basics. - What do I want to do with them? Use as a server? NAS? Replace my noisy and hot running PC? - What kind of processing power it has and is it enough for my needs described in point 1? Two years later if the room gets too tight, what are my options? Complete replacement, or simple expansion? - Power consumption, especially at 24/7 devices - Pricetag? I'm not going to spend a month worth of salary for something that is just "good to have". I own a HP ProLiant MicroServer G6 running ESXi, hosting my test environment. I have (severely underpowered) VMs running major Windows releases since 2000 and I am testing my apps on these. 24/7 availability is needed, as sometimes I code at 3 AM, sometimes at 8 PM depending on my mood and I don't want to wait for the system to start up. This machine is with me for about 6-7 years, and was only turned off when I expanded the memory, cleaned out the interior or swapped the power supply out with a PicoPSU. Price is ridiculously low (especially now, when Gen10 is the latest and greatest), processing power is acceptable, with the power consumption of 50 watts peak; averaging around 30 with 1 SSD and 2 HDDs. If I'd have to buy something like this again, I'd look in this area; not something what a startup company is attempting to crowdfund. It's usually the other way around for me. I write an app which fulfills a job I want it to, and then install it on the machine where the job is done. I'm not writing something because I have a dedicated platform and I want to make use of it 🙂
  6. aehimself

    Up-to-date 32 bit libmysql.dll?

    I guess no. LibMariaDB is a valid replacement; the question is, though, until how long they will stay compatible.
  7. aehimself

    One more memory leak and FastMM4

    Damn, forgot about multithreading, too. +1 for that sharp eye! I never actually thought about this. Running this on a Unicode Delphi shows no memory leaks (with ReportMemoryLeaksOnShutdown := True): Var pc: PChar; s: String; begin s := 'Hello, world!'; GetMem(pc, s.Length + 1); Try StrPCopy(pc, s); Finally FreeMem(pc); End; end; ...but make it StrPCopy(pc, s + s); and you have 2 unknown objects leaked. Make it 5 times s and you have 3 unknown objects leaked. I could not find 4 unknown objects without an actual access violation. I guess it's only the limitations of the shipped FastMM...? Since our company bought it, I'll run this code with DeLeaker tomorrow out of curiosity to see what it will say about it. At the end of the day, however, we all can agree that memory corruption is a bit more serious issue, and - personally - I would not even consider it as a memory leak 🙂 Still, an interesting aspect!
  8. aehimself

    One more memory leak and FastMM4

    Without manually modifying the pointer as you suggested and properly released owner... how exactly you can cause a memory leak with Strings? I always thought records, arrays behave like interfaces and are automatically discarded when their lifetime is over.
  9. aehimself

    Again with memory leaks and FastMM4

    In my personal experience, leaks pointing to some kind of a Sting routine are never the leaks you have to pay attention to. They are never the cause, they are the side effect - especially if the allocation is initiated in a in a component (let's hope 🙂 ). As @Kas Ob. said, most probably you forgot to release an instance which is keeping the reference count high. Unless if you are playing with reference counts yourself, that is. And again supporting the statement above mine - I never had a leak which could be fixed in the same method. Because of messed up design, sometimes releasing the object had to go to a different unit! Always handle allocation call stacks as a pointer only. You have to know what was allocated and why - and when that specific instance can be released.
  10. aehimself

    Trying to DL image yields a web page instead

    That is exactly how it looks like from the webapp's perspective. A is logged on, B is not. Well, not security context but it has a valid session open. But effectively yes. Having your username / password is always going to be way more easy. Normally session identifiers can distinguish between browser instances running on the same PC with the same user. Which means, even if you can "catch" that session ID somehow, it's not going to work from your Delphi app. I'd just drop a TWebBrowser / TEdgeBrowser on a form, make the users use this program to use the ticketing system. From within the program you can easily get the page source, discover and download attachments automatically within the exact same session. Even without drag & drop.
  11. aehimself

    Trying to DL image yields a web page instead

    You can try: http(s)://ticketing.system.local/images/imagetobedownloaded.jpg?username={URL_Encoded_Username}&password={URL_Encoded_Password} or, add a header to the request: Authorization=Basic {Base64_Encoded username:password} or, if you are lucky, there will be a (now unhandled) onAuth event in the component. When it fires, you can set the username / password to access the resource. These all require though that the system allows these kind of authentications. If you are unlucky, you still can "log on" first and then download the picture with the component. Just make sure you re-attach the session cookie in the second request.
  12. One connection per thread is like an unwritten rule. I experimented with one connection for 7 workers, but gave the idea up quickly. One thing I found strange is that if I called dataset.Open in a background thread, I had to call .FetchAll too, otherwise it still froze the VCL thread upon accessing .RecordCount. But the jumping between records error still makes me believe that the connection is going to be the issue - if FireDAC works similar to the components I use.
  13. You don't need much time - it's about 200 lines 🙂 As I said I tried to keep it as simple as possible. If someone needs more, the code is easy enough to be extended with someone's own needs. Completely agreed. That's one reason I chose to hand over the code to the Zeos team. I wrote a custom DB management app and I needed to keep the GUI responsive even if the user entered a hour-long query. That's when I came up with the idea of pushing it to a background thread. It does nothing though if you can not gracefully end it so aborting running operations was born. I needed it to satisfy my colleagues needs using my tool and it felt good to finally give something back to the component I was using for long years now. Effectively a win-win situation.
  14. @Dany Marmur I used to have one but I decided to discontinue my own website as it started to be a burden to maintain. The idea is to be as simple as possible: Type TProcedureOfObject = Procedure Of Object; TErrorEvent = Procedure(Sender: TObject; Error: Exception) Of Object; TZMethodThread = Class(TThread) private _runmethod: TProcedureOfObject; _onerror: TErrorEvent; protected Procedure Execute; Override; public Constructor Create(inMethod: TProcedureOfObject; inErrorEvent: TErrorEvent; inFinishEvent: TNotifyEvent); ReIntroduce; End; Constructor TZMethodThread.Create(inMethod: TProcedureOfObject; inErrorEvent: TErrorEvent; inFinishEvent: TNotifyEvent); Begin inherited Create(False); _runmethod := inMethod; _onerror := inErrorEvent; Self.OnTerminate := inFinishEvent; End; Procedure TZMethodThread.Execute; Begin Try If Assigned(_runmethod) Then _runmethod; Except On E:Exception Do If Assigned(_onerror) Then _onerror(Self, E); End; End; And then there is a "wrapper" around this, where you just pass a dataset and it is creating a TZMethodThread with Dataset.Open for example. I hope I can say this and it's not considered an advertisement; the latest version of the unit is included in Zeos 7.3 (look for ZMethodInThread.pas) which is although "specialized" can easily be ported back to use a standard dataset. Or throw the wrapper out and just use the thread with any procedure of object - with the necessary caution to VCL synchronization, of course.
  15. aehimself

    RTTI in dpr / console app dpr

    This is exactly what I started to do lately. All my applications business logics are basically a TObject-descendant, and service initializations or console launchers only create an instance of them. I find this structure really easy to test, to port, to maintain or extend. This might be my own personal preference, though.
  16. aehimself

    Error Insight error?

    This is something I can not c ompare. The first thing I always did on a fresh Delphi installation is to disable error insight altogether as it made the IDE unbearable slow with 1500+ units and 20-30 custom components. Therefore I don't know how bad it was before - I had hopes with 10.4 and LSP - it did not come up to my expectations, unfortunately. I personally like Delphi's IDE a lot more than Visual Studio, but VS's error insight works a lot better (even with large projects), unfortunately. It hogs up the system more too, though. When refactoring, I'm following these guidelines too. As least visibility to properties as absolutely needed, cutting out excess things from the Uses list, etc. As I said - unfortunately - my experience is far from yours. With a low number of units and 3rd party components wiggly lines are likely there to stay until execution / IDE restart 😞 Hopefully this week I'll start to check how Delphi 10.4 handles a big project at work... with poorly written code, interfaces here and there, 10+ depth in dependencies... that will be the true test, though. It will decide if we move or stay on 10.3.
  17. I don't use FireDAC, but a 3rd party library to connect to databases, Unfortunately though, they work in async mode only, so a huge query with lots of blob fields could take up to a couple of hours (!!!) to load through the Internet. God bless those SELECT * FROM ... JOIN ... JOIN ... JOIN ... type queries. My solution was to unhook all datasets from any datasources, and call the dataset's .Open method in a separate thread, Once the thread finishes it executes a callback routine to hook the datasets back to the datasources. This resulted a completely unblocked VCL thread, and I even could implement a button to execute the "Abort" command through the same connection if the user does not want to wait until the end of the query. You can create a custom TThread descendant with a parameter of a dataset, but I chose to take an incoming Procedure Of Object parameter instead. This way, I can execute the same thread with a Dataset.open, Dataset.Post or Connection.Commit when I please, leaving the application as responsive as ever.
  18. aehimself

    Error Insight error?

    Error insight (and code navigation) is still unreliable, unfortunately. I'm test-driving 10.4 with small projects (maximum 15 units) and sometimes the red wiggles stay until I restart Delphi (or run the application). Code navigation completely fails for some 3rd party components if the (system wide) library path is pointing to DCUs only and debug source path and browsing path is set to the source files. It usually can navigate to the first unit, but not to the second one from there (unless if it is already open)
  19. aehimself

    Your RAD Studio 10.4 Sydney issues

    This was my plan all along, I just did not see the "Custom themes" subkey 🙂 Thank you, @Lars Fosdal; this method works like a charm!
  20. aehimself

    Your RAD Studio 10.4 Sydney issues

    By mistake I already discovered this option and disabled it. It shows as off in Dephi IDE and ToggleTheme in Registry values stores 0. Still, color values in Editor \ Highlight \ * are being reset to the values of the scheme selected.
  21. aehimself

    Your RAD Studio 10.4 Sydney issues

    So I started to experiment with Delphi 10.4. When we switched to 10.3, I immediately installed the VS code color theme (https://blog.grijjy.com/2017/12/29/alternative-dark-editor-themes-for-delphi-10-2-2/) via the Migration Tool as I think it's the most eye-friendly scheme - plus I got used to it already. My issue is that Delphi 10.4 simply does not want to accept this. I tried to manually update the values in Registry but as soon as the IDE restarts they are being overwritten. Does anyone know where Delphi 10.4 stores the saved color schemes? I would try to create a new one and set it as a default for my dark theme; I just don't know where to put them 🙂
  22. Give TDirectory.GetFiles (System.IOUtils) a try. It drastically improved the time it took to discover everything compared to my recursive FindFirst / FindNext in my backup application.
  23. aehimself

    Nevrona Rave Reports

    It's fixed now. At the time of the original post my Edge reported it unsafe too, but now it goes there without an issue.
  24. aehimself

    TDBImage descendant

    Hello, I'm in the process of fixing some unusual amount of memory leaks and code errors in a legacy codebase. We have a custom TDBImage descendant, which was leaking TJPEGImages like there's no tomorrow. The code used to look like this: constructor TMyDBImage.Create(AOwner: TComponent); begin […] Picture.Graphic := TJPEGImage.Create; […] end; procedure TMyDBImage.DataChange(Sender: TObject); begin Picture.Graphic := TJPEGImage.Create; FPictureLoaded := False; if FAutoDisplay and (DataSource.DataSet.State <> dsInactive) then LoadPicture; end; procedure TMyDBImage.LoadPicture(ARefreshDataSet: Boolean = False); begin […] if not DataSource.DataSet.EOF and DataLink.Field.IsBlob then Picture.Graphic.Assign(DataLink.Field) else Picture.Graphic := TJPEGImage.Create; // Empty picture end; I guess they wanted to clear the image, so I changed all those TJPEGImage.Create-s with a simple nil assignments (Picture.Graphic := nil). I also changed the loading mechanism: procedure TMyDBImage.LoadPicture(ARefreshDataSet: Boolean = False); Var jpeg: TJPEGImage; begin [...] if not DataSource.DataSet.EOF and DataLink.Field.IsBlob then Begin jpeg := TJPEGImage.Create; Try jpeg.Assign(DataLink.Field); Picture.Assign(jpeg); // Picture.Bitmap.Assign(jpeg); This does not work either Finally jpeg.Free; End; End else Picture.Graphic := nil; // Empty picture end; The leaks are gone, but the picture is not shown in the component. I already confirmed that "jpeg" is filled correctly (stop with debugger, execute a .SaveToFile and check the result) but I can not really make the DBimage's Picture to load it. Based on my previous codes the Picture.Bitmap.Assign should be fine; I guess in this case it's the nil assignment of the .Graphic property which is not letting it to work? Where is my logic wrong? Thanks!
  25. aehimself

    Front-end vs Back-end question

    My preference is to have as low amount of files in my built applications as possible. Therefore I usually include the admin area. I really do dislike the pure "it depends" answers, but here yes, it depends on lots of different factors, including security, end-user needs and of course your own personal preference. Security, because the admin area might contain references you don't want an average "Hacker Henry" to see with a decompiler, not even as assembly code. End user needs, as for 3 checkboxes and a language selector the user might find it disturbing having to navigate somewhere else. Personal preference - which codebase is easier for you to maintain? Multiple applications with less code, or one application with more? And these are just the first ones which pop up in my mind, so treat this list as severely incomplete 🙂
×