Fifty-one years ago today, May 15 1974, First National Bank of Atlanta introduced “Tillie the All-Time Teller” ATM system. The architecture involved the integration of the bank’s mainframes, a minicomputer, and the network of ATMs. Why am I noting the 51st anniversary of the public launch of the first Docutel Total-Teller ATM system in the US? I was the lead real-time assembly language programmer for the minicomputer that sat between the ATMs and the banks mainframes. This story covers my part in the implementation software for the minicomputer as part of the launch of the bank’s ATM network.
I got my first industry job working at TRW Data Systems in El Segundo (Los Angeles) California after graduating Cal Poly San Luis Obispo, CA with a BS in Computer Science in June 1973. At Cal Poly, I learned Data General Nova assembly language programming in Professor Emile Attala‘s real time computer lab. The software running on minicomputers connected transactions between department store cash registers, check cashing and credit card readers and a company’s mainframe computers.
Our TRW division worked on the first US cash dispenser implementation for Chemical Bank in New York with a Data General Nova minicomputer sitting between the ATM and the bank’s mainframe computers. Later, in late 1973, I was the lead programmer for the minicomputer that sat between a Docutel Total Teller network and First National Bank’s mainframes. This ATM could handle cash dispensing, deposits and transfers. I worked on the software for months of 80+ hour work weeks in order to be ready for the hard launch date of the system.
My development environment in the TRW Data Systems lab was a Data General Nova 1200 with 8k or 16k of core memory with magnetic tape drive, a Teletype Model 33, a text editor, linker and rudimentary debugger. For additional debugging I would also put halt instructions (063077) in my code for “things that should never happen during execution”. We did not use the teletype’s paper tape punch for backing up (too long) and instead dumped the programs to magnetic tape. We would print listings on line printers and put the listings and memory dumps into large binders.
I flew to Atlanta to install the DG Nova software arriving at the bank’s headquarters in downtown Atlanta. Back in those days my work “uniform” was usually jeans or overalls and t-shirts. When I arrived at the bank’s office the security was worried about why I wanted to go to the mainframe computer room where the minicomputer was installed.
A TRW hardware engineer arrived and explained that I was a young Los Angeles software developer and was escorted to the raised floor air conditioned computer room. All of the computer room operators were wearing slacks, white shirts and ties. I spent several days sitting on the computer room floor or at a table and small chair next to the minicomputer installing the software, testing and applying patches to fix bugs. After about a week, we were ready for the launch on May 15, 1974.
So that customers would be comfortable with the ATM, the bank created a persona called “Tillie the All Time Teller Girl”. The bank created commercials with fun jingles and advertisements to introduce this new ATM banking solution. Tillie was a smiling, blue eyed character that appeared in the ads and commercials. There was even a jingle created for the marketing campaign.
The ATMs were red and gold to make them look more friendly and accessible to customers.
The ATMs the bank used were Docutel’s Total Teller, which was more than just a cash dispenser. Using the Total Teller you could get cash, make deposits and transfer between accounts. The software on the minicomputer would take the ATM transaction information, validate it, send the request to the bank’s mainframe, receive back the authorization (or denial) response and send the result back to the Total Teller.
While monitoring the minicomputer I started to get a sore throat that got progressively worse. I asked the TRW team to find me a doctor. I went to a downtown Atlanta doctor who checked me out and finally told me, in a wonderful southern accent, that I had the “kissing disease” (Mononucleosis). I finished the installation and flew back to LA for several months of recovery.
Fun fact about Tillie: the woman in the picture and the ads was the voice and sang a song about Tillie the All Time Teller. That woman later on became the voice of Siri, Susan Bennett.
Fun Fact about the Data General Nova minicomputer: all bit patterns could be instructions and data. This made debugging somewhat challenging. If a buggy piece of code ran into data with unpredictable side effects and crashes. We always hoped that somehow execution would hit a bit pattern that was also a halt instruction. We would then dump memory to tape, ask the customer’s computer operator to print out the memory dump and try to look back from the halt or stuck loop and find the transaction data.
By David Intersimone “David I” – Friday, February 14, 2025
Today we celebrate the 30th anniversary of the launch of Delphi version 1.0 on Valentine’s Day, February 14, 1995, at the Software Development West Conference in San Francisco California. More that 12 years of continuous IDE, language, tools and library development led up to the launch of Delphi version 1.0.
The development of Delphi can trace some of its roots and technologies across Borland product releases including Turbo Pascal 1 (DOS and CP/M), Turbo Pascal 3 (overlays), Turbo Pascal 4 (units), Turbo Pascal 5 (integrated and standalone debugger), Turbo Pascal 5.5 (objects), Turbo Pascal for the Mac, Turbo Pascal for Windows, Borland Pascal 7 for DOS and Windows, Paradox, dBase and InterBase. While Borland Pascal 7 was available, the development team had been working for about 2 years to complete the first Delphi release (see links at the end of this article for a few of the important historical documents).
The Delphi “Sneak Peak” at the Borland Conference 1994
The first public showing of Delphi took place at the Borland International Conference (BIC) 1994 Walt Disney World Dolphin and Swan Hotels, Orlando Florida. The original language track was focused on Borland C++ 4 and also Borland Pascal. Paul Gross gave the “Product Address: Languages” in the Swan Ballroom on Monday morning from 8-9:15am. Prior to the conference a last minute decision was made to add two Delphi sessions: “Sneak Peak: Rapid Application Development in Pascal” session given by Zack Urlocker (Delphi95) and Bill Dunlap’s sneak session, “Sneak Peak: Exception Handling in Pascal”. “Even Spencer the Cat hasn’t seen this,” said senior product manager Zack Urlocker. Delphi95 will “compete with Visual Basic on the low end and PowerBuilder on the high end.”
It’s funny to look back and remember that the title of the Zack and Bill sessions were titled “Sneak Peak” – instead of “Sneak Peek” – a purposeful choice of the word “Peak” to denote the state-of-the-art technologies in Rapid Application Development (Visual Basic and PowerBuilder still did not integrate native code compilers).
There was also an NDA session for leading Paradox developer partners where Delphi95 was presented. One of the questions during the session was “is this the Paradox compiler that was rumored to be in development?” The answer was no, unless you wanted to use Delphi and the BDE to access your Paradox files.
The Delphi v1 Launch – Valentine’s Day, February 14, 1995
The Delphi launch took place at the Miller Freeman Software Development Conference West in San Francisco California, on Valentine’s Day, February 14th 1995 at 7PM just after Philippe Kahn’s keynote “The Importance of Object Computing – The Algorithmic Link”. Two editions of Delphi were announced: Delphi and Delphi Client/Server. Before the launch, we were demonstrating existing Borland language products in the Borland booth. The day after the launch we demoed Delphi to overflowing crowds of enthusiastic developers.
While we annually celebrate the launch of Delphi version 1.0 on February 14, the actual RTM (release to manufacturing) date, and the date that all of the Delphi v1 files are date stamped, was February 15, 1995. Gary Whizin, R&D manager for Delphi tells the story about the RTM date in a 10 year remembrance audio interview. Gary said that the team did sign off the Delphi 1 master on February 14, 1995 before driving to the conference for the product launch. A stop ship bug was found and the product was re-mastered and the team signed off the first version again on February 15, 1995 (the date stamp on the files).
What Made Delphi version 1 So Special
While Microsoft had Visual Basic and PowerSoft had PowerBuilder, what differentiated Delphi was the combination of the power of the Object Pascal language, a visual component-based development environment and desktop and SQL database access:
High speed, native code compiler
IDE providing visual two-way tools – form designer and source code editor
TObject, records, component, and owner memory management
Property Method Event (PME)
Visual Component Library (VCL)
Runtime Library (RTL)
Structured exception handling
Data-aware components live at design time
Database support via BDE and SQL Links
Running Delphi v1 on Windows 3.1 in a DOSBox on a Win10 (or 11) PC
To Get Started
If you’re unfamiliar with how to install and run Delphi v1 on Windows 3.1, watch the YouTube video, “Stu’s Game Reviews – How to Play Windows 3.1 Games in Windows 11!!! New for 2024!!!”. Sure, it’s about installing Windows 3.1 and running games, but the information and steps work for any Windows 3.1 software including Delphi v1. Hint: you don’t need to install the drivers mentioned in the video unless you also want to play games. https://www.youtube.com/watch?v=P4vtHkan5xw
The Software You Need to Run Delphi v1 on Windows 3.1
The following is a list of the required software to get Windows 3.1 and Delphi running on your Windows 10 (or 11) PC.
Borland Delphi 1.00 (2-15-1995)(CD).7z contains the following folders:
Installing Windows 3.1 and Delphi v1
To install Windows 3.1 and Delphi v1 I used DOSBox-X because it has a feature to easily handle swapping the Windows 3.1 six floppy disk image files and because “Stu” told me to use it 🙂
Install DOSBox-X and choose a folder on your Windows 10 (or 11) PC hard drive. Select all of the default settings during the install.
To install Windows 3.1, start DOSBox-X and mount the floppy disk image files for Windows 3.1. (note: I put the Win31 floppy disk images on my hard disk in a folder named “c:\w31”. I installed Windows 3.1 in my c:\DOSBox folder). The commands I typed were:
When Windows setup asks you to put disk 2 in drive A:, use the DOSBox-X menu “Drive” menu item, select drive A and in the popup menu select “Swap disk” (note: Guy said you might be able to use CTRL-F4). This will “put floppy disk 2 into drive A”. To complete the Windows 3.1 install, repeat this procedure for each of the remaining floppy disks. Note that DOSBox-X is in control of your mouse. When the Windows install asks for input (for example when it asks you to type in your name and company), hit CTRL-F10 to switch mouse control to the program your installing and then to get mouse control back to DOSBox-X hit CTRL-F10 again (you will hear an audible beep each time you hit CTRL-F10 if your PC’s sound is turned on).
When you choose to exit the Windows 3.1 setup program click the “Reboot” button to restart the DOS virtual machine to take you back to DOSBox-X.
To install Delphi v1 I put the CDROM install image, Delphi.iso, in my c:\installs folder. Using DOSBox-X, I typed the following commands:
imgmount d: C:\Installs\Delphi.iso -t cdrom
c:
cd windows
win
After Windows 3.1 starts, use the “File Manager” app to install Delphi.
and click on the “d” drive that contains the Delphi 1 CDROM.
Open the “INSTALL” folder and you’ll see folders containing the contents for each of the 15 floppy disk images (DISK1-DISK15) and the SETUP.EXE program.
Click on the SETUP.EXE program to install Delphi 1. Note: if you have the separate floppy disk image files (not recommended), follow the Windows 3.1 DOSBox-X “imgmount” command and floppy swap disk steps above for selecting and using all 15 of the floppy disk image files.
After Windows 3.1 and Delphi v1 were installed, the following is the c:\DOSBox folder contents:
With Windows 3.1 and Delphi v1 installed you’re now ready to experience the intoxication of using Delphi version 1.0 on your Windows PC 🙂
Running Delphi version 1.0
To run the Windows and Delphi you just installed, you can use either DOSBox-X or DOSBox.
Type the following commands:
mount c: c:\DOSBox
cd windows
win
Then from within Windows open the Delphi folder and click on the Delphi icon. Note: use Ctrl-F10 to capture and release the mouse for use on your PC desktop and in the DOSBox running Windows.
Check Out the Delphi version 1.0 Easter Eggs
In the Delphi v1 IDE select the Help | About menu item.
Hold down the Alt-key and type (all caps) DEVELOPERS
Hold down the Alt-key and type (all caps) AND
You’ll see a picture of Anders Hejlsberg floating in one of the lakes on the Borland campus in Scotts Valley, California. I shot a video of Anders (in Denmark Donald Duck is called “ANDERS AND”), during an all day party to celebrate his engagement, and grabbed a video frame to put in the About Box for Delphi.
Hold down the Alt-key and type (all caps) TEAM
You’ll see multiple pages of the names of the extended Delphi team that were a part of the development, launch and support of Delphi 1.0 (in alphabetical order by first name).
Here is a group photo of the extended Delphi team taken in the outdoor amphitheater on the campus.
Three Delphi adds that appeared in developer magazines during the launch year
Happy 30th Anniversary Delphi Launch Day!!!
I send big hugs and love to all of the employees who ever worked on Delphi. I send my thanks to all of the technology partners and MVPs who support Delphi. And, I send my deepest thanks to all of the customers who have ever used Delphi (many still do), attend Delphi conferences and seminars, participate in Delphi user groups, participate in online webinars, and share knowledge, source code and suggestions to help everyone (including me) become better Delphi software engineers.
I can’t finish this Delphi anniversary story without including a special developer, author and educator in my life, my brother separated at birth, and my technology travelling companion. That very special someone is Charlie Calvert. Charlie started at Borland working in technical support. Charlie is the author of “Turbo Pascal Programming 101”. After getting to know Charlie, I knew he was a one-of-a-kind developer, author and human being. I asked Charlie to join me in Borland Developer Relations. During the development of Delphi we knew that we would need great documentation, example programs, and to rev up our global Turbo Pascal community to be ready for the launch of Delphi. Charlie used his unique talents as a developer and an author to create his “Delphi Unleashed” book and also helped the team with the documentation. Charlie and I traveled the world together to present Delphi to customers, at conferences and meet with partners. While we were both children of the 60’s wearing comfy clothes (I wear Tie-dye t-shirts almost every day), on a trip to Madrid Spain we met with the government technology team working to create Spain’s early eBanking infrastructure. Nestor Miranda, head of the Borland office in Madrid, asked us to wear suits for the meeting because we were going to meet the head of the Bank of Spain. Along with two of Charlie’s programming books here is, probably the only time, a picture of Charlie and me at our hotel before we left for the meeting.
While I don’t travel, write, present and program nearly as much as I did during my 30+ years at Borland International, Inprise, Borland Software, CodeGear and Embarcadero, I have the code, pictures, videos and great memories that keep me smiling. I still program using Delphi as a semi-retired software engineer. Programming keeps me young, happy and alive!
Here are a few technology news stories that I’ve read in the past week or so.
Cloud Native Computing Foundation Announces Rook Graduation
Rook is an open source cloud native storage orchestrator for Kubernetes, providing the platform, framework, and support for a diverse set of storage solutions to natively integrate with cloud native environments. Rook delivers its services via a Kubernetes Operator for each storage provider. It was originally accepted as a CNCF project in 2018. It is the thirteenth CNCF project, and the first project based on block, file, or object storage, to graduate. Read the announcement article
How is Robotics Changing the Healthcare Industry?
Robotics is changing the healthcare industry in a lot of fundamental ways. Robots can manage the monotonous and repetitive tasks while leaving the doctors and nurses free to do the critical tasks they were trained for. This article discusses the wide variety of applications that robotics has in healthcare to make the lives of both doctors and patients much easier. Read the article.
Looking for the Next Step in Cloud Performance? Look to Data Center Design
In the near future, data centers will need specialized storage and compute areas that are segregated from each other. For example, when designing a floor plan, it’s likely we’ll see data center operators walling off Compute-as-a-Service from Storage-as-a-Service. This can help solve issues around cooling, which is paramount to eliminating waste and improving performance. However, it doesn’t fully solve the issue of accessibility and latency speeds. Read the post.
Object Detection from 9 FPS to 650 FPS
This article is a practical deep dive into making a specific deep learning model (Nvidia’s SSD300) run fast on a powerful GPU server, but the general principles apply to all GPU programming. The SSD300 is an object-detection model trained on COCO, so output will be bounding boxes with probabilities for 81 classes of object.
Product Demo Sucks Because It’s Focused on Your Product
In this exclusive interview, Falcone shares the structure of a winning product demo and the tactics he’s discovered to convince people that they need your product in just one conversation. one of the easiest and biggest mistakes he sees is that companies don’t effectively craft their demo to fit their specific audience — i.e. they don’t distill their dozens of features and selling points into the few that will really resonate with this particular investor, prospect, or even prospective employee.
Computer Scientists Break Traveling Salesperson Record
In a paper posted online, Klein and his advisers at the University of Washington, Anna Karlin and Shayan Oveis Gharan, have finally achieved a goal computer scientists have pursued for nearly half a century: a better way to find approximate solutions to the traveling salesperson problem. Read the article. Read the paper.
The Gap: Where Machine Learning Education Falls Short
As the field of machine learning has become ever more popular, a litany of online courses has emerged claiming to teach the skills necessary to “build a career in AI”. But before signing up for such a course, you should know whether the skills acquired will directly allow you to apply machine learning better. These questions are not limited to online courses but rather encompass machine learning classes that have begun to fill lecture halls at many universities. Are these classes that students flock towards actually helping them achieve their practical goals? Read the article.
10 Popular Backend APIs
A Backend API is an Application Programming Interface that developers can use to integrate with backend services. A great place to find these APIs is in the Backend or Backend as a Service categories in the ProgrammableWeb API directory. This article gives details to the ten most popular Backend APIs on ProgrammableWeb, based on website traffic.
The unreasonable effectiveness of the Julia programming language
Six years ago, the author wrote about the enduring prominence of Fortran for scientific computing and compared it with several other languages. That article with a prediction that, in 10 years, a new language called Julia stood a good chance of becoming the one that scientists would turn to when tackling large-scale numerical problems. The author’s prediction was not very accurate, though. It actually only took Julia about half that time. Read the article.
Big Tech, Out-of-Control Capitalism and the End of Civilization
“Our digital era is a blend of “utopia and dystopia,” says Tristan Harris, who left Google to cofound The Center for Humane Technology (a phrase that sounds increasingly oxymoronic). “I can hit a button on my phone and a car shows up in 30 seconds and I can go exactly where I need to go. That is magic.” But Harris fears tech’s ill effects are outweighing its benefits. “If we don’t agree on truth,” he says, “or even that there is such a thing as truth, we’re toast.” Read the complete Scientific American article.
10 Best Text Annotation Tools and Services for Machine Learning
In the AI research and development industries, annotated data is gold. Large quantities of high-quality annotated data is a goldmine. On the other hand, sometimes finding or creating this data can be an expensive and arduous task for your team. Fortunately, there are a variety of text annotation tools and services available that can provide you with the data you need. Some of these services include entity extraction, part-of-speech tagging, sentiment analysis, and more. Read the DZone article.
30+ Tools List for GitOps
Speaking of the right tools for the job, there are countless tools to help you integrate the GitOps approach with your existing workflows. Some of the tools supporting GitOps are so popular that you may even be using it in your existing pipeline. To help you get started, here are the tools that we recommend if you want to incorporate GitOps. Read the post.
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.
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.
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:
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
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.
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)
Here are a few technology news stories that I’ve read in the past week or so.
Microsoft’s 10 app store principles to promote choice, fairness and innovation
For software developers, app stores have become a critical gateway to some of the world’s most popular digital platforms. We and others have raised questions and, at times, expressed concerns about app stores on other digital platforms. However, we recognize that we should practice what we preach. So, today, we are adopting 10 principles – building on the ideas and work of the Coalition for App Fairness (CAF) – to promote choice, ensure fairness and promote innovation on Windows 10, our most popular platform, and our own Microsoft Store on Windows 10. Read Microsoft’s blog post.
PostMan’s 2020 State of the API Report
Every year, Postman surveys industry members to get a picture of the API industry—to understand who is working with APIs, how they are getting their work done, and where they see the industry going. More than 13,500 developers, testers, executives, and others took our 2020 survey and provided insights on everything from how they spend their time to what they see as the biggest issues and opportunities for APIs. Three key findings: API investments stay strong, The pandemic has changed the world, but it didn’t stop APIs, and APIs are the nucleus of digital transformation. Read and download the report on the Postman website.
Hybrid cloud is where the action is
Multicloud is definitely a thing. However, it’s not exactly clear what that “thing” is. According to new survey data from database vendor MariaDB, 71% of survey respondents report running databases on at least two different cloud providers today. Yet when asked what would keep them from going all in on a cloud database, a vendor’s “lack of a multicloud offering” ranked dead last. In other words, everyone is doing multicloud, but no one knows why. Read Matt Assay’s InfoWorld article.
Nvidia claims Cambridge-1 is the U.K.’s fastest supercomputer
Cambridge-1, which Nvidia expects to come online by year-end 2020, is a joint project between GSK, AstraZeneca, Guy’s and St Thomas’ NHS Foundation Trust, King’s College London, and Oxford Nanopore. Built on Nvidia’s DGX SuperPOD architecture, it’s anticipated to deliver over 400 petaflops of AI performance and 8 petaflops of Linpack performance. That would rank it 29th on the TOP500 list of the world’s most powerful supercomputers and among the top three most-energy-efficient machines in the Green500. Read Kyle Wiggers’ VentureBeat article.
Aptum’s Global Cloud Impact Study reveals this with 62 percent of respondents citing complexity and abundance of choice as a hindrance when planning a cloud transformation. One of the biggest sources of complexity that crops up in more advanced cloud projects are legacy systems. The “abundance of choice” or the need to select the best of breed is a prime culprit. This usually results in a technological smorgasbord, where hundreds of decoupled cloud dev and migration teams make their own calls around what technology to use. Complexity naturally arises when it’s time to join and coordinate those apples and oranges. Read David Linthicum’s InfoWorld article.
The art of code reviews
According to Phil Hughes, front-end engineer at GitLab, it’s about how you provide and convey that feedback — and that’s an art form and a skill that is learned over time. “Reviewing code efficiently is a skill that gets learned the more you do it. Spending time coming up with a workflow that works for yourself is just as important”. Read the SD Times article by Christina Cardoza.
An AI can simulate an economy millions of times to create fairer tax policy
Scientists at the US business technology company Salesforce think AI can help. Led by Richard Socher, the team has developed a system called the AI Economist that uses reinforcement learning—the same sort of technique behind DeepMind’s AlphaGo and AlpahZero—to identify optimal tax policies for a simulated economy. The tool is still relatively simple (there’s no way it could include all the complexities of the real world or human behavior), but it is a promising first step toward evaluating policies in an entirely new way. “It would be amazing to make tax policy less political and more data driven,” says team member Alex Trott. Read the MIT Technology Review article by Will Douglas Heaven.
The most valuable software developer skills in 2020
Which developer skills are the most valuable in today’s market? We’ve pored through the data to find the most bankable developer skills for the coming years—and how best to set yourself up for success in a fraught job market: Don’t put all your eggs in one basket, Some skills are hotter than others, Going cloud native, Ordering the full stack, Data is still the new oil, and Formal education isn’t everything. Read the InfoWorld article by By Scott Carey.
Justices wary of upending tech industry in Google v. Oracle Supreme Court fight
The dispute concerns about 11,500 lines of code that Google used to build its popular Android mobile operating system, which were replicated from the Java application programming interface developed by Sun Microsystems. At the end of an hour and a half of arguments, Justice Stephen Breyer, who at one point read aloud some code, seemed to be the only sure vote. Several of the other justices, including Chief Justice John Roberts, suggested they were sympathetic to Oracle’s copyright claims. Several of the court’s conservatives, including Justices Brett Kavanaugh and Samuel Alito, noted that Google’s allies had warned that the “sky will fall” if Oracle won. But those comments were also peppered with skepticism. “I’m not aware that the sky has fallen in the last five or six years,” Kavanaugh said, noting that Google had lost its first appeals court battle in the case in 2014. Read the CNBC article by Tucker Higgins.
Section 230 will be on the Chopping Block at the Next Big US Congressional Hearing
Will Section 230 be on the chopping block at the next US congressional tech hearing. Hearing will focus on Section 230 of the Communications Decency Act, the key law that shields online platforms from legal liability for the content their users create. What is clear: Tinkering with such a foundational law could have a huge cascade of effects for the internet as we know it and isn’t something to be undertaken lightly — if at all. Read the TechCrunch article by Taylor Hatmaker.
To the moon and beyond: How HoloLens 2 is helping build NASA’s Orion spacecraft
When workers for Lockheed Martin began assembling the crew seats for a spacecraft designed to return astronauts to the moon and pave the way for human exploration to Mars, they had no need for paper instructions or tablet screens to work from. Everything they needed to see, including animations of how pieces fit together, engineering drawings and torque values for tightening bolts, was visible in HoloLens 2 devices that they wore. Read the TechXplore article by Jennifer Langston, Microsoft.
While Raspberry Pi boards are great for doing all kinds of tasks and they’re capable of doing object recognition, they can be a little slow when it comes to real-time image recognition. In 2019, Nvidia came out with an A.I.-focused Pi competitor in the $99 Jetson Nano. Fast forward to 2020 and Nvidia is back with a 2GB version of the Jetson Nano that sells for a more reasonable $59 and, for consumers in some markets (including America), comes with a compatible USB Wi-Fi dongle in the box. Due out later this month, the new Nvidia Jetson Nano 2GB is designed to make A.I. more accessible to hobbyists, kids and aspiring developers. Read the Toms Harware article by Avram Piltch.
Microsoft’s VS Code comes to Raspberry Pi and Chromebook – new v1.50 update is out
An official Microsoft build of the Visual Studio Code editor is now available for Linux Armv7 and Arm64 architecture devices, extending Microsoft’s popular cross-platform code editor to Chromebooks, the Raspberry Pi and rival Arm-based single-board Linux computers such as Odroid. Read the ZDNet article by Liam Tung.
Why Apple needed the FDA to sign off on its EKG but not its blood oxygen monitor
The features on the Apple Watch that track heart rate and heart rhythm, though, have a key difference from the blood oxygen monitor: the heart-tracking features are cleared by the Food and Drug Administration (FDA), and the oxygen monitor is not. Apple went through a long, extensive process to develop and validate an EKG feature so that the watch could detect a condition called atrial fibrillation. It didn’t need to do the same thing for the pulse oximeter. Blood oxygen monitors, or pulse oximeters, are considered Class II medical devices by the FDA. Read TheVerge article by Nicole Wetsman.
JDK 16: What’s coming in Java 16 (due March 2021)
Java Development Kit (JDK) 16 has begun to take shape, with proposed features including concurrent thread-stack processing for garbage collection, support for C++ 14 language features, and an “elastic metaspace” capability to more quickly return unused class metadata memory to the OS. Read the InfoWorld article by Paul Krill.
Microsoft launches Playwright for Python for automating testing
Microsoft is trying to make it easier for developers to automate their end-to-end tests. The company has announced a preview of Playwright for Python, which allows developers and testers to write such tests in Python. According to Microsoft, automated end-to-end tests have become more important than ever as teams build apps that run on a number of different kinds of devices. The increase in the number of targets coupled with increased delivery speed has put more pressure on the testing process, and automation is crucial to enable testing at the speed it needs to be done. Playwright for Python provides timeout-free automation, which makes it more reliable. Read the SD Times article by Jenna Sargent.
Definitely not Windows 95: What operating systems keep things running in space?
To deal with unforgiving deadlines, spacecraft like Solar Orbiter are almost always run by real-time operating systems that work in an entirely different way than the ones you and I know from the average laptop. Operating systems used in space add at least one more central criterion: a computation needs to be done correctly within a strictly specified deadline. When a deadline is not met, the task is considered failed and terminated. And in spaceflight, a missed deadline quite often means your spacecraft has already turned into a fireball or strayed into an incorrect orbit. There’s no point in processing such tasks any further; things must adhere to a very precise clock. Read the ArsTechnica article by Jacek Krywko.
GitHub Code scanning is now available!
One year ago, GitHub welcomed Semmle. We’ve since worked to bring the revolutionary code analysis capabilities of its CodeQL technology to GitHub users as a native capability. At GitHub Satellite in May, we released the first beta of our native integration: code scanning. Now, thanks to the thousands of developers in the community who tested and gave feedback, we’re proud to announce that code scanning is generally available. Read the GitHub blog post by Justin Hutchings.
4 common C programming mistakes — and 5 tips to avoid them
Common C mistake: Not freeing malloc-ed memory (or freeing it more than once). Common C mistake: Reading an array out of bounds. Common C mistake: Not checking the results of malloc. Common C mistake: Using void* for generic pointers to memory. Read the InfoWorld article by Serdar Yegulalp.
Do you need to add printer support to your C++ applications using the Visual Component Library (VCL) or FireMonkey (FMX) GUI ? In this blog post I’ll show you how to build Windows applications that support printing image bitmaps using the VCL and FMX frameworks. One of my favorite C++Builder RTL features is that both frameworks provide similar printer components and ways of programming with only a few subtle differences.
Build VCL and FMX Application Projects
Use the “File | New | Windows VCL Application – C++Builder” menu item and create a starting C++ VCL application. Save the product to a folder.
File | New | Windows VCL Application – C++Builder
Next, in the Project Window, right mouse click on the ProjectGroup node and select the “Add New Project…” menu item.
Add New Project to the Project Group
In the popup dialog choose to create a Multi-Device Application.
Add New Multi-Device Application
Click the OK button and on the next screen choose to create a “Blank Application”.
Multi-Device Project templates list – choose Blank Application
Use the File | Save All menu item (or type Shift+Ctrl+S) to save both starting projects and the project group to a folder.
Project Group with VCL and FMX Starting Projects
Each of the VCL and FMX projects have a main form (.dfm and .fmx extensions respectively). While most of the IDE will look the same, if you select each form’s unit you will see different looks for each of their form designers.
VCL Form DesignerFMX Form Designer
There are many videos, articles and help files that describe the details of each designer (check out links in the reference section below). For now, let’s dig into the VCL and FMX printer examples I’ve created.
A Simple UI for each Printer Test Project
On each of the VCL and FMX main forms you’ll see the following components.
VCL form’s components in the Structure WindowFMX form’s components in the Structure Window
Each project’s main menu contains a File and Destination menu. The Destination menu item allows the user to choose to override the printing destination (Printer or File).
The File menu provides an OpenPictureDialog (VCL) or OpenDialog (FMX), PrintPicture dialog for choosing the printer and other printing options, PrinterSetup dialog to set additional printer setup options, Panel (aligned to the top of the form)with a label and ComboBox which will list the available printer device names, and an Image component (aligned to the client area) to contain the picture bitmap.
The VCL and FMX forms look like the following.
VCL app form with componentsFMX app form with components
Right mouse click on the form and choose “View as Text” from the popup menu. Now you can see all of the form and component properties and sub-properties that have been set from their default values. You can also make changes in this text form mode but be careful to not make any errors.
To switch back to the form mode click the right mouse button (or hit Alt-F12) and choose “View as Form” from the popup menu.
VCLPrintUnit.dfm (View as Text)
object MainVCLForm: TMainVCLForm
Left = 0
Top = 0
Caption = 'Printer Test (C++, VCL)'
ClientHeight = 473
ClientWidth = 667
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
Menu = MainMenu1
OldCreateOrder = False
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object Image1: TImage
Left = 0
Top = 41
Width = 667
Height = 432
Align = alClient
Proportional = True
ExplicitLeft = 104
ExplicitTop = 102
ExplicitWidth = 424
ExplicitHeight = 317
end
object Panel1: TPanel
Left = 0
Top = 0
Width = 667
Height = 41
Align = alTop
TabOrder = 0
object Label1: TLabel
Left = 10
Top = 12
Width = 41
Height = 13
Caption = 'Printers:'
end
object PrintersComboBox: TComboBox
Left = 57
Top = 9
Width = 250
Height = 21
TabOrder = 0
Text = 'PrintersComboBox'
end
end
object PrintDialog1: TPrintDialog
Options = [poPrintToFile]
Left = 176
Top = 56
end
object PrinterSetupDialog1: TPrinterSetupDialog
Left = 304
Top = 64
end
object OpenPictureDialog1: TOpenPictureDialog
DefaultExt = 'bmp'
InitialDir = 'c:\temp'
Left = 56
Top = 56
end
object MainMenu1: TMainMenu
Left = 424
Top = 64
object File1: TMenuItem
Caption = 'File'
object File2: TMenuItem
Caption = 'Open Picture'
OnClick = File2Click
end
object PrintPicture1: TMenuItem
Caption = 'Print Picture'
Enabled = False
OnClick = PrintPicture1Click
end
object PrinterSetup1: TMenuItem
Caption = 'Printer Setup'
Enabled = False
OnClick = PrinterSetup1Click
end
object PrintPicture2: TMenuItem
Caption = 'Exit'
OnClick = PrintPicture2Click
end
end
object Destination1: TMenuItem
Caption = 'Destination'
object PrintToPrinterDestinationMenuItem: TMenuItem
Caption = 'Print to Printer'
Checked = True
OnClick = PrintToPrinterDestinationMenuItemClick
end
object PrintToFileDestinationMenuItem: TMenuItem
Caption = 'Print to File'
OnClick = PrintToFileDestinationMenuItemClick
end
end
end
end
FMXPrintUnit.fmx (View as Text)
object MainFMXForm: TMainFMXForm
Left = 0
Top = 0
Caption = 'Printer Test (C++, FMX)'
ClientHeight = 380
ClientWidth = 640
Position = Designed
WindowState = wsMaximized
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnShow = FormShow
DesignerMasterStyle = 0
object Image1: TImage
MultiResBitmap = <
item
end>
Align = Client
Size.Width = 640.000000000000000000
Size.Height = 339.000000000000000000
Size.PlatformDefault = False
end
object PrintDialog1: TPrintDialog
Options = [poPrintToFile]
Left = 68
Top = 40
end
object PrinterSetupDialog1: TPrinterSetupDialog
Left = 190
Top = 42
end
object OpenDialog1: TOpenDialog
DefaultExt = 'bmp'
Filter = '*.bmp'
InitialDir = 'c:\temp'
Left = 312
Top = 44
end
object MainMenu1: TMainMenu
Left = 418
Top = 46
object FileMenu: TMenuItem
Text = 'File'
object OpenBitmapMenuItem: TMenuItem
Locked = True
Text = 'Open Bitmap'
OnClick = OpenBitmapMenuItemClick
end
object PrintMenuItem: TMenuItem
Enabled = False
Locked = True
Text = 'Print'
OnClick = PrintMenuItemClick
end
object PrinterSetupMenuItem: TMenuItem
Enabled = False
Locked = True
Text = 'Printer Setup'
OnClick = PrinterSetupMenuItemClick
end
object ExitMenuItem: TMenuItem
Locked = True
Text = 'Exit'
OnClick = ExitMenuItemClick
end
end
object DestinationMenu: TMenuItem
Text = 'Destination'
object PrintToPrinterDestinationMenuItem: TMenuItem
Locked = True
IsChecked = True
Text = 'Print to Printer'
OnClick = PrintToPrinterDestinationMenuItemClick
end
object PrintToFileDestinationMenuItem: TMenuItem
Locked = True
Text = 'Print to File'
OnClick = PrintToFileDestinationMenuItemClick
end
end
end
object Panel1: TPanel
Align = Top
Size.Width = 640.000000000000000000
Size.Height = 41.000000000000000000
Size.PlatformDefault = False
object PrintersComboBox: TComboBox
Position.X = 72.000000000000000000
Position.Y = 8.000000000000000000
Size.Width = 233.000000000000000000
Size.Height = 22.000000000000000000
Size.PlatformDefault = False
end
object Label1: TLabel
Position.X = 8.000000000000000000
Position.Y = 9.000000000000000000
Size.Width = 57.000000000000000000
Size.Height = 17.000000000000000000
Size.PlatformDefault = False
Text = 'Printers:'
end
end
end
Additional comments about component properties and event handlers are included in the source code for the projects.
The Source Code
Below you will find the header files for the VCL and FMX form units. The header files will show the component declarations, event handlers and any public/private declarations.
Below you will find the source code for the VCL and FMX form units.
VCLPrinterUnit.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#include <Vcl.Imaging.GIFImg.hpp>
#include <Vcl.Imaging.jpeg.hpp>
#include <Vcl.Imaging.pngimage.hpp>
#include <Vcl.Printers.hpp>
#pragma hdrstop
#include "VCLPrintUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainVCLForm *MainVCLForm;
//---------------------------------------------------------------------------
__fastcall TMainVCLForm::TMainVCLForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainVCLForm::File2Click(TObject *Sender)
{
if (OpenPictureDialog1->Execute()) {
Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
PictureLoaded = true;
PrintPicture1->Enabled = true;
PrinterSetup1->Enabled = true;
}
}
//---------------------------------------------------------------------------
void __fastcall TMainVCLForm::FormShow(TObject *Sender)
{
PictureLoaded = false;
PrintToPrinterDestinationMenuItem->Checked = true;
PrintToFileDestinationMenuItem->Checked = false;
// get printers list and put in combobox
PrintersComboBox->Items = Printer()->Printers;
// make the currently selected printer the Item in the ComboBox
PrintersComboBox->ItemIndex = 0;
for (int i = 0; i < Printer()->Printers->Count-1; i++) {
if (Printer()->Printers->Strings[Printer()->PrinterIndex] == PrintersComboBox->Items->Strings[i]) {
PrintersComboBox->ItemIndex = i;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TMainVCLForm::PrintToPrinterDestinationMenuItemClick(TObject *Sender)
{
// set menu item checked for print to printer
PrintToPrinterDestinationMenuItem->Checked = true;
PrintToFileDestinationMenuItem->Checked = false;
// set PrintDialog PrintToFile checkbox off
// Note: to allow user to override the menu item - make sure
// PrintDialog Options poPrintToFile is set to true
// so that the PrintToFile checkbox appears in the dialog
PrintDialog1->PrintToFile = false;
}
//---------------------------------------------------------------------------
void __fastcall TMainVCLForm::PrintToFileDestinationMenuItemClick(TObject *Sender)
{
// set menu item checked for print to file
PrintToPrinterDestinationMenuItem->Checked = false;
PrintToFileDestinationMenuItem->Checked = true;
// set PrintDialog PrintToFile checkbox on
// Note: to allow user to override the menu item - make sure
// PrintDialog Options poPrintToFile is set to true
// so that the PrintToFile checkbox appears in the dialog
PrintDialog1->PrintToFile = true;
}
//---------------------------------------------------------------------------
void __fastcall TMainVCLForm::PrintPicture1Click(TObject *Sender)
{
// check if a picture is loaded
if (PictureLoaded) {
if (PrintDialog1->Execute()) {
// Call BeginDoc - to get the dimensions for selected printer
Printer()->BeginDoc();
try {
// use StretchDraw to do full size bitmap printing
// notes:
// printer settings can be made using the
// PrintDialog and PrinterSetupDialog
// you can also control page layout in code:
// Property is Orientation:
// poPortrait
// poLandscape
Printer()->Canvas->StretchDraw(
Rect(0, 0, Printer()->PageWidth,Printer()->PageHeight),
Image1->Picture->Graphic);
}
__finally {
// end the document and the printing will begin
Printer()->EndDoc();
}
}
}
}
//---------------------------------------------------------------------------
void __fastcall TMainVCLForm::PrinterSetup1Click(TObject *Sender)
{
// Printer Setup
PrinterSetupDialog1->Execute();
}
//---------------------------------------------------------------------------
void __fastcall TMainVCLForm::PrintPicture2Click(TObject *Sender)
{
Application->Terminate();
}
//---------------------------------------------------------------------------
FMXPrinterUnit.cpp
//---------------------------------------------------------------------------
#include <fmx.h>
#include "FMX.Printer.hpp"
#include "System.SysUtils.hpp"
#pragma hdrstop
#include "FMXPrintUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TMainFMXForm *MainFMXForm;
//---------------------------------------------------------------------------
__fastcall TMainFMXForm::TMainFMXForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainFMXForm::PrintMenuItemClick(TObject *Sender)
{
TRectF SrcRect, DestRect;
if (PrintDialog1->Execute()) {
// Set the default DPI for the printer. The SelectDPI routine defaults
// to the closest available resolution as reported by the driver.
// Printer->ActivePrinter->SelectDPI(1200, 1200);
// Printer->ActivePrinter->ActiveDPIIndex = 1; // you can also the DPI index
// Set canvas filling style
// Printer->Canvas->Fill->Color = claBlack;
// Printer->Canvas->Fill->Kind = TBrushKind(1);
// Start printing
Printer::Printer()->BeginDoc();
// Set the Source and Destination TRects
SrcRect = TRectF(0, 0, Image1->Bitmap->Width, Image1->Bitmap->Height);
DestRect = TRectF(0, 0, Printer::Printer()->PageWidth, Printer::Printer()->PageHeight);
// Print the picture, on all the surface of the page and all opaque.
Printer::Printer()->Canvas->DrawBitmap(Image1->Bitmap, SrcRect, DestRect, 1);
// Finish the printing job
Printer::Printer()->EndDoc();
}
}
//---------------------------------------------------------------------------
void __fastcall TMainFMXForm::OpenBitmapMenuItemClick(TObject *Sender)
{
// open a bitmap for printing
if (OpenDialog1->Execute()) {
Image1->Bitmap->LoadFromFile(OpenDialog1->FileName);
PrintMenuItem->Enabled = true;
PrinterSetupMenuItem->Enabled = true;
PictureLoaded = true;
}
}
//---------------------------------------------------------------------------
void __fastcall TMainFMXForm::ExitMenuItemClick(TObject *Sender)
{
// exit the application
Application->Terminate();
}
//---------------------------------------------------------------------------
void __fastcall TMainFMXForm::PrinterSetupMenuItemClick(TObject *Sender)
{
// use the Printer Setup dialog box
PrinterSetupDialog1->Execute();
}
//---------------------------------------------------------------------------
void __fastcall TMainFMXForm::FormShow(TObject *Sender)
{
// on form show event handler
PictureLoaded = false;
PrintToPrinterDestinationMenuItem->IsChecked = true;
PrintToFileDestinationMenuItem->IsChecked = false;
// populate the ComboBox with the printer device names
PrintersComboBox->ItemIndex = 0;
for (int i = 0; i < Printer::Printer()->Count-1; i++) {
PrintersComboBox->Items->Add(Printer::Printer()->Printers[i]->Title);
// set the ComboBox ItemIndex to the active printer
if (Printer::Printer()->Printers[i]->Title == Printer::Printer()->ActivePrinter->Title) {
PrintersComboBox->ItemIndex = i;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TMainFMXForm::PrintToPrinterDestinationMenuItemClick(TObject *Sender)
{
// set menu item checked for print to printer
PrintToPrinterDestinationMenuItem->IsChecked = true;
PrintToFileDestinationMenuItem->IsChecked = false;
// set PrintDialog PrintToFile checkbox off
// Note: to allow user to override the menu item - make sure
// PrintDialog Options poPrintToFile is set to true
// so that the PrintToFile checkbox appears in the dialog
PrintDialog1->PrintToFile = false;
}
//---------------------------------------------------------------------------
void __fastcall TMainFMXForm::PrintToFileDestinationMenuItemClick(TObject *Sender)
{
// set menu item checked for print to file
PrintToPrinterDestinationMenuItem->IsChecked = false;
PrintToFileDestinationMenuItem->IsChecked = true;
// set PrintDialog PrintToFile checkbox on
// Note: to allow user to override the menu item - make sure
// PrintDialog Options poPrintToFile is set to true
// so that the PrintToFile checkbox appears in the dialog
PrintDialog1->PrintToFile = true;
}
//---------------------------------------------------------------------------
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.
From his CppCon 2020 talk description: This is an exploration of a design space close to the hardware and of the use of C++ in that space, rather than a standards proposal or the presentation of a mature tool chain. And, no, by “primitive”, I don’t mean “old-fashioned, C-like” code; some of the general techniques are old, but some of the code requires C++17 and much could be done better given features we are unlikely to get even in C++23.
Links to other replays of Bjarne’s talks at past CppCon (the C++ conference) events
You will find ISO C++ articles, news, books, podcasts, training courses, events, videos, product news, standardization activities, etc. on the Standard C++ Foundation site.
Here are a few technology news stories that I’ve read in the past week or so.
Reading Code Is a Skill
The problem is not that we shouldn’t write readable code. Of course we should aim to write readable code, if only for our own poor selves further down the line (there is no one less capable of reading my code the following week than me). The problem is that these two issues are not mutually exclusive. It’s not “write readable code” or “learn to read code”. Read the DZone article by Trisha Gee.
When a digital twin becomes the evil twin
A digital twin is a digital replica of some physical entity, such as a person, a device, manufacturing equipment, or even planes and cars. The idea is to provide a real-time simulation of a physical asset or human to determine when problems are likely to occur and to proactively fix them before they actually arise. Read the InfoWorld article by David Linthicum.
The NVIDIA-Arm merger could change how we work
If the merger between Arm and NVIDIA is approved (I expect Great Britain, the EU, and China will have reservations), the result could be a massive change in AI capability. And, given that Arm is dominant in mobile devices and IoT, and NVIDIA is dominant in both graphics and AI training, it’s a merger that could have a dramatic impact on how we work as well. Read the ComputerWorld article by Rob Enderle.
Don’t write off government algorithms: Responsible AI can produce real benefits
There are many cases in which government bodies can deploy AI technology in lower risk, high-impact scenarios that can improve lives, particularly if they don’t directly use personal data. So before we leap full pelt into AI cynicism we should consider benefits as well as risks it offers, and demand a more responsible approach to AI development and deployment. Read the TechXplore article by Allison Gardner.
Postman’s New Schema Validation Feature Helps Encourage API Spec Literacy
Postman, an API development platform provider, has announced that its API Builder is gaining the ability to validate API schemas in real-time via a new UI pane that is accessible in the tool’s define tab. The addition of this functionality helps to provide developers with real-time feedback and encourage API specification literacy. Read the ProgrammableWeb article by Kevin Sundstrom.
Microsoft open-sources fuzzing test framework
Microsoft is looking to help developers continuously fuzz-test code prior to release, via the open source OneFuzz framework. Described as a self-hosted fuzzing-as-a-service platform, OneFuzz enables developer-driven fuzzing to identify software vulnerabilites during the development process. Read the InfoWorld article by Paul Krill. Access the OneFuzz framework on GitHub.
IoT Platform – Binding the IoT Ecosystem Together
The word IoT has meant many different things to different people, none of it is wrong in any sense. It has been just a matter of perspective. Device and sensor manufacturers think of it as the sensors at the center of the IoT ecosystem with some connectivity and software around the sensors to capture and transmit data. Network services providers think of IoT as a secure network that connects a bunch of commodity sensors to a backend data store. BI and Big Data platform providers think of their role in IoT as the most important; after all if you cannot process a large amount of data coming through and extract intelligence from it, what’s the point in putting all these sensors and networks in place. Read this DZone article by Seemant Ahuja
Tourists on Tech’s Toll Roads
The recent trend is toward systems that are increasingly more closed. Unfortunately it’s only the latest in an ongoing cycle throughout the history of computing between open highways and private roads. Each swing in the pendulum moves from public, open, shared innovation that lays the open roads to private companies who use those public roads to build their for-profit toll roads. Those companies fight to ensure that no matter what signs you follow, you end up on their private road. Read the blog post by Kyle Rankin.
4 Python type checkers to keep your code clean
Over the last few years, though, Python has added support for type annotations, inspiring a whole culture of software devoted to type checking Python during development. Python doesn’t check types at runtime — at least, not yet. But by taking advantage of a good type checker, riding shotgun with you in your IDE of choice, you can use Python’s type annotations to screen out many common mistakes before they hit production. Read the InfoWorld article by Serdar Yegulalp.
Interview with Homage’s Gillian Tee on how technology can serve the world’s aging population
For the second time this year I’m refactoring a program from a single purpose to have two or more modes of operation. Both times the start and end result is similar, just the processing is different. A classic case of using polymorphism. The first program was a tool to process videos from speakers, find a face and export the subframe around it into a new video. The first mode was a good approach to test it, and gave results for some speakers. The second mode did a complete scan first, and then gave a smoother video for some videos. Read the Meeting C++ blog post by Jens Weller.
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 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.
There’s lots of ISO C++ news and content happening including the unanimous voting approval of ISO C++20, CppCon2020 (starts Monday September 13, 2020) with Bjarne Stroustrup’s opening keynote “The Power and Beauty of Primitive C++”, TIOBE’s Index for September 2020 headline “Programming Language C++ is doing very well”, C++ programming tips and tricks articles and more.
Links to recent ISO C++ news and articles
CppCon 2020 Opening Keynote – The Beauty and Power of “Primitive” C++ – this keynote is an exploration of a design space close to the hardware and of the use of C++ in that space, rather than a standards proposal or the presentation of a mature tool chain. And, no, by “primitive”, I don’t mean “old-fashioned, C-like” code; some of the general techniques are old, but some of the code requires C++17 and much could be done better given features we are unlikely to get even in C++23. Monday, September 14, 2020 8:45 to 10:00 MDT(Mountain Daylight Time).
TIOBE Index for September 2020 – Headline: “Programming Language C++ is doing very well” – Compared to last year, C++ is now the fastest growing language of the pack (+1.48%). I think that the new C++20 standard might be one of the main causes for this. Especially because of the new modules feature that is going to replace the dreadful include mechanism. C++ beats other languages with a positive trend such as R (+1.33%) and C# (+1.18%).
C++20 approved, C++23 meetings and schedule update by Herb Sutter – On Friday September 4, C++20’s DIS (Draft International Standard) ballot ended, and it passed unanimously. This means that C++20 has now received final technical approval and is done with ISO balloting, and we expect it to be formally published toward the end of 2020 after we finish a final round of ISO editorial work.
Concept archetypes by Andrzej Krzemieński – Concepts in the form added in C++20 used to be called lite. This is because they do not provide one quite important functionality: having the compiler check if the author of a constrained template is only using operations and types allowed by the constraining concept. In other words, we can say that our template only requires operations A and B to be valid, but we can still use some other operations inside and this is fine with the compiler. In this post we will show how this is problematic, even for programmers aware of the issue, and how to address it with concept archetypes.
6 Efficient Things You Can Do to Refactor a C++ Project by Bartlomiej Filipe (Bartek) – Bartek took his old pet project from 2006, experimented, refactored it and made it more “modern C++”. This article contains lessons learned and six practical steps that you can apply in your projects.
volatile and Other Small Improvements in C++20 by Rainer Grimm – This article completes Rainer’s tour through the C++20 core language features with a few small improvements. One interesting of these minor improvements is that most of volatile has been deprecated.
The implication of const or reference member variables in C++ by Lesley Lai – In the conventional wisdom of the C++ community, non-static const or reference data variables are considered problematic. There are solid reasons on why you should avoid const or reference member variables in C++. Nevertheless, like many things in C++, “avoid” does not mean “never use.” And they can occasionally still find some uses.
Using Vim for C++ Development by Adem Budak – Adem shares how he uses Vim as C++ development environment, adding things like code completion, linting, formatting and snippet support. If you come from the IDE land and have been set your options with the checkbox on a GUI, you might need a mental shift to use text based configuration tools, like Vim.
LLVM 10 bolsters Wasm, C/C++, and TensorFlow by Serdar Yegulalp – LLVM 10, an upgrade of the open source compiler framework behind a number of language runtimes and toolchains, is available today after a number of delays. The biggest addition to LLVM 10 is support for MLIR, a sublanguage that compiles to LLVM’s internal language and is used by projects like TensorFlow to efficiently represent how data and instructions are handled. Accelerating TensorFlow with LLVM directly is clumsy; MLIR provides more useful programming metaphors for such projects.
Two VCL Example Applications that Use C++Builder and the C++ Boost Libraries by David I – Boost is a set of open source C++ libraries that build on the ISO C++ programming language. In some cases, the Boost library functionality has become part of recent ISO C++ standards. RAD Studio allows you to install a subset of Boost that has been fully tested and preconfigured specifically for C++Builder. Use the GetIt Package Manager to install the Boost libraries for the Win32 classic C++ compiler, Win32 Clang-enhanced C++ compiler and Win64 Clang-enhanced compiler.