WinXP Style => Label hat anderen Hintergrund als Elternfenster
-
Nabend allerseits,
auf der Arbeit muss ich mit WinAPI eine GUI basteln und die soll beim Kunden
natuerlich auch den schoenen XP-Style haben, wenn er eingestellt ist. Nun hab
ich allerdings das Problem, dass der Hintergrund eines Labels oder Radio-Button
nicht gleich dem Hintergrund des Elternfensters ist. Das sieht dann natuerlich
furchtbar schrecklich aus.Wie kann ich die Hintergrundfarbe eines Labels oder allgemein eines Kontrols,
dem Hintergrund des Elternfensters anpassen?gruss
v R
-
Dir Frage wäre eher: Was hast Du mit dem Hintergrund des Parents gemacht?
Behandelst Du WM_CTLCOLOR... Nachrichten schon selbst?
Wenn man nichts spezielles einbaut, funktioniert das wie gehabt...
-
Martin Richter schrieb:
Dir Frage wäre eher: Was hast Du mit dem Hintergrund des Parents gemacht?
Behandelst Du WM_CTLCOLOR... Nachrichten schon selbst?
Wenn man nichts spezielles einbaut, funktioniert das wie gehabt...Ich habe mit dem Hintergrund nichts gemacht, ich habe nichts spezielles
eingestellt.Testenshalber habe ich die WM_CTLCOLOR-Nachrichten jetzt mal abgefangen und
setze den Hintergrund auf den Hintergrund des Parents. Leider wird bei z. B.
Labels nur der Teil des Hintergrunds angepasst, welcher Text enthaelt. Ist das
Label an sich groesser, so sieht man den hinteren Teil immer noch in einer
anderen Farbe. Bei z. B. den Radio-Buttons hingegen passiert gar nichts.gruss
v R
-
Hmmm...hat niemand eine Idee, woran das liegen koennte?
Ich hab hier mal ein Bild hochgeladen:
http://img204.imageshack.us/my.php?image=guiproblemrz6.jpgEs ist nur ein Ausschnitt, aber man kann erkennen, dass der Hintergrund des
Parents weiss ist, aber z. B. die Labels nicht.gruss
v R
-
Ich vermute die Ursache ist folgende:
Du hast eine eigene Fensterklasse definiert?
Diese hast Du mit dem Hintergrund weiß gesetzt...
Wenn Du das möchtest musst Du WM_CTLCOLOR... Nachrichten abfangen.Die Hintergrundfarbe von Dialogen ist COLOR_BTNFACE.
Siehe auch:
http://www.microsoft.com/msj/0597/c0597.aspx
Auch wenn es MFC ist so wird doch das Nachrichten Verfahren gut erklärt.
-
virtuell Realisticer schrieb:
Leider wird bei z. B.
Labels nur der Teil des Hintergrunds angepasst, welcher Text enthaelt. Ist das
Label an sich groesser, so sieht man den hinteren Teil immer noch in einer
anderen Farbe. Bei z. B. den Radio-Buttons hingegen passiert gar nichts.Zeig mal den Code dazu, denke mal da liegt der Fehler. (Du musst sowohl den Text-Hintergrund des HDC's auf die entsprechende Farbe setzen, als auch den restlichen Hintergrund (durch das returnen eines Brushes).
-
Hallo,
ja also das ist alles etwas verzwickt mit dem Code, da er gekapselt worden ist,
trotzdem versuch ich die relervanten Codestellen zu posten, falls euch noch
etwas fehlt, bitte kurz darauf hinweisen.Zunaechst einmal haben wir eine Klasse window, deren init-Funktion schaut
wie folgt aus:void ds::window::init(const string_type& name, const string_type& window_class, const pos_type pos, const dim_type dim, const DWORD style, window* parent) { HINSTANCE instance = ::GetModuleHandle(0); static bool wndclass_created = false; if(wndclass_created == false) { const COLORREF bgcolor = RGB(255,255,255); WNDCLASSEX wndclass; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = sizeof(void*); wndclass.hbrBackground = (HBRUSH)COLOR_WINDOWFRAME; //CreateSolidBrush(bgcolor); wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hIcon = 0; wndclass.hIconSm = 0; wndclass.hInstance = instance; wndclass.lpfnWndProc = wnd_proc; wndclass.lpszClassName = default_class.c_str(); wndclass.lpszMenuName = 0; wndclass.cbSize = sizeof(WNDCLASSEX); wndclass.style = CS_HREDRAW | CS_VREDRAW; if(!RegisterClassEx(&wndclass)) throw std::runtime_error("RegisterClassEx() failed"); wndclass_created = true; } DWORD exStyle (0); /* if(window_class == default_class) ; //exStyle |= WS_EX_LAYERED; */ handle = CreateWindowEx(exStyle, window_class.c_str(), name.length() ? name.c_str() : 0, style, pos.x, pos.y, dim.w, dim.h, parent ? parent->handle : 0, 0, instance, this); if(!handle) throw std::runtime_error("CreateWindow() failed!"); /* Hier habe ich versucht, den hintergrund der fensterklasse anzupassen zum test einfach nur mal irgendwas. allerdings passiert gar nichts, es kann auch sein, dass das voelliger unsinn ist, aus der not heraus probiert man alles moegliche */ if(window_class != default_class) { int res = SetClassLongPtr(handle, GCLP_HBRBACKGROUND, RGB(167, 233, 100));//COLOR_WINDOWFRAME); Debug::print(boost::str(boost::format("SetClassLongPtr %d; GetLastError %d \n" "%s; %s") % res % GetLastError() % convert(window_class).c_str() % convert(name).c_str())); } // //save old wndproc and set the new one to the parents wndproc // if(parent) { old_wnd_proc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(handle, GWL_WNDPROC)); SetWindowLongPtr(handle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(wnd_proc)); CREATESTRUCT cs; memset(&cs, 0, sizeof(CREATESTRUCT)); cs.lpCreateParams = this; SendMessage(handle, WM_CREATE, 0, reinterpret_cast<LPARAM>(&cs)); this->parent = parent; } visible = (style & WS_VISIBLE); }Hier der Code, der fuer WM_CTLCOLOR... zustaendig ist:
case WM_CTLCOLORSTATIC: { DWORD col = GetSysColor(COLOR_WINDOWFRAME); COLORREF color = RGB(GetRValue(col), GetGValue(col), GetBValue(col)); static HBRUSH hbrush = (HBRUSH)CreateSolidBrush(col); PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); SetBkColor(hdc, color); EndPaint(hwnd, &ps); ds::Debug::print(boost::str(boost::format("WM_CTLCOLORSTATIC called for handle 0x%X") % hwnd)); return reinterpret_cast<LRESULT>(hbrush); }Obiger Code fuehrt dazu, dass der Hintergrund des Controls nur fuehr den
Bereich des Textes entsprechend angepasst wird, der Rest des Controls ist
dann schwarz.Ich bin mir sicher, dass das Problem an meinem Code liegt und nirgends sonst
zu suchen ist, aber ich weiss derzeit nicht wirklich weiter.Hilft euch das schon ein wenig? Falls ihr noch Codestellen braucht oder irgend
was anderes unklar ist, sagt mir bitte bescheid.gruss
v R
-
Hoi,
Lass das mal weg:
virtuell Realisticer schrieb:
/* Hier habe ich versucht, den hintergrund der fensterklasse anzupassen zum test einfach nur mal irgendwas. allerdings passiert gar nichts, es kann auch sein, dass das voelliger unsinn ist, aus der not heraus probiert man alles moegliche */ if(window_class != default_class) { int res = SetClassLongPtr(handle, GCLP_HBRBACKGROUND, RGB(167, 233, 100));//COLOR_WINDOWFRAME); Debug::print(boost::str(boost::format("SetClassLongPtr %d; GetLastError %d \n" "%s; %s") % res % GetLastError() % convert(window_class).c_str() % convert(name).c_str())); }Und ändere das:
virtuell Realisticer schrieb:
Hier der Code, der fuer WM_CTLCOLOR... zustaendig ist:
case WM_CTLCOLORSTATIC: { DWORD col = GetSysColor(COLOR_WINDOWFRAME); COLORREF color = RGB(GetRValue(col), GetGValue(col), GetBValue(col)); static HBRUSH hbrush = (HBRUSH)CreateSolidBrush(col); PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); SetBkColor(hdc, color); EndPaint(hwnd, &ps); ds::Debug::print(boost::str(boost::format("WM_CTLCOLORSTATIC called for handle 0x%X") % hwnd)); return reinterpret_cast<LRESULT>(hbrush); }in das ab:
case WM_CTLCOLORSTATIC: { SetBkMode(reinterpret_cast<HDC>(wParam), TRANSPARENT); ds::Debug::print(boost::str(boost::format("WM_CTLCOLORSTATIC called for handle 0x%X") % hwnd)); return (reinterpret_cast<LRESULT>(GetSysColorBrush(COLOR_WINDOWFRAME))); }Den HDC bekommst Du nämlich schon über wParam geliefert. BeginPaint bzw. EndPaint ist hier falsch
.
-
Alles klar, das werd ich machen, danke. Kann aber erst naechste Woche berichten,
ob es funktioniert hat, ich hoffe doch mal :).gruss
v R
-
Den via
GetSysColorBrush(COLOR_WINDOWFRAME)angeforderten Brush brauchste dann auch nicht wieder freigeben, ist ein System-Objekt
.
-
Wenn ich den Code umaendere, dann erhalte ich folgendes Resultat:
http://img218.imageshack.us/img218/5638/guiproblemrs4.jpg
Irgendwie gehn mir so langsam die Ideen aus, woran es liegen koennte, habt ihr
noch welche?gruss
v R
-
Hmmm....wenn ich den Code folgendermassen abaendere:
SetBkColor(reinterpret_cast<HDC>(wparam), RGB(GetRValue(COLOR_WINDOW), GetGValue(COLOR_WINDOW), GetBValue(COLOR_WINDOW))); SetTextColor(reinterpret_cast<HDC>(wparam), RGB(255, 255, 255)); ds::Debug::print(boost::str(boost::format("WM_CTLCOLORSTATIC called for handle 0x%X") % hwnd)); return (reinterpret_cast<LRESULT>(GetSysColorBrush(COLOR_WINDOW)));bekomme ich folgendes Resultat:
http://img214.imageshack.us/img214/415/guiproblemef4.jpg
Ich verstehe nicht, warum der Textbereich auf dem Label schwarz ist?
gruss
v R
-
Ok, hab nochwas rumprobiert. Der Code:
case WM_CTLCOLORSTATIC: { SetBkMode(reinterpret_cast<HDC>(wparam), TRANSPARENT); SetBkColor(reinterpret_cast<HDC>(wparam), RGB(GetRValue(COLOR_WINDOW), GetGValue(COLOR_WINDOW), GetBValue(COLOR_WINDOW))); SetTextColor(reinterpret_cast<HDC>(wparam), RGB(0, 0, 0)); ds::Debug::print(boost::str(boost::format("WM_CTLCOLORSTATIC called for handle 0x%X") % hwnd)); return (reinterpret_cast<LRESULT>(GetSysColorBrush(COLOR_WINDOW))); }leistet das gewuenschte.
gruss
v R
-
Hmm ist aber nicht soo effektiv jedesmal neu zu casten. Mach es einmal und pack es in ne Variable.
case WM_CTLCOLORSTATIC: { HDC hDC = reinterpret_cast<HDC>(wParam); SetBkMode(hDC, TRANSPARENT); SetBkColor(hDC, RGB(GetRValue(COLOR_WINDOW), GetGValue(COLOR_WINDOW), GetBValue(COLOR_WINDOW))); SetTextColor(hDC, RGB(0, 0, 0)); return (reinterpret_cast<LRESULT>(GetSysColorBrush(COLOR_WINDOW))); }...
-
Ja, da hast auch recht, danke.
gruss
v R