Jump to content

aehimself

Members
  • Content Count

    1090
  • Joined

  • Last visited

  • Days Won

    23

Posts posted by aehimself


  1. 4 hours ago, Ian Branch said:

     

    
          //
      MyForm := TMyForm.Create(self);
      MyForm.sFormID := '3';    //  Pass a key value.
      MyForm.Show;
      //

     

    You are creating the form with the owner of your main form. When you close your main form therefore (as it owns your subform) it attempts to free it. But since it is already done in the onClose event (Action := caFree) it is trying to free a non-existing object resulting an access violation.

    Try to create your subform like

     

    TMyForm.Create(nil);

     

    Or don't use caFree in the onClose event.

     

    You should consider using

    MyForm := TMyForm.Create(nil);
    Try
     MyForm.sFormID := '3';
     MyForm.ShowModal;
    Finally
     MyForm.Free;
    End;

    if applicable.


  2. 15 minutes ago, PeterPanettone said:

    Internally, a batch file is being started by a CommandLine. Windows File Explorer (but also other shell-programs) can provide that CommandLine, e.g. by double-clicking on a batch file e.g. in Windows File Explorer.

    And here I though, that the CommandLine is internally using a ConHost process (Windows Console Host) which is provided by the operating system with AllocConsole for example. I must be wrong.

     

    image.png.3b5f260120b4bc393cce0b157511ed96.png

     

    16 minutes ago, PeterPanettone said:

    BTW, it would be interesting to inspect the source code of PatchTool.exe...

    In that, we definitely agree.


  3. 38 minutes ago, PeterPanettone said:

    Obviously you don't know what you are saying. This has nothing to do with UAC (although UAC is involved). I suggest that you re-read what I have written. If you don't understand any particular topic then please ask me.

    Obviously. I forgot that the one and only way to start a batch file is Windows Explorer.

    Why are we paying sysadmins, if the answer is always so easy...? :classic_unsure:


  4. There is no such thing as hardwired to File Explorer; it is just an application which requires elevated privileges due to it unzips files to the Program Files folder. I suggest you to take a look at how UAC works on Vista+ and how you can auto-elevate everything if it disturbs you that much.

    While I completely admit that this "patch tool" is utterly useless, don't blame Emba because of how UAC works.


  5. 4 hours ago, Fr0sT.Brutal said:

    Poor man's solution: Project group with all your 100 projects -> open in RAD -> build all -> go make yourself some tea

    While the idea clearly works, there's a huge flaw with it: I don't like tea.

    • Haha 2

  6. I'd simply re-throw exceptions in an understandable way; you now can even use RaiseOuterException to include the data from the first one.

    When I am working in a service application which should operate 24/7 without interruptions, I'm placing a Try ... Except in the worker thread only. It picks an item to process from the queue, if it fails, it logs why and places it back to the end of the queue. Once an item failed to process 3 times it is discarded.

     

    Specifications (even if given by the client) are only specifications. Our client keeps sending invalid XMLs for us to process, even though they created the validating XSD for that very document.

    So yes, expect bad data; no matter what. But depending on the needs - don't change values and/or swallow errors because the code looks... cleaner.

    22 hours ago, David Schwartz said:

    I suggested that all of these functions should be replaced with ones that don't throw exceptions, like StrToXxxDef(...), and that at least there should be Try...finally fencing around each method anyway just in case something unexpectedly throws an exception.

    I'd suggest TryStrToInt and it's counterparts, or simply Val. That way you know if/where the expected data is malformed and can Rase Exception.Create('The length of your shoes must be a number, not "' + s + '"');


  7. On 7/23/2020 at 3:47 AM, Donald Shimoda said:

    I want to detect the windows active app using a tray app. Is posible?

    GetTopWindow or GetActiveWindow, depending on your needs

     

    On 7/23/2020 at 3:47 AM, Donald Shimoda said:

    And how to detect if theres keyboard or mouse activity?

    function SecondsIdle: DWord;
    var
     liInfo: TLastInputInfo;
    begin
     liInfo.cbSize := SizeOf(TLastInputInfo) ;
     GetLastInputInfo(liInfo) ;
     Result := (GetTickCount - liInfo.dwTime) DIV 1000;
    end;

     

    • Like 1

  8. 2 minutes ago, Attila Kovacs said:

    Turn this to an advantage. It will pay off.

    Modularity is the key. And the beauty of inheritance makes it really-really easy.

    Since I started to chip my code to as small blocks as possible, separate classes of course; I realized that I started to move more and more of these one-class units to my Framework folder, out of an applications folder.

    And they simply all work together.

    • Like 1

  9. While I have no experience with C++ builder, nor FMX, but if the "ScrollBox" component is available, you can use that. Place one on your form, set the Align to alClient and put your components on the scrollbox instead of the form.


  10. When I made a parser like this I was working with indexes returned by String Helpers. Look for the first opener, look for the first closer from the opener. Make sure there are no quotes (or even number of quotes) in between. Make sure there are equal amount of openers and equal amount of closers in between.

    I'm not saying it was the fastest solution, but it worked 🙂 And it handled nested sections correctly, too.


  11. Yep, you have so much freedom you can easily do

    Var
     tb: TBytes;
     a: Integer;
    Begin
     SetLength(tb, 5);
     For a := 0 To 5 Do
      tb[a] := 1;
    End;

    or...

    Var
     pc: PChar;
    Begin
     GetMem(pc, 5 + 1);
     StrPCopy(pc, 'abcde', 5);
    End;

    or even:

    Var
     obj: TObject;
     proc: TProcedure;
    Begin
     proc := addr(obj);
     proc;
    End;

    Just because you have the possibility of doing something it doesn't mean you are supposed to or should.

     

    Btw, I thought this forum is a politic-free area. Please take those ideologies to Reddit.

    • Like 1

  12. 1 minute ago, PeterPanettone said:

    That's what I call "user-centric" programming. :classic_smile:

    In a more advanced project (especially after a UI change or refactoring) you'll quickly realize why separating the UI and data storage/handling extremely important.

    In your example, let's say a user doesn't like CheckListBox and wants you to change it to something else. Apart from the visual changes, you'll have to re-code your business logic as well.

     

    It is not that important in "personal use" applications, but lately I have a separate class for data storage everywhere. The UI only displays, validation, (de)serialization, everything is handled by the class itself.

    • Like 2

  13. I don't feel fine storing information in the UI. I'd rather create a separate TList<TMyValue> and add the values to it as I'm adding the checkboxes. This way the index of the CheckBox will be equal to the index of it's value in the TList.

     

    • Like 2

  14. 21 hours ago, PeterPanettone said:

    However, your employer has to pay for the time you need to write overloaded code. (Though I assume you're a fast writer).

    These overloaded methods are like 4 lines. I really would like to have an employer who pays me double for 4 extra lines per feature request.

    In a real world scenario, overloaded methods usually point from one to the other (or call the "real" one with proper adjustments) so we can argue that this was for demonstration only, but in real life - multiple overloaded methods will not consume even 10 minutes of your time if done smartly.


  15. 2 hours ago, David Heffernan said:

    Nothing can save you at this point.

    Agreed. A destructor might be called even when the object creation is incomplete... so it must have proper "defenses" in place.

    Let's just think on the standard way of local object handling...

    myobject := TMyObject.Create;
    Try
     myobject.DoStuff;
    Finally
     myobject.Free;
    End;

    What happens if an exception is raised in the destructor? Uncaught exceptions and 99% of the times memory leaks.

    4 hours ago, Kas Ob. said:

    i am here talking about an imaginary raised exception in the destructor (which is wrong, yet it might happen)

    No, it might not. If it does, it's a bug. If it's an external component, report it to the developer. If it is yours, fix it.

    3 hours ago, Mahdi Safsafi said:

    As you can see, this class is freeing its instance before freeing its internal data.

    I might be fresh in the area, but what is the purpose of this? I would simply call it a bad code as up until now, I never really had the need to put inherited anywhere else than the very last line of a custom object destructor.


  16. 2 hours ago, dummzeuch said:

    You mean it's a bad thing that, instead of fixing the bug in 4-5 applications and compile them, you now have to fix the bug only once and still compile 4-5 applications?

    No; that was not my intention to mean that. Obviously fixing at one place is more convenient and time effective, no one doubts that. All I wanted to say was that I don't really have a dependency (or rather - uses) list, which clearly says which application is using the particular unit I am working in.

    I think I'll write a recursive crawler to discover any custom units in the uses clauses of all my applications. As a result, I can enter a unit name and see which applications I have to rebuild. An other way is to distribute each unit as a separate library and my auto updater will take care of the updates of said files. This, however, increases the number of files my application is using and the attack surface of course. Even the beginner Hacker Henry will know to check the exports of MyEncryptor.dll and launch a brute force attack on encrypted data.

    And however I don't deal with credit card / bank account numbers or personal data; I like to prepare for the worst.

     

    Anyhow, we are sliding off the original topic. This is just one thing to consider with the cherished "Write once, use anywhere" method - which is THE WAY to go.


  17. On 7/11/2020 at 8:54 AM, Rollo62 said:

    A clever design concept is a good pay-off.

    I started to see this at my biggest project. I broke it in the smallest pieces possible (random number generator, pseudorandom generator, encrypter, (de)serializer, hell I have a separate class for the application itself). Whenever I start a new project, I realize that most of these modules are now in my "Common" folder. It just started to become logical not to write a code again (or copy-and-paste) if I already wrote it once.

    The only bad thing in this is that if I make a bugfix in one of the units I have to recompile 4-5 applications now instead of one 🙂

×