Gradient Background

Bjoern78

Grünschnabel
Hallo,

uch suche eine Möglichkeit den Fensterhintergrund meiner Anwendung nicht mit einer Farbe zu zeichnen, sondern von links nach rechts heller werdend. Alle Lösungsansätze die ich bisher gefunden hab sind entweder viel zu langsam (2 sek) oder laufen nicht. Kann mir irgendwer helfen?

Meine Dialoge sind von CDialog abgeleitet.

Bin für alles Dankbar....
 

MCoder

Erfahrenes Mitglied
Hallo,

also ich würde einen Message-Handler für WM_ERASEBKND installieren und dort senkrechte, jeweils heller werdende Linien zeichen (Verwendung MoveTo und LineTo). Das sollte eigentlich auch bei großen Dialogen deutlich schneller als 2 Sek. gehen. Wie hast du das denn bisher gemacht, dass das so lange dauert?

Alternativ könntest du auch (anstatt direkt auf den Dialog zu zeichnen) zunächst in einen Speicher-DeviceContext schreiben, diesen speichern und dann den gesamten Hintergrund in einem Rutsch mit BitBlt auf den Dialog kopieren.

Gruß
MCoder
 

Bjoern78

Grünschnabel
Erst mal danke für die schnelle Antwort. Leider kann ich die Nachricht WM_ERASEBKND bei mir nicht finden. Wenn ich da eine Lösung für finden könnte, ist der Rest - den Hintergrund mit einem Gradienten zeichnen - schnell gemacht. Wie gesagt, ich arbeite mit Visual C++ 6.0 und MFC.
 

MCoder

Erfahrenes Mitglied
Leider kann ich die Nachricht WM_ERASEBKND bei mir nicht finden.
Stelle im Klassenassistenten bei der "Klassen-Info" (letzte Karteikarte) den Filter für Nachrichten auf "Fenster". Dann taucht die Message auch in der Nachrichtenliste mit auf.
Noch ein Tipp: Bei WM_ERASEBKND nicht die Methode der Basisklasse ausführen, sondern einfach nur mit "return TRUE;" rausgehen.

Gruß
MCoder
 

Bjoern78

Grünschnabel
Läuft! leider mit einem ...aber! Ich hab auf dem Dialog ein TabCtrl Steuerelement zu liegen, abgeleitet von CTabCtrl. Ich hab versucht es Transparent zu machen, aber irgendwas läuft falsch. Die Ränder sind immer noch Grau, der Hintergrund des Dialogs ist eingefärbt. Normalerweise sollte doch bei einem Transparenten Element der Hintergund an den freien Stellen durchkommen.
Gibt es irgendwo eine Möglichkeit, wenn das Steuerelement Gezeichnet wird, ihm einen Transparenten Pinsel zuzuweisen?
 

Bjoern78

Grünschnabel
So, hier hab ich mal meinen Code um den Hintergrund einmzufärben:

Code:
BOOL CPlotMain::OnEraseBkgnd(CDC* pDC) 
{
	CRect rect;
	GetClientRect(&rect);

	int r1=127,g1=127,b1=255; //Any start color
	
	int r2=255,g2=255,b2=255; //Any stop color


	for(int i=0;i<rect.Height();i++)
	{ 
	   int r,g,b;
	   r = r1 + (i * (r2-r1) / rect.Height());
	   g = g1 + (i * (g2-g1) / rect.Height());
	   b = b1 + (i * (b2-b1) / rect.Height());
	   pDC->FillSolidRect(0,i,rect.Width(),1,RGB(r,g,b));
	}

	return true;
}


Sieht auch gut aus, bis auf das oben beschriebene Problem und zwischen Menüleiste und Fensterfläche ist noch ein dünner Strich zu sehen. Ich bereits versucht die Nachricht WM_CTLCOLOR zu nutzen, klappt aber nicht.

Code:
HBRUSH CPlotPage1::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    // Hintergrund einfärben
    hbr = CreateSolidBrush(RGB(255,255,255));

    // Texthintergrund transparent machen
    pDC->SetBkMode(TRANSPARENT);

	return hbr;
}
 

MCoder

Erfahrenes Mitglied
Komplexe Steuerelemente bzw. Fenster (TabCtrl) transparent zu machen, funktioniert etwas anders. Schaue Dir mal diesen Artikel an:
Mit WM_ERASEKGND und WM_CTLCOLOR deckst du nur den Client-Bereich eines Fensters ab. Rahmen, Titelleisten usw. werden über die WM_NC... - Messages (Non-Client) bedient.

Gruß
MCoder