Ashland Oregon News Dispatches App

My first iOS/iPadOS app has been accepted by Apple! The app is powered by Embarcadero Delphi. You can read more about the app in this blog post. You can find the app in the store at https://apps.apple.com/us/app/ashland-oregon-news-dispatches/id6670345777.

Description:

Stay up-to-date with everything happening in Ashland, Oregon, with the Ashland Oregon News Dispatches app! This convenient app brings you the latest news articles from various local news sources, all in one easy-to-access place. Whether you’re interested in current events, community updates, local sports, or entertainment, Ashland Oregon News Dispatches has it all.

If you live in the Ashland Oregon area or a planning a visit to the Rogue Valley, this app is for you. Ashland Oregon News Dispatches is your go-to app for all the news and updates from the Ashland area. Download now and stay connected with your community!

Download the Ashland Oregon News Dispatcher App from the Apple AppStore

Features:

The Ashland Oregon News Dispatches app provides:

  • Curated News Feed: Easily browse through a comprehensive list of articles from multiple Ashland-area news sources, keeping you informed about what’s happening in your community.
  • Date Filtering: Stay current with today’s news or explore past articles by choosing your preferred date range. Find exactly what you’re looking for with just a few taps.
  • Customizable Sources: Personalize your news feed by selecting the specific news sources you want to follow. Tailor your experience to focus on the topics and outlets that matter most to you.
  • Easy Sharing: Found an article you want to share? With a simple tap, you can send articles to friends, family, or colleagues via messages or email, making it easy to keep everyone in the loop.

Device Platforms Currently Supported:

  • iOS – iPhone/iPad
  • Additional platform versions of the app are still in development. I will update this section as they are accepted.

App Help Information:

The Ashland News Dispatches app allows you to read articles from several news sources in the greater Ashland Oregon area. To share a page (by email, text message, etc.) in the Browser tab, click the sharing button in the upper right corner.
The Settings tab allows you to: 1) Select News sites, 2) Choose to see “Today’s News” or “All News”, 3) Set the app’s style, 4) Use the “Save Settings” button.

Technical Details:

This app was created using Embarcadero Delphi and the FireMonkey (FMX) cross-platform GUI framework.

The app displays a list with the title and date for news articles from a curated list of southern Oregon news sources. Selecting one of the articles from the list displays the article in the Browser tab. At the top right of the Browser tab title you can use the button to share the article link.

Product and Technical Support:

The app’s Help tab allows you to send an email with questions, issues, suggestions and other feedback to the developer. You can also send emails directly to david.intersimone at gmail.com.

App Screen Shots:

Ashland Oregon News Dispatches App Privacy Policy:

Effective Date: August 31, 2024

Thank you for using Ashland Oregon News Dispatches app! We value your privacy and are committed to protecting your personal information. This app does not collect any personal or contact information.

Contact Information: If you choose to share articles via email or messages, the app may request access to your contacts solely for the purpose of sharing the selected articles. We do not store or retain any contact information.

Usage Data: This app does not collect any information about your interactions with the app, such as the articles you read, the sources you select, nor the times of your interactions.

Device Information: This app does not collect any information about the device you use.

Children’s Privacy: The Ashland Oregon News Dispatches app is not intended for use by children under the age of 13. We do not knowingly collect personal information from children under 13. If we become aware that we have inadvertently collected such information, we will take steps to delete it as soon as possible.

Your Privacy Rights: Depending on your location, you may have certain rights regarding your personal information, including the right to access, correct, or delete your data. To exercise these rights, please contact us at [Insert Contact Email].

Changes to This Privacy Policy: We may update this Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on this page. We encourage you to review this Privacy Policy periodically for any updates.

Contact Us: If you have any questions or concerns about this Privacy Policy or our data practices, please contact us at david.intersimone at gmail.com

By using the Ashland Oregon News Dispatches app, you agree to the terms of this Privacy Policy.

The Worst and Best Delphi Programs I Ever Created

My Worst Delphi Program

The worst “on-the-fly” (pun intended) Delphi demo I ever wrote was a thread based sort program (Dreaded Sorts). I created the code on the flight from San Jose to Seattle for the Microsoft Windows 95 launch. The launch took place on Thursday August 24, 1995 on the Microsoft campus. Multiple software vendors, including Borland, demonstrated their support for Win95 in tents on the lawn.

During the flight I realized that I didn’t have a Delphi 2 demo that took full advantage of Win95’s 32-bit OS and other features. So, for the duration of flight (approximately 2 hours) I hacked together a 32-bit VCL application using a pre-release version of Delphi. Note: the program still compiles and runs using the latest release of Delphi 11 Alexandria!

Charlie Calvert included my “Dreaded Sorts” program in his Delphi 2 Unleashed book (pages 240-243). The source code for the project can be found on the book’s CD.

To introduce my program Charlie wrote:

“The program shown in Listing 7.9 was written by David Intersimone, a fellow Borland employee. The code has some historical significance, as it was written on the flight to the Windows 95 launch in Seattle. The fact that David was able to do some serious coding on a West Coast shuttle flight shows that almost anything is possible if you set your mind to it!”

The Original Dreaded Sorts Source Code (THSORTS.DPR)

The original name of my on-the-fly demo was THSorts. I eventually called it my “Dreaded Sorts” program when Charlie Calvert asked to include it in his Delphi 2 Unleased book. Take a look at the source code below. You’ll see that it contains many bad programming practices and hacks that I used on the flight to get the demo working. Examples of bad programming practices include using magic numbers, offset coordinate hacks, hard coded array size (Delphi now supports dynamic arrays), changing the caption for the input error message instead of a Message Box popup, etc. The most glaring warning was the note at the top of the main form’s source code: “This example program shows how to set a thread’s priority. Don’t use Canvas property in program like this! Not unless you also use the TThread object and its Synchronize procedure!”

MAIN.PAS (note: you can download a zip file of the complete program)

unit main;

{
  Dreaded Sorts
  copyright (c) 1996 by David Intersimone

  This example program shows how to set a
  thread's priority. Don't use Canvas property
  in program like this! Not unless you also
  use the TThread object and its Synchronize
  procedure!
}
  
interface

uses
  SysUtils, WinTypes, WinProcs,
  Messages, Classes, Graphics,
  Controls, Forms, Dialogs,
  StdCtrls, ComCtrls, Buttons;

const
  aMax = 300;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Label2: TLabel;
    Label1: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    BitBtn1: TBitBtn;
    BubbleTrackBar: TTrackBar;
    QuickTrackBar: TTrackBar;
    procedure Button1Click(Sender: TObject);
  private
    T1 : THandle;
    T2 : THandle;
  end;

var
  Form1: TForm1;
  a,b : array[0..aMax-1] of integer;
  numItems : integer;

implementation

uses
  secform, thform;

{$R *.DFM}

procedure BubbleSort(var ia:array of integer; items: integer);
var
  i,j,t : integer;
  DC: HDC;
begin
  DC := GetDC(Form2.Handle);
  for i := items downto 0 do
  begin
    for j := 0 to items-1 do
      if ia[j] < ia[j+1] then
      begin
        t := ia[j];
        SetPixel(DC, ia[j+1]+5, j+1+5, clBlue);
        SetPixel(DC, ia[j]+5, j+5, clBlue);
        ia[j] := ia[j+1];
        ia[j+1] := t;
        Setpixel(DC, ia[j+1]+5,j+1+5, clYellow);
        Setpixel(DC, ia[j]+5,j+5, clYellow);
      end;
   end;
   ReleaseDC(Form2.Handle, DC);
end;

procedure QuickSort(var ia:array of integer; iLo,iHi : integer);
var
  Lo,Hi,Mid,T : integer;
  DC: HDC;
begin
  Lo := iLo;
  Hi := iHi;
  mid := ia[(Lo+hi) div 2];
  repeat
    DC := GetDC(Form3.Handle);
    while ia[Lo] < mid do Inc(Lo);
    while ia[Hi] > mid do Dec(Hi);
    if Lo <= Hi then
    begin
      T := ia[Lo];
      SetPixel(DC, ia[Lo]+5,Lo+5, clBlue);
      SetPixel(DC, ia[Hi]+5,Hi+5, clBlue);
      ia[Lo] := ia[Hi];
      ia[Hi] := T;
      SetPixel(DC, ia[Lo]+5,Lo+5, clLime);
      SetPixel(DC, ia[Hi]+5,Hi+5, clLime);
      inc(Lo);
      dec(Hi);
    end;
  until Lo > Hi;
  if Hi > iLo then QuickSort(ia,iLo,Hi);
  if Lo < iHi then QuickSort(ia,Lo,iHi);
  ReleaseDC(Form3.Handle, DC);
end;

function BubbleThread(parms:pointer) : LongInt; far;
begin
  BubbleSort(a,numItems-1);
end;

function QuickThread(parms:pointer) : LongInt; far;
begin
  QuickSort(b,0,numItems-1);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i : integer;
  ThreadID : dWord;
begin
  numItems := strToInt(Edit1.Text);
  if numItems <= aMax then
  begin
    form2.free;
    form2 := TForm2.Create(self);
    form2.top := 140;
    form2.left := 2;
    form2.clientheight := numItems+10;
    form2.clientwidth := numItems+10;
    form2.color := clBlue;
    form2.caption := 'Bubble Sort';
    form2.show;

    form3.free;
    form3 := TForm3.Create(self);
    form3.top := 140;
    form3.left := 320;
    form3.clientheight := numItems+10;
    form3.clientwidth := numItems+10;
    form3.color := clBlue;
    form3.caption := 'Quick Sort';
    form3.show;

    Randomize;
    for i := 0 to numItems-1 do
    begin
      a[i] := random(numItems);
      b[i] := a[i];
      form2.canvas.pixels[a[i]+5,i+5] := clYellow;
      form3.canvas.pixels[b[i]+5,i+5] := clLime;
    end;
    T1 := createThread(nil,0,@BubbleThread,nil,0,threadID);
    setThreadPriority(T1, BubbleTrackBar.Position);
    T2 := createThread(nil,0,@QuickThread,nil,0,threadID);
    setThreadPriority(T2, QuickTrackBar.Position);
  end
  else
    Form1.Caption := 'Too Large!';
end;

end.

A Much Better Version of a Delphi Multi-Threaded Sort Demo

A much better version of a Delphi multi-threaded demo shipped in the release version of Delphi 2 (release date: February 10, 1996) is available on GitHub. You can download the Delphi multi threading demo by Bob Ainsbury and Ray Konopka that first appeared at the 1995 Borland Conference.

My Best Delphi Program

The best Delphi program I ever created is one that I haven’t written yet!

Additional Information

Embarcadero Delphi product page – https://www.embarcadero.com/products/delphi

Parts of this post first appeared on my Embarcadero Blog article celebrating the 27th birthday of Delphi – https://blogs.embarcadero.com/happy-27th-birthday-delphi-building-the-future-how-we-get-to-delphi-36/

Remembering the Iconic Windows 95 Launch by Lance Ulanof – https://onezero.medium.com/remembering-the-iconic-windows-95-launch-94cfcf215d50

Delphi 2 Unleased by Charlie Calvert – https://www.abebooks.com/9780672308581/Delphi-2-Unleashed-Calvert-Charles-0672308584/plp

Using Python4Delphi with C++Builder VCL applications

Some C++ developers also use Python for their application development. There are several ways to integrate the two languages together. One way is to create Python extension modules containing C++ functions that implement new object types and functions. Another way is to use the Boost Python C++ library that enables interoperability between the Python and C++ languages. A third way is to use the productivity, resusability, and encapsulation of components to to integrate C++Builder and Python. In this chapter you’ll learn how to use the Python4Delphi open source components in your VCL applications.

Introduction to Python4Delphi (and C++Builder)

Python for Delphi (P4D) is a set of free components (MIT Open Source License), created by Kiriakos Vlahos author of the popular PyScripter Python IDE, that wrap up the Python DLL into Delphi. The components allow you to create or extend your Delphi and C++Builder applications to execute Python scripts, create new Python modules and new Python types. You can also create Python extensions as DLLs and much more.

You’ll find Python4Delphi on GitHub at https://github.com/pyscripter/python4delphi. The GitHub project includes a readme file, installation notes, supported platforms, how Python4Delphi finds your Python distributions, tutorials and demos.

Jim McKeeth recently hosted a webinar with Kiriakos, “Python for Delphi Developers Part 1 – Introduction” (replay is available on YouTube). A Part 2 Python for Delphi Developers will take place on Wednesday, October 14, 2020 at 7am Pacific Time. While this webinar series focuses on Delphi programming, it also provides information about the Python4Delphi components and Python programming that can help C++Builder developers.

While the webinar and Python4Delphi speaks to Delphi developers, C++Builder developers can compile and install the components for use in their Win32 and Win64 C++ VCL applications. To build and install the Python4Delphi components you can use all editions of C++Builder (community, professional, enterprise and architect) and RAD Studio (professional, enterprise and architect) for versions 10.3.3, 10.4 and 10.4.1. If you only have C++Builder, you’ll learn how to use the included Delphi DCC32 and DCC64 command line compilers to build the Delphi component package project and install the components.

Installing Python for Windows (32 and 64 bit)

Before you start using the Python4Delphi components in your C++Builder VCL applications you’ll need to make sure you have Python for Win32 and Win64 installed on your computer.

You can download and install releases of Python from the Python.org web site. For Win32 and Win64 you will find installers at https://www.python.org/downloads/windows/

To find Python distributions installed on your computer, use the “where python.exe” Windows command.

By default, Python for Win32 installs into the C:\Users\david\AppData\Local\Programs\Python\Python39-32\ folder (or wherever you tell the install to put the distribution).

By default, Python for Win64 installs into the C:\Users\david\AppData\Local\Programs\Python\Python39\ folder (or wherever you tell the install to put the distribution).

Installing Python4Delphi and Using the Components

The following are the steps I followed to download and build the Python4Delphi components for use with C++Builder 10.3.3, 10.4 and 10.4.1. While I used RAD Studio (which includes C++Builder and Delphi), you can also use C++Builder along with the Delphi command line compilers to compile and install the components.

Step 1 – Download the latest release of the Python4Delphi

Grab the python4delphi-master.zip file (https://github.com/pyscripter/python4delphi) and unzip it to your hard drive (I put it in my C:\Users\david\Documents\Embarcadero\Studio\Projects/ folder).

Step 2 – In the IDE open the Python_D package project file (RAD Studio editions)

In the C++Builder 10.4.1 RAD Studio IDE, open the Python_D.dproj package project file (you’ll find it in the “python4delphi-master\Packages\Delphi\Delphi 10.4+” folder).

Step 3 – Add an $IFDEF around the requires DesignIDE unit

Look at the Python_D.dpk source file, if you don’t see an $IFDEF around the DesignIDE unit, add it to avoid a compiler error when using the Win64 C++ compiler – DesignIDE is only required for Win32 since the IDE is a 32-bit Windows app.

Notice (in the source code above) that the LibSuffix Delphi compiler directive is set to “AUTO”. This can be done in source code or in the Project | Options | Description page (in the image below) to match the package file suffix with other compiled package files. The suffix is applied before the file extension. In drop down list, you can select the $(Auto) option for the suffix to represent the compiler version suffix for binary package files.

There is a separate Python_D.dpk package source file for versions 10.3 and earlier in the “python4delphi-master\Packages\Delphi\Delphi 10.3-” folder. In this package source file there are $IFDEFs to set the LIBSUFFIX for several recent Delphi compiler releases.

If you are going to use this earlier Python_D.dpk project you may need to comment out (or remove) the “{$R *.res}” statement at the front of the package source file (it may have already been removed in the latest commit of Python4Delphi).

Step 4a – Build and Install the Python4Delphi components with RAD Studio

There are two ways to build and install the components depending on whether you have RAD Studio or one of the C++Builder editions. If you only have C++Builder skip to “Step 4b” to learn how to use the Delphi command line compilers for Win32 and Win64.

Set the Python4Delphi Project Options for the Delphi Compiler | C/C++ Output file generation for Win32 and Win64 platform (all configurations – debug and release). Build and Install the Python4Delphi components for Win32 and Win64 targets.

Building and installing the components will make sure you have the generated C++ header files, package import library files and package static library files for your C++ VCL Win32 and Win64 projects.

From the help file: the “Generate all C++Builder files (including package libs)” option generates the package and all Delphi pieces, along with all necessary header files (.hpp), package import library file (.bpi), and package static library file (.lib and .a) for C++ projects. This is the default in desktop platforms.

Set the Delphi Compiler Search Path to include the Python4Delphi source directory so that the compiler will find any required include files and other files.

Step 4b – Use the Delphi command line compilers to Build and Installing the components

You can use batch files (or other script files) that run the Delphi command line compilers for Win32 (DCC32.exe) and Win64 (DCC64.exe). These Delphi compilers (included in the bin folder) will build the Python4Delphi package file and create the C++ header files, compiled package file, static library and other files required for use in your C++ applications.

CompilePython4DelphiPackage4Win32.bat

@ECHO OFF
ECHO Compiling Python4Delphi Component Package for Win32
dcc32 Python_D.dpk ^
-I"C:\Users\david\Documents\Embarcadero\Studio\Projects\Python4Delphi\python4delphi-master\Source" ^
-LE"C:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl" ^
-LN"C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp" ^
-NH"C:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win32" ^
-NB"C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp" ^
-E"C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp" ^
-JL ^
--lib-suffix:260 ^
-NSsystem;vcl;winapi;system.win ^
-u"c:\program files (x86)\embarcadero\studio\20.0\lib\win32\release"

move /y "C:\Users\david\Documents\Embarcadero\Studio\Projects\Python4Delphi\python4delphi-master\Packages\Delphi\Delphi 10.3-\Python_D.lib" "C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Python_D.lib"

ECHO Completed Python4Delphi Component Package Win32
pause

CompilePython4DelphiPackage4Win64.bat

@ECHO OFF
ECHO Compiling Python4Delphi Component Package for Win64
dcc64 Python_D.dpk ^
-I"C:\Users\david\Documents\Embarcadero\Studio\Projects\Python4Delphi\python4delphi-master\Source" ^
-LE"C:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl\Win64" ^
-LN"C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64" ^
-NH"C:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win64" ^
-NB"C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64" ^
-E"C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64" ^
-JL ^
--lib-suffix:260 ^
-NSsystem;vcl;winapi;system.win ^
-u"c:\program files (x86)\embarcadero\studio\20.0\lib\win64\release"

move /y "C:\Users\david\Documents\Embarcadero\Studio\Projects\Python4Delphi\python4delphi-master\Packages\Delphi\Delphi 10.3-\Python_D.a" "C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64\Python_D.a"

ECHO Completed Python4Delphi Component Package Win64
pause

Install he Python4Delphi Package

In the C++Builder IDE, use the Components | Install Packages menu item and click the “Add…” button.

Navigate to the C:\Users\Public\Documents\Embarcadero\Studio\21.0\Bpl folder (the number will depend on which version of C++Builder you have) and select the Design time package (BPL) file and click the Open button. This will add the package and components to the IDE. You’ll now see “Components for Python” in the list of Design time packages. Highlight the entry and click the Components button to display the list of components in the package.

Step 4c – Verify that the generated Python4Delphi files for C++ use are generated

After you compile the Python4Delphi package project for Win32 and Win64 target platforms the following files will be generated:

C:\Users\Public\Documents\Embarcadero\Studio\21.0\hpp\Win32
Python_D.hpp
PythonEngine.hpp
PythonGUIInputOutput.hpp
MethodCallBack.hpp
WrapDelphi.hpp
C:\Users\Public\Documents\Embarcadero\Studio\21.0\hpp\Win64
Python_D.hpp
PythonEngine.hpp
PythonGUIInputOutput.hpp
MethodCallBack.hpp
WrapDelphi.hpp
C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp
Python_D.bpi
Python_D.dcp
Python_D.lib
C:\Users\Public\Documents\Embarcadero\Studio\21.0\Dcp\Win64
Python_D.a
Python_D.bpi
Python_D.dcp
C:\Users\Public\Documents\Embarcadero\Studio\21.0\Bpl
Python_D270.bpl
C:\Users\Public\Documents\Embarcadero\Studio\21.0\Bpl\Win64
Python_D270.bpl
Python_D270.rsm

In the IDE you’ll now see the components in the Component Palette window.

Building Your First C++Builder Python4Delphi VCL Application

Using RAD Studio, I opened the Python4Delphi Demo1 Delphi project and tested it to make sure that I had the components and Python working. C:\Users\david\Documents\Embarcadero\Studio\Projects\Python4Delphi\python4delphi-master\Demos\Demo01

Use File | New | C++Builder VCL application to create a starting C++Builder project (note: the source code for the project is in a zip file listed in the References section). I copied all of the components from the Delphi version of the Demo01 form file.

Demo01Unit.dfm file

object Form2: TForm2
  Left = 0
  Top = 0
  Caption = 'Demo 01 Python (C++, VCL)'
  ClientHeight = 344
  ClientWidth = 534
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Splitter1: TSplitter
    Left = 0
    Top = 153
    Width = 534
    Height = 3
    Cursor = crVSplit
    Align = alTop
    Color = clBtnFace
    ParentColor = False
    ExplicitWidth = 536
  end
  object Memo1: TMemo
    Left = 0
    Top = 156
    Width = 534
    Height = 144
    Align = alClient
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -13
    Font.Name = 'Consolas'
    Font.Pitch = fpVariable
    Font.Style = []
    Lines.Strings = (
      'print(2+2)')
    ParentFont = False
    ScrollBars = ssBoth
    TabOrder = 0
  end
  object Panel1: TPanel
    Left = 0
    Top = 300
    Width = 534
    Height = 44
    Align = alBottom
    BevelOuter = bvNone
    TabOrder = 1
    object Button1: TButton
      Left = 0
      Top = 6
      Width = 115
      Height = 25
      Caption = 'Execute script'
      TabOrder = 0
      OnClick = Button1Click
    end
    object Button2: TButton
      Left = 167
      Top = 6
      Width = 91
      Height = 25
      Caption = 'Load script...'
      TabOrder = 1
      OnClick = Button2Click
    end
    object Button3: TButton
      Left = 264
      Top = 8
      Width = 89
      Height = 25
      Caption = 'Save script...'
      TabOrder = 2
      OnClick = Button3Click
    end
  end
  object Memo2: TMemo
    Left = 0
    Top = 0
    Width = 534
    Height = 153
    Align = alTop
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -13
    Font.Name = 'Consolas'
    Font.Pitch = fpVariable
    Font.Style = []
    ParentFont = False
    ScrollBars = ssBoth
    TabOrder = 2
  end
  object PythonEngine1: TPythonEngine
    IO = PythonGUIInputOutput1
    Left = 32
    Top = 32
  end
  object OpenDialog1: TOpenDialog
    DefaultExt = '*.py'
    Filter = 'Python files|*.py|Text files|*.txt|All files|*.*'
    Title = 'Open'
    Left = 240
    Top = 32
  end
  object SaveDialog1: TSaveDialog
    DefaultExt = '*.py'
    Filter = 'Python files|*.py|Text files|*.txt|All files|*.*'
    Title = 'Save As'
    Left = 328
    Top = 32
  end
  object PythonGUIInputOutput1: TPythonGUIInputOutput
    UnicodeIO = True
    RawOutput = False
    Output = Memo2
    Left = 128
    Top = 32
  end
end

Demo01Unit.h file

//---------------------------------------------------------------------------

#ifndef Demo01UnitH
#define Demo01UnitH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include "PythonEngine.hpp"
#include <Vcl.Dialogs.hpp>
#include <Vcl.ExtCtrls.hpp>
#include "PythonGUIInputOutput.hpp"
//---------------------------------------------------------------------------
class TForm2 : public TForm
{
__published:	// IDE-managed Components
	TSplitter *Splitter1;
	TMemo *Memo1;
	TPanel *Panel1;
	TButton *Button1;
	TButton *Button2;
	TButton *Button3;
	TMemo *Memo2;
	TPythonEngine *PythonEngine1;
	TOpenDialog *OpenDialog1;
	TSaveDialog *SaveDialog1;
	TPythonGUIInputOutput *PythonGUIInputOutput1;
	void __fastcall Button1Click(TObject *Sender);
	void __fastcall Button2Click(TObject *Sender);
	void __fastcall Button3Click(TObject *Sender);
private:	// User declarations
public:		// User declarations
	__fastcall TForm2(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2 *Form2;
//---------------------------------------------------------------------------
#endif

Next, add OnClick event handlers for the 3 buttons.

Demo01Unit.cpp file

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Demo01Unit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "PythonEngine"
#pragma link "PythonGUIInputOutput"
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
	PythonEngine1->ExecStrings( Memo1->Lines );
}
//---------------------------------------------------------------------------

void __fastcall TForm2::Button2Click(TObject *Sender)
{
	if (OpenDialog1->Execute()) {
		Memo1->Lines->LoadFromFile( OpenDialog1->FileName );
	}
}
//---------------------------------------------------------------------------

void __fastcall TForm2::Button3Click(TObject *Sender)
{
	if (SaveDialog1->Execute()) {
		Memo1->Lines->SaveToFile( SaveDialog1->FileName );
	}
}
//---------------------------------------------------------------------------

Save the project to a folder.

Compile and Run the C++ VCL Demo program and try some Python code

In the TMemo at the bottom of the form, type in some Python code. In my example I print the sum of two numbers, print the value of Pi from the Python math library and print the Python version # from the Python platform library. You can also use the Load and Save script buttons to bring up dialog boxes to load and save Python script files. Click the Execute script button to see the results show up in the upper TMemo.

References

Python4Delphi and PyScripter

Python4Delphi on GitHub by Kiriakos Vlahos – https://github.com/pyscripter/python4delphi

Webinar Replay – Python for Delphi Developers – Part 1 – Introduction – https://blogs.embarcadero.com/webinar-replay-python-for-delphi-developers-part-1-introduction/

PyScripter on GitHub by Kiriakos Vlahos – https://github.com/pyscripter/pyscripter

Python for Windows

Python Releases for Windows (python.org) – https://www.python.org/downloads/windows/

Embarcadero DocWiki

Creating Packages and DLLs – http://docwiki.embarcadero.com/RADStudio/en/Creating_Packages_and_DLLs

Project | Options | Output – C/C++ – http://docwiki.embarcadero.com/RADStudio/en/Output_-_C/C%2B%2B

Project | Options | Description – http://docwiki.embarcadero.com/RADStudio/en/Descripti

Package Files Created by Compiling – http://docwiki.embarcadero.com/RADStudio/en/Package_Files_Created_by_Compiling

DCC32.EXE, the Delphi Command Line Compiler – http://docwiki.embarcadero.com/RADStudio/en/DCC32.EXE,_the_Delphi_Command_Line_Compiler

DCC64.EXE, the Delphi 64-bit Command Line Compiler – http://docwiki.embarcadero.com/RADStudio/en/DCC64.EXE,_the_Delphi_64-bit_Command_Line_Compiler

Delphi 32-bit compiler (DCC32.exe) cmd line help (from C++Builder Community Edition 10.3.3)

Embarcadero Delphi for Win32 compiler version 33.0
Copyright (c) 1983,2018 Embarcadero Technologies, Inc.

Syntax: dcc32 [options] filename [options]

  -A<unit>=<alias> = Set unit alias
  -B = Build all units             
  -CC = Console target             
  -CG = GUI target                 
  -D<syms> = Define conditionals   
  -E<path> = EXE/DLL output directory
  -F<offset> = Find error          
  -GD = Detailed map file          
  -GP = Map file with publics      
  -GS = Map file with segments     
  -H = Output hint messages        
  -I<paths> = Include directories  
  -J = Generate .obj file          
  -JPHNE = Generate C++ .obj file, .hpp file, in namespace, export all
  -JL = Generate package .lib, .bpi, and all .hpp files for C++
  -K<addr> = Set image base addr   
  -LE<path> = package .bpl output directory
  -LN<path> = package .dcp output directory
  -LU<package> = Use package       
  -M = Make modified units         
  -NU<path> = unit .dcu output directory
  -NH<path> = unit .hpp output directory
  -NO<path> = unit .obj output directory
  -NB<path> = unit .bpi output directory
  -NX<path> = unit .xml output directory
  -NS<namespaces> = Namespace search path
  -O<paths> = Object directories   
  -P = look for 8.3 file names also
  -Q = Quiet compile               
  -R<paths> = Resource directories 
  -TX<ext> = Output name extension 
  -U<paths> = Unit directories     
  -V = Debug information in EXE    
  -VR = Generate remote debug (RSM)
  -VT = Debug information in TDS   
  -VN = TDS symbols in namespace   
  -W[+|-|^][warn_id] = Output warning messages
  -Z = Output 'never build' DCPs   
  -$<dir> = Compiler directive     
  --help = Show this help screen   
  --version = Show name and version
  --codepage:<cp> = specify source file encoding
  --default-namespace:<namespace> = set namespace
  --depends = output unit dependency information
  --doc = output XML documentation 
  --drc = output resource string .drc file
  --no-config = do not load default dcc32.cfg file
  --description:<string> = set executable description
  --inline:{on|off|auto} = function inlining control
  --legacy-ifend = allow legacy $IFEND directive
  --zero-based-strings[+|-] = strings are indexed starting at 0
  --peflags:<flags> = set extra PE Header flags field
  --peoptflags:<flags> = set extra PE Header optional flags field
  --peosversion:<major>.<minor> = set OS Version fields in PE Header (default: 5.0)
  --pesubsysversion:<major>.<minor> = set Subsystem Version fields in PE Header (default: 5.0)
  --peuserversion:<major>.<minor> = set User Version fields in PE Header (default: 0.0)
  --lib-version:<version> = Output package name version
  --lib-suffix:<suffix> = Output package name suffix
Compiler switches: -$<letter><state> (defaults are shown below)
  A8  Aligned record fields         
  B-  Full boolean Evaluation       
  C+  Evaluate assertions at runtime
  D+  Debug information             
  G+  Use imported data references  
  H+  Use long strings by default   
  I+  I/O checking                  
  J-  Writeable structured consts   
  L+  Local debug symbols           
  M-  Runtime type info             
  O+  Optimization                  
  P+  Open string params            
  Q-  Integer overflow checking     
  R-  Range checking                
  T-  Typed @ operator              
  U-  Pentium(tm)-safe divide       
  V+  Strict var-strings            
  W-  Generate stack frames         
  X+  Extended syntax               
  Y+  Symbol reference info         
  Z1  Minimum size of enum types    
Stack size: -$M<minStackSize[,maxStackSize]> (default 16384,1048576)

Delphi 64-bit compiler (DCC64.exe) cmd line help (C++Builder Community Edition 10.3.3)

Embarcadero Delphi for Win64 compiler version 33.0
Copyright (c) 1983,2018 Embarcadero Technologies, Inc.

Syntax: dcc64 [options] filename [options]

  -A<unit>=<alias> = Set unit alias
  -B = Build all units             
  -CC = Console target             
  -CG = GUI target                 
  -D<syms> = Define conditionals   
  -E<path> = EXE/DLL output directory
  -F<offset> = Find error          
  -GD = Detailed map file          
  -GP = Map file with publics      
  -GS = Map file with segments     
  -H = Output hint messages        
  -I<paths> = Include directories  
  -J = Generate .obj file          
  -JPHNE = Generate C++ .obj file, .hpp file, in namespace, export all
  -JL = Generate package .lib, .bpi, and all .hpp files for C++
  -K<addr> = Set image base addr   
  -LE<path> = package .bpl output directory
  -LN<path> = package .dcp output directory
  -LU<package> = Use package       
  -M = Make modified units         
  -NU<path> = unit .dcu output directory
  -NH<path> = unit .hpp output directory
  -NO<path> = unit .obj output directory
  -NB<path> = unit .bpi output directory
  -NX<path> = unit .xml output directory
  -NS<namespaces> = Namespace search path
  -O<paths> = Object directories   
  -P = look for 8.3 file names also
  -Q = Quiet compile               
  -R<paths> = Resource directories 
  -TX<ext> = Output name extension 
  -U<paths> = Unit directories     
  -V = Debug information in EXE    
  -VR = Generate remote debug (RSM)
  -VT = Debug information in TDS   
  -VN = TDS symbols in namespace   
  -W[+|-|^][warn_id] = Output warning messages
  -Z = Output 'never build' DCPs   
  -$<dir> = Compiler directive     
  --help = Show this help screen   
  --version = Show name and version
  --codepage:<cp> = specify source file encoding
  --default-namespace:<namespace> = set namespace
  --depends = output unit dependency information
  --doc = output XML documentation 
  --drc = output resource string .drc file
  --no-config = do not load default dcc64.cfg file
  --description:<string> = set executable description
  --inline:{on|off|auto} = function inlining control
  --legacy-ifend = allow legacy $IFEND directive
  --zero-based-strings[+|-] = strings are indexed starting at 0
  --peflags:<flags> = set extra PE Header flags field
  --peoptflags:<flags> = set extra PE Header optional flags field
  --peosversion:<major>.<minor> = set OS Version fields in PE Header (default: 5.0)
  --pesubsysversion:<major>.<minor> = set Subsystem Version fields in PE Header (default: 5.0)
  --peuserversion:<major>.<minor> = set User Version fields in PE Header (default: 0.0)
  --lib-version:<version> = Output package name version
  --lib-suffix:<suffix> = Output package name suffix
Compiler switches: -$<letter><state> (defaults are shown below)
  A8  Aligned record fields         
  B-  Full boolean Evaluation       
  C+  Evaluate assertions at runtime
  D+  Debug information             
  G+  Use imported data references  
  H+  Use long strings by default   
  I+  I/O checking                  
  J-  Writeable structured consts   
  L+  Local debug symbols           
  M-  Runtime type info             
  O+  Optimization                  
  P+  Open string params            
  Q-  Integer overflow checking     
  R-  Range checking                
  T-  Typed @ operator              
  V+  Strict var-strings            
  W-  Generate stack frames         
  X+  Extended syntax               
  Y+  Symbol reference info         
  Z1  Minimum size of enum types    
Stack size: -$M<minStackSize[,maxStackSize]> (default 16384,1048576)

C++ Demo project and Delphi command line package build batch files (zip file)

A zip file is available for download at http://davidi.com/code/Python4DelphiDemo01.zip

New in C++Builder/Delphi 10.4.1 IDE: Package LibSuffix Auto Choice

The C++Builder and Delphi Project | Options | Description page allows developers to

  • Choose and Set build target configurations
  • Write a description for the package
  • Set strings for the package library filename’s prefix, suffix and version
  • Define the use of the package (designtime, runtime or both)
  • Specify how the package is built (rebuild as needed or explicit rebuild)

In previous versions (version 10.3 and earlier) of C++Builder and Delphi developers building packages needed to manually set their package’s library suffix setting. The DocWiki “What’s new in version 10.4.1” mentions a new IDE projects option for setting the library suffix:

“Package AUTO libsuffix: packages can now have an automatic version suffix, instead of manually updating and specifying the right version suffix with each new release. (The compiler quietly supported this in 10.4, but full support for the feature in the IDE and package project settings is introduced in 10.4.1.)”

While you can still set a string for the library filename suffix, selecting the new ComboBox choice, “$(Auto)”, allows the compiler to set the suffix to match the package build version used by the compiler. For each target build (debug and release) and OS platform the resulting package filename follows a pattern:

Win32 and Win64: <prefix>Package1<suffix>.<version>.bpl
Android: <prefix>Package1<suffix>.so.<version>
macOS and iOS: <prefix>Package1<suffix>.<version>.dylib

Creating and building a package with Delphi and C++Builder version 10.4.1, choosing the $Auto option for the suffix and setting other Description page settings results in a filename like the test package project images shown below.

C++Builder and Delphi also support package-specific compiler directives to include in a package project’s source code.

C++Builder Product Information

C++Builder Product Page – Native Apps that Perform. Build Windows C++ Apps 10x Faster with Less Code
C++Builder Product Editions – C++Builder is available in four editions – Professional, Enterprise, Architect and Community (free). C++Builder is also available as part of the RAD Studio development suite.