Jump to content

aehimself

Members
  • Content Count

    1030
  • Joined

  • Last visited

  • Days Won

    22

Posts posted by aehimself


  1. 18 minutes ago, Skullcode said:

    current i use this function is it fine or more correction needed ?

     

     

    
    
    Function Checkstr(const astr: string):Boolean;
    var
    Regexs : TRegEx;
    i : integer;
    svalue : string;
    Allowed : string;
    begin
    
    svalue := Trim(astr);
    for i := 1 to Length(svalue) do
    begin
    
    if Regexs.IsMatch(svalue[i], '^[ء-يA-Za-z0-9$&+=?@#~<>.^*()%!\s]+$') then
    begin
    Allowed := 'YES';
    end else
    begin
    Allowed := 'NO';
    Break;
    end;
    
    
    end;
    
    
    if Allowed = 'YES' then
    begin
    Result := True;
    end else
    begin
    Result := False;
    end;
    
    end;

     

    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]+$');

    • Thanks 1

  2. 4 hours ago, MDagg said:

    Besides, I am not seeing a RJ45 for Ethernet connection, or RS232 serial which would definitely exclude it from PLC modbus use as a master sub module and that is key in embedded designs for controls and general SCADA.

    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.


  3. 1 hour ago, David Schwartz said:

    I started my professional career working with embedded systems for nearly a decade, so I guess that's why hardware like this catches my eye. This isn't particularly useful for ordinary office tasks or testing or anything like that. But it would be great for a standalone kiosk, or some kind of dedicated application.

    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.

    1 hour ago, David Schwartz said:

    Today you can get a Raspberry Pi for under $50, sure, but you can't build stuff that runs on it with all versions of Delphi.

    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.

    1 hour ago, David Schwartz said:

    This little box includes Win 10, and for the price, the hardware is practically free

    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 🙂

    1 hour ago, David Schwartz said:

    I've always had this vision of little functional building blocks, like "smart" Lego blocks, that perform specific functions and can be plugged into a network and used to solve specific problems.

    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 🙂


  4. 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.

     

    16 hours ago, David Schwartz said:

    I was thinking of it mainly for use with embedded or dedicated Delphi apps.

    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 🙂

     

    • Like 1

  5. 1 minute ago, Kas Ob. said:

    Multi-Threading

    Damn, forgot about multithreading, too. +1 for that sharp eye!

     

    14 minutes ago, Kas Ob. said:

    overflow it and have fun finding the culprit

    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!


  6. 21 hours ago, Remy Lebeau said:

    Which means the TBetFairApi object that is holding that UnicodeString is not freeing that UnicodeString properly.

    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.


  7. 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.


  8. 48 minutes ago, David Schwartz said:

    I'm clicking and dragging from browser window A to the app, and I guess the http component looks like an unrelated browser window B.

    That is exactly how it looks like from the webapp's perspective. A is logged on, B is not.

    49 minutes ago, David Schwartz said:

    I guess Right-Click --> Save As ... runs in the security context of browser window A, but a drag&drop runs in the context of browser window B.

    Well, not security context but it has a valid session open. But effectively yes.

    49 minutes ago, David Schwartz said:

    I don't really want to force the user into a second login. That said, I could add Name + Pwd fields to this little app and save them, but that's getting into a very muddy area here....

     

    I wonder if I can set up a proxy of some kind? They really should be the same context.

    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.


  9. 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.

     


  10. 1 minute ago, Kyle Miller said:

    I'll try using a connection per thread and possibly test out TZMethodThread.

    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.

    • Like 1

  11. 2 hours ago, Dany Marmur said:

    I'll have a good thorough read of the code above, and the link.

    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.

    2 hours ago, Dany Marmur said:

    But i think that your/similar solutions somewhat needs to advertised and available to the community.

    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.


  12. @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.


  13. 5 hours ago, Lars Fosdal said:

    Treat console apps like you treat VCL or FMX apps.  Keep the actual code in units and have just the skeleton init and run code in the .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.

    • Like 2

  14. 7 hours ago, Lachlan Gemmell said:

    hopelessly broken error insight we've been putting up with for the past 15 years

     

    1 hour ago, mmb said:

    It definitely is better than 10.3 (which was just plain broken) but also <10.3.

    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.

     

    1 hour ago, mmb said:

    I am now at the point that error insight and code insight work reliably most of the time and wait times till red wiggles disappear is down to seconds. 

    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.


  15. 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.


  16. 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)

    • Like 1

  17. 2 minutes ago, Dalija Prasnikar said:

    There is new option in Options -> User Interface -> Theme Manager called Toggle style to match Windows Light and Dark mode. It is checked by default and that setting overrides any other custom settings. You need to uncheck that option before you can use custom theme settings.

     

    If you want to edit registry directly under Theme key, this new option is called ToggleTheme (DWORD) and its value should be set to 0

    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.


  18. 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 🙂


  19. 4 hours ago, dummzeuch said:

    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?

    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.


  20. 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 🙂


  21. 1 hour ago, Kas Ob. said:

    I saw this behaviour few times, it does happen with PNG and virtual image lists, couldn't track it to specific reason.

    This makes no sense to me. I was in the belief that a code either works or not. Unless if it's a problem with TDBImage and/or VCL of course; but that is out of my reach anyway.

    If I can manage to reproduce the issue somehow, I will attempt to fix it with DIBNeeded and will not forget to share the result.


  22. @Kas Ob. Often the experience gathered during the journey is more valuable than reaching your destination. Noone will actually see that I worked on this component, but I'm richer with a bit of knowledge. Yes, I would be more than willing to check your idea, however...

     

    Today, when I restored the faulty TJPEGImage assignments, it simply started to work...?! Noone else touched this code, the image is the same. Yesterday it was an empty white rectangle, today the image shows up...

×