Jump to content

Bill Meyer

Members
  • Content Count

    651
  • Joined

  • Last visited

  • Days Won

    12

Posts posted by Bill Meyer


    1. Download the packaged zip for your Delphi version from the latest release, or build from source.
    2. Unzip the folder and run the included install.bat script.
    3. Done!

    Well, no. Then I run Delphi 11.3, and get a dialog wanting me to set up external resources. I did start by installing the JRE. The dialog says that, by default, JAVA_HOME is used. But Select override is focused, and wants me to point where? I do not find a JAVA_HOME environment variable, and one might hope that the startup code would solve that for me. I am guessing this wants the location of javaw.exe? Or java.exe? I find no enlightenment on this in the readme on github, either.
    I am not a Java user, and could wish for a more useful explanation in the dialog.
    Since my guess proved not to solve the problem, I emphasize the wish for better guidance.

    • Like 1

  1. On 3/8/2022 at 9:01 PM, Steven Kamradt said:

    In your case, I would put the variables you are working with in a class or even a record and set the scope to what you selected as private to the thread.  Keep it simple, its all about preventing access from multiple threads.  If you have a global variable that needs to be accessed by multiple threads, protect the access using some sort of semaphore, such as a critical section or spin lock.

    Before anyone gets too upset, my perspective is based on dealing with legacy code you have come into. There are numerous advantages to encapsulating global variables. Not only do you establish a measure of access control, but if you expose them as properties with getters and setters, you can easily set breakpoints to discover points of interaction. Equally, you could introduce logging. But even without those benefits, you will be altering the calling code to reference MyGlobals.SomeState, rather than simply SomeState. Once you have accomplished that tedious task, it is also a simple matter to search for all such references by searching on MyGlobals.

     

    Other benefits will become apparent as you work through things.

    • Like 4

  2. Components may be a barrier to doing the complete transition in one step. In particular, there is no release version of DevExpress which supports both D2007 and the latest compilers. If DevExpress is an issue, then it may be best to update to the last version which supports D2007 and do the conversion of grids and other components which were removed later. The recent versions do not offer dxGrid, for example, but require changing to the cxGrid, which may be a good deal of work, depending mainly on event handlers used, as the architecture changed between dxGrid and cxGrid.


  3. 1 hour ago, Uwe Raabe said:

    Here is a part of the Dependency Graph from Understand for the VirtualTrees -> VirtualTrees.WorkerThread cycle with information where the dependencies come from in the Dependency Browser below:

    In tackling large legacy projects, I have seen many cycle chains which exceed 100 units. The graphs are pretty, but when the magnitude of the problems is so great, the graphical interface seems to me to be less than effective.

    I have dealt with cycle reduction painfully, sometimes getting lucky, and other times finding obvious failures to separate concerns. But in many cases, I have been defeated by the challenge of finding a starting point. And nice as it is to clean up some modules, when the result doesn't alter the cycle count, it becomes hard to maintain your enthusiasm.


  4. Let me make a rash assertion. If you have a large project in which some modules are large (>15K lines) and contain many (>200) uses references, then you are referencing some of them simply to gain access to relatively simple types. Move those to other modules with no code. Modules of types and consts can be global with no negative impact. But when those declarations are no longer found in massive units, you will begin to see your uses clauses shrink.


  5. On 7/11/2023 at 2:39 PM, Lars Fosdal said:

    https://quality.embarcadero.com/browse/RSP-41961

     

    The process of cleaning up circular references can be quite challenging, as we today have no good tool to discover and track the unit interdependcy.  "Blatant" circular references are explicitly forbidden, but since we can include units both in the interface and the implementation section - it is quite easy to circumvent this rule.

     

    Another challenge is when you inadvertently drag in a massive collection of units into your project, because someone needed a structure or function from a specific unit - which again uses other units, which uses others again - and so forth.

     

    The discovery of where this unit is included, and when in the compilation it is parsed, would be significantly helped by a simple build log. A sequential log of the compilation of each unit in the application - indicating where it first was necessary to  compile another unit to complete the current unit.

     

    I suggested it could look something like this - more comments in the QP issue.

    Pls vote/comment if you find it interesting.

    
    unit1 compiling... 
       unit2 compiling... 
         unit3 compiling...
         unit3 compiled (lines, warnings, hints)
       unit2 compiled (lines, warnings, hints)
    unit1 compiled (lines, warnings, hints)

     

    One of the issues is that in a large project with many circular references, that log will show modules appearing again and again.

    In one large project, I found over 20,000 such references, and a cold build was up to eight minutes. Reducing the circular references by about 25% brought the build time down to about a minute. And the time was stable over several builds in a session, where with 20K+ it had been increasing on successive builds.

     

    MMX does produce a report of circularity chains. It is large, and not friendly to humans, but it is easy to parse, and I built  a simple tool which delivers in a grid the counts for each of the modules with circular references, and which can compare two reports, which is useful as you continue to work on the project.

    • Thanks 2

  6. On 7/12/2023 at 9:22 AM, Brandon Staggs said:

    It's not always bad, but generally you should structure your code so that you don't have "chicken and egg" issues. I tend to think that if you have two units depending on each other to compile, the parts that are creating the dependency should be broken out into another unit that isn't dependent on either one. The most obvious example are simple types appearing in interface sections of both units when each unit needs simple types from the other. Adding a third unit to define the simple types is an easy fix that just makes code easier to manage and extend later.

    There can be exceptional cases which justify sparing use of circular dependencies. Donald Knuth makes the point with regard to sorting algorithms. @Stefan Glienke has also argued for such cases.

    My point, and what @Uwe Raabe was speaking very explicitly about is large programs where circularity is commonplace, and not at all exceptional. There is no rational case which can support that practice. In the majority of cases, circular references are needed because of badly organized code modules. And I say that based on thousands of modules and millions of lines of code, over a period of 15+ years.

    • Like 2

  7. On 12/20/2022 at 5:21 AM, Lars Fosdal said:

    It is odd that it works with remote debug symbols enabled, though.

    So yesterday I began to have this problem with 11.1 in a VM. Did some searching this morning, and that led me to this thread, which I recall reading when it was new.

    My situation is not identical, Lars, as I do not see the color of gutter dots change. But breakpoints become non-functional, depending on where they are. I can break in the DPR, or in the main form. But somewhere beyond those areas, the breakpoints do not trigger.

    Have you discovered the cause? I was going to check include remote symbols, and found it already checked, so that is not a solution here. 


  8. OK, I have been merely watching, but decided finally to take the plunge, not in ChatGPT, but with "the new Bing."

    My input:
    Using Delphi, write a class to provide CRUD operations on a dataset.

    Bing's response:
     

    Sure! Here's an example of a Delphi class that provides CRUD operations on a dataset:

     

    ```delphi
    type
      TMyClass = class
      private
        FDataSet: TDataSet;
      public
        constructor Create(ADataSet: TDataSet);
        function ReadData(AID: Integer): Boolean;
        function CreateData(AData: TMyData): Boolean;
        function UpdateData(AID: Integer; AData: TMyData): Boolean;
        function DeleteData(AID: Integer): Boolean;
      end;

     

    constructor TMyClass.Create(ADataSet: TDataSet);
    begin
      FDataSet := ADataSet;
    end;

     

    function TMyClass.ReadData(AID: Integer): Boolean;
    begin
      Result := False;
      FDataSet.Close;
      FDataSet.Params.Clear;
      FDataSet.Params.CreateParam(ftInteger, 'ID', ptInput);
      FDataSet.ParamByName('ID').AsInteger := AID;
      FDataSet.Open;
      if not FDataSet.IsEmpty then
        Result := True;
    end;

     

    function TMyClass.CreateData(AData: TMyData): Boolean;
    begin
      Result := False;
      FDataSet.Close;
      FDataSet.Params.Clear;
      FDataSet.Params.CreateParam(ftString, 'Name', ptInput);
      FDataSet.ParamByName('Name').AsString := AData.Name;
      FDataSet.Params.CreateParam(ftString, 'Description', ptInput);
      FDataSet.ParamByName('Description').AsString := AData.Description;
      FDataSet.ExecSQL;
      if FDataSet.RowsAffected > 0 then
        Result := True;
    end;

     

    function TMyClass.UpdateData(AID: Integer; AData: TMyData): Boolean;
    begin
      Result := False;
      FDataSet.Close;
      FDataSet.Params.Clear;
      FDataSet.Params.CreateParam(ftString, 'Name', ptInput);
      FDataSet.ParamByName('Name').AsString := AData.Name;
      FDataSet.Params.CreateParam(ftString, 'Description', ptInput);
      FDataSet.ParamByName('Description').AsString := AData.Description;
      FDataSet.Params.CreateParam(ftInteger, 'ID', ptInput);
      FDataSet.ParamByName('ID').AsInteger := AID;
      FDataSet.ExecSQL;
      if FDataSet.RowsAffected > 0 then
        Result := True;
    end;

     

    function TMyClass.DeleteData(AID: Integer): Boolean;
    begin
      Result := False;
      FDataSet.Close;
      FDataSet.Params.Clear;
      FDataSet.Params.CreateParam(ftInteger, 'ID', ptInput);
      FDataSet.ParamByName('ID').AsInteger := AID;
      FDataSet.ExecSQL;
      if FDataSet.RowsAffected > 0 then
        Result := True;
    end;

     

    ```

     

    I hope this helps! Let me know if you have any other questions.

     

    Source: Conversation with Bing, 4/5/2023(1) How do I solve the "Cannot perform this operation on a closed dataset .... https://stackoverflow.com/questions/6774634/how-do-i-solve-the-cannot-perform-this-operation-on-a-closed-dataset-with-borl Accessed 4/5/2023.
    (2) Leveraging ChatGPT to generate a Delphi class along with CRUD code from .... https://www.ideasawakened.com/post/leveraging-chatgpt-to-generate-a-delphi-class-along-with-crud-code-from-a-table-schema Accessed 4/5/2023.
    (3) Beginner Delphi Tutorial on CRUD/Add, Edit, Delete and ... - YouTube. https://www.youtube.com/watch?v=h2rZTgEJDPg Accessed 4/5/2023.
    (4) GitHub - onryldz/express-dataset: Delphi JSON - CRUD DataSet. https://github.com/onryldz/express-dataset Accessed 4/5/2023.

    I must say that the footnotes impressed me, not only by their inclusion, but the fact that one article cited was from today.

     

    Let me add that I have not looked closely, nor even run it through Delphi looking for errors. However, neither did I need to refine my request, nor work around any limit to emitted line count.


  9. 2 hours ago, programmerdelphi2k said:

    Now, the lucky ones, can have 8K screens (we can display thousands of "things" per line), and still complain, because "it hurts my eyes to have to turn my head to be able to see the whole line)

     

    So I ask: Is the "human" still the same as before, or has he evolved?

    Evolved? No. But sitting in front of the monitor and not turning your head at all leads to stiffness and pain, sooner or later. Our bodies are meant to be in motion.


  10. 2 hours ago, Kryvich said:

     And thanks to the developers for open sourcing it!

    Unless I missed something, it does not appear to be open source. Rather, they specify that each download contains pre-compiled DCU files.

    It appears that I did miss the zip file with source. Makes it much more interesting.


  11. On 3/16/2022 at 5:13 AM, Mike Torrettinni said:

    I just compiled one of my projects on D11.1 and it uses NativeXML. I used to use it a lot, then replaced with OXML, but still keep NativeXML around just for a few tasks.

    Curious about your experience with OXML. It looks interesting, and corporate makes it very hard to use open source, so NativeXML is not an option.


  12. 13 minutes ago, programmerdelphi2k said:

    really, I dont see "ControlIndex" helping in this task...  try expand/colapse the "FlowPanel" as my sample above and see the real resulted... 😩 no no no!

    now, if you need just "hide/show" then, any other "container with many panels" do it, not? (be Panel, FlowPanel, Rectangles, etc...

    And if you are correct, then the ultimate solution lies in coding.


  13. On 3/12/2023 at 4:48 PM, programmerdelphi2k said:

    The problem with the "FlowPanel" is precisely the "flow of controls inside it"... Try placing the 5 panels above (left aligned) and resizing the "FlowPanel" to different sizes, including changing the "FlowStyle" to whatever others...

     

    First, you may not be able to keep all the sub-panels left-aligned (like the sample above), as the "FlowPanel" will have its own alignment rule! So the "Align" property of the sub-panels will have no effect!

     

     

    bds_fKXjkriXO9.gif

    With the Flow Panel, you use the ControlIndex property to set the order. And the FlowStyle to manage orientation.  Your original question was about what happens to order when you hide and restore elements. The Flow Panel can resolve that. Alternately, you can achieve the results by setting the Tag property of each control on the panel and managing the order in code. I have done it both ways. The Flow Panel is easier, by far.


  14. 1 hour ago, CyberPeter said:

    I'm convinced Delphi would run into the same problems.  The code is simply too old (2007) and hence dates back from before proper Unicode implementation etc.  For a Delphi developer it's probably not that difficult to update the code.

    The author has provided email addresses, and it may be worth dropping a note. Some projects have been updated in the last 30 days.


  15. 50 minutes ago, CyberPeter said:

    Too many errors when trying to build with C++ Builder 11.3

    Not knowing much about Delphi syntax this currently is too much an uphill battle, especially because the result (look / feel) is a big unknown.

    Yes, understood. As far as I know, C++ Builder supports a subset of Delphi, not everything. But that knowledge is from years ago.

×