Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.119.159.150] |
|
Сообщ.
#1
,
|
|
|
Здравствуйте. Я периодически (по таймеру) заполняю ListView, но есть одна маленькая проблема: после обновления списка он автоматически пролистывается на начало, что делает работу с прогой затруднительной. Хотелось бы, чтобы после обновления список проскролливался на то положение, какое было до обновления.
Яркий пример - диспетчер задач, taskmgr.exe. Там скроллбары ListView неподвижны. Я наконпелял код, но он не совсем корректно работает. Прошу помочь поправить. Есть код: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, commctrl, ExtCtrls; type TForm1 = class(TForm) ListVw: TListView; LstRefillBtn: TButton; CheckBox1: TCheckBox; Timer1: TTimer; procedure LstRefillBtnClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure CheckBox1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.CheckBox1Click(Sender: TObject); begin Timer1.Enabled:=TCheckBox(Sender).Checked; end; procedure TForm1.FormCreate(Sender: TObject); begin listvw.HandleNeeded; end; procedure TForm1.LstRefillBtnClick(Sender: TObject); var lst:tlistitem; i,idx:integer; appn,s:string; fpos,hpos:integer; sc:tscrollinfo; begin s:=''; idx:=-1; sc.cbSize:=sizeof(tscrollinfo); sc.fMask:=SIF_ALL; GetScrollInfo(Listvw.Handle, sb_horz, sc); hpos:=sc.nTrackPos; fpos:=ListVw.Perform(LVM_GETTOPINDEX, 0, 0); // запоминаем заголовок выделенного элемента, чтобы после обновления вернуть ему фокус lst:=listvw.Selected; if assigned(lst) then begin idx:=lst.Index; s:=lst.Caption; end; // listvw.Items.BeginUpdate; try listvw.Clear; for i:=0 to 19 do begin lst:=ListVw.Items.Add; appn:=format('%s (%d)',[application.ExeName, i]); // для простоты. не обращайте внимания на этот бред. lst.Caption:=appn; lst.SubItems.Add(inttostr(i)); lst.SubItems.Add(inttostr(GetTickCount)); // если заголовок совпадает, запоминаем его индекс. if (s <> '') and (appn=s) then idx:=lst.Index; end; finally // возвращаем выделение, если заголовок элемента совпал. if idx >=0 then ListVw.Items[idx].Selected:=true; //[ прокрутка правого скроллбара, работает без нареканий. Listview_ensurevisible(ListVw.Handle, listVw.Items.Count - 1, True); Listview_ensurevisible(ListVw.Handle,fpos,true); ListVw.Items.EndUpdate; //] { прокрутка нижнего скроллбара. Необходима только в XP. На Win 7 вызывает самовольное смещение скроллбара. Вопрос в том, как сделать код совместимым с обоими платформами (XP и 7) На Win 7 нет необходимости запоминать позицию нижнего скроллбара, т.к. он не смещается при обновлении. } ListVw.Scroll(hpos,0); end; end; procedure TForm1.Timer1Timer(Sender: TObject); begin LstRefillBtn.click; end; end. |
Сообщ.
#2
,
|
|
|
Я давно делал так: запоминал текущую позицию и после добвления строк возвращался к ней
|
Сообщ.
#3
,
|
|
|
можно сделать
if idx >=0 then begin ListVw.Items[idx].Selected:=true; ListVw.Items[idx].Focused:=true; ListVw.Items[idx].MakeVisible(false); end; не то что бы скроллы будут неподвижными, но интересующий элемент будет виден после обновления списка |
Сообщ.
#4
,
|
|
|
Товарищи, речь идёт именно о горизонтальной автопрокрутке, интересует нижний скроллбар. Нужно сделать механизм прокрутки совместимым с семеркой и XP.
|
Сообщ.
#5
,
|
|
|
Если затык только в том, чтобы поддерживать обе версии винды, то что мешает определить ее версию и выполнять прокрутку только тогда, когда нужно?
|
Сообщ.
#6
,
|
|
|
Решение найдено, можно закрывать тему.
|
Сообщ.
#7
,
|
|
|
закрыть ты её сам можешь
решил поделись с народом |
Сообщ.
#8
,
|
|
|
Цитата Cfon @ решил поделись с народом Народ сам догадается |