![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Несколько вопросов про ListBox
Boris Mouradov © (2004-01-22 15:37:00)Привет!
Не могу совладать с TKOLListBox (v1.89), помогите, пожалуйста.
1) Как узнать, над какой строкой сейчас мышиный курсор? LVItemAtPos не работает. Аналогично, как узнать прямоугольник для отрисовки той или иной строки?
2) Как узнать какая по номеру строка сейчас изображена первой?
3) Как узнать/задать высоту строки, если указано OwnerDrawFixed?
4) Задал OwnerDrawFixed, описал OnDrawItem. Всё рисуется, но появляется такой момент:
У меня всего 10 строк. Влезает на экране 9 с половиной. Видно всё нормально. Но когда я прокручиваю на одну вниз, я вижу нижние 9 (как и должно быть), и должен ещё увидеть ниже пустую половинку, как бы 11-й элемент. Вместо этого там ещё остался нарисован 10-й. (теперь 10-й виден дважды). Подскажите, как с этим бороться.
Спасибо,
Борис
Ajax (2004-02-02 07:50:00) [1]Попробуй рисовать без использования lbItems.Canvas. У меня для ComboBox нормально работает.
var Brush:HBrush;
Pen:HPen;
Font:HFont;
begin
if (odsSelected in ItemState) then
begin
brush:=CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
SetBkColor(dc,GetSysColor(COLOR_HIGHLIGHT));
SetTextColor(dc,GetSysColor(COLOR_HIGHLIGHTTEXT));
end
else
begin
brush:=CreateSolidBrush(GetSysColor(COLOR_WINDOW));
SetBkColor(dc,GetSysColor(COLOR_WINDOW));
SetTextColor(dc,combComand.Font.Color);
end;
SelectObject(dc, Brush);
pen:=CreatePen(PS_NULL,0,0);
SelectObject(dc, pen);
Font:=CreateFont(combcomand.font.FontHeight,0,0,0,FW_NORMAL,cardinal(false),cardinal(false),cardinal(false),
DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,DEFAULT_PITCH,'MS Sans Serif');
SelectObject(dc,font);
Rectangle(dc,Rect.Left, Rect.Top, Rect.Right, Rect.Bottom);
TextOut(dc,Rect.Left+3,Rect.Top,pchar(combComand.Items[ItemIdx]),length(combComand.Items[ItemIdx]));
DeleteObject(brush);
DeleteObject(pen);
DeleteObject(font);
Result:=true;
end;
bMouradov (2004-02-01 10:17:00) [2]Только что обнаружил тот же эффект при прокручивании колесиком мыши - EraseBkgnd в этом случае тоже не вызывается.
bMouradov (2004-02-01 02:11:00) [3]Если все упростить, то вот так:
function TMainForm.lbItemsDrawItem(Sender: PObj; DC: HDC;
const Rect: TRect; ItemIdx: Integer; DrawAction: TDrawAction;
ItemState: TDrawState): Boolean;
var R: TRect;
begin
Result := True;
lbItems.Canvas.FillRect(Rect);
R := Rect;
R.Left := 10;
lbItems.Canvas.TextOut(R.Left, R.Top, Strs[ItemIdx]);
end;
Кстати, EraseBkgnd не помогло. Точнее, пустое пространство она отрисовывает, но вот когда я нажимаю на скроллбаре стрелочку вниз, - не желает. В результате (пока) обхожусь вот так:
//OnMessage
function TMainForm.lbItemsMessage(var Msg: tagMSG;
var Rslt: Integer): Boolean;
begin
Result := False;
if Msg.message = WM_VSCROLL then
lbItems.Invalidate;
end;
Но это же не совсем правильно.
Борис
Ajax (2004-01-31 08:00:00) [4]>Boris Mouradov
Приведи пожалуйста код, которым рисуешь.
SPeller (2004-01-30 06:16:00) [5]4) - нужно очищать фон. Обрабатывай OnEraseBkgnd.
Boris Mouradov (2004-01-30 03:47:00) [6]Разобрался с 1-3. Может, кому пригодится:
1)
function ItemAtPos(lb: PControl; Pos: TPoint; Existing: Boolean): Integer;
var
Count: Integer;
ItemRect: TRect;
begin
if PointInRect(Pos, lb.ClientRect) then begin
Result := SendMessage(lb.Handle, LB_GETTOPINDEX, 0, 0);
Count := lb.Count;
while Result < Count do begin
WndFunc(lb.Handle, LB_GETITEMRECT, Result, Longint(@ItemRect));
if PointInRect(Pos, ItemRect) then
Exit;
Inc(Result);
end;
if not Existing then
Exit;
end;
Result := -1;
end;
2) Result := SendMessage(lb.Handle, LB_GETTOPINDEX, 0, 0);
3)
WndFunc(lb.Handle, LB_SETITEMHEIGHT, 0, 15);
WndFunc(lb.Handle, LB_GETITEMHEIGHT, 0, 0);
Vladimir Kladov (2004-01-22 17:42:00) [7]1) не надо путать. LVxxxx методы - для ListView, а не для ListBox