Quantcast
Channel: Latest blog entries - Embarcadero Community
Viewing all 1683 articles
Browse latest View live

IBLiteをWindowsで使用する

$
0
0

IBLiteとは

IBLiteはInterBaseデータベースのローカルバージョンです。

セッション数やデータベースサイズといった機能に一部制限がありますが、無料で使用することができ、InterBase Server Editionと完全な互換性があります。違いはDocWikiを参照してください。

特別なインストールは不要で、DLLとライセンスファイルを配置するだけで、アプリケーションに組み込むことができます。

IBLiteの初期設定

Windows上でIBLiteを使用したアプリを作成するには、以下の設定をします。

  1. Visual Studio 2013 の Visual C++ 再頒布可能パッケージをインストールします。
  2. RAD StudioのGetIt パッケージマネージャーから、"InterBase 2017"を検索し、IBLiteをインストールします。

    インストールされたファイルは$(IBREDISTDIR)\InterBase2017に配置されます。


  3. $(IBREDISTDIR)\InterBase2017\win32_togo(64bitはwin64_togo)フォルダを任意のフォルダ(本記事ではC:\toolsとします)にコピーして、そのフォルダ(C:\tools\win32_togo)を環境変数PATHに追加します。
  4. PCを再起動します。
  5. RAD Studioの[ツール|環境オプション|環境変数|ユーザー定義環境変数]のPATHから"$(PUBLIC)\Documents\Embarcadero\InterBase\redist\InterBase2017\IDE_spoof"を削除します。
  6. "$(IBREDISTDIR)\InterBase2017"フォルダにある、IBLiteのライセンスファイル"reg_iblite.txt" を IBLiteのライセンスフォルダ(C:\tools\win32_togo\InterBasel\icense)にコピーします。

IBLiteをFireDACから使用する

データモジュールかフォームにTFDConnectionを配置し、接続情報を以下のように設定します。

項目
ドライバID IBLite
Database InterBaseのファイル名
User_Name sysdba
Password masterkey

IBLiteのDLLが読み込めているかは、FireDAC接続エディタの[情報]タブで確認出来ます。

 

あとは、通常のデータベース開発と同じです。

もし、InterBase 2017のDeveloperエディションがインストールされている場合、IBLiteと「混在」すると動作しなくなることがあります。モバイル向けなどでIBLiteを使う場合は、仮想マシンなどにIB2017をインストールしていない環境と分離することをおすすめします。
IBliteはDelphi Community EditionC++Builder Community Editionでも使用できます。iOS/Androidもサポートしていますので、是非ともお試し下さい。


Read More

RAD Server: Beyond the Basics Webinar Tomorrow

$
0
0

Over the last few months and the 10.2.x updates, RAD Server has been extended with several new features. But the technology also has several other advanced features we rarely discuss, because the typical one hour webinars we do are often only enough to cover the basic introduction. In this webinar, I'm going to skip the intro, rapidly walk you over a first demo, and move from it to more advanced topics.

You can sign up here. The date is Wednesday, Jul 25, 2018 and the webinar is scheduled at 5 PM Central Europe time, 11 AM US Easterna time, and 8 AM California time. The sign up page has a handy time zone tool you can use to convert it to your local time.

To get to more details, I plan covering:

- the various approaches added over the last year to generate JSON data

- the support for hosted files (and HTML + JavaScript hosting), with the ability to use it as a back end of JavaScript applications

- performance and scalability of the architecture (including also the recent performance patch)

- the ability to have dynamic resource management with "edges" resources

- the various tools to manage the system and its configuration

- custom login modules

Finally, I'll touch upon coming features on the RAD Server roadmap.


Read More

Learn to program C++ with C++Builder Community Edition: #1, Introduction and Installation

$
0
0

Welcome to the first entry in the ‘Learn program C++ with C++Builder’ series - a set of five articles taking you from knowing nothing about C++ to writing a real-world, useful application.

I’m David Millington, the C++Builder Product Manager, and in parallel we have the same series and same app in Delphi. We have posts taking you step by step through programming in the two respective languages, with Delphi and C++Builder. We’ll be taking you through from the very beginning, assuming you know no Delphi or C++ at all, and show you how to build a real-world, useful application - we’re currently thinking a scientific calculator, because it demonstrates UI, UI and logic separation, and many useful classes like stacks and utility methods, ie is a great overview of many areas you need to know about.

One really neat thing is that you can use both languages together in one natively compiled application, something we won’t show in this series but is one of the amazing integrations our tooling offers.

Today’s post is an introduction and will show you how to install C++Builder Community Edition - this is a free and fully-featured edition - and then next week we’ll dive into code. We are assuming that you know some programming basics: we’re not going to explain what a class is, for example, but instead will show how to write and use one in C++.

If you are

  • hobbyist who’s done some programming but never used C++ (or Delphi) before,
  • student,
  • or a professional who wants to learn something new,

this series is for you.

C++Builder is a particularly powerful C++ platform, because not only does it give you C++ (of course), but it includes a large variety of libraries and frameworks that other C++ tooling does not. This includes tools for writing cross-platform user interfaces, including using native controls; database access for several dozen databases in a very clean and powerful library; REST, JSON and other web frameworks; and more. The libraries and frameworks are fast to use - we find that users who know our tooling can achieve polished and complete applications in fractions of the time it takes using other IDEs, whether that be C++ or other languages like C#. The end result is you can build an application once, including designing its UI for multiple platforms, and deploy it - natively compiled - to Windows, iOS, Android, and macOS, fast.

So let’s get started! Today’s post is an introduction to the series, and shows you how to install C++Builder Community Edition. The following four posts will introduce you to the IDE and to C++ itself, and then go on to develop a real-world, cross-platform, useful application.

Installation

Let's install C++Builder Community. It's free - go download it now!

Important note: The 10.2 Tokyo Community Edition does not co-exist with any other edition (SKU) of 10.2 Tokyo. Ie, if you have Delphi 102 Pro, you cannot install 10.2 Community. On the other hand, if you have 10.1, ie another version, they co-exist fine. It's just that Community Tokyo doesn't co-install with AnythingElse Tokyo. If you have, say, Delphi 10.2 Tokyo Pro (or Community) already installed, install C++Builder Community on another PC or in a virtual machine. If you want both, you can always download the RAD Studio trial instead - it includes both C++Builder and Delphi.

When you visit that link, you will be asked to create an EDN account if you haven't already got one. EDN is the Embarcadero Developer Network. Go ahead and fill in the info, or if you already have an account, click the Login text in the middle right to just enter your email and password.

Once done, you'll get a download automatically starting, and a notice that you've been sent an email with your license key.


and if you check your email, you'll see something like this (with my key redacted in yellow.)

So, you have the download and a license key. Run the installer:


Agree to the license agreement:

(You can ignore the Options button; there's nothing there you need to change.)

Click Next, and on the next screen select that you already have a serial number (you do; this is the key that was in your email):

 

When you click Next, you might see a regular install progress window for a few seconds, but pretty soon you'll be asked for the serial key in a popup dialog. Enter it in the top section, and your login details from when you downloaded below.


...and click Register.

You'll get the install progress window for a while...


Right now, it's installing the IDE shell. (In fact, after this bit completes you'll even be able to run and use the IDE as a text editor. It just won't have Delphi or C++Builder living inside it - that comes in a moment.)

 

Pretty soon, you'll be greated with this really pretty window. This is where you select the "personalities" and platforms that live in the IDE. Since you've downloaded C++Builder Community, you can install Windows, macOS, iOS, and Android. I recommend at least Win32 and Win64. Select the ones you need, and click Continue.

On the next page, you can click through, but I'd recommend you select to install samples and help. The samples are useful demo programs we ship to demonstrate various features, libraries, etc. The help gives you a language reference, information about the various libraries and classes, the various parts of the IDE, etc.

If your version of Windows is set up to use another language, you should also choose to install that language (if available) so you see the IDE properly localized. For example, if you're a native German speaker, select the German language pack.

Then it will install. This should go by very quickly - the installer you're seeing is known as the GetIt Feature Installer, and it uses GetIt, our package manager.

You may see another dialog to install the Windows SDK. This is a Microsoft redistributable:

However, you don't need to install everything it suggests. If you want, you can install just the Windows Software Development Kit:

This might take a while. Sorry. It's not ours.

And then, oh happy day...


Success! 'Start working', now that's a good button to click.

And in a moment, you'll have the IDE!


Congratulations! You're installed, and ready for the next post digging into the IDE.

In this screenshot, you can see what the IDE looks like when you first start, allowing you to choose a light or dark theme (which you can choose at any time from the moon icon on the toolbar).  We also have the Welcome page in the background, which gives you fast access to recent projects or new projects, a few online samples from our package manager (GetIt, also look in the Tools menu), and news about events and recent Youtube videos.

What is Community Edition?

So what is Community Edition after all? Is it free? Can it be used commercially? Can I use it as a student? What about writing programs at home?

Community is a fully-features version of C++Builder.  It is equivalent to our Professional edition, including support for mobile platforms. You can visually design for Windows and cross-platform; debug applications including on-device; build apps with local or embedded databases; and use hundreds of components to enhance your app.

There are some key restrictions.  Consult the EULA for full information - this is not legal advice - but roughly, you can use it until you make $5000 revenue from programming, or until you have 5 developers.  Ie if you make enough money to buy it, please buy it; if you have lots of developers, buy it.  There are a few other ones, such as not using it for a build server.  Consult the EULA, but we hope these restrictions are fair.

Community is intended to get people started with Delphi or C++Builder, and be there for you if programming is not a serious part of your income, and that can be either getting started with programming in general - such as a student - or for starting something else, such as writing software for your startup company.  Individual developers, hobbyists, students and developers who are learning new programming languages, starting to develop cross-platform apps, or learning the IDE - it's for you.  Early stage startups without revenue yet - it's for you.  Spreading the word about Delphi and C++Builder - Community is great for that.

  • So if you’re a hobbyist or at-home developer, coding for fun? It’s free. Enjoy!
  • If you’re a student? It’s free. Enjoy!
  • If you’re a startup? It’s free, but once you start getting incoming revenue or growing, you need to move to Professional or above.
  • If you’re an existing company? You may find the revenue / commercial use options mean that Professional, Enterprise or Architect are a better option for you. Remember there is always the fully-featured trial version if you just want to try RAD Studio out. 

We’re very glad you’re using our products, and this series of blogs is a great resource to get you started.

See you next week!


Read More

Learn to program C++ with C++Builder Community Edition: #2, Building and Debugging

$
0
0

Welcome to the second blog post in the ‘Learning to program with C++Builder’ series - a set of five articles taking you from knowing nothing about C++ to writing a real-world, useful application. The first entry covered installing C++Builder Community. Now it’s time to start using it! Today, we’ll cover the tools you use, creating your first app, and basic debugging.

Understanding the IDE

C++Builder, the product, is what we call the IDE (Integrated Development Environment), which is the program you see when you start C++Builder. An IDE has three general areas or things that it helps you do:

  • A code editor
  • A compiler
  • A debugger

The code editor - and because C++Builder is great for UI programming, the form designer fits into this area too - is where you write code, a text editor with special enhancements for programming. When you have a form (that is, a window you are designing), one tab of the code editor lets you edit the form.

The compiler is what converts the code into a program that Windows can run.

The debugger lets you run the program and see what it’s doing. You can pause it, look at various parts of it, run through your code step by step, and so forth, all to understand what your code is doing and find the cause of any unexpected behaviour - that is, bugs.

All three of these are integrated together and accompanied by a number of dockable tool windows, other tools, etc. You don’t even need to think of these are separate things, more as just different actions you do: “now I’m writing code”, “now I’m running my program”.

Projects

Typically, you want to use more than one single source code file to create your application. A project is how the IDE groups together multiple source code files into one app, and includes other information, things like which platform you’re compiling for, or ‘targeting’, such as Windows or Mac, if when you compile you add in extra information for the debugger so it can see more about your app’s internals, etc.

When you create a new project the IDE creates several files for you. Let's have a look at these files.

The first thing to do is create a new project. Start C++Builder, go to the File menu, and choose New > “Multi-Device Application - C++”. This create a new FireMonkey project, one that can be used on Windows, iOS, Android, etc.  (You need to have these platforms installed if you want to build for them. Check this in the Tools menu, Manage Platforms.) In the dialog that appears, select “Blank application” and click OK.

You now have a project, and you’ll see this in the Project Manager, a window that by default is docked on the right hand side of the IDE.

Before going any further, click the Save All button. You will be prompted to save several files. Put them all in the same folder. You’ll notice they are files listed in the Project Manager.

So what are these files? Open up the folder where you saved everything and have a look. For me, many of these are labeled ‘Project2’ - for you, they might have a different number. Most likely, yours will be Project1.

  • Project*.cbproj (for me, Project2.cbproj.)  This file describes the project - what files are in it, what the settings are. It corresponds to the bold top-level node labeled ‘Project2’ in the Project Manager.
  • Project2.cpp: this is the first, main source code file for the application. Applications have an ‘entry point’, a place where they start. This file contains that.
  • Project2PCH1.h: ‘PCH’ stands for ‘precompiled header’. We’ll get to headers later, but basically this file is used as an optimisation for making your application compile faster.
  • Unit1.cpp, .fmx, and .h: C++ splits its code units into two files, the main implementation file, where your methods etc are actually written, and a header, which is where they’re declared. A header basically tells the compiler ‘this is what you should expect to see’; the implementation .cpp is where you actually implement it. These two are logically paired in the mind of any C++ programmer, but C++Builder formalises it by calling them a ‘unit’. (If you go File > New > Unit you will get a new .cpp/.h pair.) In fact, in the code editor, C++Builder opens them as a single entity too, and you switch between the .cpp and header using tabs at the bottom of the code editor.
    So what is the .fmx file? The new project created a new unit by default, but this unit is special: it is used for a form (a form is what becomes a window when you run the app.) A window has a UI design part too, and this UI is stored in the .fmx file. So for visual parts of your application, which are both code and UI, the unit has three parts: cpp, header, and form.

This app will become our calculator, and those default names are not very good. We could have saved the files with new names, but I wanted to explain what each one is first - project file, main file, precompiled header, form and unit. But let’s rename these.

In the project manager, right-click the bold Project2 node, and select Rename. Type in CppSuperCalculator. You’ll notice that the precompiled header and main file are renamed too - that’s because the IDE manages those and keeps them in sync. Then rename the unit - right-click it, Rename, and call it ‘uFormCalculator.cpp’. Notice that the unit has a + symbol next to it so you can see all three files that together form the unit - you can rename any one of these and the others will automatically rename to match.

Click Save All and check back in Explorer. The files will have been renamed.

You might see some other files - ‘*.local’, a ‘__history’ folder, etc - ignore these. The IDE uses them.

Building the project

Building is compiling - going from all the text source code to a final EXE file. You can build from either the Project menu, or by right-click the project and selecting Build. (Make is like a light build - it compiles only the bits that changed since last time. Clean wipes everything, all the intermediate saved files, so you start compiling from a clean slate next time.)

Do this, and you’ll see a window appear telling you it built successfully.

When you go back into Explorer, you’ll notice some new files and folders. There is now ‘CppSuperCalculator.res’ - this contains the program icon and version. There is also a Win32 folder, and inside that a Debug folder. These are where the temporary files are saved while building, and the final EXE is located. Win32 is the target platform (the only one available for Starter) and Debug is the build configuration - you can see this node in the Project Manager; there are two configurations by default, Debug and Release.  (Debug does less optimization and includes information helpful for the debugger to see what’s going on inside your program; Release does more optimization and less debug info. You use Debug while developing, and Release for the app you give your users.)

Going by file extensions, the .#01 (and other number) files and the .pch file are to do with precompiled headers - something that doesn’t matter now. The .obj files are object files, which are compiled versions of each source code file or unit. The .map and .tds files are used by the debugger, and the .exe file is your final program!

Running and debugging

Don’t run this EXE (although you can) - let’s make the IDE run it.

Back in the IDE, there are two toolbar buttons, one a large green arrow and one the same green arrow but smaller, over a program.

These are Run Without Debugging and Run (implied, this means Run With Debugging). They are in the Run menu too. Run Without Debugging just runs the program and doesn’t do any IDE / debugger magic; the most useful, and the one you’ll want to use every single time you run, is Run, which debugs as well. Go ahead and click it.

You will see the IDE change a couple of docked windows, and lots of messages appear in a window at the bottom. Then, you will see your application appear - a blank window, currently, but it’s your app!

Congratulations. Close the app by clicking its X button in its window, or in the IDE, click the red Program Reset button near the run buttons.

Debugging

Debugging is part of the art of programming, and is the process of figuring out why your app is not doing what you want it to be doing. When you’re doing that, the debugger is a very useful tool: it lets you examine the internal of your program to see what it’s actually doing, and step through code to see why it does particular things. You can change your program too: change the values of variables, call methods, right down to changing the values in processor registers if you really want to.

In order to demonstrate this, we’re going to add some more code to what is currently a very minimal project. Make sure the blank form is visible in the center of the IDE (if it isn’t, in the Project Manager double-click uFormCalculator, then in the center part, the code, editor, click the Design tab at the bottom. You will see the form designer appear: mostly white, with a grey blank form in the middle. This corresponds to the blank grey window when you ran the app.) In the bottom right part of the IDE, below the Project Manager, you will see the Tool Palette, and this contains lots of reusable components - visible controls, like buttons or checkboxes, and non-visual controls as well which perform other actions. (Make sure your app isn’t running; the IDE has different layouts when debugging vs coding.)

Expand the Standard item, and double-click TButton. A button will appear in the middle of our form. (Note you can drag and drop a control to the form too.)

Now, double-click on the button. This creates an event handler for when the button is clicked, that is, a method that is called when the button is clicked, and moves to the code editor. The method has been generated for you. Let’s add a line to show a message dialog - change it so it looks like this:

Note you need to get this exactly right. The L prefix to the string says it's a Unicode string (specifically, this is actually a string literal using wide characters, an array of wchar_t); the " marks have to be as they are on the keyboard, not Word-style quotes that change to point slightly towards the text they enclose; you need a semicolon at the end. If you make an error here, when you click run, you will get an error message in the Messages window at the bottom of the dialog.

Click Run, and your app will run. Now click the button, and you’ll see the message:

So far so good. Go back to the code editor, and notice that the ‘ShowMessage’ line has a blue dot next to it. That means the EXE contains code relating to that line.

Click the dot, and it will turn red and highlight the line. This is called a breakpoint, and means that whenever the application reaches that line of code, it will pause.

Click the button again, and this time instead of showing the message, the IDE will bring itself to the front. The red dot now has a blue arrow over it - that indicates the current line.

The program is now paused in the debugger. You can do several things - run it, so it continues; step line by line, so it executes the ShowMessage line but stops at the next, and so forth. Have a look at the other buttons on the toolbar next to the Run buttons, and also look in the View menu, Debug Windows, at all the things you can see.

That’s it for this post. We’ve created our first project, seen what a project contains, seen how the IDE manages some parts of it, run it, and debugged it. If you want to explore before next week, experiment with the debug windows, with the Step Over button on the toolbar near the Run buttons, with the breakpoint properties (if you right-click one), with the call stack window which shows the ‘stack’ of which method has called what to get you where you are now. Next week we’ll continue this app and start turning it into a real, useful calculator.


Read More

Learn to program C++ with C++Builder Community Edition: #3, Design, Architecture, and UIs

$
0
0

Welcome!  Last time we looked at the IDE, projects, a simple first application, and basic use of the debugger. Today we’re actually going to write code! 

We are going to write a scientific calculator.  It’s a useful, real-world app. You might put it on your phone and use it (and we’ll show how to do this in the last blog post of the series.)  Not only can you do normal math like addition and division, but some more advanced operations - trigonometry (sin, cos, tan), powers, and other useful functions.

Part of programming is good design. Programming is an art, and when you’re writing code, and you envisage your whole app, you feel very creative. It’s important to create well, though - to value quality. This isn’t just out of a philosophical drive to do something well if you’re going to do it at all; instead, it’s practical. Good code is code you can come back to later and keep working on after you’ve forgotten how it worked. To write code like that, it needs to be well designed, so you or anyone else can read it and figure out how it works. This makes debugging much easier, too.  Debugging is hard enough already - if your app is clear, though, you can figure out problems with it much more easily than if it’s messy.

But also important is not just to design it well, but as you make changes, to keep it designed well.

Let’s illustrate this. First we’ll create the UI, and then we’ll start coding it wrong.

Building the UI

A scientific calculator has a fairly simple UI. It has buttons for numbers 0-9, a decimal point, math operations like addition and subtraction, and equals. (We will add sin, cos, tan etc next week.) Finally, it has a display area which displays what you’re entering, or the result of the operation.

Let’s build this.

Opening the app you had last week, delete the button on the form, so it is a completely blank form. Make sure you’re in the Master view in the toolbar at the top of the form designer - we can specialize for another platform, like iOS, later. Now in the Tool Palette, find TButton (you can type in the Search field, or open the Standard section, TButton is about the eighth entry) and add enough for all the buttons you need to the form. You can drag-and-drop, or double-click to just add in the center and drag them around later.

Important considerations for design:

Give your buttons good names. What is “Button14”? Who knows. But “btnEquals” is very clear. You can change this in the Object Inspector, Properties tab, Name.

While you’re at it, change your buttons’ Text property to reflect their function - eg, change them to ‘0’ or ‘=’.

Hint

Note you can multi-select items by dragging a selection, or holding Shift while clicking. You can then edit the properties of multiple controls at once. I want my buttons to be square, so I’ve done that to change the Width and Height properties for all of them at once.

Next, add an edit box for the calculator to show its input and result. Use TEdit, and set its ReadOnly property to true - we don’t want users typing in it.

This is what mine looked like:

...partway through designing (after double-clicking on TButton a lot)

..and after moving the buttons, renaming, and setting caption Text.

UI design: done, for the moment. It's simple and we're going to improve it in a later post. Now, onto code! Bad code.

Homework question

We built a completely normal scientific calculator interface. We’ve all seen them before - we implemented the standard physical desktop calculator, with a grid of buttons and a small text area at the top.

But is implementing the norm the best approach? Yes, because we know how to use it already, but what if there’s a better way? If you were to reinvent the calculator, what would it look like? Pretend you’re Steve Jobs in 2001 - maybe the calculator could be more obvious and more intuitive? I have some ideas about this myself and would be interested to read more in the comments.

Starting coding - the wrong way

This is where it all goes wrong, and you can immediately tell the difference between a newbie and someone who has some coding experience. The aim of this article is to jump you right past being a newbie into best practices immediately.

We’re really enthusiastic. We want to get some numbers up on screen. So, let’s start making buttons do stuff.  Double-click btnZero (this auto-creates its OnClick event; you can create other events in the Events tab of the Object Inspector) and write some code:

 

.
void __fastcall TForm1::btnZeroClick(TObject *Sender)
{
	edtResult->Text = L"0";
}

And repeat this for the other buttons. (What is the L prefix for the string? This was briefly covered in part 2; it indicates the string is a Unicode string - specifically, this is actually a string literal using wide characters, an array of wchar_t. There are lots of string types. This one is compatible with the Windows Unicode size and the VCL's String.)

Ok, now we can make the display have a number. But how do you enter a two-digit number? Hmm, maybe take what’s already there, assume it’s a number, and add in another digit:

 

.
void __fastcall TForm1::btnOneClick(TObject *Sender)
{
	edtResult->Text = IntToStr(StrToInt(edtResult->Text) * 10 + 1);
}

This is already convoluted - a bad sign.  It takes the text, makes it an integer, multiples it by ten (so 2 becomes 20) then adds 1 (so 2 -> 20 -> 21), then converts it back to a string and sets the text.

If you try that, it will crash if 1 is the first button you press, because the edit has no text and so can’t be converted to an int. So let’s fix that:

 

.
void __fastcall TForm1::btnOneClick(TObject *Sender)
{
	if (edtResult->Text.IsEmpty()) {
		edtResult->Text = L"1";
	} else {
		edtResult->Text = IntToStr(StrToInt(edtResult->Text) * 10 + 1);
	}
}

...but this needs to work for all buttons, so copy/paste to event handlers for all the others.

But wait, this needs to keep some kind of track of the operation, so it knows if this is the first or second number in, say, a “+” operation. So maybe store the text as a std::wstring field in the form…

Hold on, all ten number events have to be updated...

No. No no no. This is getting out of control: code is convoluted, confused, hacked together, mixing data types (why is a string holding a number?), and is duplicated.

What happened?

It all started so obviously: press a number, that number displays. Then it grew. Then we had to add some logic, and that did odd things with strings and integers, for what is really a number (so why is it ever a string?) Then the code got copied ten times, even though it varies only a tiny little bit between all ten. Then we realised we needed to keep track of state, so we started adding various state fields in the form as variables. What happens when we need to implement Plus or Minus? How will we do that?

It got really messy, really fast, even though it started off perfectly logically.

The problem here is one of clean design.  The form is the user interface - just that, the interface or graphics. Nothing else. We started trying to put calculator logic inside the form, mixing the UI and the calculations and state. That’s what led to a fundamental error like reading a number from a text field (the edit box) and to getting convoluted logic.

We started from the premise, “We have a UI; let’s make it do stuff”. That was the wrong premise, but it’s a really easy one to fall into when you have software that makes building a UI easy. The right premise is, “We have a UI, let’s connect it to something else that does stuff”.

There is a really important principle in app development, which is

Separate your user interface and logic

There are many ways to do this, most with acronyms (Presentation modelMVCMVVMYMMV (wait a second…), etc.)

Separating your user interface and logic means having several layers. Here we only need two: the user interface, and a calculator.

This all boils down to something else:

One class should have one purpose.

Here, the UI form (which is a class) should just be the UI: respond to button presses, display pretty stuff onscreen. That’s it. You want calculations? Have something that knows how to calculate - but doesn’t directly interact with the UI. That also means that the calculator doesn’t know about a TForm, per se - it just knows about some abstract presentation layer.

The nice thing here is that not only does this keep your code clean, but it means you can change any layer. Suppose you don’t want this to be a FireMonkey application, but you want it to be a command-line application (Linux support is coming in the next release!) If all your logic was in your UI, you’d be stuck with a huge rewriting job. As it is, if you have separate UI and logic layers with a clean interface between them, you can replace the form with a command-line interface that works exactly the same way. The moment your app is in a state where you can do something like that - even if you don’t need to right now - you know it’s well designed.

Starting coding - the right way

So, we need two layers: UI and calculator.

Clear out all the UI event code so we start clean. Then let’s think about how we want the two layers, UI and calculator, to talk to each other.

We actually don’t want the calculator to know it’s talking to a form - just a presentation or UI object of some kind. Similarly, the form can know it’s talking to “a” calculator but doesn’t need to know it’s this specific class or implementation. (We could replace the calculator layer as easily as we can replace the UI layer.)

The answer to this is to program to interfaces.

C++ doesn’t have interfaces as a language feature. Delphi does, and through our C++ compiler extensions you can use real genuine interfaces from C++, but we’ll stick to fairly pure C++ code in this series. C++ instead makes you use a class with pure virtual methods - that is, virtual methods that do not have an implementation. We’re defining a base class, but it is treated like an interface.

This is an excellent time to jump into some C++ syntax…

C++ class declarations

In C++, a class is declared with the “class” keyword, a name, and optional inheritance. Members go inside the braces. Methods have the type first, name second, as do variable.  Here’s an example:

 

.
class Foo : public Bar {
private:
	int m_Number;
public:
	virtual void DoSomething(int a, float b);
};

This declares a class called Foo, which inherits from Bar. (You’re probably familiar with visibility specifiers in a class declaration in other languages; C++ allows those for inheritance too. It’s an advanced feature, use public by default.)

Then it has a private int member variable, and a public method which returns nothing (void, it’s a procedure not a function) and has two parameters, the first an int and the second a float. It is a virtual method, meaning it can be polymorphically overridden in a descendant class.  Note the colons after “private” and “public”, and the semicolon after the class declaration (if you miss that, it actually expects a variable. Just keep the semicolon.)

Defining interfaces

Back to our interfaces. We want two: one that represents the UI or display layer, and one that represents the calculator itself. We’ll expand these as we add more features.

Create a new unit by right-clicking the project and selecting Add New > Unit - C++ Builder. Rename it “uInterfaces” and save.  The following we’re going to put in the header half of the unit. We could also just add a header file through File > New > Other.

The display

A calculator only displays one thing: a few characters of text. (Let’s keep it text, not a number, to let the calculator control how the number is shown. A UI prints text, it does not print a number.)

Add this to the top of the .h, inside the #ifndef, #define section, so the whole file looks like this:

 

.
#ifndef uInterfacesH
#define uInterfacesH

#include <string>

class ICalculatorDisplay {
public:
	virtual void UpdateUI(const std::wstring& strText) = 0;
};

#endif

See that “=0” at the end of the virtual method declaration? That says it has no implementation, or is “pure”. This is how it’s an interface; ICalculatorDisplay declares methods but leaves it to a descendant to implement them; through the magic of polymorphism you can refer to an ICalculatorDisplay and the behaviour is actually that of whichever derived class, or class implementing the interface, you actually have. (C++ has multiple inheritance, so implementing an interface is just inheriting from that pure virtual class and implementing the methods, as well as possibly inheriting from concrete classes as normal.) Read more about declaring an interface here including some quirks to do with destructors not in the simple example above.

Some more C++ syntax. “std::wstring” is the variable type. Here, “std” (pronounced exactly as it’s written, no vowels like “stad” or “stod” - it’s “std” or “st’d”) is the standard namespace. C++ defines a lot of useful things in this namespace usually referred to as the STL, or standard template library, except it contains a lot more than templates. The :: accesses something inside the namespace; :: is used for all scope identification like classes, too, so MyClass::MyMethod refers to the method itself. std::wstring is a wide string, which uses a character size compatible with Windows Unicode and FMX’s String type.

The #include statement includes the string header, which is part of the STL and is where std::wstring is defined. C++ has a very basic mechanism for units and for referring to other files. A logical unit is split up into code and a header, as mentioned in part 2. Instead of “using” or “referencing” another unit, it includes the header, and that means literally includes - to the compiler, the entire contents of the “string” header will be inserted at that location. All it does it let it know the classes and methods defined in the header should exist; it won’t actually check they exist, though, until it tries to use them, which means a header can contain lots of methods (say) that don’t exist but you won’t get an error until you link. This is also where the #ifndef part comes in - it means if a header is included twice, it will only actually be included the first time, because the second time around the macro is defined and so the preprocessor will skip the contents of the ifdef block.  You’re quite right, this is crazily basic for a language in 2016. A long-awaited feature, modules, may make it better in C++19.

Includes should be at the top of the file, whether it’s a .h or .cpp file. (You can include something anywhere, but this is good practice.)

The ampersand means it is a reference. A reference means you are accessing the object itself - the parameter here is not a string object but points to a string object somewhere else. Unlike a pointer, references are guaranteed to exist - they cannot be null - and you use them with syntax exactly like a normal non-pointer stack-allocated object, not like a pointer.

Const means the reference cannot be modified; you can only call const methods (methods that don’t mutate, or change, the object state) and you cannot set strText to be something else.

The calculator

After the ICalculatorDisplay declaration, still inside the #ifdef, add the following:

 

.
enum class eOperator {
	eEquals,
	eAdd,
	eSubtract,
	eMultiply,
	eDivide
};

class ICalculator {
public:
	virtual void AddDigit(const int Digit) = 0;
	virtual void AddDecimalSeparator() = 0;
	virtual void SetOperator(const eOperator Op) = 0;
};

The methods in ICalculator are self-explanatory. AddDigit is for when 0-9 is pressed; AddDecimalSeparator is for when you press “.” to start entering fractional numbers, and SetOperator is to define whether it should be using plus, minus, and so forth. We will expand this interface in the future - this is a rough draft.

You can see the skeleton of a better design appearing. The calculator has no knowledge of buttons or edit boxes and it’s going to look after all its own state. The form has no knowledge of the calculator’s internals, because it will refer just to this interface - the class implementing the interface could do anything and it won’t know or care.

We have some new syntax here, defining an enumeration.  Old C++ used the “enum” keyword; in C++11 you can use enum class; the difference is basically better type safety, so enum will behave as you might expect it to behave if you’ve used other languages. This requires C++11, so at this point make sure you’ve gone into the project options, C++ Compiler, and turned off “Use classic Borland compiler” to make sure you use the new, modern, Clang-based compiler.

Finally, let’s actually implement these interfaces.

Implementing the interfaces

In the form

In the form header, change the form’s class declaration to look like this, multiply inheriting from both TForm and from the interface:

 

.
class TForm1 : public TForm, ICalculatorDisplay

Then we want to implement the interface. In the public: section of the form, copy the interface method, but remove the =0 because we want it to exist in the form:

 

.
public:		// User declarations
	__fastcall TForm1(TComponent* Owner);
	virtual void UpdateUI(const std::wstring& strText);

And implement it in the form. You’ve already seen implemented methods in the form of event handlers (which are just methods), so go ahead and implement an empty method in the form’s .cpp file like so:

 

.
void TForm1::UpdateUI(const std::wstring& strText) {
	//
}

You don’t need (and in fact can’t have) the virtual keyword on the implementation, only the declaration.

Creating the calculator

Add a new unit, and rename it to uCalculator. In the header, include the interface header file, define a class inheriting from ICalculator, and containing its methods as virtual but not pure any more - exactly as in the form. It should look like this:

 

.
#include "uInterfaces.h"

class TCalculator : public ICalculator {
public:
	TCalculator();
	virtual ~TCalculator();
public: // ICalculator
	virtual void AddDigit(const int Digit);
	virtual void AddDecimalSeparator();
	virtual void SetOperator(const eOperator Op);
};

I’ve added a constructor and destructor, too. These have the same name as the class, except the destructor is prefixed with ~. Note that this means a C++ class can have multiple constructors with different parameters, but because the constructor is indicated by it having the same name as the class, it cannot have multiple named constructors (CreateEmpty, CreateWithFoo, etc.)

I also separated and commented the methods that come from the interface vs those introduced in the class itself. This is personal preference.

On to the .cpp file, and copy the methods and implement. Note the method is declared with ClassName::MethodName syntax, following :: described earlier.  For the time being, leave the methods empty.

 

.
#include "uCalculator.h"


TCalculator::TCalculator() {

}

TCalculator::~TCalculator() {

}

void TCalculator::AddDigit(const int Digit) {

}

void TCalculator::AddDecimalSeparator() {

}

void TCalculator::SetOperator(const eOperator Op) {

}

What did we cover today?

Our calculator now has a UI and a calculator class. They're not aware of each other yet, but will be in the next lesson, where we'll hook the two together and implement the calculator class to start doing math. (Why not in this lesson? Because it moves on to many other things, such as smart pointers. Cool stuff - next week!)

This week we covered:

  • Editing properties in the UI designers
  • Code design considerations:
    • Separation of UI and logic
    • Separation of responsibility
  • C++ syntax:
    • Classes
    • Methods
    • Variables
    • Interfaces
  • C++ standard library:
    • What it is
    • One small part of it, std::wstring
  • Implementing classes
  • Multiple inheritance (briefly)
  • Plus links to other interesting topics

See you next week!


Read More

Learn to program C++ with C++Builder Community Edition: #4, Real code and Useful C++: Ownership, smart pointers, styles, and optional values

$
0
0

Welcome! Last time we looked at the architecture of a simple calculator app, showing how to design an application well by separating the UI and logic, abstracting through interfaces, and ensuring each class had a single responsibility.  That's important stuff, stuff that many developers skip, and is really important. Now we've done that, though, we can dig into the actual code. Today's blog post is almost entirely code, and will introduce you to several very interesting C++ concepts and techniques.

Important note: We’re going to use Boost, the most common C++ library.  It’s available through GetIt and is large and it takes some time to install, so I’d suggest installing it while reading through this blog post.  Open the IDE, go to the Tools menu, GetIt Package Manager, type ‘boost’ into the Search field, and when it appears, install it. For the Clang-enhanced compilers, we ship Boost 1.55, and the same installer will install an earlier version (1.39) for the old, ‘classic’ compiler. You will need to restart the IDE afterwards.

Part I: Connecting the UI and calculator, and object ownership

The code as it stands has a form, an interface representing a UI that can display results which the form implements, an interface representing a calculator, and a skeleton calculator class implementing that interface.

There are a couple of changes to the interface from last week: Equals is not an operator, but an operation, so remove it from the enumeration of operations and add a method to the ICalculator interface: void Equals(); It doesn't need to return anything because it's just for the UI to tell the calculator that Equals was pressed: results are displayed through the ICalculatorDisplay interface.

The form and the calculator need to know about each other. However, also important is the concept of ownership - which object controls the lifetime of the other?  Here, the form is going to own the calculator, so the calculator will be created when the form is and be destroyed when the form is.

Ownership is important for several reasons:

  • Preventing memory leaks. You want an object to exist for only as long as it needs to exist. You don’t want it to be created and forgotten about (a leak) and you don’t want it to be created and kept around longer than required (wasted resources).
  • Clear program logic. Suppose the calculator object wants to ask the UI to print something, but it’s not sure if the UI exists or not. It will have to check if it has (say) a null pointer instead of a valid pointer before trying to access the UI. That doesn’t make sense; better for it to be guaranteed that the UI exists. If the form owns the calculator, the calculator knows that if it is alive, the UI is alive.
    Similarly, since the form needs the calculator object for its lifetime (if the form exists, someone might press buttons and do calculations) so it too knows that it can always access its calculator object without checks. A guarantee like that isn’t required - often it’s very valid for something to maybe not exist, and in fact we’ll examine several cases like that very shortly. However, strict and clear ownership makes the rules of what exists when clear, avoiding crashes or other bugs.

Let’s first look at the calculator. It is owned by the form, and if it exists, the form is guaranteed to exist, so we can give it a reference to the UI (the form, through an interface.)

Remember, a reference is like a pointer that is guaranteed to exist, and the syntax is like a normal object (eg foo.bar()) not like a pointer (which would be foo->bar()).

To avoid leaking details about the concrete implementation, rather than the interface, we’ll create it through a factory method, so add one to the uInterfaces.h and .cpp file.

In the header:

 

.
ICalculator* CreateCalculator(ICalculatorDisplay& Display);

and in the implementation:

 

.
#include "uInterfaces.h"
#include "uCalculator.h"

ICalculator* CreateCalculator(ICalculatorDisplay& Display) {
	return new TCalculator(Display);
}

It accepts a reference to the UI, and creates a calculator returning a pointer (it is created on the heap; the Type-asterisk syntax indicates the type it returns is a pointer to Type.)  Note that this hides the existence of the calculator class completely - the form never has to #include it.  That’s good design; things are abstracted behind interfaces and unaware of the actual implementations.  In the calculator class, add this constructor and store the member reference:

In the header:

 

.
class TCalculator : public ICalculator {
private:
	ICalculatorDisplay& m_Display;
public:
	TCalculator(ICalculatorDisplay& Display);
	...

and in the implementation:

 

.
TCalculator::TCalculator(ICalculatorDisplay& Display) :
	m_Display(Display)
{
}

 

Smart pointers

More interesting is the owning object and how it owns the calculator.

C++ allows raw pointers, and old C++ code often uses them liberally. They lead to problems:

  • You have a pointer. What has to delete it (free it) and when? How many other objects have a copy of this pointer, ie are relying on it not being freed/deleted? This is ownership and lifetime
  • You have a pointer. Is it valid? What if it was deleted, but never set to null - you have an invalid pointer where accessing it will crash. How do you know? This is validity

Smart pointers are an answer to these two problems. (Other languages solve it with automatic reference counting (ARC) or a garbage collector (GC); both these effectively rely on a reference count or discovering the number of active uses of an object. C++ allows you to refcount if you wish, but also to use other patterns.)

Smart pointers are classes which manage the lifetime of pointers. They own a pointer, and they delete it. Because you know how they behave, you can use them to own a pointer and have guarantees about its lifetime and validity. Normally, they take ownership when they are created, and delete the pointer (or decrement a refcount, etc) when they are destructed.  This is particularly useful for using them as members of a class - when the class destructs, the pointers it owns are automatically deleted (or refcount decremented) too - or stack-allocated in methods, because when the smart pointer goes out of scope it is destructed, it will automatically delete (or decrement a refcount) the pointer it owns.  There are two types in C++11:

  • shared_ptr. This keeps a count of how many places are accessing the pointer, and the pointer is only deleted once the last reference disappears and the reference count drops to zero. Use this when many objects need to refer to a pointer and the pointer’s lifetime can end when the last shared_ptr referring to it is destroyed.
  • unique_ptr. Only one owner of a pointer is allowed. When the unique_ptr is destructed, the pointer it owns is deleted.

What does this mean? It means you never use the delete (freeing) keyword in your code, and you never manually manage pointer lifetime.

Destruction vs deletion

What is the difference between destruction and deletion?

Deletion is when a pointer is deleted or freed.  That is, in the code:

 

.
Foo* foo = new Foo();
delete foo;

An object of class Foo is created on the heap, calling its constructor; a pointer is returned; that pointer is deleted, and that destroys the object calling its destructor.  That is, deletion is one mechanism to destruct and object.

What’s the other? Stack-allocated objects are destructed when they go out of scope. Consider this code snippet:

 

.
{
	Foo A; // A is created on the stack
	{
		Foo B; // B is created on the stack
		// code here. This might cause an exception, but that’s ok
		B.Hello(); // let’s use B
		// code here...
	} // B is destroyed at its scope end
} // A is destroyed at its scope end

A stack-allocated object has its storage space allocated at the point it is constructed, and it is destructed when it “goes out of scope”, that is, execution leaves the scope - the block { } - where it was created. It is not ‘deleted’, because it was not ‘new’-ed (allocated on the heap), but its destructor runs.

When an exception occurs, all stack-allocated objects are destructed as the exception is propagated upwards to its handler.  That means, provided that an scope-lifetime object does not throw an exception of its own when it is destructed, that you have a guarantee the destructor will always be called - either when execution normally moves on to more code, or when an exception is thrown. Either way, in the code snippet above, both B and A will have their destructor called.

RAII

This leads to a really neat trick called Resource Acquisition Is Initialization, which uses the destruction rules to make classes that look after resources and clean them up when they are no longer needed.  When it is created, it is given a resource (it acquires - takes ownership - as it is initialized) and when it is destructed, it cleans up that resource.

Consider some code that turns on a tap. You want to make sure the tap is always turned off, not matter what happens, otherwise you will be flooded. You can write a RAII object that takes a newly turned on water resource, and in its destructor turns it off:

 

.
class TapHandler {
private:
	Tap& m_tap;
public
	TapHandler(Tap& tap) : m_tap(tap) {}
	~TapHandler() { m_tap.TurnOff(); }
	const Tap& get() { return m_tap; }
}

It is created with a reference to a tap, and the destructor always turns the tap off.  That means that the lifetime of the tap being turned on can be given to an instance of this object:

 

.
Tap tap(CreateTap());
{
	TapHandler myTap(tap);
	myTap.get().TurnOn(); // Also tap.TurnOn(), same object
	throw std::exception(); // oh no!
	myTap.get().TurnToCold(); // never called
	myTap.get().TurnOff(); // never called
}

TurnToCold() will never be called, because an exception is thrown. But myTap’s destructor is run anyway, and the tap is always turned off.  Even if an exception had not been thrown, you could rely on the tap being turned off - you never needed to remember to code it, because you used a RAII object that always did it.

If you had used a TapHandler as a member of a class, then when an instance of that class was destroyed, because all its members are destroyed too, the turned on tap would be turned off.

You can do write RAII objects for any kind of resource - Windows GDI handles, network sockets, file handles… and pointers.

Back to smart pointers

A smart pointer is an example of a RAII object.  Unique_ptr only allows one owner of a pointer; shared_ptr keeps a reference count.  Both of them control pointer lifetime in different ways; both mean that will well-written, modern C++, you should never write the keyword ‘delete’ - never manually manage lifetime.

One other thing: pointer access semantics. When you have a pointer, you use the arrow operator to access a member field or method:

 

.
foo->bar();

For languages like Delphi which automatically dereference pointer access and would write the above as foo.bar() even though foo is heap-allocated, this seems unnecessary. (You can do this two ways: through the arrow operator foo->bar(), which is a synonym for dereferencing the pointer and using the dot operator: (*foo).bar().  The *foo dereferences; the brackets are required because of operator precedence. Use ->.)

A smart pointer is not heap-allocated (or shouldn’t be!) so you’d think you’d use the dot operator, but it has its own methods - in fact, you can directly access the raw pointer it holds with get(), for example:

 

.
unique_ptr<Bar> bar(new Bar());
bar.get(); // is a Bar*

Instead, the smart pointer uses operator overloading to provide a -> operator:

 

.
bar->Open();

Calls the Open() method on the pointer bar is managing.

So you have a pointer, and access it using pointer semantics.

Back to connecting the UI and calculator

The form should own the calculator. Managing this ownership should now be clear: we will use a unique_ptr member field in the form, so that when the form is destroyed, the pointer to the calculator will be deleted and the calculator destroyed too, all automatically. You don’t need to write any code in the destructor; deletion is automatic.

In the header for the form, add #include <memory> to be able to use the smart pointers, and in the form class declaration add:

 

.
private:	// User declarations
	std::unique_ptr<ICalculator> m_Calc;

And in the .cpp, change the constructor to initialize the unique_ptr with an instance of a calculator:

 

.
__fastcall TfrmCalculator::TfrmCalculator(TComponent* Owner) :
	TForm(Owner),
	m_Calc(CreateCalculator(*this))
{
}

 

Now, the form or UI owns a calculator, and its lifetime is managed; the calculator knows about the form / UI. There is no manual lifetime or memory management required, no delete (as you might call .Free; in other languages); it all Just Works.

When you want to access the calculator, you use pointer semantics:

 

.
m_Calc->AddDigit(5);

Part II: Connecting the UI

Time for a break from C++ language features, cool though they are.  Let’s finish the UI.

Overriding the font style

FireMonkey is a styled UI, and while it can use native controls on some platforms, it mimics the native look and feel very closely - hopefully identically - in other situations.  That includes the font, where the styles for each platform specify the right platform font for button text, label text, and so forth.  But for the calculator, we want to override this and use a larger font for each button and the edit box, so each button has a large caption and the calculator entry and result has large text.

To do this, select all the controls.  (You can select one by clicking and then holding Shift while clicking others to multiselect, or click and drag a rectangle on the form.)  The Object Inspector will show the properties that are shared by the buttons and edit, and that includes the TextSettings property. Expand it by clicking the + sign, then again on the plus next to Font, and find the Size property.  Set it to 30.

The font size changed, but what happened? Scroll up, and you’ll see the StyledSettings property has changed (it’s non-default, indicated by bold text.) Expand it, and you’ll see that the Size item is not in the set of options.  The buttons and edit text are now drawing using their assigned style font, but overriding the font size set in the style. You can see the effect by clicking the checkbox next to Size on and off; it toggles between the style font size and the one you set. 

Experimenting with styles

Styles are a really useful part of the FMX UI framework.  Not only do they allow your applications to match the look and feel (and behaviour) of controls on any platform, and using system fonts is an example, but they also contain presets for a wide variety of difference but common alternatives. A button, for example, has many slight variations depending on how it’s used. Select just a button, and then find the StyleLookup property in the Object Inspector and click the dropdown arrow. Note how many different presets there are, such as ‘refreshtoolbutton’ for a tool button (one where the border becomes visible when you mouseover) with a Refresh icon. You can add your own, too.

However, clear the StyleLookup property since for the calculator, we want our buttons to look like standard buttons and show the Text we set as a caption.

Complete style changes

You can change a FMX app’s style completely.  Drop a TStyleBook on the form from the Tool Palette, and double-click it.  In the style designer tab that opens, click the Merge button, and navigate to ‘C:\Program Files (x86)\Embarcadero\Studio\18.0\Redist\styles\Fmx’. Open any style, such as ‘Blend’. Then, right-click the Style Designer tab and select close, and apply changes.

Back on the form, make sure the form’s StyleBook property is set to StyleBook1. The form will now have a completely different style.

You can load as many styles into the stylebook as you want, through its Styles list, and change them at runtime. (The Style Designer also lets you modify styles for any element. For example, a panel is normally represented by a rectangle, but it could be a roundrect or any shape or colour you want.)

However, for the time being delete the style book, which will revert to the default Windows platform style.

Connecting the UI

UI events

First, let’s connect up the operators. Select the Add button, and either double-click it, or in the Object Inspector’s Events tab, double-click the blank dropdown for the OnCreate event.  An event handler will be generated in the form.  Fill it in like so:

 

.
void __fastcall TfrmCalculator::btnAddClick(TObject *Sender)
{
	m_Calc->SetOperator(EOperator::eAdd);
}

Repeat this for the other operator buttons.  For the Equals button, call the calculator’s Equals method, and similarly for the decimal place button.

But what about the numbers? We could have a separate event handler for each, and repeat the same code, modified for each one.  But code duplication is bad style.  Instead, let’s make a single event handler for all buttons.  Select them all, then in the Events tab of the Object Inspector, type a name in the blank space next to OnClick - for example, type ‘btnNumberClick’, and press Enter.  An event handler will be created, and all buttons will use the same handler.  Fill in the code to add a digit:

 

.
m_Calc->AddDigit(0);

Obviously we need to change this depending on which button was pressed, and the Sender parameter holds that information: it is the object associated with the method, a TObject since event handlers with this signature aren’t limited to just buttons.

You could do this via a large if statement: if Sender is btnOne, call AddDigit(1), else if Sender is btnTwo… but this is messy.  We would gain very little.

FMX controls can have a data payload attached, called a tag, as a property.  There are several propreties: Tag, an integer; TagFloat, a floating-point number; TagString, a string; and TagObject, a TObject pointer, allowing you to associate almost anything.

In the Object Inspector, find the Tag property for each button and set it to match the button’s number - for example, set btnZero’s Tag property to 0, btnFive’s Tag property to 5, and so on. Now the event handler needs only a single line of code:

 

.
m_Calc->AddDigit(dynamic_cast<TButton*>(Sender)->Tag);

Dynamic cast is C++’s polymorphic type casting operator.  (In Delphi, this would be ‘Sender as TButton’.)  TButton is a descendant of TObject, so you can cast Sender to a TButton* and that cast will succeed if it is in fact a TButton. (It might not be.)  Once it is, we can access the Tag property.  (In fact, Tag is introduced a few levels up, so you could cast to TFmxObject.)

A dynamic cast will return nullptr if the cast fails, and accessing the Tag could then cause an access violation. Make sure you are certain of your types - or check. Here, we know that this event handler will only be called with a button as the Sender.

Display

The display interface has a method defined, UpdateUI, which is in the form but empty.  Fill it in to make the edit box display the text:

 

.
void TfrmCalculator::UpdateUI(const std::wstring& strText) {
	edtResult->Text = strText.c_str();
}

The edit’s Text property is String, while strText is the C++ standard wide string, but you can assign one to the other through the c_str() method returning a C-style character array pointer.

The UI is now fully hooked up to the calculator.  The calculator is given digits and operators, and the form can display a string by the calculator.

Part III: Entering a number

The final part of today’s post is to allow the user to enter a number, and to display that onscreen.

You can update the UI by calling m_Display.UpdateUI(std::wstring), but scattering calls to that throughout the calculator would be bad design - one method might update it with some text, some with another. What is better is to have a single place that is responsible for updating the UI that figures out what to display based on the calculator’s current state.

Add a private void method UpdateUI() in the header and implement it in the calculator. Until we have a number, this will display nothing.

 

.
void TCalculator::UpdateUI() {
	m_Display.UpdateUI(L"");
}

We’ll fill in that method later.

Entering a number

The calculator is told when the user presses a digit, but it needs to assemble those digits into a number. How? The first thing to realise is that accumulating digits is not a calculator’s responsibility - a calculator is really only responsible for doing calculations.  Separating responsibilities, and making a class only do one thing, leads to clear, concise, and understandable code.

Given that, let’s define a new class to accumulate digits, that we can query for a number.  Define this in the header:

 

.
class Accumulator {
private:
	int m_Whole;
public:
	Accumulator();
	int Value() const;
	void AddDigit(const int Digit);
};

This defines a class which stores an integer number, can be queried for that number, and can have a digit appended to that number.

Give the calculator a member variable:

 

.
class TCalculator : public ICalculator {
private:
	ICalculatorDisplay& m_Display;
	Accumulator m_Accum;
	void UpdateUI();

And initialise it in the constructor:

 

.
TCalculator::TCalculator(ICalculatorDisplay& Display) :
	m_Display(Display),
	m_Accum()
{
}

We can now fill in the AddDigit method to defer to this object to build the number, and update the UI:

 

.
void TCalculator::AddDigit(const int Digit) {
	m_Accum.AddDigit(Digit);
	UpdateUI();
}

Finally, the UI can display whatever the accumulator has got:

 

.
void TCalculator::UpdateUI() {
	m_Display.UpdateUI(std::to_wstring(m_Accum.Value()));
}

This uses the to_wstring method that converts an integer to a string.

Let’s fill out the accumulator class.  It’s pretty simple: initialises the number it has to 0, returns that number in the Value() method, and in AddDigit, adds that digit. That part is also simple: if the accumulator has the value 1, and the user presses 2 to turn that into 12, we just multiply the current accumulated value by ten and add the digit.

 

.
Accumulator::Accumulator() :
	m_Whole(0)
{}

int Accumulator::Value() const {
	return m_Whole;
}

void Accumulator::AddDigit(const int Digit) {
	m_Whole = m_Whole * 10 + Digit;
}

Things to note:

  • The constructor can initialise a list of all member variables; here we just have one, m_Whole
  • What does the ‘const’ mean after the method name, in ‘int Accumulator::Value() const’? It means that the method does not change the state of the object. This is useful for optimization and more.
  • Why ‘whole’? Because currently we only support entering an integer, or whole, number. We really want to enter a real number, a floating point number.  How are we going to do this?

If you run the app, you should now be able to type in a number and see the screen update to display it.

Handling the decimal point and introducing boost::optional

The logic for appending a digit to a integer or whole number is simple. But doing the same to the fractional side of a number is not quite so easy.

Let’s examine the basic method.  Keeping the whole part a separate number, we can track the fractional part as another integer, and append the digit the same way.  We can convert the integer to a fraction (123 to 0.123) later.  To do this, we split the append-digit logic away to another method, and call it on either the whole or fractional member variable depending on if the decimal point has been pressed. How do we track that? Keep state; add a boolean member and when the decimal point is pressed, pass that from the calculator to the accumulator.

However, how do we keep track of leading zeroes?  How do we tell the difference between 0 as no value, and 0 as something to keep and transform to ‘01’? How do we represent that in an integer, anyway?  You can’t.  Assuming we keep the fractional value as a number, we need to track the number of leading zeroes separately.  This is rapidly becoming messy.  It’s not going to be as simple as the integer whole number was, but we can simplify it.

First, let’s expand to keep track of the whole and fractional parts separately; to store if the user has pressed the ‘.’ button or not (if they are entering the fractional part); and add a digit to the appropriate half.

Extend the header to add a int m_Frac value; change Value() to return a double (a 64-bit floating-point type), add a method SetEnteringFraction to flag that the user is now typing into the fractional side, and change AddDigit to use it.  We’ll also, for reasons we’ll get to later, change Value() to get the value of the whole and fractional parts through a getter method for each.  Right now they will just return the member variable, but these will change soon.  You should end up with something like this (only the implementation shown):

 

.
Accumulator::Accumulator() :
	m_Whole(0),
	m_Frac(0),
	m_EnteringFraction(false)
{
}

double Accumulator::Value() const {
	return Whole() + Frac();
}

double Accumulator::Whole() const {
	return m_Whole;
}

double Accumulator::Frac() const {
	// Todo: fill in logic here
}

void Accumulator::SetEnteringFraction() {
	m_EnteringFraction = true;
}

int Accumulator::InternalAddDigit(const int& Value, const int Digit) {
	return Value * 10 + Digit;
}

void Accumulator::AddDigit(const int Digit) {
	if (m_EnteringFraction) {
		m_Frac = InternalAddDigit(m_Frac, Digit);
	} else {
		m_Whole = InternalAddDigit(m_Whole, Digit);
	}
}

The secret to the fractional value, ie turning 123 into 0.123, lies in calculating its magnitude (tens, hundreds, etc) and dividing it by that amount, which is ten to the nth power. log10(123) will give 2, whereas we want 3, to divide by 10^3 = 1000, because 123 / 1000 = 0.123.

Thus, the method looks like:

 

.
double Accumulator::Frac() const {
	if (m_Frac != 0) {
		return m_Frac / pow(10, floor(log10(m_Frac) + 1));
	}
	return 0.0;
}

This is the most complicated part of the whole blog series :)

This avoids doing the logarithm with a value of 0, or dividing 0 by a value, returning 0 in this situation as a fallthrough.

Now you can enter a complete, decimal-point-separated number by digits individually.  But we still haven’t addressed how to handle leading zeroes.  Let’s keep a count of them (we’ll address when to know a 0 is a leading zero in a moment), so the above line becomes:

 

.
return m_Frac / pow(10, floor(log10(m_Frac)) + m_FracLeadingZeroes + 1);

(Make sure you initialise the count of leading zeroes to 0 in the constructor.)

But how do we tell the difference between m_Frac being ‘not entered’, so 0 is a leading 0, and for legitimately holding a value?  Because we track leading zeroes, we can assume if m_Frac is not equal to 0, it’s a valid value.  But this logic is obscure - someone reading the code later might wonder what’s going on.

Optionals

What if there was a way to track if a variable genuinely held a value, or was empty?

In C# or Delphi, this is called a ‘nullable type.’ In C++, we use a boost template called ‘optional’. An optional may, or may not, have a value, and you can check if it does.  And while you could implement the accumulator without using them, using them makes the state clear and provides a very nice demonstration - important because we’re going to use them in a much more essential place next blog post.

Hopefully you installed boost at the beginning of this post; it takes a while. The Boost library has a vast variety of useful classes and methods; optional is just one.

An optional is declared like so:

 

.
boost::optional<int> m_Frac;

and has the following features:

  • Can be constructed with or without a value: m_Frac() does not have a value; m_Frac(0) has a value of 0
  • Can be reset to not hold anything: m_Frac.reset();
  • Can be checked if it has a value in an if statement, as a bool: if (m_Frac) { … } is true and goes into the body of the if only when the optional holds a value; if (!_Frac) { … } will enter the loop if the optional does not have a value.
  • Can get the value it holds - if it has one - through pointer semantics, specifically being dereferenced: int i = *mFrac;

Does this look familiar?  It’s very similar to a smart pointer, and a smart pointer, although we introduced it as a way of controlling lifetime, is also conceptually something that may have a value (a pointer) or may not (nullptr).

Include <boost/optional/optional.hpp>, and change m_Frac to boost::optional<int> m_Frac; The constructor should also be changed to initialise it as ‘m_Frac()’, ie without a value, because the accumulator starts off without the fractional part having a value.

AddDigit() can now check if it’s counting leading fractional zeroes like so:

 

.
if (Digit == 0 && !m_Frac) {
	++m_FracLeadingZeros;
} else { ...

If the fractional part has no value, and the user entered 0, it must be a leading zero. The else statement will add the digit as normal.

"++" here increments the value by 1. ++i is a preincrement, and i++ is a postincrement; the difference lies in evaluating.  If i has the value 1, j = ++i gives j a value of 2, and i of 2 (i is incremented first, ‘preincrement’); but j = i++ gives j a value of 1 and i a value of 2 (i is incremented second, ‘postincrement’). Pre- and pos- refers to evaluation. How often do you need this? Most often in loops, but modern C++ rarely loops via integers. It’s a holdover from C. The above code could be written either way.

The Frac() method can check if there is a fractional value and return 0.0 if not, and should get the value by *m_Frac.  Finally, since we want to avoid duplicating code, the AddDigit method now has to add a digit to either an int or a boost::optional<int>; change the whole number to an optional too, because it is valid for it not to have a value yet. It's very valid for it not to have a value: the user might go straight to entering the fraction, and while 0 is a valid value in this case, this code is meant to demonstrate optional<>. Remember to initalise it to empty, and to check if it has a value when returning its value in Whole().

Putting it all together, we get the following accumulator class:

 

.
Accumulator::Accumulator() :
	m_Whole(),
	m_Frac(),
	m_FracLeadingZeros(0),
	m_EnteringFraction(false)
{
}

double Accumulator::Value() const {
	return Whole() + Frac();
}

double Accumulator::Whole() const {
	if (m_Whole) {
		return *m_Whole;
	}
	return 0.0;
}

double Accumulator::Frac() const {
	// Convert an integer like 123 to 0.123
	// Magnitude can be calculated via log10
	// log10(123) -> 2, +1 -> 3
	// pow(10, 3) -> 1000
	// 123 / 100 = 0.123
	// Note leading zeroes - handle separately
	if (m_Frac && (*m_Frac != 0)) {
		return *m_Frac / pow(10, floor(log10(*m_Frac) + m_FracLeadingZeros + 1));
	}
	return 0.0;
}

void Accumulator::SetEnteringFraction() {
	m_EnteringFraction = true;
}

int Accumulator::InternalAddDigit(const boost::optional<int>& Value, const int Digit) {
	// Add a digit to the number. If it doesn't exist, the number is the digit
	if (Value) {
		return *Value * 10 + Digit;
	} else {
		return Digit;
	}
}

void Accumulator::AddDigit(const int Digit) {
	if (m_EnteringFraction) {
		// Leading zeroes won't get added, mathematically (to enter 1.00001, for
		// example, InternalAddDigit will multiply by 10 and add 0.) Track separately
		if (Digit == 0 && !m_Frac) {
			++m_FracLeadingZeros;
		} else {
			m_Frac = InternalAddDigit(m_Frac, Digit);
		}
	} else {
		m_Whole = InternalAddDigit(m_Whole, Digit);
	}
}

You can now enter a decimal fractional number.  Is using optional<> overkill here? Possibly, because it could be implemented another way, but it is clear - you can see when a variable may or may not have a value. The bit I don’t like is the logic to count the leading zeroes in AddDigit - the if statements are too nested and starting to become unclear. That logic could mostly be moved to InternalAddDigit, but the leading zero count should only occur if we’re dealing with the fractional part.  It works, but it is not as simple as I would like. Suggestions are welcome.

Overview

What have we covered this week? A lot:

  • C++:
    • Ownership: being clear what owns and is responsible for freeing what resources
    • RAII: Resource Acquisition Is Initialisation, a key C++ technique
    • Smart pointers, memory management using RAII
    • That modern C++ never uses the delete keyword: never manually manage memory
  • FireMonkey:
    • Styles
    • Overriding style elements
    • Importing completely new styles
    • Connecting event handlers and attached data to controls
  • C++ again:
    • The Boost library
    • boost::optional<>, one of many useful classes, and the concept of an optional or nullable type and (perhaps over-)use of it
    • Some math (the most complicated bit of this whole blog series!)
  • Putting it all together, a class that accumulates key presses to have optional whole and fractional parts of a number, returning the whole thing as a floating-point number

Next week, we pause for CodeRage! (Register for three free days of great C++ and Delphi content.) The week following, we examine operators (implementing addition, subtraction etc with small classes), moving a number from the accumulator to a left or right operand, and putting it all together - including a more accurate or important use of optionals - into a functioning calculator.


Read More

Learn to program C++ with C++Builder Community Edition: #5 Operators, and final application!

$
0
0

Welcome to the fifth and final episode of Learning C++ with C++Builder Starter. Last time, we had a calculator and numerical input, demonstrating using boost::optional, smart pointers, and more. This post is shorter: it will finish the calculator with operators (implementing addition, subtraction, etc) and end with a full application, ready to move to cross-platform if you wish.

Operators

The calculator is almost functional. The one thing missing is actually performing the math operations.

We want to support four operations: addition, subtraction, multiplication, and division. Each of these is an operation; each takes two operands, a left and a right operand.  In the expression

3 x 4

The left operand is 3, the right operand is 4, and the operation is Multiply.

This gives us a good basis for an interface, and an object-oriented design for operations, and is a good excuse to make a polymorphic class hierarchy with virtual methods - a useful thing to see done when learning C++.  Let’s make an interface and factory methods in a new unit called uOperator.cpp:

 

.
class IOperator {
public:
	virtual double Calc(const double A,const double B) = 0;
	virtual std::wstring Name() const = 0;
};

std::unique_ptr<IOperator> CreateOp(const EOperator Op);

And implement these in the .cpp file. For example, Add would be:

 

.
	class TAdd : public IOperator {
		virtual double Calc(const double A, const double B) {
			return A + B;
		}
		virtual std::wstring Name() const {
			return L"+";
		}
	};

Along with the factory method, switching on Op.

Any call to the interface's methods, Calc or Name, will call into the implemented descendant.

Next, create this when the user sets the operator.  Add a std::unique_ptr<IOperator> m_Op; to the TCalculator class, and change TCalculator::SetOperator to look like so:

 

.
if (Op == EOperator::eNull) {
		m_Op.reset();
	} else {
		m_Op = CreateOp(Op);
	}
	UpdateUI();
}

This is currently simplified - we’ll examine some other things that have to happen here in a moment.

This allows us to calculate the result of an operator, so long as we have two numbers. How do we get those two numbers?

Left and Right Operands, and the Result

Last post, we had an accumulator - a small object whose job was to take button keypresses and turn them into numbers. When has the user finished typing?

  • When the user presses an operator (like + or -)
  • When the user presses Equals

In both these cases, it indicates one number is complete, and something else needs to happen: in the first case, that the second number needs to be entered; in the second, to calculate the result. Also in the first case, entering the second number might mean calculating as well - if the user has entered ‘1 + 2’, and presses the multiply button, they want to multiply 3 by something. That something is the new right operand, and the result is the new left operand.

This means that SetOperator needs to be able to promote the accumulator’s value to a new left or right operand value, and also sometimes invoke Equals and moving the result to the left operand, before setting the operator.

Secondly, the left and right operands, and the result, do not always exist.  When the calculator app has just started, and the user has entered nothing, there are no operands or result. When Equals has been pressed, there is a result but no left or right operand. This harks back to last week’s post: how do you represent something that may or may not exist? Using boost::optional.

Let’s add three optional values to the calculator class’s declaration:

 

.
	boost::optional<double> m_Left;
	boost::optional<double> m_Right;
	boost::optional<double> m_Result;

They’re not initialised to any value in the class constructor, since at app startup they are empty.

Promoting the accumulator

First, let’s create a method for moving a number from being typed in (the accumulator) to a left or right operand. It’s fairly simple: if there is no left operand, initialize the left with the accumulator’s value; if there is, then initialize the right operand with the accumulator’s value. If there’s already both a left and a right, that indicates a logic error.

 

.
void TCalculator::PromoteAccumulator() {
	if (!m_Accum.Entering()) {
        return;
	}

	if (!m_Left) {
		m_Left = m_Accum.Value();
	} else {
		assert(!m_Right);
		m_Right = m_Accum.Value();
	}
	// Reset
	m_Accum = Accumulator();
}

Setting the operator

We can now expand the method called when the user wants to set the operator - when they press + or -.

  • If the operator changes, and the user was typing, that needs to be promoted to an operand.
  • If there are two operands, both left and right, then it needs to calculate (this addresses when the user has typed 1, +, 2 and then presses *. In this situation they want to get the result of three, and multiply that by something soon to be typed in, so move the result to the left.)
  • Assuming all this resulted in a left-side operand, create an operator class instance.

The code to do this looks like so:

 

.
void TCalculator::SetOperator(const EOperator Op) {
	if (Op == EOperator::eNull) {
	   m_Op.reset();
	} else {
		PromoteAccumulator(); // once the op changes, stop entering, make it a number

		// 1 + 2 [now press -] -> want to calc that, make it the left operand
		if (!m_Result && m_Left && m_Right) {
			Equals();
		}
		if (m_Result) {
			// Operator after result -> want the result to be the new left operand
			m_Left = m_Result;
			m_Right.reset();
			m_Result.reset();
		}
		if (m_Left) {
			// Require a left operand, because all ops have to operate on at least
			// one operand
			m_Op = CreateOp(Op);
		}
	}

    UpdateUI();
}

Calculating

Not much left!  We can now make use of the operator classes we created at the beginning of the post.  The calculation method, called Equals after the button, will promote the accumulator if necessary (the user might have been typing what should become a right-side operand); if it has a left, a right, and an operator, call the virtual Calc method to get a result.

 

.
void TCalculator::Equals() {
	PromoteAccumulator();

	if (m_Left && m_Right && m_Op) {
		m_Result = m_Op->Calc(*m_Left, *m_Right);
		m_Left.reset(); // No operands any more
		m_Right.reset();
		SetOperator(EOperator::eNull); // Nothing to do any more
	}
	UpdateUI();
}

 

Printing

One final step: displaying this onscreen.

A traditional calculator only displays the number currently being entered, or the result. The operator interface we designed has an operator name, and there’s no reason our app can’t be slightly more advanced than a desktop calculator.  If the user is trying to calculate “1 + 2” why display only 1, or only 2, and no sight of ‘+’?

My version of this code will show the left and right operands, if they exist, along with the operator if it’s set, accounting for the user typing (for example, there might not be a right operand, just the accumulator in use - same with the left operand.)

There's not much new here: this uses string streams, and dereferences the optional left or right values.

 

 

.
void TCalculator::UpdateUI() {
	std::wstringstream stream;
	if (m_Left) {
		stream << *m_Left;

		if (m_Op) {
			stream << L" " << m_Op->Name() << L" ";

			if (m_Right) {
				stream << *m_Right;
			} else if (m_Accum.Entering()) {
				stream << m_Accum.ValueStr();
			}
		}
	} else if (m_Accum.Entering()) {
		stream << m_Accum.ValueStr();
	} else if (m_Result) {
		stream << *m_Result;
	}

	m_Display.UpdateUI(stream.str());
}

The Calculator

And that’s it. Really. Congratulations, you now have a fully functional calculator!

This code, being FireMonkey, can be compiled on Windows, macOS, and mobile. (Note some possible problems with Android's boost - looking into it.)  You can theme it, and change the layout for any device using the multi-device designer. What you've done is create a cross-platform app without even trying.

We've covered:

  • Basics
    • Installing C++Builder Starter
    • Basic debugging
    • Designing a UI
  • UI design
    • FMX styles, to give your app a new theme
  • Coding
    • Basic C++ syntax
    • Basic object oriented classes in C++
    • Useful C++ classes and techniques, including smart pointers and optionals, an understanding of heap-allocated objects, RAII, and other C++ basics
    • Good application architecture: separating the UI and logic
      • Interfaces and implementing interfaces
    • Good application architecture: principles of ownership

and ended with a complete, working, very nice calculator. Your challenge? Recompile it for macOS or iOS! (Hint: investigate the 'Target Platforms' node in the Project Manager...)

Thanks for reading each post. I hope you learned some good stuff!

Source code


Read More

Create App Store ready apps with Community Edition

$
0
0

Start building visually stunning multi-device applications right away with these great tools accessible from the IDE’s Welcome Page.  

TIP: If you accidentally close the Welcome Page, you can reopen it by going to View > Welcome Page. 

This article covers the following:

  • Guided Tour in the IDE

  • Code Samples and Mobile Snippets

  • Stunning, ready-to-use Application Templates

Guided Tour

The Guided Tour is a step-by-step bubble pop-up tour that introduces you to the Form Designer and shows you how to build your first multi-device application using the FireMonkey framework. You can access the Guided Tour from the Welcome Page.

 

Code Samples and Mobile Snippets

 

We provide a number of FireMonkey mobile snippets for both Delphi and C++, designed to help you get started with specific mobile functionality, including location sensor information, camera access, gestures and more. More full featured demos can be found in the Multi-Device Samples folder. All product samples are included as part of the Samples directory installed with Delphi and C++Builder Community Edition.

TIP: If you didn’t install the Samples during the original product installation, you can add them easily by going to Tools > Manage Platforms > Additional Options > Samples.

 

FireMonkey UI Templates

Quickly build stunning, ready-to-use user interfaces by customizing the included FMX GUI templates. The FireMonkey framework is the app development and runtime platform behind Delphi and C++Builder. FireMonkey is designed for developers looking to build multi-device, true native apps for Windows, macOS, Android and iOS.

There are six sets of templates, each set demonstrating a different type of UI, and three examples in each set for a total of eighteen templates.

FMX GUI Templates are organized in six categories: 

  • Contacts Screens: the Contacts screens demonstrate a groups contact list, an address book list, and a searchable employee list

  • Home Screens: the Home screens demonstrate a central navigation menu of buttons for a health related home screen, a meeting or group related home screen, and a resort, hotel, or spa related home screen

  • Login Screens: the Login screens demonstrate a number of different login screen styles with username and password input fields, login buttons, create account buttons, and forgotten password buttons

  • Profile Screens: the Profile screens demonstrate a number of different profile style layouts with a profile image, various profile settings or stats, and quite a few different buttons for configuring the user’s profile.

  • Settings Screens: the Settings screens demonstrate some different vertical layouts for displaying and changing settings with various input controls

  • Signup Screens: the Signup screens demonstrate a number of different signup layout style screens with username and password input fields and sign up buttons. 

 

Some of the templates can be accessed right from the Welcome Page:

The other GUI templates are available via the GetIt Package Manager in the IDE (Tools > GetIt Package Manager). The GetIt Package Manager in the IDE lets you search and browse available packages that can be installed into Delphi or C++Builder Community Edition.

The templates serve as a great starting point for developers looking to build stunning cross-platform UIs, and can easily be customized by changing the images, iconography, styles and more. There are separate project templates for both Delphi and C++Builder. The different templates demonstrate responsive design in a variety of layout styles which makes it easy to design and customize your applications visually at design time. The GUI templates were created using Frames, Styles, LiveBindings, and FireMonkey Effects which make it simple to build stunning UIs with Delphi and C++Builder.

Creating applications that not only are visually stunning but also scale properly across multiple platforms and devices is key. A responsive design is at the forefront of the strategy used when designing the FMX GUI Templates. For the GUI templates, a responsive design means that regardless of the screen size or scale the design will automatically resize itself to the available screen space available on each device with no additional code or device specific configurations required.  The templates can easily be customized for your own use by changing the colors, icons, adding your own logo etc.

   

 

 

 

Providing a good user experience in your application is not only important for user adoption, but also to get accepted in the iOS App Store and Android Google Play Store. For more information on cross-platform design patterns, watch our webinar replay on UX excellence.

Note: Only the first template will be auto-opened after installing a GUI template, but you can access the other two templates by navigating to C:\Users\Public Documents\Embarcadero\Studio\19.0\Samples\Object Pascal\  or C:\Users\Public Documents\Embarcadero\Studio\19.0\Samples\CPP

About Delphi and C++Builder Community Editions

Delphi Community Edition and C++Builder Community Edition provide developers with integrated and professional-level developer tools from Day 1. Community Edition is designed for freelance developers, startups, students and non-profits with annual revenues of less than USD $5000 or teams with up to 5 developers. Community Edition is licensed with a one year term license.

The templates and samples above are also available in our Professional, Enterprise, and Architect Editions, and our 30-day Trial. Learn More about Delphi and C++Builder.

 

Helpful Community Edition Links: 


Read More

Replay and Code for My Webinar on RAD Server Last Week

$
0
0

Last week webinar on RAD Server was well attended, which is great because we see increased interest on the RAD Server technology. We have great plans for it for the coming release. In the meantime here are some additional links:

Source code for the demos I showed during the sessions are on GitHub in my "Sessions Repository": https://github.com/marcocantu/DelphiSessions/tree/master/RADServerBeyondBasics

The video of the webinar is on YouTube at https://www.youtube.com/watch?v=NculJwVfKKA

Moreover, if you need a great introduction, refer to Cary Jensen white paper at https://www.embarcadero.com/rad-in-action/mobilizing-your-business-with-cary-jensen

Finally, the RAD Server home page is at https://www.embarcadero.com/products/rad-server. As a reminder, the development support is included in Delphi, C++Builder, and RAD Studio Enterprise and Architect, and these RAD Studio licenses also come with a single site RAD Server deployment license included.


Read More

Deadline Approaching: Google’s new Android API level 26 Requirements

$
0
0
If you’re not currently building for Android and your team doesn’t have plans to target Android in the near future, you can disregard this upcoming Google Play Store requirement.
Do you know how you will meet the new Google Play requirements that apps support at least Android 8.0 (API level 26)? Here are the critical dates you need to know:
  • AUGUST 1, 2018.  All new apps must target Android API level 26
  • NOVEMBER 1, 2018. All app updates for existing apps must target Android API level 26.
We’ve gotten a number of questions from our customers on this and wanted to share how you can address these new requirements. There are at least two solutions.

 

Option 1: Get the 10.3 Beta Release including support for Android API level 26

The change to support Android API level 26 requires significant work, and is not possible in a 10.2 update. We plan to deliver full support for Android API level 26 in the next major release of RAD Studio, 10.3. While this release will take some more time, we understand that some customers require a solution soon. We will invite all customers on active Update Subscription to join our upcoming 10.3 Beta (under NDA). More details on the Beta and how to sign up will be shared in the coming weeks over email - check your inbox.
The 10.3 beta will allow you to target Android API level 26. Although the usual beta restrictions do not allow for building and deploying production apps, this beta will have a special EULA provision allowing you to deploy (production) Android apps to the Google Play Store.
Being able to participate in our Beta program is one of the great benefits of Update Subscription. You can check how many days you have remaining on your Update Subscription using the License Manager.

 

Option 2: Using 10.2.3

In lieu of using the 10.3 beta to deliver Android API level 26 ready apps, another option is to follow Embarcadero MVP Dave Nottage’s excellent blog post on how to target Android API Level 26 with Delphi, C++Builder and RAD Studio 10.2.3 Tokyo: http://delphiworlds.com/2018/06/targeting-android-8-and-higher-continued/
 
Note: Features discussed above are not committed until completed and GA released.
 

Read More

デッドラインアプローチ:Googleの新しいAndroid APIレベル26要件

$
0
0

この記事は、Sarina DuPontによるDeadline Approaching: Google’s new Android API level 26 Requirementsの抄訳です。

 

開発したアプリケーションをAndroid向けにビルドしておらず、またAndroid向けのリリースを予定していない場合は、今後予定されている Google Play ストアの要件を気にする必要はありません。
アプリケーションが少なくとも Android 8.0 (APIレベル26)をサポートする新しい Google Play の要件をどのように満たしているかをご存じですか? Android 向けのアプリを開発している場合には、下記の日付が重要です。


Read More

Largest World Recording Holding Model Train Set Powered By Delphi

$
0
0

Miniatur Wonderland Hamburg is the world's largest model train set as officially certified by the Guinness World Book of Records. Apparently the whole system is powered by software built in Delphi on the back end (including the control room). Embarcadero's Jim McKeeth has another article where he details more about the control room and the other software like Railware that controls the whole setup.

The train set has a 1,490 m² layout, contains 260,000+ figures, cost over 21 million Euro's to build, has 42 planes up in the air, has 9,250 cars, 1,040 trains, 1,380 signals, 385,000 LEDs, 4,110 buildings, 130,000 trees, a track length of 15,400 meters, and took over 760,000 hours to build.

This video is by the Guinness World Book of Records touring the facility including the control room and it's electric model car charging station.



[YoutubeButton url='https://www.youtube.com/watch?v=2mNhxi_D5kE']
 

Read More

GetItベースのインストーラーのログを有効にする方法

$
0
0
 この記事は MARCO CANTUによる、Enabling GetIt Install Logs for RAD Studio Installationの抄訳です。    


RAD StudioのGetItベースのWebインストーラは、時々、かなり曖昧なエラーメッセージで停止します。

これは、ネットワーク接続の問題、奇妙なファイルシステムの構成、ディスク領域の不足、不完全なインストール、および、その他の原因である可能性があります。

しかし、 エラーメッセージの中には、"操作エラー"のように、問題の原因を説明していないものがあります。

将来的には、「フォルダxyzを作成できませんでした」、「ファイルfoo.dcuをフォルダbarにコピーできませんでした」などの特定のエラーが発生していることを確認出来るようにしています。

当面の間ですが、Quality Portalへエラーを詳細に報告する方法として、文書化されていませんが、インストーラの進捗状況のログファイルを生成するためのレジストリの設定があります。

注:インストールと機能マネージャは同じログファイルに出力します。GetItパッケージマネージャーでは出力しません。

 インストールを開始した後 (障害が発生した時点まで、または正常に動作した後)、プロセスを再起動すると構成設定が読み取られます

RegEditを実行し、次のキーに移動します。

HKEY_CURRENT_USERSOFTWAREEmbarcaderoBDSxx.0CatalogRepository

ここでの、xx.0はRAD Studioの内部バージョンです(最新バージョンは19.0など)。

そのキーの下に、 "Debug"という名前のDWORD値を追加し、値に1を設定します。

インストーラーを再起動するか、IDE を再起動して新しい機能を追加すると、システムは次のような場所に詳細なログファイルを作成します。

C:UsersPublicDocumentsEmbarcaderoStudioxx.0GetItInstall.log

これにより、エラーが発生した場合に詳細な情報を得ることができます。

時間が経過すると同じログファイルが使用され、最後にデータが追加されます。

サポート担当者に連絡するとき、または、インストーラの問題を報告するときこのログファイルを添付することで、コアな問題を特定するのに役立ちます。

 


Read More

On the road again: DevTracks 12. September, Oldenburg

$
0
0

Schnelle, langlebige und kostengünstige Softwareentwicklung

Wir laden Sie zu einer weiteren Veranstaltung unsere DevTracks am 12. September 2018 nach Oldenburg ein. Die Softwareentwicklung durchläuft zur Zeit in vielen Bereichen einen Wandel. Bestehende Anwendungen müssen mit immer neuen Plattformen kooperieren.

Das Re-Engineering und das Re-Design von Legacy Anwendungen, sowie die Einbindung mobiler Geräte ist eine große Herausforderung. Embarcadero steht mit seinen Produkten speziell für die langfristige Nutzung vorhandener Anwendungen und gleichzeitig für die Modernisierung auf heutige Anforderungen. Die Erfolge vieler unserer Kunden basiert insbesondere auf der langfristigen Wartbarkeit des Programmcodes. Anwendungen die vor vielen Jahren entwickelt wurden sind noch heute auf neuen Plattformen im Einsatz.

Mehr Infos und Anmeldung (kostenfreie Veranstaltung!)

https://www.devtracks.de

 


Read More

On the road again: EKON 22, 5.-7- November, Düsseldorf

$
0
0

EKON 22 – DIE ENTWICKLER KONFERENZ FÜR DELPHI-DEVELOPER

Die 22. Entwickler-Konferenz startet vom  5. bis 7. November 2018 in Düsseldorf. Die EKON versorgt Delphi-Entwickler wieder mit geballtem Know-how, Best Practices und fundierten Grundlagen für die effiziente Entwicklung mit Delphi. Seit vielen Jahren ist die EKON das große Konferenz-Highlight für die Delphi-Community. Die besten nationalen und internationalen Delphi-Experten vermitteln Ihnen umfassend, wie Sie mit den wichtigsten Tools und Methoden Ihre Delphi-Projekte effizienter und erfolgreicher gestalten. Erleben Sie 36 Sessions, 4 Power Workshops, ein spannendes Speaker Panel, eine Keynote mit Marco Cantú von Embarcadero, beste Networking-Gelegenheiten und die legendäre EKON-Konferenzatmosphäre!

Ich selbst werde zwei Vorträge halten:

Delphi ist nicht nur Desktop: HTML/JavaScript Client mit Sencha Ext JS und Embarcadero RAD Server

Schneller ans Ziel: Tipps und Tricks zum aktuellen Delphi

Alle Infos auf https://entwickler-konferenz.de/de/


Read More

August 2018 Roadmap Commentary from Product Management

$
0
0

2018 has been a very exciting year so far for Embarcadero. In our roadmap, you can find the key features that we’ve planned for calendar year 2018/2019. Before we get to the details of our updated roadmap, we wanted to recap what we’ve delivered so far:

Back in March, we introduced RAD Studio 10.2.3, also known as 10.2 Tokyo Release 3, of Delphi, C++Builder and RAD Studio. This was the third release of Tokyo, and included CMake Command Line Support for C++, Rename Refactoring, Mobile support in Delphi and C++Builder Pro, RAD Server enhancements, FireMonkey User Interface Templates and more. 

Just last month, for the first time ever, we launched a full featured Community Edition for Delphi and C++Builder. Not only is it great for new developers, but our existing community can look forward to the next generation of knowledgeable Delphi developers picking up the torch and furthering their legacy with new Delphi projects. This is also true for C++Builder, since Community Edition provides a great entry point for C++ developers around the world to experience all that C++Builder has to offer, especially in terms of our multi-platform capabilities.   

As you will see in our roadmap, we have a lot of exciting features planned for the next major version release, 10.3 (aka Carnival), with the themes for the release being Language and Platform Enhancements for Multi-Device and Windows Developers. The modernization of the IDE will also continues at full pace.

We wanted to take this opportunity to share with you more details on several key focus areas outlined in our updated roadmap. 

 

More Details from Sarina DuPont

Sarina focuses on FireMonkey, the component libraries’ UX and styles, the installation experience and demos and documentation  

FireMonkey Z-Order and Native Controls

One of my focus areas since I started at Embarcadero back in 2011 has been FireMonkey. I’m very passionate about what developers can do with the FireMonkey framework to deliver on their multi-device application requirements. If you’ve been following my blog, you’ve seen that building stunning UIs with FMX is a theme carried through many of my posts. It’s an area where FireMonkey really shines, and combined with our FireUI designer, a very unique offering in the developer tools space.

The FireMonkey UI Templates that we released over the past several months for Delphi and C++Builder developers not only make it easy to get started building your own multi-platform applications, but they also showcase the flexibility that FireMonkey provides, and how to easily tweak UI themes to create a totally custom look and feel.  

For several years, we’ve gotten customer requests for Z-order and native controls support on Android. We’ve heard your requests and are actively working on Android Z-Order support in 10.3. This will allow developers to use FireMonkey styled controls such as buttons, labels and checkboxes with natively rendered controls like the browser and map control on the same form without the native control covering the styled control. This also provides the foundation for supporting natively rendered UI controls, such as TEdit, on Android. In the coming weeks, we’ll be inviting customers current on Update Subscription to our 10.3 NDA beta, so those interested can get an early look at what’s been in the works. We also plan to expand our native Android controls support to more controls in future releases.

Z-order support for Android will work the same as it does for Windows and iOS today, allowing developers to mix both styled controls and controls rendered by the underlying OS on the same form without any overlap issues.

Another Android related feature we’re working on is upgrading our Android API level support in RAD Studio to support level 26 (Android 8.0). This change requires significant work, and is not possible in a 10.2 update. This support is coming in 10.3. Although the usual beta restrictions do not allow for building and deploying production apps, active update subscription customers who join our 10.3 beta will find a special EULA provision allowing them to deploy (production) Android apps to the Google Play Store.

New Platform Support

Platform support is key with a multi-platform framework like FireMonkey. We know that Android 64-bit support will be mandatory by the summer of 2019, and are working on plans to ensure our customers can meet this requirement next summer. 

One roadmap change you may notice compared to the September 2017 roadmap is that we removed macOS 64-bit platform support from the initial 10.3 release.

This doesn’t mean that we don’t think macOS 64-bit is important. We removed it from the 10.3 release to focus on providing more quality and stability for the other key features that are in flight. With that said, our intent is to provide support for macOS 64-bit, including support for targeting the iOS 11 (and iOS 12) simulators, in a follow-on 10.3.x release. We know that developers looking to target the macOS App Store or leverage 64-bit APIs require macOS 64-bit support.

We have a number of customers today who distribute their existing 32-bit applications through their own web store and are currently not impacted by this Apple requirement. 

In terms of looking ahead, a couple of months ago Apple announced that it was deprecating support of OpenGL in favor of Metal 2, Apple's new GPU library. While OpenGL will continue to be supported in the next versions of macOS and iOS, we are reviewing what will be required to support Metal later next year.

  

More Details from Marco Cantu

Marco focuses on the Delphi language and RTL, the VCL library and Windows integration, all things database and Web oriented, including RAD Server 

VCL and Windows

While over the last few years RAD Studio and Delphi have expanded their focus on multi-device and mobile development with a single source code and compiled applications, the product remains rooted on Windows and in recent years we have made sure to keep a significant focus on VCL, the best component framework for Windows client applications. We have been adding new components and controls in each release. 

Today VCL offers great support for Win32 API, but also integration to the newer WinRT API of Windows 10. We have new controls with modern UI, styling, and offer a great migration path to a modern UX while preserving most of your existing source code. Moreover, the IDE integrates the Desktop Bridge to build UWP applications you can distribute via the Windows Store.

As you can see in the roadmap, the plan is to continue and increase our investment in this area, specifically around store applications and the ability to check the application status in the store (checking if the customer has paid for the app, if it is a trial, and managing in-app purchases and subscriptions).

We are also going to expand our Win32 API coverage, given Microsoft has added important subsystems to it, and focus on continuous improvement for our support for High-DPI and 4K monitors on Windows. In this regard, we are going to introduce a new image list control that can manage images at multiple resolutions, similarly to what we do in FireMonkey. This will allow the application to avoid relying on image scaling (which often negatively affects image quality) but rather pick the best image for the current screen resolution. In terms of High-DPI support, we are working on the new “Per-Monitor V2” mode Windows 10 offers and plan to focus on resolving a large number of issues the current multi-monitor support has.

Delphi Language and RTL

Beside the Windows 10 focus (which is for both Delphi and C++Builder), there are many other features we are working on for the Delphi personality. We have gone back to the drawing board for the language, and are planning on releasing the new features in phases -- as stability at the compiler level is of critical importance. We found out that  good quality support for nullable types (planned, but deferred) requires changes in other areas of the language. The first we’ll be tackling is custom managed records, that is the ability to define a default parameterless constructor, a destructor and a copy operator for any record type. This adds a lot of power to records, a very nice complementary feature to classes and objects.

In terms of the Run-Time Library (RTL), the focus will be on performance and quality, more than additional features. From generic lists to large memory data structures, from JSON processing to the HTTP client library, we have found large room of improvements and are sure every customer will be pleased, because whether you are building a client application or a server one, whether you are using mobile or desktop platforms, performance gains are always nice to have. 

The RTL performance enhancement also helps RAD Server. After 10.2.3, we released a performance update for our REST API engine, mostly focused on internal elements and better memory management in case of heavy multi-threading. What we couldn’t do in an update was improve the performance of your RAD Server modules, something we’ll achieve in the next release by making JSON processing, string processing, the TStringBuilder class and more core classes faster. Also, it is important with JSON and HTTP services to better support all standards and protocols, including borderline scenarios that other HTTP servers or clients expect.

RAD Server

We have much more than that for RAD Server, though. The next release will see a major overhaul of the logic RAD Server uses to map an incoming HTTP request to an internal resource (that is, a class offering methods to handle the HTTP method calls). Until now, the mapping has been based only on the URL and it has been fairly rigid. Now we plan on adding the ability to consider other HTTP request parameters, like the Content Type, Accepts, file extensions, and more to allow for more sophisticated mapping. For example, the same URL can return a JSON data structure, an image, or a PDF depending on the invocation context. Also, while today you often have to repeat the same code to handle requests over and over, you’ll be able to delegate the actual implementation of a resource request to a separate component, sharing most of the same code for multiple requests and reducing boilerplate code. 

It is a really new version of RAD Server that’s coming along, and coupling it with the licensing changes (deployment licenses are now included with higher end SKUs) we are certain that this REST API engine will see additional interest and focus. 

 

More Details from David Millington

David focuses on the C++ language, the debugger, and IDE and user experience

C++

In the past couple of releases of RAD Studio, we’ve introduced some great tools for C++ developers. First, rename refactoring: our first C++ refactoring.  It’s one of the most common refactorings and significantly speed up and makes more reliable a common task. Second, we introduced command-line CMake support for C++Builder. This is the first of a couple of CMake-focused steps we have planned, and explicitly supports using ninja for fast builds. You can target Windows, iOS, and Android, including deploying to the device, all from CMake.

We have significant plans for C++ over the next year.

We will introduce our upgraded C++17-capable compiler.  This will be for a single platform (Win32) initially, then rolled out to others since we want to support the same level on all platforms.  When macOS64 support arrives, it will use this new version too. We will continue to update our compiler toolchain and keep it close to a recent version of Clang, meaning our users will get the benefits of both the optimizations and language support of Clang and the language extensions and power our environment provides.

Paired with this will be a new C++17 version of the Dinkumware STL, and performance enhancements.

We also plan a followup to the CMake support introduced in 10.2.2. This support was command-line only. Ultimately, we plan for further integration, aiming to make it very easy to import a CMake project into the IDE, and to build.  Paired with this is an ongoing project to ensure common C++ libraries work with C++Builder (not hard, we have excellent language compatibility, and increasing this is constant and ongoing) and add them into GetIt, our package manager. Ultimately, any C++ user - used to our ecosystem or not - should find it very easy to use any app or library they choose with C++Builder.  And our users should find it easy to bring in any C++ library into your apps.

Finally, some readers may have seen the very recent announcement that Idera acquired Whole Tomato.  Whole Tomato make Visual Assist, a Visual Studio extension which is arguably the best C++ tooling addon for any IDE, period.  It has excellent code insight, refactorings, and other tools.  Visual Assist users can rely on its continued development for Visual Studio - it is an excellent standalone tool we want to see grow and thrive - and we also plan to integrate some key parts into C++Builder. 

The IDE

The RAD Studio IDE is used daily by many tens of thousands of Delphi and C++Builder users.  Recently, in 10.2.2, we introduced a new dark theme for the IDE and code editor - one of our most popular additions ever, greeted with enthusiasm by large number of our users.

In 10.3.x, we plan a number of IDE improvements, both to the UX (user experience) and functionality. 

Over the past few years, the IDE has had many extensions and changes.  But, the way these have been presented in the UI has not always been polished.  In 10.3, we plan some careful UX improvements that should make the IDE significantly nicer to look at and more pleasant to use for hours on end.  Not all of these are just UI polish: many dialogs have improvements and reorganisation, and the end result is something significantly functionally better while also looking a lot more pleasant.  We can’t wait to show you.

We are also integrating a number of items from Andreas Hausladen’s IDE Fix Pack, which we licensed earlier this year.

Longer term, we have some other improvements lined up.  We have spent quite some time internally examining code completion and other code tooling, and have some significant improvements planned for both Delphi and C++.

Finally, we are also paying a lot of attention to better high DPI support in the IDE.  Marco wrote above about significant improvements for high DPI in the VCL, and the RAD Studio IDE is mostly written in Delphi and C++Builder and most UI is built using the VCL. We hope to leverage the VCL improvements within the IDE too, though this will be done carefully and likely arrive after a release gives it to you our users in the VCL itself.

Debugger

We don’t typically write much about the debugger in blog posts.  The debugger is one of the core pillars of a development environment, but we tend to write about the compilers - after all, they’re where you see the language enhancements, the performance, etc.  The debugger just does its work for you every day, silently, and is quietly updated as we also work on the flashier side of the toolchain. 

However, we have some great improvements planned.  On mobile platforms, we use a mix of LLDB and GDB depending on the platform.  LLDB is the way forward, and we will be working on our Delphi front-end (language understanding) integration before making use of LLDB on more platforms. The end result as seen in the IDE will be a faster and more powerful debugger, which also understands and can interpret more Delphi statements. Naturally, C++ benefits from this too.

 

Overall

We have some great improvements planned for you: C++17, further CMake support, debugger improvements, language tooling, new FireMonkey features and new platform support (macOS 64-bit and Android 64-bit), Android native controls, HighDPI improvements, RAD Server enhancements, Delphi language features, great UX and look-and-feel improvements to the IDE.  

  

Note: These plans and roadmap represent our intentions as of this date, but our development plans and priorities are subject to change. Accordingly, we can’t offer any commitments or other forms of assurance that we’ll ultimately release any or all of the described products on the schedule or in the order described, or at all. These general indications of development schedules or “product roadmaps” should not be interpreted or construed as any form of a commitment, and our customers’ rights to upgrades, updates, enhancements and other maintenance releases will be set forth only in the applicable software license agreement.

 


Read More

Upload An Attachment To SalesForce With The Delphi 10.2 Tokyo Enterprise Connectors

$
0
0

I am working on a project that utilizes the Embarcadero Enterprise Connectors powered by CData to access SalesForce through it's API. The Enterprise Connectors provide you a wide variety of connectors for quickly and easily accessing APIs like SalesForce, Google AdWords, Mailchimp, Facebook, Azure, YouTube, and many many more.

The Enterprise Connectors work through FireDAC and give you an SQL interface to the various APIs that are on offer. This means you don't have to learn new APIs you simply use standard SQL to access all of the data that you need.

In the case of SalesForce one of the requirements of the project is to upload attachments and attach them to an existing item in SalesForce. I created this function which shows how to do this quickly and easily. SalesForce takes files as a Base6 encoded string so I utilized the System.NetEncoding unit to do this.

There are a number of different ways to write the below code and this is just one way. You'll have to add your own try..finally or try..except statements to make it more boilerplate.

//
//
function TForm1.UploadAttachment(const AObjectId, AFileName: String; ABitmap: TBitmap): String;
var
SS: TStringStream;
MS: TMemoryStream;
begin
  Result := '';

  MS := TMemoryStream.Create;
  SS := TStringStream.Create;
  ABitmap.SaveToStream(MS);
  MS.Position := 0;
  TNetEncoding.Base64.Encode(MS,SS);
  SS.Position := 0;

  FDQuery1.SQL.Text := 'EXEC CData.Salesforce.UploadAttachment `ObjectId` = :ObjectId, `Base64Data` = :Base64Data, `FileName` = :FileName';
  FDQuery1.ParamByName('ObjectId').AsString := AObjectId;
  FDQuery1.ParamByName('Base64Data').AsMemo := SS.DataString;
  FDQuery1.ParamByName('FileName').AsString := AFileName;
  FDQuery1.Open;
  FDQuery1.First;
  if FDQuery1.RecordCount>0 then
    begin
      Result := FDQuery1.FieldByName('Id').AsString;
    end;

  SS.Free;
  MS.Free;
end;

Find out more about the Enterprise Connectors and how you can utilize them in your Delphi and C++ apps using FireDAC.


 
[YoutubeButton url='https://www.youtube.com/watch?v=t6_UxH_ivpQ']

Read More

RAD Studio 10.x Files Permissions Patch Released

$
0
0

Embarcadero has just released RAD Studio Files Permissions Patch, applicable to all versions of RAD Studio 10, 10.1.x and 10.2.x installed using the GetIt web based installer.

The GetIt-based installers (up to but excluding RAD Studio 10.2.3 build 3231, made available in July 2018) copy files under the main application folder, most likely something like C:\Program Files (x86)\Embarcadero\Studio\1x.0\, using read-write or read-write-execute privileges instead of read or read-execute privileges as typical of the C:\Program Files (x86) subfolders.

If you’ve installed any 10.x version using the GetIt-based online installer, we recommend downloading and applying the patch, as it will help prevent unintended modification of your installation files. The executable fils are signed, so they are not affected, but other text and intermediate binary files could be.

This patch consists of a simple tool that scans the folders of your recent RAD Studio installations and updates the file permissions with more limited access, preventing modifications of those files without full administrator access or elevated access to the computer. Alternatively, you can select the application folder and manually tune its permissions for increased security by removing the Modify and Write permissions and setting the files as read only (preserving the execution privilege, if assigned).

For downloads, refer to  https://cc.embarcadero.com/item/30850  (broadly available to all registered users).


Read More

RAD Studio 10, 10.1, 10.2 向けファイルパーミッションパッチをリリースしました [JAPAN]

$
0
0

この記事は、Marco Cantu によるRAD Studio 10.x Files Permissions Patch Releasedの抄訳です。

 

エンバカデロは、Delphi/C++Builder/RAD Studio 向けのファイルパーミッションパッチをリリースしました。これは、GetIt Webベースのインストーラを使用してインストールされたRAD Studio 10,10.1.xおよび10.2.xのすべてのバージョンに適用されます。


Read More

Уточнение планов: RAD Studio August 2018 Roadmap

$
0
0

Не секрет, что планы следует корректировать. Компания Embarcadero регулярно публикует программу развития своих продуктов (Roadmap) на будущее, по которой вы сможете ориентироваться в составе и сроках включения в состав используемых вами инструментов тех или иных полезных или даже необходимых возможностей. К счастью, жизнь также не стоит на месте, и мы регулярно вносим в планы разработку поддержки новых технологий или платформ, а также своевременную адаптацию наших продуктов с использованием самых свежих библиотек и API. Обновленные планы также публикуются на сайте Embarcadero.

На этой неделе был опубликован пост с описанием обновленной дорожной карты для Delphi, C ++ Builder и RAD Studio.(https://community.embarcadero.com/article/news/16638-rad-studio-august-2018-roadmap)  В этой дорожной карте в августе 2018 года зафиксированы планы на вторую часть этого года и основные направления деятельности на следующий год. Правда, пост представлен в виде набора слайдов на английском языке. Поэтому, вслед за этим постом была сделана публикация статьи с комментариями главных менеджеров продуктов к этой дорожной карте. 

В нашей дорожной карте вы можете найти ключевые функции, которые мы запланировали на календарный год 2018/2019. Я приведу список основных запланированных пунктов и пояснения к ним в изложении на русском языке.

2018 год был очень интересным для Embarcadero. Чего удалось достичь? 

Еще в марте мы представили RAD Studio 10.2.3 , также известную как 10.2 Tokyo Release 3 -- Delphi, C ++ Builder и RAD Studio. Это был третий релиз в Токио и включал поддержку CMake Command Line для C ++, Rename Refactoring, поддержку мобильных устройств в Delphi и C ++ Builder Pro, усовершенствования RAD Server, шаблоны пользовательского интерфейса FireMonkey и многое другое. Впервые в нашей практике,  мы выпустили полнофункциональную  Community Edition для Delphi и C ++ Builder . Отличный вариант для осваивающих мощь Delphi или C ++ Builder, поскольку Community Edition обеспечивает отличную отправную точку для разработчиков C ++ по всему миру, чтобы опробовать все, что может предложить C ++ Builder, особенно с точки зрения  многоплатформенных возможностей.

Как видно из нашей дорожной карты, для следующего выпуска основной версии, 10.3 (aka Carnival) запланировано много интересных функций. Основные темы новой версии - расширение языка и платформ для многоуровневых и Windows-разработчиков. Модернизация IDE также продолжится в полном объеме.

Sarina DuPont - отвечает за FireMonkey, UX и стили библиотеки компонентов, а также User Experience. Она рекомендует отметить следующие возможности:

FireMonkey Z-Order и Native Controls

Удивляет, что разработчики могут сделать с помощью инфраструктуры FireMonkey для реализации требований к приложениям, работающих на нескольких устройствах. В своем блоге Сарина постоянно касается темы создания потрясающих пользовательских интерфейсов с помощью FMX. Это область, где FireMonkey действительно нет равных, особенно в сочетании с дизайнером FireUI, уникальным решением в пространстве инструментов разработчика.

Шаблоны пользовательского интерфейса FireMonkey, которые мы выпустили за последние несколько месяцев для разработчиков Delphi и C ++ Builder, не только упрощают создание собственных многоплатформенных приложений, но также демонстрируют гибкость, обеспечиваемую FireMonkey, и как легко настроить темы пользовательского интерфейса, чтобы создать совершенно индивидуальный внешний вид.

В течение нескольких лет мы получили запросы клиентов на поддержку Z-Order и встроенных средств управления на Android. В ответ на них мы активно работаем над поддержкой Android Z-Order в 10.3. Это позволит разработчикам использовать элементы управления FireMonkey, такие как кнопки, ярлыки и флажки, с элементами визуализированного визуализации, такими как браузер и управление картой в той же форме, без встроенного элемента управления, охватывающего стилизованный элемент управления. Это также обеспечивает основу для поддержки применения нативных элементов управления пользовательского интерфейса, таких как TEdit, на Android. В ближайшие недели мы будем приглашать клиентов, с действующей подпиской на обновления в тестирование непубличной бета-версии 10.3, поэтому заинтересованные могут заранее получить представление, как это работает. Мы также планируем расширить поддержку нативных элементов управления Android для большего количества элементов управления в будущих выпусках. 

Поддержка Z-Order для Android будет работать так же, как и для Windows и iOS сегодня, что позволяет разработчикам смешивать элементы управления и элементы управления, созданные базовой ОС, в одной и той же форме без каких-либо проблем.

Еще одна связанная с Android функция, над которой мы работаем, - это модернизация нашей поддержки уровня API Android в RAD Studio для поддержки 26-го уровня (Android 8.0). Это изменение требует значительной переработки и не возможно в виде обновления 10.2. Эта поддержка появится в 10.3. Хотя обычно ограничения на бета-версии не позволяют создавать и развертывать промышленные приложения, пользователи, которые присоединяются к нашей бета-версии 10.3, найдут специальное условие EULA, позволяющее им, при наличии активной подписки на обновления, разворачивать (выпускать) Android-приложения в Google Play Store.

Поддержка новой платформы

Поддержка разных платформ является ключевой для многоплатформенной библиотеки, такой как FireMonkey. Мы знаем, что поддержка Android на 64-битной основе станет обязательной к лету 2019 года, поэтому будем работать для обеспечения того, чтобы наши клиенты могли выполнять это требование следующим летом.

Изменение, по сравнению с сентябрьским планом 2017 года, заключается в том, что поддержку 64-битной платформы MacOS была исключена из начальной версии 10.3. Мы удалили его из первого релиза 10.3, чтобы сосредоточиться на обеспечении большего качества и стабильности для других ключевых функций. С учетом сказанного, наша цель - обеспечить поддержку 64-разрядного MacOS, включая поддержку таргетинга на iOS 11 (и iOS 12), в последующем релизе 10.3.x. Мы не забыли, что разработчикам, которые хотят настроить MacOS App Store или использовать 64-битные API-интерфейсы, требуется поддержка 64-разрядных файлов MacOS.

Что касается перспектив, то пару месяцев назад Apple объявила, что отказывается от поддержки OpenGL в пользу новой библиотеки GPU от Metal 2. Хотя OpenGL будет продолжать поддерживаться в следующих версиях macOS и iOS, мы рассмотрим, что потребуется для поддержки Metal в следующем году.

Marco Cantu - отвечает за развития Delphi и RTL, библиотеки VCL и интеграции в Windows, всех баз данных и веб-ориентированных инструментов, включая RAD Server

VCL и Windows

Хотя за последние несколько лет RAD Studio и Delphi расширяли свои возможности в области разработки приложений для разных и мобильных устройств с использованием единого исходного кода и скомпилированных приложений, продукт по прежнему базируется в Windows. В последние годы мы уделяем особое внимание VCL - лучшем наборе компонентов для клиентских приложений Windows. В каждом выпуске мы добавляли новые компоненты и элементы управления.

Сегодня VCL предлагает отличную поддержку Win32 API, а также интеграцию с новым WinRT API для Windows 10. У нас есть новые элементы управления с современным пользовательским интерфейсом, стиль и отличный переход к современному UX при сохранении большей части вашего существующего исходного кода. Кроме того, IDE интегрируется с Desktop Bridge для создания приложений UWP, которые можно распространять через Windows Store.

Мы будем продолжать и увеличивать инвестиции в эту область, расширим охват API Win32, учитывая, что Microsoft добавила к нему важные подсистемы, сосредоточимся на постоянном улучшении нашей поддержки мониторов High-DPI и 4K в Windows. В связи с этим мы собираемся представить новый элемент управления списком изображений, который может управлять изображениями с несколькими разрешениями, аналогично тому, что мы делаем в FireMonkey. Это позволит приложению вместо использования масштабирования изображения (что часто отрицательно сказывается на качестве изображения), выбрать наилучшее изображение для текущего разрешения экрана. Что касается поддержки High-DPI, мы работаем над новым режимом «Per-Monitor V2» в Windows 10 и планируем сосредоточиться на решении большого количества проблем, которые присутствуют в текущей поддержке нескольких мониторов.

 Развитие языка Delphi и RTL

Помимо фокуса на поддержке Windows 10 (как для Delphi, так и для C ++ Builder), есть много других функций, над которыми мы работаем для включения в Delphi. Мы планируем выпускать новые конструкции языка поэтапно, так как стабильность на уровне компилятора имеет решающее значение. Мы выяснили, что качественная поддержка nullable типов (запланированных, но отложенных) требует изменений в других областях языка. Перед этим мы займемся custom managed records, то есть возможностью определять конструктор по умолчанию без параметров, деструктор и оператор копирования для любого типа записи. Это сильно расширяет возможности для записей, очень приятную дополнительную функцию для классов и объектов.

Что касается библиотеки времени выполнения (RTL), то основное внимание будет уделяться производительности и качеству, нежели расширению функций. От generics списков до больших данных в памяти, от обработки JSON до клиентской библиотеки HTTP, мы мы нашли много перспектив для улучшений и уверены, что каждый клиент будет доволен, потому что, если вы создаете клиентское приложение или серверное, независимо от того, используете мобильные или настольные платформы, увеличить производительность всегда хорошо.

Повышение производительности RTL также помогает улучшению RAD Server. Уже после выхода 10.2.3 мы выпустили обновление для повышения внутренней производительности нашего механизма REST API, в основном ориентированного на внутренние элементы и улучшенное управление памятью в случае обильной многопоточности. Пока в обновление не попало повышение производительность пользовательских модулей RAD Server. Это будет сделано в следующем выпуске, за счет ускорения обработки JSON, обработки строк, класса TStringBuilder и ряда основных классов. Кроме того, важно, чтобы службы JSON и HTTP лучше поддерживали все стандарты и протоколы, включая пограничные сценарии, которые используют другие HTTP-серверы или клиенты.

RAD Server

Для RAD Server мы запланировали намного больше доработок. В следующем релизе будет капитально пересмотрен логики RAD-сервера, которая будет использоваться для сопоставления входящего HTTP-запроса с внутренним ресурсом (т.е. предоставления метода класса для обработки вызовов метода HTTP). До сих пор отображение основано только на URL-адресе, и оно было довольно жестким. Теперь мы планируем добавить возможность учитывать другие параметры HTTP-запроса, такие как Content Type, Accepts, расширения файлов и т.д., чтобы обеспечить более сложное сопоставление. Например, один и тот же URL-адрес может возвращать структуру данных JSON, изображение или PDF в зависимости от контекста вызова. Кроме того, в то время как сегодня вам часто приходится повторять один и тот же код для обработки запросов снова и снова, вы сможете делегировать фактическую реализацию запроса ресурса отдельному компоненту, используя один и тот же код для нескольких запросов и уменьшая объем кода.

Это будет практически новая версия RAD Server, которая сочетается с изменениями лицензирования (лицензии на развертывание теперь включены в старшие редакции). Мы уверены, что этому механизму реализации API REST уделят больше внимания и усилий.

Дэвид Миллингтон - отвечает за развитие поддержки C ++, отладчика, IDE и его пользовательского интерфейса

C ++

В двух последних релизах RAD Studio мы представили несколько отличных инструментов для разработчиков на C ++. Сначала rename refactoring - наш первый рефакторинг на C++. Это один из самых распространенных рефакторингов и значительно ускоряет работу и делает более согласованным общий проект. Во-вторых, мы ввели поддержку CMake для командной строки для C++Builder. Это первый из нескольких запланированных по поддержке CMake шагов, который  явно поддерживает использование Ninja для ускорения сборок. Вы можете настроить сборку на Windows, iOS и Android, включая развертывание на устройстве, все из CMake.

Мы представим наш обновленный компилятор, совместимый с C++ 17. Сначала для одной платформы (Win32), а затем и для других, поскольку мы хотим поддерживать один и тот же уровень на всех платформах. Когда будет выпущена поддержка macOS 64, там также будет использована эта новая версия. Мы продолжим обновлять набор инструментов компилятора (toolchain) в соответствии с текущей версией Clang, что означает, что наши пользователи получат преимущества как оптимизации, так и языковой поддержки Clang, а также расширения языка и обеспечения нашей среды.

Одновременно с этим выйдут новая версия C ++ 17 Dinkumware STL и повышение производительности.

Мы также планируем расширение поддержки CMake, представленной в 10.2.2. Эта поддержка была только для командной строки. В конечном счете, мы планируем дальнейшую интеграцию, чтобы очень легко импортировать проект CMake в среду разработки и собирать его. Одновременно обеспечивать, чтобы стандартные библиотеки C++ всегда работали с C++Builder (не сложно, у нас отличная языковая совместимость) и добавить их в GetIt, наш менеджер пакетов. В конечном счете, любой пользователь C++, знаток нашей экосистемы разработки или нет, должен очень легко использовать любое приложение или библиотеку по их выбору в C++ Builder. И наши пользователи должны легко применять любую C++-библиотеку в своих приложениях.

Наконец, некоторые читатели, возможно, видели недавнее сообщение о том, что Idera приобрела Whole Tomato. Whole Tomato делает Visual Assist, расширение Visual Studio, которое, возможно, является лучшим дополнением к инструментарию C++ для любого IDE. Он дает прекрасные инструменты анализа кода, рефакторинг и другие инструменты. Пользователи Visual Assist могут полагаться на его непрерывную разработку для Visual Studio - это отличный автономный инструмент, которому мы желаем развиваться и процветать - и мы также планируем интегрировать некоторые ключевые части в C++ Builder.

IDE

RAD Studio IDE ежедневно используется десятками тысяч пользователей Delphi и C++Builder. Недавно, в 10.2.2, мы добавили новую темную тему для IDE и редактора кода - это одно из наших самых популярных дополнений, встреченного энтузиазмом со стороны большого числа наших пользователей.

В 10.3.x мы планируем ряд усовершенствований IDE, как для UX (работа пользователей), так и для функциональности.

За последние несколько лет в IDE произошло много расширений и изменений. Но способ, которым они реализуются в пользовательском интерфейсе, не всегда самый удобный. В 10.3 мы планируем некоторые минимальные усовершенствования UX, которые должны сделать среду IDE значительно более приятной и удобной для использования в течение нескольких часов подряд. Многие диалоги получат улучшения и реорганизацию, а конечный результат - значительно функционально лучше, но также выглядит намного приятнее.  

Мы также интегрируем ряд продуктов из пакета IDE Fix Pack от Andreas Hausladen, на который мы получили лицензию в начале этого года.

В долгосрочной перспективе планируются и другие улучшения. Мы потратили довольно много времени на code completion и другие инструменты работы с кодом и значительные улучшения, запланированные как для Delphi, так и для C ++.

Наконец, мы также уделяем большое внимание лучшей поддержке high DPI в среде IDE. Было уже сказано о значительных улучшениях high DPI в VCL, а RAD Studio IDE, в основном, написана в Delphi и C++Builder, и большинство пользовательских интерфейсов построено с использованием VCL. Мы надеемся также использовать усовершенствования VCL в среде IDE, хотя это будет сделано осторожно и не сразу.

Отладчик

Обычно мы ничего не пишем об отладчике в блогах.Отладчик просто делает свою работу для вас каждый день , молча и тихо обновляется по мере работы над набором инструментов.

Тем не менее, у нас запланированы большие улучшения. На мобильных платформах мы используем сочетание LLDB и GDB в зависимости от платформы. LLDB - это путь вперед, и мы будем работать над интеграцией интерфейса Delphi (понимание языка), прежде чем использовать LLDB на других платформах. Конечный результат, как планируется, будет более быстрым и мощным отладчиком, который также понимает и может интерпретировать больше операторов Delphi. Естественно, C++ тоже пользуется этим.

В общем и целом

У нас запланированы большие улучшения: C++17, расширенная поддержка CMake, усовершенствование отладчика, языковые инструменты, новые функции FireMonkey и поддержка новых платформ (64-разрядные MacOS и Android), нативные элементы управления Android, улучшения HighDPI, RAD Server, функций языка Delphi, отличный UX и улучшения в среде IDE.

Важно!. Эти планы и дорожная карта представляют собой наши намерения на эту дату, но наши планы развития и приоритеты могут быть изменены. Соответственно, мы не берем какие-либо обязательства или другие формы гарантий в том, что в конечном итоге мы выпустим какие-то или все описанные продукты в сроки, или в описанном порядке, или вообще.


Read More
Viewing all 1683 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>