Hintergrundfarbe ändern
-
So, ich hoffe jemand kann mir helfen. Ich möchte ebenfalls die Farbe meiner Steuerelemente zur Laufzeit ändern. Ich habe mich hier auch schon umgeschaut, und gesehen, dass überall auf die Methode OnCtlColor bzw. auf die WM_CTLCOLOR-Message hingewiesen wird. Mein Problem ist, dass die Farbe sich ständig ändern soll. Je nachdem, welche Werte ich habe, möchte ich die Farbe meiner Steuerelemente anpassen. Die OnCtlColor-Funktion wird nur einmal aufgerufen, und zwar immer dann wenn der Dialog neugezeichnet wird. Also nehem ich an, ich muss die Wm_CTLCOLOR-Message an mein Steuerelement senden, damit die Methode auch dann aufgerufen wird, wenn ich das möchte. Ich habe es so versucht:
Wenn ich weiss, dass sich ein Wert geänder hat, möchte ich die Farbe eines CStatic-Elements, in dem der Wert angezeigt wird ändern und rufe die folgende Zeile auf:m_InAbtastrate.SendMessage(WM_CTLCOLOR);
In der OnCtlColor-Methode ändere ich dann die Farbe:
HBRUSH CBoeCOMPortDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { COLORREF colorBlue = RGB(68, 68, 230); COLORREF colorRed = RGB(253, 33, 28); if (m_COMPort.IsOpen()) { if (nCtlColor == CTLCOLOR_STATIC) { switch (pWnd->GetDlgCtrlID()) { case IDC_INABTASTRATE: { if (m_Param.m_Abtastrate.m_Value <= m_Param.m_Abtastrate.m_MIN) { pDC->SetBkColor(colorBlue); return m_BlueBrush; } else if (m_Param.m_Abtastrate.m_Value >= m_Param.m_Abtastrate.m_MAX) { pDC->SetBkColor(colorRed); return m_RedBrush; } break; } } } } return CDialog::OnCtlColor(pDC, pWnd, nCtlColor); }
Das funktioniert aber nicht. Wenn ich die Nachricht an das Steuerelemt sende, erhalte ich einen Fehler in der OnWndMsg-Methode von CWnd. Und zwar in der folgenden Zeile:
CDC dcTemp; dcTemp.m_hDC = pCtl->hDC;
Hier stelle ich fest, dass pCtl = NULL ist. Warum, ist mir nicht klar.
Nun, wie mache ich es denn richtig ? Wie oben schon gesagt, ich möchte zur Laufzeit die Farbe der Steuerelemente ändern. Das mache ich in der OnCtlColor-Methode. ABER !!! Wie teile ich dem Framework mit, dass diese Methode aufgerufen wird ? Oder muss mann in dem Aufruf SendMessage(WM_CTLCOLOR) auch die anderen Parameter vielleicht setzen ? (wParam, lParam) ???
-
...wie du schon sagtest, OnCtlColor wird immer dann aufgerufen, wenn der Dialog neu gezeichnet wird, deswegen must du, wenn du die Farbe des Dialoges ändern willst vorher den Dialog neu zeichnen und das machst du mit RedrawWindow()
-
Ok, danke schon mal für die Antwort. Ich habe das ausprobiert, und es funktioniert auch. Jedoch ist das noch nicht optimal: und zwar muss ich die aktualiserung der Farben ca. 4 x pro Sekunde machen (ich empfange Werte über die serielle Schnittstelle). Und wenn ich das so mache, wie du das vorgeschlagen hast, wird mein Dialog 4 x /sec komplett neugezeichnet. Man sieht wie der Dialog die ganze Zeit am "blinken" ist. Wie kann man das jetzt umgehen ?
-
Ändert sich denn auch jedesmal die Farbe?
Probier doch mal, wie es aussieht, wenn du nur dann neu zeichnest, wenn sich wirklich war geändert hat.
-
Es kann durchaus vorkommen, dass sich die Farbe 2x pro sec ändert. Außerdem, wenn es auch nicht so wäre, wenn die Farbe also nur 2 x pro Minute geändert werden müsste -> Der "Blink"-Effekt ist ja nicht weg. Kann man da nicht noch etwas anderes machen ?
-
WS_CLIPCHILDREN und WS_CLIPSIBLINGS
-
was ist denn damit ?
-
Shaggy schrieb:
WS_CLIPCHILDREN und WS_CLIPSIBLINGS
Kannst du mir mal sagen, was du damit meinst ? Was kann ich damit machen ?
Ich habe diese Eigenschaften des Dialoges gesetzt und ausprobiert, der Effekt ist, dass der Dialog nicht gezeichnet wird, sondern nur alle Steuerelemente und der Dialograhmen. Ausßerdem wird jetzt die Methode OnCntColor gar nicht mehr aufgerufen, auch wenn man diese mit RedrawWindow auslösen will.
-
Ist schon gut, ich habe eine Lösung auf der Code Project Seite gefunden. Das machen die dort mit Subclassing. Trotzdem danke.