Hintergrundbild auf eine MDI-Form malen

  • MDI Forms bieten standardmäßig keine Möglichkeit darauf Grafik zu malen, man muß sich mit einem eigenen Canvas-Objekt behelfen
  • imgBackImage beinhaltet das Hintergrundbild, das auf die Form kopiert wird
  • Problem dabei ist, dass alle auf der Form befindlichen Objekte übermalt werden, auch die Child-Windows. Man muß also erreichen, dass diese sich alle neu zeichnen.
void __fastcall TfrmMain::RepaintBackGround()
{
    int iTop = 48;
    int iLeft = 0;
    int iWidth = this->Width - iLeft;
    int iHeight = this->Height - iTop;

    TRect SourceRect, DestRect;

    // Ausschnitt aus dem Quellbild definieren
    SourceRect = Rect(0, 0, iWidth, iHeight);

    // Zielrechteck definieren
    DestRect = Rect(iLeft, iTop, iWidth, iHeight);

    TCanvas * FCanvas = new TCanvas();

    if (FCanvas)
    {
        // auf die akt. Form malen
        FCanvas->Handle = GetWindowDC(Handle);
        SetBkMode(FCanvas->Handle, TRANSPARENT);

        // Quelle in das Ziel kopieren
        FCanvas->CopyRect(DestRect, imgBackImage->Picture->Bitmap->Canvas, SourceRect);

        delete FCanvas;
    }
}

Herausfinden, ob große/kleine Schriftarten eingestellt

bool __fastcall TForm1::IsBigFont()
{
    bool bRetVal = true;
    HWND lHwnd; 
    long lPrevMapMode; 
    HDC hdc; 
    TEXTMETRIC tm; 

    lHwnd = GetDesktopWindow(); 
    hdc = GetWindowDC(lHwnd);
    
    if (hdc)
    {
        lPrevMapMode = SetMapMode(hdc, MM_TEXT); 
        GetTextMetrics(hdc, &tm); 
        lPrevMapMode = SetMapMode(hdc, lPrevMapMode); 
        ReleaseDC(lHwnd, hdc);
        bRetVal = (tm.tmHeight -> 16); // true == große Schriftarten, false == kleine Schriftarten
    } 

    return bRetVal;
}

JPEG Kompression

// die Header-Datei jpeg.hpp muss eingebunden sein
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    TJPEGImage *jpg = new TJPEGImage();

    try
    {
        jpg->LoadFromFile("c:Tempsq15.jpg");
        jpg->CompressionQuality = 1; // 1..100
        jpg->DIBNeeded();
        jpg->Compress();
        jpg->SaveToFile("c:Tempcompressed.jpg");
    }
    catch ( ... )
    {
        ShowMessage("Compression error.");
    }

    delete jpg;
}

JPEG Bilder anzeigen

// die Header-Datei jpeg.hpp muss eingebunden sein
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    // JPEG-Bild laden
    TJPEGImage *JPEGImage = new TJPEGImage;
    JPEGImage->LoadFromFile("test.jpg");

    // JPEG-Bild mit einem TImage verknüpfen
    Image1->Width = JPEGImage->Width;
    Image1->Height = JPEGImage->Height;
    Image1->Picture->Assign(JPEGImage);

    delete JPEGImage;
}

Schneller Bitmap-Zugriff per Scanline

// Die normalen Canvas-Zeichenmethoden brauchen viel zu lange,
// um akzeptable Bearbeitungszeiten bei einem Bitmap zu erreichen.
// Besser ist es, man greift direkt auf das Bitmap per Scanline zu.
// im Beispiel wird ein TImage mit dem Namen "Image" und
// PixelFormat = pf24bit auf der MainForm verwendet
void __fastcall TMainForm::TestBtnClick(TObject *Sender)
{
    PRGBTriple srcRow;
    int iHeight = Image->Picture->Bitmap->Height;
    int iWidth = Image->Picture->Bitmap->Width;
    int r,g,b;

    // überprüfen, ob ein 24Bit Bild vorliegt
    if (Image->Picture->Bitmap->PixelFormat == pf24bit)
    {
        try
        {
            // Bild in y-Richtung durchlaufen
            for (int ySrc = 0; ySrc<iHeight; ySrc++)
            {
                // Scanline holen
                srcRow = (PRGBTriple)Image->Picture->Bitmap->ScanLine[ySrc];

                // Scanline durchlaufen (x-Richtung)
                for (int xSrc = 0; xSrc < iWidth; xSrc++)
                {
                    // r,g,b auslesen
                    r = srcRow&#91;xSrc&#93;.rgbtRed;
                    g = srcRow&#91;xSrc&#93;.rgbtGreen;
                    b = srcRow&#91;xSrc&#93;.rgbtBlue;

                    // irgendwas mit den RGB-Werten machen

                    // r,g,b setzen
                    srcRow&#91;xSrc&#93;.rgbtRed = r;
                    srcRow&#91;xSrc&#93;.rgbtGreen = g;
                    srcRow&#91;xSrc&#93;.rgbtBlue = b;
                }
            }
        }
        catch ( Exception &E )
        {
            MessageDlg(E.Message, mtError, TMsgDlgButtons() << mbOK, 0);
        }
    }
    else MessageDlg("Das Bild muss ein Bitmap mit 24Bit Farbtiefe sein!", mtError, TMsgDlgButtons() << mbOK, 0);

    Image->Repaint();
}

RGB decodieren

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    int r, g, b;
    TColor Clr = ColorBox1->Selected;

    r = Clr &amp; 0xFF;
    g = (Clr &amp; 0xFF00) / 0x100;
    b = (Clr &amp; 0xFF0000) / 0x10000;
}

Alle Controls einer Form mit “Schatten” versehen

// die folgende Funktion zeichnet hinter ein Control einen Schatten
void __fastcall TForm1::shadow(TForm *F, TControl *C, int width, TColor color)
{
    TRect rec;
    TColor old;

    rec = C->BoundsRect;
    rec.Left += width;
    rec.Top += width;
    rec.Bottom += width;
    rec.Right += width;

    old = F->Canvas->Brush->Color;
    F->Canvas->Brush->Color = color;
    F->Canvas->FillRect(rec);

    F->Canvas->Brush->Color = old;
}

void __fastcall TForm1::FormPaint(TObject *Sender)
{
    int iSchattenbreite = 3;
    TColor clSchattenfarbe = clBlack;

    for (int i=0; i<this->ControlCount; i++)
    {
        // im Bsp. bekommen nur TPanels und Buttons einem Schatten verpasst
        // es steht natürlich jedem frei weitere if-Anweisungen hinzuzufügen

        if (this->Controls[i]->ClassName().operator AnsiString() == &quot;TButton&quot;) shadow(this, this->Controls[i], iSchattenbreite, clSchattenfarbe);
        if (this->Controls[i]->ClassName().operator AnsiString() == &quot;TPanel&quot;) shadow(this, this->Controls[i], iSchattenbreite, clSchattenfarbe);
    }
}

Panel-Schatten anders färben

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    // Panel1 ist das Panel was eingefärbt werden soll

    HDC hdc = GetDC(Panel1->Handle);
    TCanvas* canvas = new TCanvas;
    canvas->Handle = hdc;
    canvas->Pen->Color = clRed;
    canvas->PenPos = Point(0, Panel1->Height - 2);
    canvas->LineTo(Panel1->Width - 2, Panel1->Height - 2);
    canvas->LineTo(Panel1->Width - 2, 0);
    canvas->PenPos = Point(Panel1->Width - 1, 0);
    canvas->LineTo(Panel1->Width - 1, Panel1->Height - 1);
    canvas->LineTo(0, Panel1->Height - 1);
    delete canvas;
    ReleaseDC(Panel1->Handle, hdc);
}