Formatierte, gedrehte, mehrzeilige Textausgabe

void __fastcall StringGridRotateTextOut(TStringGrid *Grid, int ARow, int ACol, TRect Rect, AnsiString sOutput, AnsiString sFontName, TColor clFontColor, int iFontSize, int iRotation)
{
     Grid->Canvas->Font->Name = sFontName;
     Grid->Canvas->Font->Size = iFontSize;
     Grid->Canvas->Font->Color = clFontColor;

     // neue Schrift für die gedrehte Ausgabe zusammenbauen
     TFont *tf = new TFont();
     TLogFont lf;
     tf->Assign(Grid->Canvas->Font);
     GetObject(tf->Handle, sizeof(lf), &lf);
     lf.lfEscapement = iRotation * 10;
     lf.lfOrientation = 0;
     HFONT hfont = CreateFontIndirect(&lf);
     tf->Handle = hfont;
     Grid->Canvas->Font->Assign(tf);
     delete tf;

     // Zelle malen
     Grid->Canvas->FillRect(Rect);
     // Text ausgeben
     // Beachten: abhängig vom Drehwinkel muss die X- und Y-Koordinate richtig gesetzt werden!
     // bei 90° z.B. Rect.Left + 2, Rect.Bottom - 2
     // DrawText bietet u.A. die Möglichkeit Text mehrzeilig (DT_WORDBREAK) auszugeben
     DrawText(Grid->Canvas->Handle, sOutput.c_str(), -1, &Rect, DT_VCENTER | DT_CENTER | DT_WORDBREAK);

     // Textausgabe könnte anstatt mit DrawText auch mit TextRect erfolgen,
     // es ist hierbei aber keine mehrzeilige Ausgabe möglich
     // Grid->Canvas->TextRect(Rect, Rect.Left + 2, Rect.Top + 2, sOutput);
}

void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect, TGridDrawState State)
{
     TStringGrid *Grid = (TStringGrid *)Sender;
     Grid->Canvas->Font->Color = clBlack;

     if (ACol == 0)
     {
        // 1. Spalte "normal" fett und schwarz zeichnen
        Grid->Canvas->Font->Style = TFontStyles() << fsBold;
        Grid->Canvas->FillRect(Rect);
        DrawText(Grid->Canvas->Handle, Grid->Cells[ACol][ARow].c_str(), -1, &Rect, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
     }
     else
     {
         // alle anderen Spalten gedreht und verkleinert zeichnen
         Grid->Canvas->Font->Style = TFontStyles() >> fsBold;
         AnsiString sOutput = Grid->Cells[ACol][ARow] + "\n" + "noch eine Zeile :)";
         StringGridRotateTextOut(Grid, ARow, ACol, Rect, sOutput , "Arial", clBlack, 6, -10);
     }
}

Zwischenablage verwenden

#include <Clipbrd.hpp>

// Zwischenablage löschen
Clipboard()->Clear();

// Text in Zwischenablage kopieren
char caText[80] = "Testtext";
Clipboard()->SetTextBuf(caText);

// Text aus der Zwischenablage kopieren
char caTextBuffer[1024];
Clipboard()->GetTextBuf(caTextBuffer, sizeof(caTextBuffer));
AnsiString sOutput = caTextBuffer;

C – Logdatei schreiben

#include <stdio.h>
#include <stdlib.h>

/* Textfile zum Schreiben und Anfügen öffnen */
FILE *f = fopen("c:\\logfile.log", "a+t");

if (f != NULL)
{
    float fValue = 0.1;

    /* eine Zeile in die Datei schreiben */
    /* siehe auch: http://www.cplusplus.com/reference/clibrary/cstdio/fprintf/ */
    fprintf(f, "value:%f\n", fValue);

    /* Datei schließen */
    fclose(f);
}

Verwendung von _TCHAR, wchar_t (Unicode)

Ein schöner Artikel zum Thema befindet sich hier: Link

Zu beachten: Unicode/Multibyte-Einstellung unter Projekt->Eigenschaften->Konfigurationseigenschaften->Allgemein->Zeichensatz

#include <tchar.h> // meist in stdafx.h

// Anwendung, wobei die Makros _T und _TEXT identisch sind
wchar_t wcText[] = _T("Unicode-Text");

oder

wchar_t wcText[] = _TEXT("Unicode-Text");

AnsiString in Teile (Tokens) splitten, ähnlich explode() bei PHP

TStringList *slTokens = new TStringList();

AnsiString sData = "Meier, Schulze, Lehmann";

// sData in Tokens aufsplitten und führende und folgende Leerzeichen trimmen
Explode(sData, ",", slTokens, true);

...
irgendwas mit slTokens machen
...

delete sl;

void __fastcall Explode(AnsiString sData, AnsiString sSeparator, TStringList *slTokens, bool bTrim)
{
    // wurde eine Liste übergeben?
    if (slTokens != NULL)
    {

        if (bTrim)
        {
           sData = sData.Trim();
        }

        // Datenstring nicht leer?
        while (sData.Length() > 0)
        {
            // ersten Separator im String suchen
            int iPos = sData.Pos(sSeparator);
            
            // wenn Separator gefunden
            if (iPos -> 0)
            {
                // vorderen Stringteil (Token) in Liste einfügen
                slTokens->Add(sData.SubString(0, iPos - 1));
                // Reststring für neue Suche kürzen
                sData = sData.SubString(iPos + 1, sData.Length() - iPos);

                if (bTrim)
                {
                    sData = sData.Trim();
                }
            }
            else
            {
                // nur noch ein Token
                slTokens->Add(sData);
                // Reststring ist leer, führt zu Abbruch der while-Schleife
                sData = "";
            }
        }
    }
}

[Linker Error] XYZ.LIB contains invalid OMF record, type 0x21 (possibly COFF)

Die im Projekt verwendete Bibliothek (*.lib) ist vom falschen Typ (z.B. mit Visual Studio erstellt). Mit dem Konvertierungsprogramm coff2omf.exe (CBuilder/bin) kann diese konvertiert werden.

  • evtl. xyz.lib sichern
  • xyz.lib und coff2omf.exe in einen gemeinsamen temporären Ordner kopieren
  • coff2omf.exe xyz.lib xyz2.lib
  • die neue xyz2.lib ins Projektverzeichnis kopieren und einbinden/verwenden

Richtiger Vergleich von floating-point-Werten

#include <math.h> // für fabs()

float f1 = 0.11111111111;
float f2 = 0.1111111111;

// um Rundungsfehler zu umgehen sollte man mit einer
// Epsilon-Schranke (minimaler Abstand) arbeiten
// im Beispiel beträgt diese Schranke 1E-5
if (fabs(f1 - f2) < 1E-5)
{
    // f1 gleich f2
}

// verbesserte Version:
if (fabs(f1 - f2) < 1E-5 * f1)
{
    // f1 gleich f2
}

C – Datenwerte (float) aus einer Textdatei lesen und umwandeln

#include <stdio.h>
#include <stdlib.h>

/* Textfile zum Lesen öffnen */
FILE *f = fopen("myfile.txt", "rt");

if (f != NULL)
{
    /* Puffer mit 20 Zeichen */
    char buf[20];

    /* 25 Zeilen lesen */
    for (int d = 0; d < 25; d++)
    {
        /* eine Zeile mit max. 20 Zeichen aus dem File in den Puffer einlesen */
        if (fgets(buf, 20, f) != NULL)
        {
            /* Zeichenkette in float wandeln, Dezimalseparator muss '.' sein */
            float fVal = atof(buf);
        }
    }

    /* Datei schließen */
    fclose(f);
}