Embarcadero · RAD Studio

C++Builder 2026
Referenční příručka

Praktický přehled jazyka, VCL frameworku a nejčastějších úloh — s hotovými příklady kódu, které stačí zkopírovat do editoru.

Verze 13 „Florence" C++ 23 · Clang VCL FMX FireDAC

01 — Základ

Úvod a přehled

C++Builder je vývojové prostředí (IDE) firmy Embarcadero pro tvorbu nativních aplikací v moderním C++ pomocí vizuálního návrháře formulářů a rozsáhlé knihovny komponent.

Aplikace se skládá vizuálně: komponenty přetáhnete na formulář, vlastnosti nastavíte v Object Inspectoru a chování dopíšete do obslužných metod událostí. Ke kódu máte dva hlavní frameworky:

  • VCL (Visual Component Library) — nativní Windows komponenty, nejrychlejší cesta k desktopové aplikaci pro Windows.
  • FMX / FireMonkey — multiplatformní framework s GPU vykreslováním (Windows, macOS, iOS, Android) a jednotným vzhledem přes styly.

Tato příručka se zaměřuje především na VCL, protože je pro Windows aplikace nejběžnější. Většina jazykových příkladů (řetězce, výjimky, kolekce, vlákna) platí v obou frameworcích.

Tip

Typ String v C++Builderu je alias pro System::UnicodeString — Unicode řetězec indexovaný od 1, nikoli od 0 jako u std::string.

02 — Prostředí

Verze a edice

Aktuální řada nese kódové jméno „Florence" (C++Builder 13) a je dodávána jako současná verze roku 2025/2026. Přináší toolchain postavený na Clangu pro Win64 a podporu standardu C++23.

EdiceUrčení
CommunityZdarma pro jednotlivce, studenty a malé firmy (omezená komerční licence). Plné IDE pro Windows.
ProfessionalKomerční vývoj desktopových aplikací s lokálním přístupem k datům.
EnterprisePřidává klient/server databáze, FireDAC ovladače a RAD Server.
ArchitectNejvyšší edice s modelovacími a databázovými nástroji.

C++Builder je také součástí balíku RAD Studio společně s Delphi. Frameworky VCL i FMX jsou v obou jazycích sdílené.


03 — Projekt

Struktura projektu

Projekt (.cbproj) sdružuje jednotky. Každý formulář má tři soubory: hlavičku .h (deklarace třídy), implementaci .cpp a návrh .dfm (rozložení komponent, spravuje IDE).

Vstupní bod aplikace

Project1.cpp
#include <vcl.h>
#pragma hdrstop
#include <tchar.h>

USEFORM("Unit1.cpp", Form1);

int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    try {
        Application->Initialize();
        Application->MainFormOnTaskBar = true;
        Application->CreateForm(__classid(TForm1), &Form1);
        Application->Run();
    }
    catch (Exception &e) {
        Application->ShowException(&e);
    }
    return 0;
}

Hlavička formuláře

Unit1.h
#ifndef Unit1H
#define Unit1H

#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>

class TForm1 : public TForm
{
__published:              // komponenty spravované IDE
    TButton *Button1;
    void __fastcall Button1Click(TObject *Sender);
private:                  // vlastní deklarace
public:                   // vlastní deklarace
    __fastcall TForm1(TComponent* Owner);
};

extern PACKAGE TForm1 *Form1;
#endif

Implementace

Unit1.cpp
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"

#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;

__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    ShowMessage(L"Ahoj z C++Builderu!");
}
Klíč

Metody napojené na návrhář jsou vždy void __fastcall a mají parametr TObject *Sender — odkaz na komponentu, která událost vyvolala.


04 — Formuláře

Formuláře

Formulář (TForm) je okno aplikace. Kromě hlavního formuláře můžete zobrazovat další, buď nemodálně (Show) nebo modálně (ShowModal).

Události životního cyklu

UdálostKdy nastane
OnCreatePři vytvoření formuláře — inicializace.
OnShowTěsně před zobrazením.
OnActivateKdyž formulář získá fokus.
OnCloseQueryDotaz, zda smí být zavřen (lze zrušit).
OnClosePři zavírání — úklid.

Zobrazení druhého formuláře

Unit1.cpp
#include "Unit2.h"   // hlavička druhého formuláře

void __fastcall TForm1::OtevritClick(TObject *Sender)
{
    // Modální dialog — čeká na uzavření a vrací výsledek
    if (Form2->ShowModal() == mrOk) {
        ShowMessage(L"Uživatel potvrdil: " + Form2->Edit1->Text);
    }
}

Potvrzení při zavírání

Unit1.cpp
void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
    CanClose = MessageDlg(L"Opravdu ukončit aplikaci?",
                          mtConfirmation,
                          TMsgDlgButtons() << mbYes << mbNo, 0) == mrYes;
}

05 — Komponenty

Vizuální komponenty

Komponenty přidáte přetažením z Tool Palette. Za běhu k nim přistupujete přes ukazatel a nastavujete vlastnosti (Caption, Text, Enabled, Visible…).

KomponentaPoužití
TLabelStatický popisek (Caption).
TEditJednořádkové textové pole (Text).
TMemoVíceřádkový text (Lines).
TButtonTlačítko (OnClick).
TCheckBoxZaškrtávátko (Checked).
TComboBoxRozbalovací seznam (Items, ItemIndex).
TListBoxSeznam položek.
TStringGridMřížka řetězců (Cells[c][r]).

Čtení a zápis hodnot

Unit1.cpp
void __fastcall TForm1::SecistClick(TObject *Sender)
{
    // Edit -> číslo, výpočet, výsledek do Label
    int a = StrToIntDef(Edit1->Text, 0);
    int b = StrToIntDef(Edit2->Text, 0);
    Label1->Caption = L"Součet: " + IntToStr(a + b);

    // Zaškrtávátko ovládá dostupnost tlačítka
    Button2->Enabled = CheckBox1->Checked;
}

Naplnění seznamu a práce s Memo

Unit1.cpp
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    ComboBox1->Items->Add(L"Praha");
    ComboBox1->Items->Add(L"Brno");
    ComboBox1->Items->Add(L"Ostrava");
    ComboBox1->ItemIndex = 0;          // předvybraná položka

    Memo1->Lines->Add(L"První řádek");
    Memo1->Lines->Add(L"Druhý řádek");
}

void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
    if (ComboBox1->ItemIndex >= 0)
        Label1->Caption = L"Vybráno: " + ComboBox1->Text;
}

Mřížka TStringGrid

Unit1.cpp
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    StringGrid1->ColCount = 3;
    StringGrid1->RowCount = 2;
    StringGrid1->FixedRows = 1;                 // záhlaví
    StringGrid1->Cells[0][0] = L"ID";
    StringGrid1->Cells[1][0] = L"Jméno";
    StringGrid1->Cells[2][0] = L"Město";
    StringGrid1->Cells[0][1] = L"1";
    StringGrid1->Cells[1][1] = L"Jan Novák";
    StringGrid1->Cells[2][1] = L"Praha";
}

06 — Události

Události

Obslužnou metodu vytvoříte dvojklikem na komponentu nebo v Object Inspectoru na kartě Events. Kód se pak spustí, když událost nastane.

Přiřazení obsluhy za běhu

Handler nemusí být z návrháře — lze jej přiřadit i v kódu, i více komponentám najednou:

Unit1.cpp
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    // Stejná obsluha pro tři tlačítka
    Button1->OnClick = SpolecnyClick;
    Button2->OnClick = SpolecnyClick;
    Button3->OnClick = SpolecnyClick;
}

void __fastcall TForm1::SpolecnyClick(TObject *Sender)
{
    // Sender rozliší, které tlačítko událost vyvolalo
    TButton *btn = dynamic_cast<TButton*>(Sender);
    if (btn)
        Label1->Caption = L"Stiskl jsi: " + btn->Caption;
}
Pozor

Metoda musí být v hlavičce deklarovaná se stejnou signaturou (void __fastcall Metoda(TObject *Sender)), jinak ji nelze přiřadit do vlastnosti typu TNotifyEvent.


07 — Text

Řetězce (String)

Typ String (= UnicodeString) je hlavní řetězcový typ VCL. Znaky se indexují od 1 a délku vrací metoda Length().

ukazka.cpp
String s = L"C++Builder";

int n       = s.Length();          // 10
Char první  = s[1];                // 'C'  (indexováno od 1!)
String část = s.SubString(1, 3);   // "C++"  (pozice, délka)
int pozice  = s.Pos(L"Build");     // 4     (0 = nenalezeno)

String velká = s.UpperCase();      // "C++BUILDER"
String malá  = s.LowerCase();      // "c++builder"
String bezMezer = String(L"  text  ").Trim();   // "text"

// Spojování
String celek = L"Ahoj, " + s + L"!";

// Náhrada podřetězce
String r = StringReplace(L"a-b-c", L"-", L"/",
                         TReplaceFlags() << rfReplaceAll);  // "a/b/c"

// Porovnání
if (s.CompareIC(L"c++builder") == 0)   // bez ohledu na velikost
    ShowMessage(L"Shodné");
Tip

Předpona L"…" značí wide literál. U přiřazení do String se převod provede automaticky, ale L je bezpečnější pro diakritiku.


08 — Konverze

Konverze a formátování

Pro převody mezi čísly a řetězci slouží globální funkce z jednotky System.SysUtils.

FunkceVýznam
IntToStr(n)Celé číslo → řetězec.
StrToInt(s)Řetězec → int (vyhodí výjimku při chybě).
StrToIntDef(s, d)Jako výše, ale vrátí d místo výjimky.
FloatToStr(x)Desetinné číslo → řetězec.
StrToFloat(s)Řetězec → double.
IntToHex(n, m)Číslo → hexadecimální řetězec.
FormatFloat(fmt, x)Formátování s maskou.
ukazka.cpp
int    n = StrToIntDef(L"42", 0);
double x = StrToFloat(L"3,14");         // pozor na desetinnou čárku dle lokalizace

String a = IntToStr(255);               // "255"
String b = IntToHex(255, 2);            // "FF"
String c = FormatFloat(L"0.00", 3.1);   // "3,10"

// Format s poli argumentů (ARRAYOFCONST)
String zprava = Format(L"%s má %d let a měří %.1f m",
                       ARRAYOFCONST((String(L"Jan"), 30, 1.82)));
// -> "Jan má 30 let a měří 1,8 m"

// Datum a čas
String dnes = FormatDateTime(L"d.m.yyyy hh:nn", Now());
Pozor

StrToFloat respektuje regionální nastavení Windows. V českém prostředí očekává desetinnou čárku. Pro pevný formát použijte StrToFloat(s, formatSettings).


09 — Dialogy

Dialogy a zprávy

ukazka.cpp
// Jednoduchá informace
ShowMessage(L"Hotovo.");

// Dotaz s tlačítky – vrací mrYes / mrNo / mrCancel …
int odp = MessageDlg(L"Uložit změny?", mtConfirmation,
                     TMsgDlgButtons() << mbYes << mbNo << mbCancel, 0);
if (odp == mrYes) { /* uložit */ }

// Vstup od uživatele
String jmeno = InputBox(L"Přihlášení", L"Zadej jméno:", L"");

// Otevření souboru
if (OpenDialog1->Execute()) {
    Memo1->Lines->LoadFromFile(OpenDialog1->FileName);
}

// Uložení souboru
if (SaveDialog1->Execute()) {
    Memo1->Lines->SaveToFile(SaveDialog1->FileName);
}
Typ zprávyIkona
mtInformationInformace.
mtWarningVarování.
mtErrorChyba.
mtConfirmationOtázka / potvrzení.

10 — Data

Kolekce a seznamy

Pro seznamy řetězců je nejpraktičtější TStringList. Pro obecná data se v C++Builderu běžně používají i standardní kontejnery STL (std::vector, std::map).

TStringList

ukazka.cpp
// std::unique_ptr zajistí automatické uvolnění
std::unique_ptr<TStringList> seznam(new TStringList());

seznam->Add(L"banán");
seznam->Add(L"jablko");
seznam->Add(L"citron");
seznam->Sort();                       // abecedně

for (int i = 0; i < seznam->Count; i++)
    Memo1->Lines->Add(seznam->Strings[i]);

bool jeTam = seznam->IndexOf(L"jablko") >= 0;

// Klíč=hodnota páry
seznam->Values[L"barva"] = L"červená";
String v = seznam->Values[L"barva"];   // "červená"

STL kontejnery

ukazka.cpp
#include <vector>
#include <map>

std::vector<int> čísla = { 3, 1, 2 };
čísla.push_back(4);

std::map<String, int> věk;
věk[L"Jan"] = 30;
věk[L"Eva"] = 25;

for (const auto &p : věk)
    Memo1->Lines->Add(p.first + L": " + IntToStr(p.second));
Tip

VCL objekty (potomci TObject) je nutné rušit přes delete, nebo je svěřit vlastníkovi (Owner) či std::unique_ptr. STL kontejnery se uvolňují samy.


11 — Soubory

Práce se soubory

Nejrychlejší je jednotka System.IOUtils se statickými třídami TFile, TDirectory a TPath.

ukazka.cpp
#include <System.IOUtils.hpp>

// Zápis a čtení celého textu
TFile::WriteAllText(L"C:\\data\\poznamka.txt", L"Obsah souboru");
String text = TFile::ReadAllText(L"C:\\data\\poznamka.txt");

// Existence
if (TFile::Exists(L"C:\\data\\poznamka.txt")) { /* ... */ }

// Sestavení cesty nezávisle na platformě
String cesta = TPath::Combine(L"C:\\data", L"poznamka.txt");

// Výpis souborů ve složce
TStringDynArray soubory = TDirectory::GetFiles(L"C:\\data", L"*.txt");
for (const String &f : soubory)
    Memo1->Lines->Add(f);

Proudové čtení po řádcích

ukazka.cpp
std::unique_ptr<TStringList> řádky(new TStringList());
řádky->LoadFromFile(L"C:\\data\\seznam.csv");

for (int i = 0; i < řádky->Count; i++) {
    String r = řádky->Strings[i];
    // zpracování řádku...
}

12 — Databáze

Databáze (FireDAC)

FireDAC je univerzální knihovna pro přístup k databázím (SQLite, InterBase, PostgreSQL, MySQL, MSSQL, Oracle…). Základ tvoří TFDConnection (spojení) a TFDQuery (dotaz).

ukazka.cpp
#include <FireDAC.Comp.Client.hpp>

// Připojení k SQLite
FDConnection1->DriverName = L"SQLite";
FDConnection1->Params->Values[L"Database"] = L"C:\\data\\firma.db";
FDConnection1->Connected = true;

// SELECT s parametrem (chrání před SQL injection)
FDQuery1->SQL->Text = L"SELECT id, jmeno, mesto "
                     L"FROM zakaznici WHERE mesto = :mesto";
FDQuery1->ParamByName(L"mesto")->AsString = L"Praha";
FDQuery1->Open();

while (!FDQuery1->Eof) {
    String jmeno = FDQuery1->FieldByName(L"jmeno")->AsString;
    int    id    = FDQuery1->FieldByName(L"id")->AsInteger;
    Memo1->Lines->Add(IntToStr(id) + L" — " + jmeno);
    FDQuery1->Next();
}
FDQuery1->Close();

Zápis dat (INSERT)

ukazka.cpp
FDConnection1->ExecSQL(
    L"INSERT INTO zakaznici (jmeno, mesto) VALUES (:j, :m)",
    ARRAYOFCONST((String(L"Petr Svoboda"), String(L"Brno"))));

// Nebo v transakci pro více příkazů
FDConnection1->StartTransaction();
try {
    FDConnection1->ExecSQL(L"UPDATE ucty SET zustatek = zustatek - 100 WHERE id = 1");
    FDConnection1->ExecSQL(L"UPDATE ucty SET zustatek = zustatek + 100 WHERE id = 2");
    FDConnection1->Commit();
}
catch (...) {
    FDConnection1->Rollback();
    throw;
}
Tip

Přidáte-li na formulář TDataSource a napojíte na TFDQuery, můžete data zobrazit vizuálně v TDBGrid bez psaní cyklu.


13 — Chyby

Výjimky

Všechny VCL výjimky dědí od třídy Exception. Zachytávejte je referencí. Pro úklid, který musí proběhnout vždy, slouží borlandovský blok __finally.

ukazka.cpp
try {
    int x = StrToInt(Edit1->Text);      // může vyhodit EConvertError
    double y = 100.0 / x;               // může vyhodit EDivByZero
    Label1->Caption = FloatToStr(y);
}
catch (EConvertError &e) {
    ShowMessage(L"Neplatné číslo: " + e.Message);
}
catch (Exception &e) {                  // obecný VCL základ
    ShowMessage(L"Chyba: " + e.Message);
}

Zaručený úklid a vlastní výjimka

ukazka.cpp
TStringList *list = new TStringList();
try {
    if (list->Count == 0)
        throw Exception(L"Seznam je prázdný");   // vlastní vyvolání
    // ...práce se seznamem...
}
__finally {
    delete list;      // proběhne i při výjimce
}
Tip

Voláním Abort() vyvoláte „tichou" výjimku EAbort — přeruší operaci bez zobrazení chybové hlášky uživateli.


14 — Souběžnost

Vlákna

Dlouhé výpočty patří do vlákna, aby okno nezamrzlo. Vizuální komponenty se ale smějí měnit jen z hlavního vlákna — proto se aktualizace UI obalují do TThread::Synchronize nebo TThread::Queue.

Anonymní vlákno (nejjednodušší)

ukazka.cpp
void __fastcall TForm1::StartClick(TObject *Sender)
{
    Button1->Enabled = false;

    TThread::CreateAnonymousThread([this]() {
        // běží na pozadí
        int soucet = 0;
        for (int i = 1; i <= 1000000; i++)
            soucet += i;

        // aktualizace UI zpět v hlavním vlákně
        TThread::Synchronize(nullptr, [this, soucet]() {
            Label1->Caption = L"Výsledek: " + IntToStr(soucet);
            Button1->Enabled = true;
        });
    })->Start();
}

Vlastní třída TThread

ukazka.cpp
class TVypocet : public TThread
{
protected:
    void __fastcall Execute() override
    {
        while (!Terminated) {
            // ... práce ...
            Queue(nullptr, [this]() {
                Form1->ProgressBar1->Position++;
            });
            Sleep(50);
        }
    }
public:
    __fastcall TVypocet() : TThread(false) {   // false = spustit ihned
        FreeOnTerminate = true;                // vlákno se samo uvolní
    }
};
Pozor

Nikdy nesahejte na Caption, Text a další vlastnosti komponent přímo z běžícího vlákna. Vždy přes Synchronize (počká) nebo Queue (nečeká).



16 — Čas

Časovač

TTimer spouští událost OnTimer v pravidelných intervalech (v milisekundách). Běží v hlavním vlákně, takže smí přímo měnit komponenty.

ukazka.cpp
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    Timer1->Interval = 1000;    // 1 sekunda
    Timer1->Enabled  = true;
}

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    // Aktualizace hodin každou sekundu
    Label1->Caption = FormatDateTime(L"hh:nn:ss", Now());
}

void __fastcall TForm1::StopClick(TObject *Sender)
{
    Timer1->Enabled = false;    // zastavení
}

17 — Produktivita

Klávesové zkratky IDE

ZkratkaAkce
F9Spustit s laděním.
Shift+Ctrl+F9Spustit bez ladění.
F8 / F7Krok přes / do funkce (debugger).
F5Přepnout breakpoint na řádku.
F11Object Inspector.
F12Přepnutí formulář ⇄ kód.
Ctrl+Shift+CDoplnit deklaraci/definici metody.
Ctrl+SpaceNápověda dokončování kódu.
Ctrl+Shift+↑ / ↓Skok mezi deklarací a implementací.
Ctrl+kliknutíPřejít na definici symbolu.
Kai

Novější RAD Studio nabízí integrovaného AI asistenta Kai pro generování kódu, vysvětlení chyb a refaktoring přímo v editoru — s možností volby lokálního i cloudového modelu.