-
Можно примерчик, как изменить у некоторых ячеек цвет шрифта, не нашел по OwnerDraw на форуме ничего... =(
-
В качестве примера можно посмотреть компонент ECMListEdit
-
Да смотрел я его, что то не вкуриваю я в эту систему, буду пробовать раз трудно показать самый простой пример
-
Примеры на форуме есть!!! Вот, разбирайся: OwnerDrawFixed:=True Колонок - 3 Style=lvsDetail;
function TForm1.ListView1DrawItem(Sender: PObj; DC: HDC; const Rect: TRect;
ItemIdx: Integer; DrawAction: TDrawAction;
ItemState: TDrawState): Boolean;
var
br:HBRUSH;
iR:Trect; iCol:Integer;
s:string;
begin
Result := TRUE;
iR:=Rect;
if (odsSelected in ItemState) then begin
br := GetSysColorBrush(COLOR_HIGHLIGHT);
SetTextColor(DC,GetSysColor(COLOR_HIGHLIGHTTEXT));
end else begin br := GetSysColorBrush(COLOR_WINDOW);
end;
FillRect(DC,iR,br);
for iCol:=0 to Pcontrol(Sender).LVColCount-1 do
begin
if (iCol in [1,3]) and (ItemIdx in [2,4,5,7]) then
SetTextColor(DC,clRed)
else
SetTextColor(DC,clBlack);
iR:=Pcontrol(Sender).LVSubItemRect(ItemIdx,iCol);
if iCol=0 then begin
iR.Right:=Pcontrol(Sender).LVColWidth[iCol];
iR.Left:=iR.Left;
end;
Inc(iR.Left, 5);
S:=Pcontrol(Sender).LVItems[ItemIdx,iCol];
DrawText(DC,@S[1], Length(s),iR,
DT_SINGLELINE or DT_NOPREFIX or DT_VCENTER or DT_WORD_ELLIPSIS);
end;
end;
-
Хм, раз тут пошло такое дело, не подскажет ли кто, как можно перехватить рисование заголовка ListView'а (Style = lvsDetail)? А то это единственная деталь в программе, которая рисуется не моим кодом :(
-
[b]Compiler[/b],
> Вот, разбирайся
Спасибо огромное, наконец-то получилось
-
> Хм, раз тут пошло такое дело, не подскажет ли кто, как можно > перехватить рисование заголовка ListView'а (Style = lvsDetail)? > А то это единственная деталь в программе, которая рисуется > не моим кодом :(
Смотри TKOLmdvHeaderControl. Там есть пользовательская отрисовка заголовка. А в ListView используется тот же SysHeader32.
-
Можно примерчик, как изменить у некоторых ячеек цвет шрифта, не нашел по OwnerDraw на форуме ничего...
Есть ещё вариант для Listview без ownerdraw. Удобен в тех случаях, когда не нужно всё рисовать по-своему, а только подправить цвет (я изменял цвет фона, но вроде бы можно и шрифта).
FList.AttachProc( WndProcCustomDraw );
function WndProcCustomDraw( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; var NMCustDraw: PNMLVCustomDraw; NMHdr: PNMHdr; ItemIdx : Integer; ItemState: TDrawState; begin Result := FALSE; If Msg.message = WM_NOTIFY then begin NMHdr := Pointer( Msg.lParam ); if (NMHdr.code = NM_CUSTOMDRAW) then begin NMCustDraw := Pointer( Msg.lParam ); ItemIdx := -1; If LongBool( NMCustDraw.nmcd.dwDrawStage and CDDS_ITEM ) then begin ItemIdx := NMCustDraw.nmcd.dwItemSpec; If (ItemIdx > 0) and (нужно выделить данный Item) then NMCustDraw.clrTextBk := SelColor; // или NMCustDraw.clrText Rslt := 0; end else Rslt := CDRF_NOTIFYITEMDRAW; Result := TRUE; end; end; end;
-
Как цвет менять я понял, а как стиль изменить шрифта?
-
> RGaysin © (28.08.08 13:23) [8]
Listview1.Font.FontStyle:=[fsBold];
Listview1.Font.FontName:='Arial Black';
Listview1.Invalidate;
-
> Listview1.Font.FontStyle:=[fsBold];Listview1.Font.FontName: > ='Arial Black';Listview1.Invalidate;
Дык я не про это, как DrawText-ом вывести жирный шрифт? В примере который Вы выкладавали выше с изменением цвета
-
> RGaysin © (28.08.08 20:50) [10]
А пример-то из [9] пробовали? Меняем у ListView FontStyle и будет жирный шрифт
-
А можно ли вручную рисовать в ListView элементы разной высоты? (нужно выводить многострочные тексты)
-
Да нет, он же меняет стиль всей таблицы, а я имел ввиду только в одной ячейке, извиняюсь, за неточность =)
-
> Да нет, он же меняет стиль всей таблицы, а я имел ввиду > только в одной ячейке, извиняюсь, за неточность =)
Проверяешь строку и столбец текущей отрисовываемой ячейки, меняешь для нужной шрифт и после вывода меняешь его обратно.
-
Точно забывал убирать стиль. А почему тогда все мигает в таблице: for iCol:=0 to PControl(Sender).LVColCount-1 do
begin
iR:=Pcontrol(Sender).LVSubItemRect(ItemIdx,iCol);
if iCol=0 then begin
iR.Right:=PControl(Sender).LVColWidth[iCol];
iR.Left:=iR.Left;
end;
Inc(iR.Left, 8);
S:=PControl(Sender).LVItems[ItemIdx,iCol];
SetTextColor(DC,clBlack);
if (Str2Int(S)>49) then SetTextColor(DC,clRed);
if (Str2Int(S)>55) then SetTextColor(DC,clGreen);
if (iCol in [1]) then SetTextColor(DC,clBlue);
if (Str2Int(S)>49) then PControl(Sender).Font.FontStyle:=[fsBold]
else PControl(Sender).Font.FontStyle:=[];
DrawText(DC,@S[1], Length(s),iR,
DT_SINGLELINE or DT_NOPREFIX or DT_VCENTER or DT_WORD_ELLIPSIS);
end;
-
А зачем ручную отрисовывать все элементы через цикл? В обработчике нужно управлять прорисовкой только текущего элемента. Только DrawItem в отличии от CustomDraw, вызывается для всей строки, а не для каждого подъэлемента (при отрисовке вручную - не проблема).
Еще можно в включить двойную буферизацию отрисовки.
-
Ну я делаю через DrawItem как [b]Compiler[/b] научил. Я пока чайник в этих перехватах отрисовки
-
Вот мой пример (примерно так сейчас отрисовываю в своей проге):
function TForm1.ListView1DrawItem(Sender: PObj; DC: HDC; const Rect: TRect; ItemIdx: Integer; DrawAction: TDrawAction; ItemState: TDrawState): Boolean; var TempStr: string; SolidBrush: HBRUSH; DefaultColor: COLORREF; R: TRect; TextSize: TSize;
//вывод подъэлементов с формированием многоточия для длинных строк procedure SubItemTextOut; var i, l: Integer; d, iprev: Integer; begin l := Length(TempStr); iprev := 0; for i := 0 to l do begin GetTextExtentPoint32W(DC, PWideChar(TempStr), i, TextSize); d := (R.Right - R.Left - 4) - TextSize.cx; if (d < 0) then begin if (iprev = 0) then iprev := i; if (l - iprev <= 3) then SetLength(TempStr, l + 3); TempStr[iprev] := '.'; TempStr[iprev + 1] := '.'; TempStr[iprev + 2] := '.'; l := iprev + 2; Break; end //if else if (d < 9)and(iprev = 0) then//if iprev := i; end; //for
ExtTextOut(DC, R.Left + 4, R.Top, ETO_CLIPPED, @R, PWideChar(TempStr), l, nil); end;
begin Result := True;
//смена цвета шрифта и фона для выделения текущего элемента DefaultColor := GetTextColor(DC); if (odsSelected in ItemState)and(odsFocused in ItemState) then begin SolidBrush := CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); FillRect(DC, Rect, SolidBrush); DeleteObject(SolidBrush); SetTextColor(DC, $FFFFFF - DefaultColor); end;// else //FillRect(DC, Rect, CreateSolidBrush(GetSysColor(COLOR_WINDOW))); R := Rect; //вывод подъэлемента 1 //--тут меняем шрифт-- TempStr := ListView1.LVItems[ItemIdx, 0] R.Right := R.Left + PControl(Sender).LVColWidth[0] - 2; SubItemTextOut;
//вывод подъэлемента 3 //--тут меняем шрифт-- TempStr := ListView1.LVItems[ItemIdx, 1] R.Left := R.Right + 2; R.Right := R.Left + PControl(Sender).LVColWidth[1] - 2; SubItemTextOut;
//вывод подъэлемента 2 //--тут меняем шрифт-- TempStr := ListView1.LVItems[ItemIdx, 2] R.Left := R.Right + 2; R.Right := R.Left + PControl(Sender).LVColWidth[2] - 2; SubItemTextOut;
//возврат цвета по муолчанию SetTextColor(DC, DefaultColor); end;
-
С LVustomDraw можно делать вывод только со сменой шрифта и фона, без ручного вывода текста. Но по тех.причинам он мне не подошел и примера дать не могу. Сам находил хорошо расписанные примеры с LVCustomDraw на http://www.delphikingdom.com
-
Вместо
if (Str2Int(S)>49) then PControl(Sender).Font.FontStyle:=[fsBold]
else PControl(Sender).Font.FontStyle:=[]; вставил
Font: Cardinal;
LFont: LOGFONT;
FillChar( LFont, SizeOf( LFont ), 0 );
LFont.lfHeight := LV1.Font.FontHeight;
LFont.lfFaceName:='Verdana';
if (iCol in [1]) then LFont.lfWeight:=700
else LFont.lfWeight:=0;
Font := CreateFontIndirect(LFont);
SelectObject(DC,Font);
Перестало маргать =)
-
Я шрифты через CreateFontIndirect создаю при инициализации формы и уничтожаю при закрытии программы. Создавать и удалять шрифт в процессе вывода - не оптимально.
-
Эх, точно, это я не подумал! Спасибо за подсказку)
|