Cześć.
Mam problem z banalną sprawą. Operuje na dialogu tworzonym z zasobów. Mam taki kod jak poniżej dla obsługi WM_DRAWITEM
. Mój ListBox oczywiście ma styl LBS_OWNERDRAWFIXED
. I jeżeli taki sam warunek jak dla porównania Pos
ze stałą HTTP_Prefix
przy sprawdzaniu zaznaczenia. To po kliknięciu na element czcionka zaznaczonego elementu ze standardowej się zmniejsza.
Dla elementów odznaczonych jest ok. Bez dodatkowego if
oraz else
ze sprawdzaniem ListBox zachowuje się prawidłowo, ale nie mam wtedy rozróżniania kolorów. Co robię nie tak? Prosił bym o przykładowy kod pod WinAPI do rozwiązania mojego problemu. ForeColor
i BackColor
to zmienne zawierające domyślnie clLime
oraz clBlack
. Wartości wzięte ze źródel VCL, jak i funkcja RGBToColor
.
Dodam, że jezeli zrobię na próbę prosty warunek w stylu if DIS.itemID mod 2 = 0 then
i wtedy zrobię kolorowanie to nie ma problemu. Googlowałem, ale przykłady są raczej nie pod Delphi i albo VCL, albo jakieś naprowadzenia na C++'owe rozwiązania z MFC, co mnie nie urządza. Ale może i niedokładnie te rezultaty z Google przejrzałem.
procedure OnDrawStationsLB(DIS : PDrawItemStruct);
var
DC : HDC;
S : string;
HB : HBRUSH;
begin
DC := DIS.hDC;
S := LBGetItemText(DIS.hwndItem, DIS.itemID);
if (DIS.itemAction = ODA_FOCUS) and (DIS.itemState and ODS_FOCUS > 0) then
begin
SetTextColor(DC, ColorToRGB(ForeColor));
SetBkColor(DC, ColorToRGB(BackColor));
HB := CreateSolidBrush(ColorToRGB(BackColor));
end
else
begin
if Pos(Http_Prefix, TStationData(DIS.itemData).Url) = 1 then
begin
SetTextColor(DC, ColorToRGB(clYellow));
end
else
begin
SetTextColor(DC, ColorToRGB(ForeColor));
end;
SetBkMode(DC, TRANSPARENT);
HB := CreateSolidBrush(ColorToRGB(BackColor));
end;
FillRect(DC, DIS.rcItem, HB);
DeleteObject(HB);
DrawTextEx(DC, PChar(S), Length(S), DIS.rcItem, DT_LEFT, nil);
if DIS.itemState and ODS_FOCUS > 0 then
begin
DrawFocusRect(DC, DIS.rcItem);
end;
end;
Wywołuję tę procedurę w funkcji komunikatów dialogu (wycinek) tak:
//...
WM_DRAWITEM :
begin
DrawItem := Pointer(LParam);
case LoWord(WParam) of
IDC_STATIONSLB :
begin
OnDrawStationsLB(DrawItem);
Result := 1;
Exit;
end;
end;
end;
//...
Pobieranie tekstu z Itema to taki kod:
function LBGetItemText(LBHandle : HWND; AnIndex : Integer) : string;
var
L : Integer;
begin
L := SendMessage(LBHandle, LB_GETTEXTLEN, AnIndex, 0);
SetLength(Result, L);
SendMessage(LBHandle, LB_GETTEXT, AnIndex, LParam(PChar(Result)));
end;
P.S.: poza tym powyższa zmiana skutkuje tym, że okno dialogwe programu zamyka się dopiero po drugim naciśnięciu "X" a po naciśnięciu Escape, co normalnie zamyka dialog to program się "wywala". Takich sytuacji oczywiście chciałbym uniknąć i zamknąć program.