Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.01.30;
Скачать: [xml.tar.bz2];

Вниз

Две проблемки с TStringList   Найти похожие ветки 

 
MegaVolt ©   (2005-01-10 16:32) [0]

Есть 2 проблемы при исспользовании TStringList:
1. При изменении размеров колонок автоматически происходит сортировка :( Как можно этого избежать?
Вот код:

procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
 x1,y1:integer;
begin
 StringGrid1.MouseToCell(x,y,x1,y1);
 if y1=0
   then
     case x1 of
       1:Displ.Sort(SortName);
       2:Displ.Sort(SortSize);
       3:Displ.Sort(SortPath);
     end;
 UpdateDispl;
end;


2. Прокрутка колёсиком работает по разному в зависимости от того загружен драйвер мыши или нет. А так же от типа драйвера :( В одном случае прокрутка работает так как нужно в другом по StringGrid бежит полоска выделения :( Пользователи жалуются а как убрать я не знаю :( Может кто посодействует?

Заранее благодарен :)


 
jack128 ©   (2005-01-10 19:02) [1]

1. Попробуй перенести этот код в OnClick


 
MegaVolt ©   (2005-01-11 12:51) [2]

А в OnClick нету координат где я кликнул.


 
Семен Сорокин ©   (2005-01-11 12:54) [3]


> MegaVolt ©   (11.01.05 12:51) [2]
> А в OnClick нету координат где я кликнул.

координаты есть здесь:
Mouse.CursorPos
GetCursorPos


 
MegaVolt ©   (2005-01-11 14:21) [4]

OnClick не генерится для верхней строчки в которой написаны названия колонок :(


 
Poirot ©   (2005-01-11 14:25) [5]

OnColumnClick()
помоему так:)


 
Ega23 ©   (2005-01-11 14:42) [6]

Чё-то я не пойму: а при чём тут TStringList?????????


 
Poirot ©   (2005-01-11 14:43) [7]

упс.. моя промазать:)


 
MegaVolt ©   (2005-01-11 14:47) [8]

TStringList ни при чём. ОписАлся я :(


 
KSergey ©   (2005-01-11 14:48) [9]

> [6] Ega23 ©   (11.01.05 14:42)
> Чё-то я не пойму: а при чём тут TStringList?????????

Тссс... Главное они друг друга понимают :)


 
Ega23 ©   (2005-01-11 14:49) [10]

KSergey ©   (11.01.05 14:48) [9]

:о)


 
MegaVolt ©   (2005-01-11 14:50) [11]

А по делу так же красиво и остроумно слабо? А то к описке так прицепились а по делу 0 :(


 
KSergey ©   (2005-01-11 14:51) [12]

Как вариант - проверять. что курсор мыши "стрелочка" а не "ресайз". Да и на OnMouseDown я бы перенес.

PS
Весь EhGrid построен на опознавании текущего вида курсора.. Я офигел, когда увидел...


 
Думкин ©   (2005-01-11 14:53) [13]

0. TNewStringGrid = class(TStringGrid)
1. DrawInfo: TGridDrawInfo;
2. CalcDrawInfo(DrawInfo);CalcSizingState(X, Y, State, Index, Pos, Ofs, DrawInfo);
3. if State = gsColSizing then


 
begin...end ©   (2005-01-11 14:57) [14]

> [11] MegaVolt ©   (11.01.05 14:50)

По делу: использовать ListView. Виртуальный.


 
MegaVolt ©   (2005-01-11 15:06) [15]


> Как вариант - проверять. что курсор мыши "стрелочка" а не
> "ресайз".

Почему то в OnMouseUp курсор всегда обычный :(

> Да и на OnMouseDown я бы перенес.

Это не есть гуд :( Когда пользователь только нажал на заголовок сортировки ещё не должно быть.

Думкин Понял :( Если не найду варианта покрасивее так и сделаю.


> По делу: использовать ListView. Виртуальный.

Тормозит он.


 
begin...end ©   (2005-01-11 15:07) [16]

> [15] MegaVolt ©   (11.01.05 15:06)

> > По делу: использовать ListView. Виртуальный.
> Тормозит он.

Именно виртуальный тормозит? Интересненько. Особенно в сравнении с TStringGrid.


 
MegaVolt ©   (2005-01-11 16:54) [17]


> Именно виртуальный тормозит? Интересненько. Особенно в сравнении
> с TStringGrid.

Извиняй я невнимателен. Что значит виртуальный? Мне отображать список нуна а что толку от виртуального? Или я что то не понимаю?


 
begin...end ©   (2005-01-11 17:03) [18]

> [17] MegaVolt ©   (11.01.05 16:54)

Как сейчас организовано отображение данных в TStringGrid? Где находятся сАми данные? В TStringList? Код - ?


 
MegaVoltik   (2005-01-11 17:17) [19]

Данные в TList а элементами TList являются записи. Код чего нужно привести? У меня проблема с TStringGrid плохо работает прокрутка и при изменении размеров колонок одновременно вызывается сортировка. Код вроде выше привёл.


 
begin...end ©   (2005-01-11 17:23) [20]

> [19] MegaVoltik   (11.01.05 17:17)

Данные прорисовываются в обработчике OnDrawCell или присваиваются массиву Cells?


 
MegaVoltik   (2005-01-11 17:31) [21]

Присваиваются Cell.


 
begin...end ©   (2005-01-11 17:56) [22]

> [21] MegaVoltik   (11.01.05 17:31)

Вот, наваял небольшой примерчик.

Поместите на форму ListView и Button. У ListView установите свойство OwnerData в False (это и делает его виртуальным) и добавьте 2 колонки (свойство Columns). Для ListView определите обработчики OnData и OnCustomDrawItem (см. код ниже).

Вот код модуля формы:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ComCtrls;

type
 PMyRecord = ^TMyRecord;

 TMyRecord = record
   Index: Integer;
   IntField: Integer;
   Color: TColor
 end;

 TForm1 = class(TForm)
   ListView1: TListView;
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
   procedure ListView1Data(Sender: TObject; Item: TListItem);
   procedure ListView1CustomDrawItem(Sender: TCustomListView;
     Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
 private
   { Private declarations }
   List: TList;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
const
 ItemsCount = 100;
var
 I: Integer;
 pR: ^TMyRecord;
begin
 List := TList.Create;
 for I := 1 to ItemsCount do
 begin
   New(pR);
   with pR^ do
   begin
     Index := I;
     IntField := Random(1000);
     Color := TColor(Random($7FFFFFFF))
   end;
   List.Add(pR)
 end;
 ListView1.Items.Count := ItemsCount;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
 I: Integer;
begin
 if Assigned(List) then
   for I := 0 to Pred(List.Count) do
     Dispose(PMyRecord(List.Items[I]));
 List.Free
end;

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
var
 Index: Integer;
begin
 if Assigned(List) then
 begin
   Index := Item.Index;
   if Index < List.Count - 1 then
   begin
     Item.Caption := IntToStr(PMyRecord(List.Items[Index])^.Index);
     Item.SubItems.Add(IntToHex(PMyRecord(List.Items[Index])^.Color, 8))
   end
 end;
end;

procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
 Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
 if Assigned(List) then
   (Sender as TListView).Canvas.Font.Color := PMyRecord(List.Items[Item.Index])^.Color
end;

end.


Нажмите кнопку.

Заметьте, что если увеличить константу ItemsCount (например, 1000), работать будет ненамного медленнее.

См. также пример из Delphi: {Delphi}\Demos\Virtual Listview.


 
begin...end ©   (2005-01-11 17:57) [23]

Поправка к [22]: OwnerData должно быть, наоборот, True.


 
MegaVolt ©   (2005-01-12 09:10) [24]

Спасибо буду пробовать :) О результатах сообщу.


 
MegaVolt ©   (2005-01-12 12:37) [25]

Блеск :):) Я в полном восторге :) ListView в 35 раз быстрее!!!
Если не сложно теперь пару вопросов:
1. Почему если рисовать стандартными средствами ListView отображение на порядок медленнее?
2. Как вы нашли этот способ. Я лично до сих пор считал что OwnerDraw нужно для каких то моих способов отрисовки и сообтветственно OwnerData для чего то сильно навороченного и отличного от вывода простого текста.

Большушая вам благодарность вы мне очень помогли :)


 
begin...end ©   (2005-01-12 13:30) [26]

> [25] MegaVolt ©   (12.01.05 12:37)

> 1. Почему если рисовать стандартными средствами ListView
> отображение на порядок медленнее?

В обычном ListView содержатся данные обо всех элементах. Виртуальный ListView, напротив, самих элементов не содержит: он хранит только данные об их количестве, текущем выделении и т.д. Другими словами, виртуальный список не является контейнером данных - данные хранятся в другом месте (например, в TList или массиве, которые с ListView никак не связаны).

Когда возникает необходимость отобразить какой-то элемент (например, при показе списка или его прокручивании), срабатывает обработчик события OnData - там мы узнаём, какие элементы в данный момент нужно отобразить, и указываем, что нужно отображать.

Подчеркну: в OnData запрашивается информация не обо всех элементах (их может быть очень много), а только о тех, которые нужно прорисовать сейчас (ведь обычно в списке одновременно видны всего 20-30 элементов), - отсюда и прирост производительности.

Более того, используя список в виртуальном режиме, мы получаем ещё ряд приятных возможностей. Например, непосредственно перед срабатыванием обработчика OnData сработает обработчик OnDataHint. В него тоже передаётся диапазон индексов элементов, которые сейчас надо показать. Так вот - этот обработчик можно использовать для подготовки (например, обновления) данных перед показом - опять же, не всех данных, а только тех, которые нужны сейчас.

> 2. Как вы нашли этот способ.

Посмотрел справку по свойству OwnerData, а затем - пример из Delphi.

См. в справке: TListView.[OnData, OnDataFind, OnDataHint].
И обязательно посмотрите пример: {Delphi}\Demos\Virtual Listview.


 
MegaVolt ©   (2005-01-12 13:36) [27]

Обязательно посмотрю. Заодно если не сложно подскажите как сделать так чтобы при добавлении пользователь мог просматривать то что уже добавлено. Т.к. процесс поиска занимает до пару минут пользоваетель мог бы уже просматривать то что найдено.


 
begin...end ©   (2005-01-12 13:48) [28]

> [27] MegaVolt ©   (12.01.05 13:36)

> как сделать так чтобы при добавлении пользователь мог просматривать
> то что уже добавлено

Устанавливайте значение свойства TListView.Items.Count в нужное, т.е. делайте его равным текущему количеству найденных элементов. Только не слишком часто.


 
MegaVolt ©   (2005-01-12 14:21) [29]

При каждом ListView1.Items.Count := ItemsCount; прыгает на самое начало :( Пролистать не даёт :(


 
MegaVolt ©   (2005-01-12 14:30) [30]

если ListView1.Items.Count задать достаточно большим то вроде всё нормально но пока не прокрутишь первая страница не видна :(


 
begin...end ©   (2005-01-12 14:50) [31]

> [29] MegaVolt ©   (12.01.05 14:21)
> [30] MegaVolt ©   (12.01.05 14:30)

Скроллировать можно с помощью метода TListView.Scroll, например:

ListView.Scroll(0, {высота одного item"а} * (ListView.Items.Count - 1))

Но я бы отказался от идеи отображения результатов в процессе поиска.


 
MegaVolt ©   (2005-01-12 15:10) [32]

Я бы тоже отказался но пользователи жаждют. Пролистывают они мышью. Т.е. нужно сделать так чтобы добавление шло в фоне и юзверь этого не замечал. Т.е. он бы мог работать с результатами поиска с самых первых строк.


 
MegaVolt ©   (2005-01-12 17:11) [33]

Т.е. как сообщить ListView что обновились данные а он обновил сам только те что вписываются в экран.


 
begin...end ©   (2005-01-12 17:14) [34]

> MegaVolt

А чего у Вас там за поиск? Почему так долго? Может, тоже ускорить можно? :-)


 
MegaVolt ©   (2005-01-12 17:25) [35]

Прога ищет в файле с 2милионами записей. Каждая запись 1 файл найденый в локалке с инфой о нём. Поиск по маске в этом файле занимает около минуты :(


 
begin...end ©   (2005-01-12 17:28) [36]

> [35] MegaVolt ©   (12.01.05 17:25)

Так ищутся файлы или записи в файле? Код можно увидеть?

Хотя в обоих случаях поиск может быть долгим, конечно.

Я Вас, наверное, по неверному пути повёл.


 
MegaVolt ©   (2005-01-12 17:35) [37]

Ищутся файлы совпадающие с условием. Т.е.
if Rec.Name="*.avi" then отобразить
Само собой проверка условия не так сделана ;) Сам поиск вылизан круче некуда. Программеры на си пока не в состоянии сделать быстрее. А вот с интерфейсом я проигрываю :(
Сделал так если добавляемый элемент лежит на экране то вызываю invalidate или Repain один фиг. Пока заполняется первый экран моргает безумно :( А путь вы верный дали. Мне очень понравилось. Осталось поправить мелкие баги.


 
Erik1 ©   (2005-01-12 17:46) [38]

Помоему лучше найденые записи кидать в TMemTableEh и отображать все через тотже EhGrid. При большом количестве значений это самый удобный метод.


 
MegaVolt ©   (2005-01-12 17:52) [39]

А во время добавления будет можно просматривать то что уже добавлено?


 
MegaVolt ©   (2005-01-12 18:38) [40]

Короче от мерцания избавился так:
Вначале выставляю количество элементов очень большое (100000) далее добавляю элементы так
j:=Displ.Add(tRec);
if ((j-1)>=ListView1.TopItem.Index) and ((j-1)<=ListView1.TopItem.Index+ListView1.VisibleRowCount) then ListView1.UpdateItems(j-1,j);
и всё :) Красота да и только :) Скорость офигенная.
Доделаю пойду сишников дразнить :):)

begin...end ограмадное вам спасибо за то что научили такой класной вещи :) Теперь придётся все проги так переделывать ведь не выдержу :):)



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

Форум: "Основная";
Текущий архив: 2005.01.30;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.052 c
14-1105518608
syte_ser78
2005-01-12 11:30
2005.01.30
Господа, кто писал под Автокад?


1-1105784757
Separator
2005-01-15 13:25
2005.01.30
Автодозвон


14-1105438926
NewDelpher
2005-01-11 13:22
2005.01.30
генератор 3D-моделей людей


1-1105696520
thvfrjd
2005-01-14 12:55
2005.01.30
Работа с Excel с помощью ExcelApplication


4-1102306451
TankMan
2004-12-06 07:14
2005.01.30
А как заставить работать WMI на 9х?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский