Форум: "Основная";
Текущий архив: 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 ограмадное вам спасибо за то что научили такой класной вещи :) Теперь придётся все проги так переделывать ведь не выдержу :):)
← →
Erik1 © (2005-01-13 10:25) [41]А в чем проблема, разумеется можно добовлять и отображать что добавлено. При этом пользоватся лучше EhGrid www.EhLib.com при этом решение абсолютно стандартное и всем понятное, нетребующее написания дополнительного кода. А MemDataSet можно любой выбирать, есть очень скоростные варианты.
← →
MegaVolt © (2005-01-14 08:59) [42]Какой дополнитеьный код? Одну птичку переключить?
EhLib денежек хочет. Зачем мне платить за то что есть в стандартной поставке и летает как самолёт?
← →
MegaVolt © (2005-01-14 08:59) [43]Какой дополнитеьный код? Одну птичку переключить?
EhLib денежек хочет. Зачем мне платить за то что есть в стандартной поставке и летает как самолёт?
← →
MegaVolt © (2005-01-14 09:00) [44]Упс... Это справка платная. Но EhGrid на сайте пока не нашел :(
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2005.01.30;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.035 c