Jump to content

PeterBelow

Members
  • Content Count

    468
  • Joined

  • Last visited

  • Days Won

    13

Posts posted by PeterBelow


  1. 4 hours ago, Stefan Glienke said:

    I see this many times I put a breakpoint into a line with an inline variable declaration - it looks like some debug symbol issue so the breakpoint is not set into the proper instructions but into the prologue code the inline declaration brings with it.

    This can be very annoying and confusing indeed.

    Well, the cure is simple: do not use inline variables 😉. They are alien to the language anyway and serve no real purpose IMNSHO...

    • Like 4

  2. 3 hours ago, ertank said:

    Hello,

     

    I am using Delphi 10.3.2.

     

    There is that Delphi7 project which uses over 200 units and forms.

     

    I am asked to migrate it to Delphi Rio. There are some components used for skinning that will be removed during migration. Other than this, code is mostly compatible.

     

    However, I cannot have a good compile. I get one of below errors too frequently that it gets a person fed up. Consider each line as an error returned after a different compile

     

    
    Could not create output file 'DCU-DEBUG\xyz.dcu'
    
    File not found: 'UnitMainForm.pas'
    
    File not found: 'UnitLogin.pas'
    
    File not found: 'UnitSalesEntry.pas'
    
    File not found: 'ERP.dpr'
    
    

     

    Ertan

    Did you just open the old D7 project in Rio to start the migration? That is not a good idea for such a massive version jump.

     

    After you have extracted the complete old project from version control,  close all files and the RIO IDE and go to the project folder on disk and move all files not having one of the following extensions to a zip folder:

     

    dpr, pas, res, rc, ico

     

    If the project contains other resources you may keep them as well. The important part is to delete the old project file (do not remember what extension it used in D7, perhaps bdsproj, and the old cfg file as well.

     

    Then open the IDE and open the project's dpr file.  This will create a new project file. The project will show up in the project manager view and should have the Win32 target assigned automatically. It will also have a default build configuration assigned, but the settings used for that will not all be suitable for your project. So the next step is to open the project options dialog (from the Project menu or the project manager view's context menu) and adjust the settings, especially the search and output pathes.

    Beware! The settings dialog is completely different from the one you may know from D7! Since you can have multiple build configurations for multiple target platforms the settings are organized as a kind of hierarchy, and you have to first select the correct hierarchy level for the settings you want to modify. You do this using the combo box at the top of the right-side pane, pick "32 bit windows platform" under "all configurations".

     

    In the left-hand treeview you should have the top node (Delphi compiler) selected, that shows the page with the project-specific path settings on the right. The most important things here to get your project to compile are the unit scope names and the search path.

     

    Delphi uses namespace-like scope names on the run-time and framework units and has done so since many versions. But D7 did not use unit scope names. To make migration easier the IDE and the compiler will automatically search for units named in Uses clauses within the scopes listed in the unit scope names field if the unit is not found by the given name (the System scope is always searched, though).

    The default list contains the most frequently used scopes, but you have to make sure that VCL and VCL.Win are in the list as well.

     

    The search path becomes important if your project uses custom units not located in the project folder (where the dpr file and the generated dproj file reside). You have to add all pathes for units there that are not found on the IDE library path (as dcu or pas).

     

    I don't know how you organize your project files on disk. I usually use something like

    • projectname (dpr, dproj, cfg)
      • source (pas, inc)
      • bin (dcus)
      • exe (exe)
      • doc (documentation)
      • resources (rc and res files, files embedded in them)
      • test (unit tests and other test programs)

    So the output folder path set in the dialog would be (without the quotes, of course) ".\exe".

    The unit output path would be ".\bin\$(platform)\$(config)"

    The search path would be ".\bin\$(platform)\$(config);.\source;$(common);$(include)"

     

    "common" and "include" are environment variables defined in the IDE Options dialog that contain the pathes to my code library (not project specific units).

     

    The resource compiler node on the left also has a search path setting, these are for rc and res files, but in my experience this has been a bit unreliable in recent versions; i often have to add rc files explicitely to a project to get them compiled and linked in.

     

     

     

    • Like 2

  3. 27 minutes ago, FredS said:

    Today was my first attempt to actually use these, but that ended once I placed a Breakpoint on one.

     

    Perhaps not news to others..

     

    
    program Project1;
    
    {$APPTYPE CONSOLE}
    {$R *.res}
    
    uses
      System.SysUtils;
    
    {$INLINE OFF}
    
    function NewBytes:TBytes;
    begin
      SetLength(Result, 10);
    end;
    
    begin
      try
        /// <summary>
        ///   F9 from the Breakpoint will repeat 3 times, once for each Inline Variable
        ///   Uncomment the others to prove my point
        /// </summary>
        /// <remarks>
        ///   You can also try F7 or F8
        /// </remarks>
        var Eins := NewBytes;  // << Breakpoint
        var Zwei := NewBytes;
        var Drei := NewBytes;
    
    //    var NochEins := NewBytes;
    //    var NochZwei := NewBytes;
    //    var NochDrei := NewBytes;
    
        writeln('Something Happened!');
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.

     

    I'm surprised that you can even set a breakpoint on a variable declaration. Makes no sense in my opinion.  Could you please run to the breakpoint and switch to the CPU disassembly view to see what statement the breakpoint is actually on? I have not been able to install 10.3.2 myself yet due to trouble with the licence, so cannot test that myself.


  4. 15 hours ago, Steve Maughan said:

    Is the new release (10.3.2) component compatible with 10.3.1?

     

    I'm seeing some component vendors (e.g. DevExpress) say their latest release supports 10.3 (i.e. no mention of the ".1" or ".2"). This implies it will install components into 10.3.1 and 10.3.2. even thought this version of their components was released before 10.3.2

     

    Can anyone confirm?

     

    Thanks - Steve

    Generally the minor releases of Delphi (e.g. 10.3.1 10.3.2) are binary compatible, which means there are no changes to the interface part of run-time library or frame work units, so dcus and packages build for one release can be used with other. The same applies to the open tools API, so components you bought for 10.3.1 should work in 10.3.2, even if you cannot recompile them since you don't have the source. This only applies if said components play by the rules, of course. If they rely on undocumented features or dig around in the IDE's innards all bets are off.

    • Thanks 1

  5. 2 hours ago, Tommi Prami said:

     

    Delayed initialization is an separate problem I think, and that can be handled Case by case, if needed.

     

    How, why and when Delphi will recreate the Hvnd for a Form? Never heard of this, this might explain rare weirdness.

     

    -Tee- 

    Some of the form properties (e.g. border and bordericons) are implemented via window styles on the API level, and Windows only honors some of the styles when the window is first created. Changes to these properties recreate the window handle for this reason. Another reason are modal forms with popupmode pmauto or pmexplicit; their window handle has to be recreated when they are shown to tie them to their popup parent in Z-order. Changing the formstyle also recreates the handle.

    • Thanks 1

  6. There is no panacea for this kind of problem, too much depends on how the form in question has been set up. What you can do from "outside" the process is

    • check if the window is visible (IsWindowVisible)
    • check whether it is the current foreground window (GetForegroundWindow)
    • check whether its message loop is running (WaitForInputIdle, or use SendMessageTimeout to send a do-nothing message to the form, e.g. wm_null, the call will not return until the loop is running)

    Nothing will help you if the form does some kind of delayed initialization, e.g. using a timer started when the form is created.

     

    Also keep in mind that a Delphi form may recreate its window handle at the drop of a (virtual) hat during the initialization phase.

    • Like 1

  7. The <projectname>.res file is the one the IDE builds for the form resources, it also contains versioninfo if you enabled that in the project options. The verinfo.res has to be something you added yourself to the project, or some add-in you use added. Look for a {$R verinfo.rc verinfo.res} line in the project dpr file and delete it. The confllict arises since both resources have the same ID.


  8. 7 hours ago, Mike Torrettinni said:

    I'm trying to resolve unit dependencies, cycling. I have a global unit where in some cases I need to reference Form Control - so I need the Form units used in uses:

     

    TranslatorUnit - custom translation unit that translates all forms, controls, message...

     

    I run TranslateProject method that has this:

    
    FormsList[0] := MainForm; // <- REFERENCE TO FORM
    FormsList[1] := CustomDialog; // <- REFERENCE TO FORM
    ...
    for i:= 0 to High(FormsList) do
    begin
      if FormsList[i] = MainForm then  // <- REFERENCE TO MAINFORM
      begin
        for j := 0 to FormsList[i].ComponentCount - 1 do
        if FormsList[i].Components[j] = CustomButton then  // <- REFERENCE TO CONTROL
         ...
      end
      else
      	// common translation of Form and Controls
    end;

     

    I know I can loop Forms in Application and refer them by 'MainForm' name and same for Controls, I can refer to them by name like FindComponent('CustomButton'), but I don't like it since it doesn't validate names, like compiler does when I refer to them as objects.

     

    Is there any way I can refer to Forms and  Form Controls without using the units in uses, but will still give me some way to verify I don't misspell the names or when I change a name that translation will still work as needed?

     

    Any suggestion how to solve this?

     

     

     

    You cannot do it this way without using the form units. It is not a good way to translate an application anyway.  Have you looked at the IDE Translation Manager?

    • Thanks 1

  9. You can tell the debugger to ignore certain types of exceptions, this is offered as a button on the exception dialog you get when the IDE debugger catches an exception. Perhaps you did this by accident.

     

    Call up the Tools --> Options dialog,on the left scroll down to the end of the list. There you find a "debugger options" node with two subnodes for language and OS exceptions. The associated pages list the exception types to ignore; you can reactivate them there as well. see the attached dcreenshot, unfortunately from  a german IDE.

     

     

    1.PNG


  10. 21 minutes ago, A.M. Hoornweg said:

    Hello all,

     

    All of a sudden I can't login to Quality Central ( https://quality.embarcadero.com/secure/Dashboard.jspa ) anymore.  And the "contact support" link on that page requires me to be logged in, so that effectively makes support totally unreachable to me. 

     

    Can anyone please give me a pointer to the person or team who is responsible for that web site?

     

     

     

     

     

     

    Can you get to members.embarcadero.com and log in there with your EDN account?


  11. 1 hour ago, PeterPanettone said:

    Unfortunately, the Delphi License Manager does not have an "Export" feature where I can export all my licenses shown in the License Manager. It has only an "Import" feature:

     

    image.png.24c1aaf84cc89cef964293f9e6ccb249.png

    You only need the licence key, which you can copy from the Licence manager via clipboard.


  12. 18 hours ago, Bill Meyer said:

    No. And also have done a comparison of the map files of good and bad. Nothing odd there, either.

    Did you check the dpr file for bad line ends (only cr or only lf)? What happend to me some time ago was that the IDE inserted a new form unit name in the DPR file smack in the middle of an existing one, which of course did not build anymore and resulted in some weird error messages (no IDE crash, though). I found out that the file had become corrupted, with  mix of linebreak styles. I never found out how that happended...


  13. 1 hour ago, baeckerg said:

    Hi,

     

    in a program I have a central FireDAC connection to my database in a datamodule. I intend to have all record related activities (CRUD) in a class that holds the record. My questions are:

     

    1) is there any penalty if I pass the connection (as var parameter?) to the constructor of the class?

    2) is this the best way to separate the data from the UI?

     

    many thanks in advance

    Gernot

    For 1: If you like to set up the connection at design-time in a datamodule the approach is OK, and you do not need to pass the connection object as a Var parameter. Objects are reference types, so you pass a reference to the connection object, and that can even be done as const, since you can work with the object's properties or pass the reference on this way as well. Just do not free the connection object in the "record class", it belongs to the datamodule and will be freed by it when the datamodule is destroyed.

     

    For 2: "Best" is hard to define in this context. For a complete separation of the UI from the data it works with you need a bit more than just keeping connection and query/table objects out of the forms/frames and business logic code out of event handlers there. But writing a model-view-presenter framework or a full-blown object-relational mapper (ORM) framework from scratch is a lot of work. For smaller projects it may not pay to go to these length, especially if you only aim for one platform with a desktop client.

     


  14. Using threads to do thing in parallel obviously only works efficiently if the "things" do not depend on each other. As soon as a thread has to wait on the results of another  the processing slows down and the chance of deadlocks goes up. Also, using more threads than the hardware has cores/cpus quickly gets you to a point of diminishing returns, since the OS has some administrative overhead to manage the threads. So, don't overdo it, especially in a scenario like a parallel for loop, where the code can only continue after the loop has finished completely it may be more efficient to split the loop into several and run each in its own thread. If the loop does not have that many iterations and executes each round fairly quickly setting up the individual tasks in a parallel for may consume more time than you gain by doing stuff in parallel.

     

    There is no substitute for thorough testing and timing in such a scenario.

    • Like 1

  15. 5 hours ago, Der schöne Günther said:

    But doesn't that defeat the purpose of using a thread in the first place if there can only be one canvas operation at a time?

    No, you can operate on several canvases (of offline bitmaps or metafiles) in parallel, its is just a little bit less efficient since each canvas has to create its own font, pen, brush instead of using an existing one from the VCL sharing pool.

    • Like 2

  16. If you want to use a database that requires COM (e.g. via dbGo) inside a thread you have to call CoInitialize at the start of the execute method and CoUninitialize at the end. You are not doing that, your InitializeDatabase method calls CoUnInitialize, so any subsequent use of the database connection may not work as intended.

     

    You thread Execute method does not contain a loop, after one pass through the code the thread will exit. Also keep in mind that database connections are usually bound to the thread that created them, so using a dataset bound to the connection created by the thread in another thread (e.g. in the main thread through a Synchronize call) may either not work or involve some internal thread synchronization done by the framework you are using (COM objects using appartment threading are such a case) that may block until the code returns to the message loop.

     

    Something else that may foul your design: Creating a datamodule inside a thread is not a problem per se, but if you have design-time links of components on forms, frames, other datamodules to stuff on this datamodule (or vice versa) the way the VCL streaming mechanism resolves them may torpedo your intent. This mechanism is not thread-safe, and it resolves the links using the Name of the component linked to, and it looks for the container (form etc.) in a global list, where it will only find the first created instance of the container, even if you have created several.


  17. 22 hours ago, PeterPanettone said:

    In Delphi Rio 10.3.1, the Project is configured for Debugging:

     

    image.png.896489da4bee954670311541250efd73.png

     

    Steps:

     

    1. First I make sure that all source files are saved.

     

    2. Then I start debugging (F9) image.png.97ed530d55a35b012d961b97ade2f09e.png

     

    3. Then, at the first breakpoint, I press F8 (Step Over). This makes this dialog appear:

     

    image.thumb.png.2f78de612a40eafd9793b986fe8095ac.png

     

    When I look in the project folder, the only file which has been changed since debug start is MyProject.res.

     

    So why this file gets changed after the start of the debug session?

     

    This is the content of the RES file:

     

    image.png.dc4d330788660bbac0c251589175b858.png

     

    This is very annoying and did not happen in previous Delphi versions.

     

    How can this be avoided?

    This is not normal behaviour, i have never encountered that myself with Rio. Do you also get that if you do a build before starting the debug session?


  18. 13 minutes ago, Mike Torrettinni said:

    I tested this and it works OK when private method is assigned in runtime, not in design time:

     

    I removed Button1Click from begin assgned to Button1 OnClick, and assign it in FormCreate:

     

    
    type
      TForm6 = class(TForm)
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
      private
        procedure Button1Click(Sender: TObject);
      public
      end;
    
    var
      Form6: TForm6;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm6.FormCreate(Sender: TObject);
    begin
      Button1.OnClick := Button1Click;
    end;
    
    procedure TForm6.Button1Click(Sender: TObject);
    begin
      showmessage('click');
    end;

     

    This also makes sense why compiler doesn't complain in cases above. I assume this so called 'streaming framework' should be updated. If I can do it in FormCreate, why it can't do while 'creating form'.

    The form streaming process relies on run-time type information (the old styele), and that is only generated for published members of a class.

    • Like 1
    • Thanks 1
×