Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.08.27;
Скачать: CL | DM;

Вниз

OwnerDraw для ListView   Найти похожие ветки 

 
Maloric   (2008-08-27 16:00) [0]

Можно примерчик, как изменить у некоторых ячеек цвет шрифта, не нашел по OwnerDraw на форуме ничего... =(


 
mdw ©   (2008-08-27 16:02) [1]

В качестве примера можно посмотреть компонент ECMListEdit


 
Maloric   (2008-08-27 20:41) [2]

Да смотрел я его, что то не вкуриваю я в эту систему, буду пробовать раз трудно показать самый простой пример


 
Compiler ©   (2008-08-28 00:28) [3]

Примеры на форуме есть!!!

Вот, разбирайся:

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);
//  SetTextColor(DC,clBlack);
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;


 
andreil   (2008-08-28 08:02) [4]

Хм, раз тут пошло такое дело, не подскажет ли кто, как можно перехватить рисование заголовка ListView"а (Style = lvsDetail)? А то это единственная деталь в программе, которая рисуется не моим кодом :(


 
Maloric   (2008-08-28 08:50) [5]

[b]Compiler[/b],

> Вот, разбирайся

Спасибо огромное, наконец-то получилось


 
mdw ©   (2008-08-28 12:22) [6]


> Хм, раз тут пошло такое дело, не подскажет ли кто, как можно
> перехватить рисование заголовка ListView"а (Style = lvsDetail)?
>  А то это единственная деталь в программе, которая рисуется
> не моим кодом :(

Смотри TKOLmdvHeaderControl. Там есть пользовательская отрисовка заголовка. А в ListView используется тот же SysHeader32.


 
Sapersky   (2008-08-28 13:18) [7]

Можно примерчик, как изменить у некоторых ячеек цвет шрифта, не нашел по 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 ©   (2008-08-28 13:23) [8]

Как цвет менять я понял, а как стиль изменить шрифта?


 
Compiler ©   (2008-08-28 19:48) [9]

> RGaysin ©   (28.08.08 13:23) [8]

Listview1.Font.FontStyle:=[fsBold];
Listview1.Font.FontName:="Arial Black";
Listview1.Invalidate;


 
RGaysin ©   (2008-08-28 20:50) [10]


> Listview1.Font.FontStyle:=[fsBold];Listview1.Font.FontName:
> ="Arial Black";Listview1.Invalidate;

Дык я не про это, как DrawText-ом вывести жирный шрифт?
В примере который Вы выкладавали выше с изменением цвета


 
Compiler ©   (2008-08-29 00:09) [11]

> RGaysin ©   (28.08.08 20:50) [10]

А пример-то из [9] пробовали? Меняем у ListView FontStyle и будет жирный шрифт


 
L`Autour ©   (2008-08-29 06:15) [12]

А можно ли вручную рисовать в ListView элементы разной высоты? (нужно выводить многострочные тексты)


 
RGaysin ©   (2008-08-29 12:17) [13]

Да нет, он же меняет стиль всей таблицы, а я имел ввиду только в одной ячейке, извиняюсь, за неточность =)


 
L`Autour ©   (2008-08-29 13:23) [14]


> Да нет, он же меняет стиль всей таблицы, а я имел ввиду
> только в одной ячейке, извиняюсь, за неточность =)

Проверяешь строку и столбец текущей отрисовываемой ячейки, меняешь для нужной шрифт и после вывода меняешь его обратно.


 
RGaysin ©   (2008-08-29 15:23) [15]

Точно забывал убирать стиль.
А почему тогда все мигает в таблице:
 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;      


 
L`Autour ©   (2008-09-01 08:05) [16]

А зачем ручную отрисовывать все элементы через цикл? В обработчике нужно управлять прорисовкой только текущего элемента. Только DrawItem в отличии от CustomDraw, вызывается для всей строки, а не для каждого подъэлемента (при отрисовке вручную - не проблема).

Еще можно в включить двойную буферизацию отрисовки.


 
RGaysin ©   (2008-09-01 12:49) [17]

Ну я делаю через DrawItem как [b]Compiler[/b] научил. Я пока чайник в этих перехватах отрисовки


 
L`Autour ©   (2008-09-01 14:31) [18]

Вот мой пример (примерно так сейчас отрисовываю в своей проге):

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;


 
L`Autour ©   (2008-09-01 14:38) [19]

С LVustomDraw можно делать вывод только со сменой шрифта и фона, без ручного вывода текста. Но по тех.причинам он мне не подошел и примера дать не могу. Сам находил хорошо расписанные примеры с LVCustomDraw на http://www.delphikingdom.com


 
RGaysin ©   (2008-09-01 15:58) [20]

Вместо

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);
 
Перестало маргать =)


 
L`Autour ©   (2008-09-02 06:18) [21]

Я шрифты через CreateFontIndirect создаю при инициализации формы и уничтожаю при закрытии программы. Создавать и удалять шрифт в процессе вывода - не оптимально.


 
RGaysin ©   (2008-09-02 18:27) [22]

Эх, точно, это я не подумал! Спасибо за подсказку)



Страницы: 1 вся ветка

Текущий архив: 2010.08.27;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.063 c
2-1273099349
concord
2010-05-06 02:42
2010.08.27
Выпадающий список


2-1274384328
pro_xaoc
2010-05-20 23:38
2010.08.27
Ошибка с процедурой


15-1271172177
bss
2010-04-13 19:22
2010.08.27
Объясните, пожалуйста, насчет синтаксиса XSD


2-1269859107
kulon
2010-03-29 14:38
2010.08.27
Отображение вещественных чисел в компанентах


2-1270461234
ПарамПамПам
2010-04-05 13:53
2010.08.27
TClass