Jump to content

JonRobertson

Members
  • Content Count

    171
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by JonRobertson


  1. 5 minutes ago, RTollison said:

    in 10.2 i do not have the Office 2000 options turned on.

    When I code any Office app automation in Delphi using the bundled wrappers, I use the more recent one. There may be a reason to use the Office 2000 wrapper. But I've never had a reason to use the older version.


  2. Has anything changed in the Delphi environment between the "original compiled dll" and the one you are testing? Such as version of Delphi and any third-party components?

     

    Is the DLL interfacing with Word through COM Automation? If so, are you using the component wrappers included with Delphi or something else?

     

    Are your tests with "original dll" and new dll each talking to the same version of Word on the same machine?


  3. On 10/18/2023 at 11:32 AM, RTollison said:

    i put 52 compiles into a batch file and they completed fairly quickly(< 1 minute). but those same programs in my mass compile program took 6 minutes to finish

    I came across this while searching for something completely different. :classic_wink: Although an old thread, I have a suggestion (if you have not already tried):

     

    Change your program to create .bat files in C:\coboldev to do a batch compile, say 50 compiles per batch file. Launch cmd.exe and pass it the name of the batch file. Monitor for completion, as you mentioned previously. Or have cmd.exe exit upon batch completion (cmd.exe /c comp01.bat) and wait for the created process to end. Perhaps have 10 cmd.exe processes running simultaneously performing batch compiles. And delete each batch file once the process completes.

     

    This may solve the slowness cause by the AV scanner, if it is having fits about separate processes being created for each launch of ccbl32, but not when launched several times by a single process.

     

    You could also try using a language/tool more powerful than cmd batch, such as PowerShell or Python, to prompt which folders to compile and launch ccbl32 for each file. Or roll your own CI by comparing timestamps of the source against the most recent compiled module. Or try a tool like Jenkins. Lots of options. :classic_biggrin:


  4. 42 minutes ago, Ian Branch said:

    The objective here is to prevent the following code exceuting if the Semaphore exists

    Using AInitialCount and AMaximumCount values of 1, the semaphore may only be acquired "one time" and other calls to Acquire will block until the semaphore has been released by calling Release. 

     

    You could call GlobalSemaphore.WaitFor(1) and check the result for wrTimeout. But that only tells you that the semaphore was already acquired when the call as made. The semaphore could be released, and possibly acquired by a different thread, before you called Acquire again.

     

    I hope that makes sense.


  5. 1 hour ago, alogrep said:

    [dcc32 Fatal Error] : F2051 Unit Vcl.ExtDlgs was compiled with a different version of Vcl.Dialogs.TOpenDialog

    You want to look for Vcl.ExtDlgs.* and Vcl.Dialogs.*

     

    Do you recall modifying either Vcl.ExtDlgs.pas or Vcl.Dialogs.pas?  Do you have multiple versions of Delphi installed? Are your library and search paths set correctly?

     

    The compiler is finding versions of those two units that are not compatible. This primarily occurs when the interface section of one unit does not match the interface that the other unit was compiled against.


  6. 28 minutes ago, Ian Branch said:

    Which I think will do the job, but I can't find out where/how PW_CLIENTONLY is declared/defined.

    What unit do I need to add???

    I do not see it in standard Delphi RTL/VCL units. However I did find it defined elsewhere.

    const PW_CLIENTONLY = $1;

     


  7. 32 minutes ago, Lars Fosdal said:

    In case there are multiple drivers installed, I wrote the following simple code to pick my preferred driver

    I do the same thing with ADO, preferring MSOLEDBSQL if it is installed. Although not my actual code, the code below does the job. In my case, I dynamically update the ADO Connection String before connecting to SQL Server.

    function GetADOProvider: string;
    const
      PREFERRED_SQL_PROVIDER = 'MSOLEDBSQL';
      SQLOLEDB_SQL_PROVIDER  = 'SQLOLEDB.1';
    begin
      var lstProviderNames := TStringList.Create();
      try
        GetProviderNames(lstProviderNames);
        if lstProviderNames.IndexOf(PREFERRED_SQL_PROVIDER) > -1 then
          Result := PREFERRED_SQL_PROVIDER
        else
          Result := SQLOLEDB_SQL_PROVIDER;
      finally
        lstProviderNames.Free();
      end;
    end;

     


  8. 6 hours ago, Lars Fosdal said:

    ADO has been succeeded by FireDAC.

    I wouldn't say FireDAC succeeded ADO/dbGo. I would agree that FireDAC succeeded dbExpress.

     

    As far as I know, FireDAC uses SQL Native Client, which Microsoft deprecated, I think in 2019. Microsoft no longer updates it or supports it and Native Client is not fully compatible with newer versions of SQL Server. There is a QC to add support for MSOLEDBSQL to FireDAC, but that QC was closed.

     

    RSP-32494


  9. On 12/17/2023 at 12:49 PM, Stephanus Kusuma said:

    Few times ago, when using TQuery, I have to implement its UpdateObject property to manipulate table. Now, I have a problem with TADODataSet.

    There's no such update object in TADODataSet.

    When you say "manipulate table", do you mean insert/update/delete data in the table? If so, nothing special is needed. Use the Insert, Edit, Post, and Delete methods of TADODataSet. If you are modifying the structure/schema of a table, you can do that with SQL statements using TADODataSet or TADOQuery. In that scenario, I recommend setting the ExecuteOptions property to [eoExecuteNoRecords].

     

    The CommandType property specifies whether CommandText contains SQL Text (cmdText), the name of a table (cmdTable), the name of a stored procedure (cmdStoredProc), or the filename of a dataset persisted on disk (not in a database). Best practice is to avoid cmdTable, or the equivalent component TADOTable, as that doing a SELECT * FROM and will always retrieve all rows and all columns. Best practice is to limit the SELECT to only the columns needed.


  10. Copy your patched FMX.Platform.UI.Android.pas to the same folder containing your project. You could also add it to the project. Delphi will compile and use the one in your project folder rather than the version shipped with Delphi.

     

    If you need to use this for multiple projects, or later need to patch another FMX unit, you could create a folder named something like FMXOverrides. I don't use FMX but I've had a VCLOverrides folder for years. :classic_wink:


  11. On 1/8/2024 at 4:04 AM, Lars Fosdal said:

    I'd use a log broker service, i.e. have log requests from the different apps go through the broker APIs.

    I used CodeSite Express (and later upgraded to full version) for years at a previous job. It worked well for our needs.

     

    @hsvandrew  CodeSite Express can be installed via GetIt Package Manager. There are a couple others that I came across that you may want to investigate:

     

    loggerpro and SynLog

     

    There is also SmartInspect. Although not free, there is a trial version available.


  12. 3 hours ago, ErikT said:

    Okay, I see that the "hacker" term has mellowed over time. Apparently, I'm a bit old.

    I disagree. In my opinion, hack/hacker/hacking has never been a bad thing. Hacking is a terrific way to learn, especially for self-taught individuals such as myself.

     

    Sure, people have done a great deal of malice, which is unfortunate. And believing that all hackers are malicious is an unfortunate side effect of the harm caused by others.


  13. 2 minutes ago, ErikT said:

    At the moment I'm struggling with the Indy Ping procedure, that apparently has a problem.

    You could try another set of Internet components, such as ICS. I have not needed low-level Internet functionality for a while. But I used to use ICS quite a lot.

     

    Internet Component Suite

     

    ICS is available for VCL and FMX. In recent versions of Delphi, it can also be installed via GetIt Package Manager.


  14. I suggest searching using a search engine. You will find several results. The most common approach is to calculate the IP range for your LAN using the computer's IP address and subnet mask. Once you know the range of IP addresses for the LAN, ping each IP address. For better performance, use multiple threads to ping several addresses simultaneously.

     

    Note that just because ping does not receive a response does not mean that there is not a device at that address. Not all devices respond to ping requests.

     

    If you want to "search deeper", you could scan a port range for each IP address. Although that would take significantly longer.

     

    If you are looking for a particular device or application, you may be able to find out what it uses for network discovery, such as Apple's Bonjour. If you are wanting to discover your own applications running on other machines within the network, take a look at UDP broadcasts (servers and listeners).


  15. On 12/23/2023 at 2:21 PM, Columbo said:

    I am not trying to be nasty or anything but what difference does it make if it is in lowercase?  Just curious as to the reasoning.

    No difference. It is either personal preference or, in a professional setting, a team policy or design decision. I prefer field names to be "CamelCase". For example, FirstName. I prefer this for variables and class members as well. 


  16. 31 minutes ago, Columbo said:

    but that seems to be impossible as well in Delphi

    Not impossible. If the "system buttons" to minimize, maximize, and close the application are not important, set the form's BorderStyle property to bsNone in the Object Inspector. Note that the window will not be movable or sizable without some additional code.

     

    You could paint the caption bar yourself, although that is not trivial. See StackOverflow for one possible answer: Change the color of the applications title bar

     

    I suggest experimenting more with CustomTitleBar and TTitleBarPanel. Use TTitleBarPanel instead of TPanel for pnlTitlebar, then set CustomTitleBar.Control to your TTitleBarPanel. Unfortunately I don't have specific advice on property values for CustomTitleBar. But experimenting is a great way to learn. You could start a new VCL Project and experiment with an empty form.


  17. 38 minutes ago, Gary said:

    CustomTitleBar = False // You cannot move it around or Min Max with this set true

    I have not explored the CustomTitleBar parameter or TTitleBarPanel component until today. Columbo's project gave me an opportunity to do so. When using an image that spans the width of the window, it covers TTitleBarPanel CustomButtons. I suspect buttons would need to be painted in OnPaint and "clicking" them handled in an OnClick handler. But I am still exploring those options...

     

    However, moving the form using the mouse is possible by adding an OnMouseDown event handler to the Image1 component:

    procedure TfrmDino.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    const
      sc_DragMove = $F012;
    begin
      ReleaseCapture;
      Perform(wm_SysCommand, sc_DragMove, 0);
    end;

     


  18. The easy way is via frmDino.BorderStyle.

     

    Forms.TFormBorderStyle

     

    Value Meaning

    bsDialog

      Not resizable; no minimize/maximize menu

    bsSingle

      Not resizable; minimize/maximize menu

    bsNone

      Not resizable; no visible border line

    bsSizeable

      Standard resizable border

    bsToolWindow

      like bsSingle but with a smaller caption

    bsSizeToolWin

      like bsSizeable with a smaller caption


  19. 52 minutes ago, Columbo said:

    so iSelect would match the record number in the databse.   In the database, Cephalaspis is record number 6.  Using your code, if I select Cephalaspis in the Listbox I get record number 5, Megalograptus.

    The code below assigned ItemIndex + 1 to iSelect, then assigned lbxData.Items[iSelect] to selectedItem. In the source you posted, selectedItem is not used for anything. However, that assignment does result in a "List index out of bounds" error if you click on the last item in the list box.

      iSelect := lbxData.ItemIndex +1;  //Get the item number of the slected item in the listbox.  Add 1 because item list starts at zero (0).
      lboxNum := iSelect -1;
      selectedItem := lbxData.Items[iSelect];

    This attached version builds the paths for the DB and images using Application.ExeName, as Remy suggested. It shows an alternate way of building the full path for both images.

     

    It still expects your database and image folders to be in the same folder as Dinobase_p.exe.

     

    Jon

    Dinobase_u.pas


  20. 1 minute ago, Stano said:

    For my own use I changed the DB in conPLife. Because the suggested dynamic path setting gives me nonsense. I'm not that familiar with it.

    That works if you always run it from the location where Delphi writes the .EXE. If you want it use it on another machine or give it to your friends, that doesn't work so well.


  21. You have a misunderstanding of Delphi list controls. Nearly everything in Delphi is zero indexed. Strings (UnicodeString, AnsiString, etc) are a notable exception.

        iSelect := lbxData.ItemIndex +1;  //Get the item number of the slected item in the listbox.  Add 1 because item list starts at zero (0).

    You use iSelect to retrieve the selected item from lbxData:

     

    selectedItem := lbxData.Items[iSelect];

    If the last item in the list is selected, an "Index out of bounds" error will occur. Since the "item list starts at zero", you need to use a zero-based index for lbxData.Items[].

     

    I wanted to show how you can use the dataset's events to your advantage. I have attached a modified Dinobase_u.pas/.dfm that implements TFDTable.AfterScroll to eliminate duplicating code/work in other methods.

    Dinobase_u.zip

×