Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > ListBox и длительное действие


Автор: MacTep 21.5.2006, 14:02
Есть ListBox. В немн несколько пунктов. При щелчке на каждый из этих пунктов, выполняется како-либо длительное действие. У меня такая фигня. При щелчке на один из них, действие начинает выполняться, но в этот момент, если случайно сдвинуть мушь на следующий пункт, то действие прерывается и выполняется уже второе, т.е. то, которое назначено на уже тот пункт, который в данный момент под мышью??? Как этого не допустить? 

Автор: Dynamic 21.5.2006, 14:26
заводишь флаг, типа InProcess: boolean, перед выполнением процесса проверяешь его на false 

Автор: MacTep 21.5.2006, 14:49
Делаю так:

Код

var process:boolean;

procedure TForm1.Create(Sender: TObject);
begin
      process:=false;
end;

procedure TForm1.lb1Click(Sender: TObject);
begin
  if (lb1.ItemIndex<>-1)and(not process) then
   begin
      process:=true;
      RefreshLB(lb1.ItemIndex);
      process:=false;
   end;
end;
Все равно не работает. Такое ощущение, как будто это действие (нажатие кнопки мыши и небольшое ее перемещение) не делится на составляющие. Как одно целое воспринимается... 

Автор: Dynamic 21.5.2006, 14:55
вот это 
Цитата(MacTep @  21.5.2006,  14:49 Найти цитируемый пост)
process:=false;

попробуй вставить в тело 
Цитата(MacTep @  21.5.2006,  14:49 Найти цитируемый пост)
RefreshLB(lb1.ItemIndex);

 

Автор: Демо 21.5.2006, 15:08
Код

  public
    procedure onWM_USERP1(var Msg: TMessage); message WM_USER+1;

procedure TForm1.onWM_USERP1(var Msg: TMessage);
var
  s: String;
begin
  s := ListBox1.Items[Msg.lParam];
  ShowMessage(s);
  ListBox1.Tag := 0;
end;

procedure TForm1.ListBox1Click(Sender: TObject);
begin
  if (ListBox1.ItemIndex<>-1) and (ListBox1.Tag=0) then
   begin
      ListBox1.Tag := 1;
      PostMessage(Form1.Handle,WM_USER+1,0,ListBox1.ItemIndex);
   end;
end;

 

Автор: MacTep 21.5.2006, 15:41
Dynamic, Демо, ни один из перечисленных вами способов не дал результата.
А в примере Демо вообще странно все работает... Для чего, например, выводит окно с названием пункта ListBox? 

Автор: Демо 21.5.2006, 16:08
Цитата(MacTep @  21.5.2006,  15:41 Найти цитируемый пост)
 Для чего, например, выводит окно с названием пункта ListBox? 


Ну блин... Это пример. в обработчиеке сообщения нужно заменить вывод на твой код - то, что тебе нужно выполнить. 

Автор: Albinos_x 21.5.2006, 16:08
Цитата(MacTep @  21.5.2006,  15:41 Найти цитируемый пост)
Dynamic, Демо, ни один из перечисленных вами способов не дал результата.

моё предположение... хотя может и не верное, т.к. не знаю содержание процедуры RefreshLB
видимо ты действие передаёшь в отдельный поток, а переменную не правильно устанавливаешь....
т.е. при выполнении:
Код

 if (lb1.ItemIndex<>-1)and(not process) then    
   begin    
      process:=true;    
      RefreshLB(lb1.ItemIndex);    
      process:=false;    
   end;

запускает поток, делает process:=false и выходит, а поток продолжает работать.... отсюда делаем вывод что установить process:=false надо в конце работы потока...
Цитата(MacTep @  21.5.2006,  15:41 Найти цитируемый пост)
А в примере Демо вообще странно все работает... Для чего, например, выводит окно с названием пункта ListBox?

это всего лишь пример... 

Автор: Демо 21.5.2006, 16:09
Код

procedure TForm1.onWM_USERP1(var Msg: TMessage);    
var    
  s: String;    
begin    
//  s := ListBox1.Items[Msg.lParam];    
  ЗДЕСЬ ДЕЛАЕШЬ ТО, ЧТО ТЕБЕ НУЖНО
//  ShowMessage(s);    
  ListBox1.Tag := 0;    
end;
 

Автор: MacTep 21.5.2006, 16:29
нет, так тоже не работает. Какое-то странное действие: как будто бы команда OnClick выполняется два раза. Сначала первый раз после того, как я нажал на пункт списка. Второй раз, после завершения действий по нажатию на первый пункт.

Добавлено @ 16:34 
вот содержимое процедуры:
Код

procedure RefreshLB(indx:integer);
var ext:string;
begin
  with MacTepWMForm do
    begin
      if (lb1.Count<>0)and
         (PrevItemLB<>indx)and
         (FileExists(groups[clb1.ItemIndex+1].Strings[indx]))then
        begin
          btnPreview.Enabled:=true;
          Screen.Cursor:=crHourGlass;
          // загрузка картинки
          Image4.Picture.LoadFromFile(groups[clb1.ItemIndex+1].Strings[indx]);
          // расположение картинки
          Label4.Caption:=groups[clb1.ItemIndex+1].Strings[indx];
          // выделяем расширение
          ext:=LowerCase(ExtractFileExt(groups[clb1.ItemIndex+1].Strings[indx]));
          // если картинка не BMP, а JPEG
          if ext<>'.bmp' then
            begin
              bm:=TBitMap.Create;
              JpegIm:=TJpegImage.Create;
              JpegIm.LoadFromFile(groups[clb1.ItemIndex+1].Strings[indx]);
              bm.Assign(JpegIm);
              // разрешение
              Label6.Caption:=IntToStr(bm.Width)+'x'+IntToStr(bm.Height);
              bm.Destroy;
              JpegIm.Destroy;
            end
          else
            Label6.Caption:=IntToStr(Image4.Picture.Bitmap.Width)+'x'+IntToStr(Image4.Picture.Bitmap.Height);
          Screen.Cursor:=crDefault;
          PrevItemLB:=indx;
        end;
    end;
end;
Думаю, что ничего криминального в этом коде нет. smile 

Автор: Демо 21.5.2006, 16:35
Цитата(MacTep @  21.5.2006,  16:29 Найти цитируемый пост)
 Какое-то странное действие: как будто бы команда OnClick выполняется два раза.


Значит, лшибка в другом месте. 

Автор: Yanis 21.5.2006, 22:14
Может быть не в тему (так и не понял в чём проблема), но почему нельзя делать просто 
Код
Enable := False
 пока выполняется (длительное) действие? 

Автор: MacTep 21.5.2006, 23:47
Yanis, потому что это тоже, хотя странно, не привело к успеху. smile 

Автор: Dynamic 22.5.2006, 05:35
КАК вариант: запоминай значение ItemIndex в момент клика в листбоксе и процедуре RefreshLB работай с переменной, а не с ItemIndex....... 

Автор: Albinos_x 22.5.2006, 06:00
Цитата(MacTep @  21.5.2006,  23:47 Найти цитируемый пост)
, не привело к успеху

видимо всё таки:
Цитата(Демо @  21.5.2006,  16:35 Найти цитируемый пост)
Значит, лшибка в другом месте

 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)