Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Hi,

ich versuche die Einträge in einer Listbox in unterschiedlichen Farben darzustellen.

In einem 2. Thread werden der Listbox per LB_ADDSTRING die Strings zugeschickt

und in der Nachrichtenschleife fange ich die WM_CTLCOLORLISTBOX Nachricht

folgendermaßen ab:


case WM_CTLCOLORLISTBOX:
{
if ((HWND)lParam == GetDlgItem(hDlg,IDC_TEXT))
{
if (SetTextColor((HDC)wParam,rgbColor) == CLR_INVALID)
Fehler("SetTextColor fehlgeschlagen.",GetLastError());
if (TextOut((HDC)wParam,0,0,szString,strlen(szString)) == NULL)
Fehler("TextOut fehlgeschlagen.",GetLastError());
}
return 0;
}
[/PHP]

Es tritt kein Fehler auf, trotzdem werden die Einträge nur in der standard Farbe

dargestellt.

:confused:

Habt ihr eine Idee was ich falsch mache?

Gruß

Guybrush

Geschrieben

Ist die HDC Variable die in wParam übergeben wird ein Handle auf den

Device Kontext der Gesamten Listbox oder nur der Zeile des aktuellen

Eintrags?

Wenn es sich um die gesamte Listbox handelt, müßte ich ja auch jedesmal die

gesamte Box neu Zeichnen.

Geschrieben

Soweit ich weiß, kannst du mit WM_CTLCOLORLISTBOX nur die gesamte Listbox färben, nicht einzelne Einträge. Du kannst auch nur die Farben setzen, die Listbox zeichnet sich immer noch selbst.

Du wirst wohl den OwnerDraw-Style setzen und WM_DRAWITEM behandeln müssen.

Geschrieben
Original geschrieben von Klotzkopp

Du wirst wohl den OwnerDraw-Style setzen und WM_DRAWITEM behandeln müssen.

Achso...

Ich hab mir das mal angekuckt und hab noch ein paar Verständisfragen.

Muss ich, wenn ich WM_DRAWITEM abfange, alle Zeichenarbeiten in der Listbox

selber machen? Also, einen Rahmen drum, wenn etwas ausgewählt wird,

oder wenn gescrollt wird die entsprechenden Einträge darstellen?

Und was passiert wenn die Anwendung im Hintergrund verschwindet und dann

wieder in den Vordergrund geholt wird?

Geschrieben

Vielleicht hilft es dir weiter, in der Hilfe Visual bei Suchen mal "Ask Dr. GUI #43, List Box, Draw Thyself" einzugeben.

Auf der Seite die gefunden wird, steht in der Mitte mit der Überschrift "List Box, Draw Thyself" , wie du einzelne Einträge farblich anpassen kannst. Hoffe, daß hilft dir weiter...

Geschrieben

Irgendwie hab ich den Artikel nicht und auf der Microsoftseite konnte ich ihn auch

nicht finden.

Das Problem ist halt, wenn ich das richtig verstanden habe, muß ich mich

bei WM_DRAWITEM um so viel kümmern, dass ich auch direkt hingehen kann und

mir die komplette Listbox selber zeichen.

Geschrieben

Ja und nein. komplett selber zeichnen ist IMHO noch zu aufwendig

Hier der Artikel*******************************************************

******************************************************************

List Box, Draw Thyself

Dear Dr. GUI,

Please forgive me if I am suffering from amnesia and have already bugged you about this.... I remember I was going to send you e-mail, I just don't remember if I actually sent it. So on with my question...

I need to have individual lines inside a CListBox to possibly be different colors. I know that I can change the color for all of the text but that really doesn't help me that much. I have searched and searched for something that would help me do this and all I can find is how easy it is to do in Visual Basic. Is there any solution in VC++ that will give me this functionality?

Thanks!

Dr. GUI replies:

The good doctor notes that this won't be trivial, but your problem gives him a great chance to show how to use "owner-draw" list boxes. "Owner-draw" is a common Windows technique whereby Windows asks you to draw the item that needs to be drawn. Many Windows controls, including buttons and menus, also support owner-drawing.

So, for this example, we'll use an owner-drawn list box. The entire process involves just four simple steps:

Derive a class from CListBox.

Override the CListBox::MeasureItem virtual function to specify the height for each item.

Override the CListBox::DrawItem virtual function to perform the painting.

Override the CListBox::CompareItem virtual function to determine the order in which the a string has to be added. This is necessary only if you wish to have a sorted list.

Note that the list box should have the LBS_OWNERDRAWVARIABLE and LBS_HASSTRINGS styles set. You need to select these styles for the list box when you create it using a resource editor. Otherwise, if you create the list box dynamically, specify these styles during creation.

The following CLineListBox class provides an implementation. Here the color for the text is stored as item data and retrieved during painting. First, we implement the AddItem function, which adds the string to the list box and stores the color in the 32-bit item data associated with the string:

void CLineListBox::AddItem(const CString& str, COLORREF rgbText)

{

int nIndex;

nIndex = AddString(str);

if( CB_ERR != nIndex )

SetItemData(nIndex, rgbText);

}

Next, we override DrawItem to draw the string in the color stored in the item data:

void CLineListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)

{

CDC dc;

CRect rcItem(lpDIS->rcItem);

UINT nIndex = lpDIS->itemID;

COLORREF rgbBkgnd = ::GetSysColor(

(lpDIS->itemState & ODS_SELECTED) ?

COLOR_HIGHLIGHT : COLOR_WINDOW);

dc.Attach(lpDIS->hDC);

CBrush br(rgbBkgnd);

dc.FillRect(rcItem, &br);

if( lpDIS->itemState & ODS_FOCUS )

dc.DrawFocusRect(rcItem);

if( nIndex != (UINT)-1 )

{

// The text color is stored as the item data.

COLORREF rgbText = (lpDIS->itemState & ODS_SELECTED) ?

::GetSysColor(COLOR_HIGHLIGHTTEXT) : GetItemData(nIndex);

CString str;

GetText(nIndex, str);

dc.SetBkColor(rgbBkgnd);

dc.SetTextColor(rgbText);

dc.TextOut(rcItem.left + 2, rcItem.top + 2, str);

}

dc.Detach();

}

Then, we have to override MeasureItem to tell Windows how high each item is. (Note that the items could each be of different height if we wanted.)

void CLineListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)

{

// Set the item height. Get the DC, select the font for the

// list box, and compute the average height.

CClientDC dc(this);

TEXTMETRIC tm;

CFont* pFont = GetFont();

CFont* pOldFont = dc.SelectObject(pFont);

dc.GetTextMetrics(&tm);

dc.SelectObject(pOldFont);

lpMIS->itemHeight = tm.tmHeight + 4;

}

Finally, we support sorting by overriding CompareItem:

int CLineListBox::CompareItem(LPCOMPAREITEMSTRUCT lpCIS)

{

CString str1, str2;

GetText(lpCIS->itemID1, str1);

GetText(lpCIS->itemID2, str2);

return str1.Compare(str2);

}

All that is needed to see the new list box in action is to create a variable of class CLineListBox, associate it with a list box window (perhaps using Class Wizard), and set the color for each text entered using SetItemData. If no color is specified for a string, it gets displayed in black when it is not selected. Suppose m_listBox is a variable of type, ClineListBox. In that case you may use:

m_listBox.AddItem("Hello", RGB(255, 0, 0)); // Add string, "Hello", and display it in red.

m_listBox.AddItem("Windows", RGB(255, 0, 255)); // Add string, "Windows", and display it in magenta.

m_listBox.AddItem("Color listbox"); // Add string, "Color listbox", and display it in default black."

  • 3 Monate später...

Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren

Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde Dich hier an.

Jetzt anmelden

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...