Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблема с PopupMenu в ListBox [D7, XP]


AlexanderMS ©   (2006-05-09 19:04:00) 

Помогите, пожалуйста! При нажатии правой кнопкой мыши на невыделенный пункт ListBox (зд. List) этот пункт становится выделенным, и выскакивает PopupMenu. Если User щёлкнул по пустому месту, где нет пунктов, то делается недоступным пункт меню PMDeleteLine.
Всё реализовано, вот код:

procedure TWindow.ListMouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
var n : integer;
begin
 if not (ssright in shift) then exit;
 n := List.itematpos(point(x, y), true); {видимо здесь задержка}
 if n = -1
   then
     PMDeleteLine.Enabled := false
   else
     begin
       PMDeleteLine.Enabled := true;
       if List.Selected[n] = false
         then
           begin
             List.ClearSelection;
             List.Selected[n] := true;
             List.ItemIndex := n;
             ListClick(Window)
           end
     end

end;


У меня проблема с быстродействием на этом участке кода.
Вопрос: как улучшить код для большего быстродействия?


KilkennyCat   (2006-05-09 20:00:00) [1]


> Что нужно указать в качестве параметра?


то, что требуется обработчику.
в данном случае я бы оставил Sender.
Меня не это интересовало, а что крутится в обработчике клика. Ибо здесь задержки нет.


AlexanderMS   (2006-05-09 19:56:00) [2]

Я насчёт Sender. Что нужно указать в качестве параметра?


KilkennyCat   (2006-05-09 19:54:00) [3]


> ибо MultiSelect = true.


тогда да, некатит.


AlexanderMS   (2006-05-09 19:52:00) [4]


> проблема не в машине

и не в ListClick'е.

KilkennyCat ©   (09.05.06 19:28) [7]
Ваш вариант не прокатывает, ибо MultiSelect = true.


AlexanderMS   (2006-05-09 19:51:00) [5]


> проблема не в машине

и не в ListClick'е.

KilkennyCat ©   (09.05.06 19:28) [7]
Ваш вариант не прокатывает, ибо MultiSelect := true.


AlexanderMS   (2006-05-09 19:40:00) [6]

Кстати, без ListClick(Window)ничего не меняется (я о быстродействии).


AlexanderMS   (2006-05-09 19:38:00) [7]


> ListClick(Window) - это что?

Попутный вопрос : что нужноуказывать в качестве Sender?
Я указал Window (главную форму), всё работает.
Насчёт кода, его трудно понять, но я погляжу, может, что исправить.


> KilkennyCat ©   (09.05.06 19:28) [7]

Благодарю.


KilkennyCat   (2006-05-09 19:28:00) [8]

    begin
      PMDeleteLine.Enabled := true;
      if List.Selected[n] = false
        then
          begin
            List.ClearSelection;
            List.Selected[n] := true;
            List.ItemIndex := n;
            ListClick(Window)
          end
    end


можно сократить до:

    begin
      PMDeleteLine.Enabled := true;
      List.ItemIndex := n;
      ListClick(Window)
    end


KilkennyCat   (2006-05-09 19:25:00) [9]

нормально.
проблема не в машине.

ListClick(Window) - это что?


AlexanderMS   (2006-05-09 19:24:00) [10]


> Что интересно, машина не слабая: 2400 MHz, 512 RAM...

По крайней мере, 2 года назад была не слабая...


AlexanderMS   (2006-05-09 19:23:00) [11]

Что интересно, машина не слабая: 2400 MHz, 512 RAM...
У меня итемов 7 тысяч.


KilkennyCat   (2006-05-09 19:19:00) [12]

Какая машина? на 6000 итемах у меня задержки не возникло. АМД 64 3000+ 1 гиг


AlexanderMS   (2006-05-09 19:16:00) [13]


> Смотрим реализацию ItemAtPos

и видим перебор.
У меня сначала всё нормально, но как нажму на предпоследнюю строчку...
Если затем вернусь на первую, то откуда-то берётся задержка...


KilkennyCat   (2006-05-09 19:09:00) [14]

Смотрим реализацию ItemAtPos

f unction TCustomListBox.ItemAtPos(Pos: TPoint; Existing: Boolean): Integer;
var
 Count: Integer;
 ItemRect: TRect;
begin
 if PtInRect(ClientRect, Pos) then
 begin
   Result := TopIndex;
   Count := Items.Count;
    while Result < Count do
   begin
     Perform(LB_GETITEMRECT, Result, Longint(@ItemRect));
     if PtInRect(ItemRect, Pos) then Exit;
     Inc(Result);
   end;

   if not Existing then Exit;
 end;
 Result := -1;
end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо