Autor Beitrag
acnut
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 172
Erhaltene Danke: 3

Windows 7, Windows Vista, Windows XP, Ubuntu, Kubuntu, Pardus
Delphi 2010 SV, Java Editor, VS 2010 SV
BeitragVerfasst: Mo 18.07.11 18:22 
ich hab schon alles durchprobiert und das ding funzt einfach nicht. nach jedem update des listviews springt das ding einfach wieder nach oben.
hab onkel google gefragt, auch er kann mir nicht weiterhelfen :(

also mit diesem procedure füge ich alle items&subitems in das listview


ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
procedure TForm1.DoAfterUpdateProcesses(Sender: TObject);
var
  Process: TProcessItem;
  ListItem : TListItem;
  i : integer;
  CurrentItem : string;
begin
  if DontUpdateList then
    Exit;

  ListView1.Items.BeginUpdate;
  try
    if Assigned(ListView1.Selected) then
      CurrentItem := ListView1.Selected.Caption;
    ListView1.Clear;
//    for Process in ProcessInfo1.RunningProcesses do
    for I := 0 to ProcessInfo1.RunningProcesses.Count- 1 do
    begin
      Process := ProcessInfo1.RunningProcesses[i];
      ListItem := ListView1.Items.Add;
      ListItem.SubItems.Add(IntToStr(Process.ParentProcessID));
      ListItem.Caption := IntToStr(Process.ProcessID);
 //   ListItem.SubItems.Add(IntToStr(Process.CpuUsage));
      ListItem.SubItems.Add(IntToStr(Process.ThreadsCount));
      ListItem.SubItems.Add(IntToStr(Process.PriorityClassBase));
      ListItem.SubItems.Add(IntToStr(process.MemoryInfo.WorkingSetSize));
      ListItem.SubItems.Add(Process.UserName);
      ListItem.SubItems.Add(Process.ExeFile); 
      ListItem.Data := Process;
    end;
    ListView1.Selected := FindIdInList(ListView1,CurrentItem);
    if Assigned(ListView1.Selected) then
      ListView1.Selected.MakeVisible(False);
  finally
    ListView1.Items.EndUpdate;
   end;
end;


und hier die funktion damit ich die process id in der liste krieg und diese dann wieder vergleiche:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function TForm1.FindIdInList(ListView: TListView; const ID: string): TListItem;
var
  I : Integer;
begin
  Result := nil;
  for I := 0 to ListView.Items.Count-1 do
  begin
    if CompareStr(ListView.Items[I].Caption,ID) = 0 then
    begin
      Result := ListView.Items[I];
      Exit;
    end;
  end;
end;



nun ist mein ansatz überhaupt richtig oder mach ich eigentlich die ganze zeit nur schwachsinn :) bitte helft mir ;)



mfg
ACnut

_________________
Hey, die Sonne scheint, da werd ich mal in kurzen Hosen fernsehn…
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 18.07.11 21:37 
Moin!

user profile iconacnut hat folgendes geschrieben Zum zitierten Posting springen:
ist mein ansatz überhaupt richtig
Also grundsätzlich würde ich sagen, ist das schon OK. Allerdings würde ich das Selektieren ausserhalb der Update-Klammer machen:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
procedure TForm1.DoAfterUpdateProcesses(Sender: TObject);
  var
    Process: TProcessItem;
    ListItem : TListItem;
    i: Integer;
    CurrentItem: String;
begin
  if DontUpdateList then
    Exit;

  CurrentItem := '';
  if Assigned(ListView1.Selected) then
    CurrentItem := ListView1.Selected.Caption;
  ListView1.Items.BeginUpdate;
  try
    ListView1.Clear;
    for i := 0 to ProcessInfo1.RunningProcesses.Count- 1 do begin
      Process := ProcessInfo1.RunningProcesses[i];
      ListItem := ListView1.Items.Add;
      ListItem.SubItems.Add(IntToStr(Process.ParentProcessID));
      ListItem.Caption := IntToStr(Process.ProcessID);
      //...
    end;
  finally
    ListView1.Items.EndUpdate;
  end;
  if (CurrentItem <> ''then begin
    ListView1.Selected := FindIdInList(ListView1, CurrentItem);
    if Assigned(ListView1.Selected) then
      ListView1.Selected.MakeVisible(False);
  end;
end;

function TForm1.FindIdInList(ListView: TListView; const ID: String): TListItem;
  var
    i: Integer;
begin
  for i := 0 to ListView.Items.Count-1 do begin
    Result := ListView.Items[i];
    if (CompareStr(Result.Caption, ID) = 0then
      Exit;
  end;
  Result := NIL;
end;
cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.

Für diesen Beitrag haben gedankt: acnut
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 18.07.11 21:44 
Besser wäre allerdings die Items gar nicht alle zu löschen, sondern nur die ggf. überflüssigen zu löschen bzw. fehlende zu ergänzen.

Dann stellt sich das Problem gar nicht erst, da die Items gar nicht unnötig gelöscht werden, und schneller ist es auch noch.

Für diesen Beitrag haben gedankt: acnut
acnut Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 172
Erhaltene Danke: 3

Windows 7, Windows Vista, Windows XP, Ubuntu, Kubuntu, Pardus
Delphi 2010 SV, Java Editor, VS 2010 SV
BeitragVerfasst: Di 19.07.11 13:26 
@Narses danke für den geänderten code allerdings ändern tut sich da gar nichts (war ja eig klar).
bin echt verzeifelt :(

@jaenicke also wie meinst du das? soll ich die process ids in einem array speichern und dann nach dem update dann mit der neuen liste vergleichen? und änderungen dann einfach darunter einfügen? und das geht wirklich schneller als die liste zu löschen und wieder einfügen?

gibt es vllt eine andere komponente mit der das updaten wirklich schön flüssig funktioniert?


mfg
acnut

_________________
Hey, die Sonne scheint, da werd ich mal in kurzen Hosen fernsehn…
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 19.07.11 13:51 
Moin!

user profile iconacnut hat folgendes geschrieben Zum zitierten Posting springen:
@Narses danke für den geänderten code allerdings ändern tut sich da gar nichts (war ja eig klar).
Hm, probier das mal aus:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
procedure TForm1.DoAfterUpdateProcesses(Sender: TObject);
  var
    Process: TProcessItem;
    ListItem : TListItem;
    i: Integer;
    CurrentItem: String;
begin
  CurrentItem := '';
  if Assigned(ListView1.Selected) then
    CurrentItem := ListView1.Selected.Caption;
  ListView1.Items.BeginUpdate;
  try
    ListView1.Clear;
    for i := 0 to ProcessInfo1.RunningProcesses.Count- 1 do begin
      Process := ProcessInfo1.RunningProcesses[i];
      ListItem := ListView1.Items.Add;
      ListItem.SubItems.Add(IntToStr(Process.ParentProcessID));
      ListItem.Caption := IntToStr(Process.ProcessID);
      //...
    end;
  finally
    ListView1.Items.EndUpdate;
  end;
  if (CurrentItem <> ''then begin
    ListItem := FindIdInList(ListView1, CurrentItem);
    ShowMessage(ListItem.Caption);
    ListView1.Selected := ListItem;
    if Assigned(ListView1.Selected) then
      ListView1.Selected.MakeVisible(False);
  end;
end;

function TForm1.FindIdInList(ListView: TListView; const ID: String): TListItem;
  var
    i: Integer;
begin
  for i := 0 to ListView.Items.Count-1 do begin
    Result := ListView.Items[i];
    if (Result.Caption = ID) then
      Exit;
  end;
  Result := NIL;
end;


user profile iconacnut hat folgendes geschrieben Zum zitierten Posting springen:
soll ich die process ids in einem array speichern
Wieso in einem Array, du hast doch eine Referenz in der .Data-Eigenschaft des ListItems. :nixweiss:

user profile iconacnut hat folgendes geschrieben Zum zitierten Posting springen:
und dann nach dem update dann mit der neuen liste vergleichen? und änderungen dann einfach darunter einfügen? und das geht wirklich schneller als die liste zu löschen und wieder einfügen?
Naja, wenn es sehr viele Objekte sind, schon. Aber eine Prozessliste? Das sollte man kaum merken. :| Ich würde das erstmal so lassen und schauen, warum das mit dem Fokus nicht klappt, denn daran wird auch eine andere Komponente nix ändern. ;)

user profile iconacnut hat folgendes geschrieben Zum zitierten Posting springen:
gibt es vllt eine andere komponente mit der das updaten wirklich schön flüssig funktioniert?
Falsche Frage, jetzt wird user profile iconjaenicke dir gleich den VirtualStringTree ans Herz legen. 8) OK, ist auch besser, aber auch deutlich schwerer zu verstehen. :?

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.

Für diesen Beitrag haben gedankt: acnut
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 19.07.11 14:03 
Ohne sich zu merken welcher Eintrag vorher als erster angezeigt wurde, kann das nicht klappen. Denn so wird nur der markierte wieder markiert und dieser auch sichtbar gemacht, aber die Scrollposition wird nicht wiederhergestellt. :nixweiss:

Dieser erste sichtbare Eintrag steht bei einer ListView in TopItem, bei einer TVirtualStringTree in TopNode und einer ListBox in TopIndex. Es reicht also hier zusätzlich TopItem.Index in eine Variable zu speichern und danach TopItem auf Items[OldTopIndex] zu setzen.

Für diesen Beitrag haben gedankt: acnut
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 19.07.11 14:10 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Ohne sich zu merken welcher Eintrag vorher als erster angezeigt wurde, kann das nicht klappen. Denn so wird nur der markierte wieder markiert und dieser auch sichtbar gemacht, aber die Scrollposition wird nicht wiederhergestellt. :nixweiss:
Von einer Scrollposition war bisher auch nicht die Rede. :idea: ;)

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Dieser erste sichtbare Eintrag steht bei einer ListView in TopItem, bei einer TVirtualStringTree in TopNode und einer ListBox in TopIndex. Es reicht also hier zusätzlich TopItem.Index in eine Variable zu speichern und danach TopItem auf Items[OldTopIndex] zu setzen.
Theoretisch - ja. Praktisch ist allerdings zu berücksichtigen, dass sich die Liste verändert haben könnte und z.B. der Eintrag gar nicht mehr da ist oder die Differenz TopItemIndex zu SelectedItemIndex nicht mehr passen könnte. :shock: Ganz soo einfach ist das also auch nicht. Deshalb hätte ich gesagt, dass:
ausblenden Delphi-Quelltext
1:
2:
if Assigned(ListView1.Selected) then
  ListView1.Selected.MakeVisible(False);
zwar unter Umständen einmal "Ruckelt", aber ausreichd ist.

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.

Für diesen Beitrag haben gedankt: acnut
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 19.07.11 14:16 
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Ganz soo einfach ist das also auch nicht.
Doch, zuerst den TopItem wiederherstellen und danach den zuletzt markierten falls vorhanden. ;-)

Und falls man auch den Eintrag aus dem TopItem wiederherstellen will, muss man eben dessen Inhalt speichern und danach suchen und nicht nur den Index. Dann kann man entweder nach Name oder bei Fehlschlag nach Index die Position wiederherstellen und wenn der zuletzt markierte noch existiert danach auch die Markierung.

Das habe ich hier gerade auch gemacht, wenn auch mit den VirtualTrees.

Für diesen Beitrag haben gedankt: acnut
acnut Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 172
Erhaltene Danke: 3

Windows 7, Windows Vista, Windows XP, Ubuntu, Kubuntu, Pardus
Delphi 2010 SV, Java Editor, VS 2010 SV
BeitragVerfasst: Di 19.07.11 14:25 
aha jetzt funktionerts (thanks brother @Narses, i'm pushin' tethanks buttn for you!) :D
allerdings muss ich sehr schnell sein damit ich ein prozess auswählen kann sonst rutscht es wieder zur markierten stelle (war ja unser ziel :mrgreen:)
nun will ich jetzt weiterscrollen und nicht zur markierten stelle zurückspringen:
also in welchen on(mouseup,...od anderes)...events vom listview muss ich jetzt sozusagen ein "dontupdatelist" machen?
oder kann ich das so machen, so dass ich mit der änderung des scrollbars auch die position der markierten stelle erhöhe bzw. erniedrige?



mfg
ACnut


so sieht es mal zurzeit aus:
Moderiert von user profile iconNarses: Programm als Anhang hochgeladen.
Einloggen, um Attachments anzusehen!
_________________
Hey, die Sonne scheint, da werd ich mal in kurzen Hosen fernsehn…
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 19.07.11 14:29 
user profile iconacnut hat folgendes geschrieben Zum zitierten Posting springen:
also in welchen on(mouseup,...od anderes)...events vom listview muss ich jetzt sozusagen ein "dontupdatelist" machen?
oder kann ich das so machen, so dass ich mit der änderung des scrollbars auch die position der markierten stelle erhöhe bzw. erniedrige?
Habe ich ja gerade geschrieben wie das geht. ;-)

Für diesen Beitrag haben gedankt: acnut
acnut Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 172
Erhaltene Danke: 3

Windows 7, Windows Vista, Windows XP, Ubuntu, Kubuntu, Pardus
Delphi 2010 SV, Java Editor, VS 2010 SV
BeitragVerfasst: Di 19.07.11 14:51 
Zitat:
Habe ich ja gerade geschrieben wie das geht. ;-)

danke ich lese es gerade versteh aber nur cornflakes aber ohne milch. mehr saft bzw. milch wäre von vorteil :mrgreen:

also laut der delphi hilfe bekomme ich das:
Zitat:
//
TopItem:
Gibt das oberste sichtbare Element einer Listenansicht an.

Mit TopItem können Sie das oberste sichtbare Element der Listenansicht ermitteln und daraus den Umfang eines vorangegangenen Bildlaufs ablesen. Eine Wertzuweisung an TopItem ermöglicht außerdem Der Wert der Eigenschaft TopItem kann nicht geändert werden.
//

aber wird mit dem bildlauf einfach nur die anzahl der prozesse gemeint?

du hast geschrieben das ich den topitem speichern soll (ok kein problem) und wie mach ich das mit dem "oldtopindex"?
iwas hab ich da nicht verstanden bzw. ist mir unklar und ich kanns mir nicht vorstellen :(
Zitat:
Theoretisch - ja. Praktisch ist allerdings zu berücksichtigen, dass sich die Liste verändert haben könnte und z.B. der Eintrag gar nicht mehr da ist oder die Differenz TopItemIndex zu SelectedItemIndex nicht mehr passen könnte.
eben das verwirrt mich an diesem ganzen topitem-ding

Moderiert von user profile iconNarses: Zitat repariert.

_________________
Hey, die Sonne scheint, da werd ich mal in kurzen Hosen fernsehn…
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 19.07.11 14:56 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Es reicht also hier zusätzlich TopItem.Index in eine Variable zu speichern
ausblenden Delphi-Quelltext
1:
2:
3:
4:
var
  OldTopIndex: Integer;
begin
  OldTopIndex := ListView1.TopItem.Index;
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
und danach TopItem auf Items[OldTopIndex] zu setzen.
ausblenden Delphi-Quelltext
1:
2:
if OldTopIndex < ListView1.Items.Count then
  ListView1.TopItem := ListView1.Items[OldTopIndex];

Für diesen Beitrag haben gedankt: acnut
acnut Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 172
Erhaltene Danke: 3

Windows 7, Windows Vista, Windows XP, Ubuntu, Kubuntu, Pardus
Delphi 2010 SV, Java Editor, VS 2010 SV
BeitragVerfasst: Di 19.07.11 15:19 
ausblenden Delphi-Quelltext
1:
2:
if OldTopIndex < ListView1.Items.Count then
  ListView1.TopItem := ListView1.Items[OldTopIndex];

schön und gut (jetzt versteh ich es glaube ich) allerdings ist topitem nur readonly. wie mach ich das jetzt? mit assign?

_________________
Hey, die Sonne scheint, da werd ich mal in kurzen Hosen fernsehn…
Tryer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 226
Erhaltene Danke: 7



BeitragVerfasst: Mi 20.07.11 05:12 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var
  TpItemIndex: Integer;
  TpItemPos, Pos: TPoint;
begin
  TpItemIndex :=  ListView.TopItem.Index;
  TpItemPos :=  ListView.TopItem.GetPosition;

  // mach was

  Pos := ListView.Items[TpItemIndex].GetPosition;
  ListView.Scroll(Pos.X - TpItemPos.X, Pos.Y - TpItemPos.Y);
end;


Grüsse, Dirk

Für diesen Beitrag haben gedankt: acnut
acnut Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 172
Erhaltene Danke: 3

Windows 7, Windows Vista, Windows XP, Ubuntu, Kubuntu, Pardus
Delphi 2010 SV, Java Editor, VS 2010 SV
BeitragVerfasst: Mi 20.07.11 14:30 
user profile iconTryer hat folgendes geschrieben Zum zitierten Posting springen:
[delphi]var
TpItemIndex: Integer;
TpItemPos, Pos: TPoint;
begin
...
Grüsse, Dirk



wenn ich mehrmals auf danke drücken dürfte, dann würde ich mindestens 20 mal weiter drücken ;)

erstens danke für Narses
zweitens danke für jaenicke
drittens danke für Tryer
ihr seid die coolsten ;)

_________________
Hey, die Sonne scheint, da werd ich mal in kurzen Hosen fernsehn…