Transparenter Static-Text auf Hintergrundgrafik



  • Hallo!
    Ich habe ein Problem mit der Transparenz von Textfeldern.

    Ich zeichne mit dem folgenden Code ein Hintergrundbild in das Dialogfenster meiner Anwendung:

    void CWControlsDlg::PaintBackground(CPaintDC* pdc)
    {
      CRect rRect;
    
      GetClientRect(rRect);
      rRect.NormalizeRect();
      m_bmpBackground.Draw(pdc->m_hDC, rRect);
    }
    

    Jetzt möchte ich ein transparentes CStatic-Textfeld auf das Fenster platzieren. Allerdings klappt das nicht so ganz: Anstelle des Bildes sieht man direkt auf die Hintergrundfarbe vom Dialogfenster.
    Ich habe dann versucht den Text mittels CPaintDC::DrawText(...) zu zeichnen, was im Prinzip auch funktioniert - der Text landet direkt auf dem Bild und es ist kein Rahmen drum herum. Allerdings ändert sich der Text laufend - und mit dieser Methode entstehen dann mehrere Lagen Text übereinander. Erst wenn ein Aufruf der OnPaint() Methode dafür sorgt, dass das Fenster neu gezeichnet wird verschwinden die alten Textlagen. Manuell kann die OnPaint-Methode aber nicht getriggert werden, weil sich der Text dafür viel zu häufig ändert.

    Also meine Frage:
    Wie muss ich diesen Hintergrund erstellen, sodass man durch ein transparentes Textfeld diesen sehen kann?



  • Hmm du musst die OnCtlColor überschreiben und wenn es ein Aufruf von einem Static-Control ist hingehen und pDC->SetBkMode(TRANSPARENT) aufrufen ... und/oder nen NULL_BRUSH rurückgeben.



  • Der Teufel sei gepriesen 🙂
    Die OnCtlColor zu überschreiben und SetBkMode(TRANSPARENT) für das Textfeld hatte ich schon ausprobiert, aber das hatte nicht geklappt.

    Den NULL_BRUSH zurückzugeben war allerdings die Lösung. Wie man aus NULL_BRUSH einen HBRUSH castet musste ich allerdings nochmal googeln:

    (HBRUSH)GetStockObject(NULL_BRUSH)
    


  • Zu früh gefreut!
    Sobald sich der Inhalt des Textfeldes wieder ändert passiert das Gleiche wie schon oben erwähnt:
    Der alte Text wird nicht entfernt sondern nur der neue darüber gezeichnet. Wenn ich jetzt jedoch vor dem Ändern des Textes die Größe des Textfeldes mit MoveWindow(...) verändere, wird auch der Hintergrund des ganzen Textfeldes zurückgesetzt und der alte Text verschwindet.
    Das ganze funktioniert nur, wenn eine Größenänderung bewirkt wird, nur das Textfeld zu verschieben (also die Parameter nWidth, nHeight konstant zu lassen) umgeht das Problem nicht.
    Scheinbar wird also von MoveWindow unter bestimmten vorraussetzungen eine Funktion aufgerufen, welche mir den Hintergrund neu zeichnet.

    Welche Funktion könnte das sein und wie kann ich das Programm veranlassen diese bei jeder Änderung des Textfeldes auszuführen?



  • InvalidateRect ... sagt welcher Bereich für ungültig erklärt werden soll und somit neu gezeichnet werden soll ...



  • Das hab ich auch ausprobiert und es funktioniert in gewisser Weise auch. Allerdings flackert die Anzeige etwas, wenn der Bereich neu gezeichnet wird. Dazu habe ich jetzt mal einen Brush aus dem Hintergrundbild gemacht, welcher für das Dialogfenster von der OnCtlColor-Funktion zurückgegeben wird. Das reduziert das flackern schon einmal erheblich, allerdings verschwindet manchmal durch das Invalidate() der Text für den Bruchteil einer Sekunde.
    Fällt dazu noch jemandem etwas ein?


  • Mod

    Hier ist der klassische Artikel zu dem Thema, wie so oft Paul DiLascia
    http://www.microsoft.com/msj/0597/c0597.aspx



  • Hallo ich hab das gleiche Problem finde aber in dem Artikel irgendwie nicht die Lösung... ich "zwinge" das Window durch

    this->RedrawWindow(0, 0, RDW_INVALIDATE);
    

    Dann verwende ich in der OnPaint() folgendes

    afx_msg void CFISLabel::OnPaint() {
    
      if (!this->IsIconic()) {
        CRect oRectText;
        this->GetClientRect(oRectText);
    
        CDC* pDC = this->GetDC();
        pDC->.DrawText((m_bOn ? "AN" : "AUS"), &oRectText, DT_CENTER|DT_VCENTER|DT_NOCLIP|DT_WORDBREAK);
    
        this->ReleaseDC(pDC);
      }
      CWnd::OnPaint();
    }
    

    Das AN wird jedoch immer vom AUS überschrieben bzw. umgekehrt... Also ich sehe immer einen Mix aus AN und AUS...

    Wieso?


Anmelden zum Antworten