WinXP Style => Label hat anderen Hintergrund als Elternfenster
-
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