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.
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.
| Edice | Určení |
|---|---|
| Community | Zdarma pro jednotlivce, studenty a malé firmy (omezená komerční licence). Plné IDE pro Windows. |
| Professional | Komerční vývoj desktopových aplikací s lokálním přístupem k datům. |
| Enterprise | Přidává klient/server databáze, FireDAC ovladače a RAD Server. |
| Architect | Nejvyšší 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
#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
#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
#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!");
}
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álost | Kdy nastane |
|---|---|
| OnCreate | Při vytvoření formuláře — inicializace. |
| OnShow | Těsně před zobrazením. |
| OnActivate | Když formulář získá fokus. |
| OnCloseQuery | Dotaz, zda smí být zavřen (lze zrušit). |
| OnClose | Při zavírání — úklid. |
Zobrazení druhého formuláře
#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í
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…).
| Komponenta | Použití |
|---|---|
| TLabel | Statický popisek (Caption). |
| TEdit | Jednořádkové textové pole (Text). |
| TMemo | Víceřádkový text (Lines). |
| TButton | Tlačítko (OnClick). |
| TCheckBox | Zaškrtávátko (Checked). |
| TComboBox | Rozbalovací seznam (Items, ItemIndex). |
| TListBox | Seznam položek. |
| TStringGrid | Mřížka řetězců (Cells[c][r]). |
Čtení a zápis hodnot
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
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
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:
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;
}
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().
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é");
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.
| Funkce | Vý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. |
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());
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
// 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ávy | Ikona |
|---|---|
| mtInformation | Informace. |
| mtWarning | Varování. |
| mtError | Chyba. |
| mtConfirmation | Otá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
// 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
#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));
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.
#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
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).
#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)
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;
}
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.
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
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
}
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šší)
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
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í
}
};
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.
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
| Zkratka | Akce |
|---|---|
| F9 | Spustit s laděním. |
| Shift+Ctrl+F9 | Spustit bez ladění. |
| F8 / F7 | Krok přes / do funkce (debugger). |
| F5 | Přepnout breakpoint na řádku. |
| F11 | Object Inspector. |
| F12 | Přepnutí formulář ⇄ kód. |
| Ctrl+Shift+C | Doplnit deklaraci/definici metody. |
| Ctrl+Space | Nápověda dokončování kódu. |
| Ctrl+Shift+↑ / ↓ | Skok mezi deklarací a implementací. |
| Ctrl+kliknutí | Přejít na definici symbolu. |
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.