WM_CTLCOLORSTATIC und HOLLOW_BRUSH für eine Trackbar
-
Hallo,
also irgendwie bekomme ich folgendes nicht vernünftig hin:LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdcStatic = (HDC)wParam; case WM_CREATE: { ... hwndSlider = CreateWindow(TRACKBAR_CLASS,"",WS_CHILD | WS_VISIBLE | TBS_NOTICKS ,1,1,120,20, hwnd,(HMENU)0,(HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),NULL); ... } case WM_CTLCOLORSTATIC: { SetBkMode(hdcStatic, TRANSPARENT); return (LONG)GetStockObject(HOLLOW_BRUSH); } }leider führt das zu sowas:
http://img316.imageshack.us/my.php?image=bild18km.jpgWenn ich irgendeinen Brush mit Farbe wähle, also z.B. GRAY_BRUSH funktioniert es.
mfg
Peter
-
das bild funktioniert nicht!!
-
Also bei mir funktioniert dein Bild.
So sieht ein Fenster nun mal aus, wenn man mit einem durchsichtigen Pinsel den Hintergrund übermalt. Was hast du denn erwartet, dass man das darunter liegende Fenster sieht? Im echten Leben kannst du eine Wand ja auch nicht so anstreichen, dass sie durchsichtig wird. Du kannst Sie allerdings so anmalen, dass sie so aussieht, also ob sie durchsichtig wäre.
Im Programm musst du also WM_ERASEBKGND von der Trackbar verarbeiten (Subclassing) und dort den Hintergrund deines Fensters malen. (zumindest theoretisch sollte es so funktionieren)
-
ach das bild war so klein ich dachte das gehört zur seite.

-
Irgendeinen kleinen weiterführenden Tip vielleicht?
Ich habe jetzt verschiedene Möglichkeiten von WM_ERASEBKGND in der Subclass von TRACKBAR_CLASS getestet, aber irgendwie scheint sich das nicht auf den HINTERGRUND der Trackbar auszuwirken, wenn ich z.B. folgenden Code in der Subclasse verwende:static HBRUSH hBrush = NULL; static RECT rect; switch(msg) { case WM_ERASEBKGND: hBrush = CreateSolidBrush( RGB(255, 0 ,0) ); GetClientRect( hwnd, &rect ); FillRect( (HDC)wParam , &rect , hBrush ); return TRUE; case WM_PAINT: XXXX break; } return CallWindowProc(oldSliderWindowProc, hwnd, msg, wParam, lParam);So wenn ich das WM_PAINT weglasse passiert genau dasselbe wie im Bild des ersten postings, wenn ich einen Zeichencode in WM_PAINT einfüge erhalte ich einen konstanten roten Balken, ohne "Schieberegler"

(Was mich aber auch nicht wundert)Konstruktionen wie:
case WM_ERASEBKGND:
return True;
führen auch nur zum ergebnis des ersten Postings.Also irgendwie stehe ich im Moment ziemlich auf dem Schlauch, und für irgendeinen kleinen Tip wäre ich dankbar.
Peter
-
Ich hab es jetzt auch mal probiert, auch noch andere Varianten mit WM_PAINT, usw. aber bei mir hats auch nicht geklappt, sorry. Die Trackbar zeichnet den Hintergrund leider selbst in WM_PAINT (wahrscheinlich nutz Sie einen Backbuffer und löscht dessen Hintergrund mit dem aktuellen Pinsel).
Evtl. ginge es noch mit Custom Draw. Die Trackbar besteht laut MSDN aus drei Elementen: TBCD_CHANNEL, TBCD_THUMB, TBCD_TICS. Vlt. kann man bei TBCD_CHANNEL den Hintergrund selbt zeichnen. Die Custom Draw - Funktionen der CommomControls mag ich allerdings nicht und werde es deshalb jetzt auch nicht testen. Ich wünsch dir aber noch viel Erfolg damit.
-
Wer an einer Lösung interessiert ist:
a) Slider subclassen, im WM_PAINT folgenden Code:
PAINTSTRUCT ps;BeginPaint(_hWnd,&ps);
clsWrapDC DC(wParam ? (HDC)wParam : ps.hdc);
clsRect rc(ps.rcPaint);__ThemeManager.DrawThemeParentBackground(_hWnd,DC,rc); // Hintergrund malen!
SendMessage(_hWnd,WM_PRINT,HANDLE2INT((HDC)DC),PRF_CLIENT);EndPaint(_hWnd,&ps);
return(0); // we did it!b) bei dem Dialog WM_CTLCOLORSTATIC abfangen, und dann beim Slider-Control:
if (GET_ID(hWnd) == IDC_SLIDER)
{
clsWrapDC DC((HDC)wParam);// oofffff..... nicht des feinen Mannes Art!!!
__ThemeManager.DrawThemeParentBackground(hWnd,DC,clsRect(hWnd));
SetBkMode(DC, TRANSPARENT);
SelectObject(DC, GetStockBrush(HOLLOW_BRUSH));
return(HANDLE2INT(GetStockBrush(HOLLOW_BRUSH)));
}Sorry für die Benutzung interner Klassen, aber das Prinzip dürfte klar sein. So kann man einen Slider (zumindest unter XP getestet) sogar auf beliebigen Hintergründen, also auch Bitmaps oder Farbverläufen, 'transparent' malen lassen.
Ch.