Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   ListView TopItem (https://www.delphipraxis.net/191385-listview-topitem.html)

EWeiss 10. Jan 2017 07:11


ListView TopItem
 
Wie kann ich mit Win32Api mitteln den ausgewählten Eintrag des ListView an erster Position setzen (Scrollen)

Bei der ListBox geht das schön.. ;)
Delphi-Quellcode:
procedure TSkinListBox.ListSetTopIndex(hList: hWnd; nTopIndex: Integer);
begin
  if nTopIndex > 0 then
    dec(nTopIndex);
  if hList <> 0 then
    SendMessageW(hList, LB_SETTOPINDEX, nTopIndex, 0);

  if assigned(LVScrollBar) then
    LVScrollBar.Value := nTopIndex;
end;
Für die ListView gibt es kein SetTopItem oder ähnlich.

jemand ne Idee?

gruss

HolgerX 10. Jan 2017 08:02

AW: ListView TopItem
 
Hmm..

Delphi-Quellcode:
procedure LWScrollUp(AListView : TListView);
begin
  if AListView.Items.Count > 0 then
    AListView.Items[0].MakeVisible(False);
end;

Sherlock 10. Jan 2017 08:04

AW: ListView TopItem
 
Nicht VCL sondern Win32 API.

Sherlock

HolgerX 10. Jan 2017 08:10

AW: ListView TopItem
 
Hmm..

OK, mal in den Source reingeschaut und da steht (Delpi 6):

Delphi-Quellcode:
procedure TListItem.MakeVisible(PartialOK: Boolean);
begin
  ListView_EnsureVisible(Handle, Index, PartialOK);
end;


function ListView_EnsureVisible(hwndLV: HWND; i: Integer; fPartialOK: Bool): Bool;
begin
  Result := SendMessage(hwndLV, LVM_ENSUREVISIBLE, i,
    MakeLong(Integer(fPartialOK), 0)) <> 0;
end;
Somit sollte er das SendMessage auch direkt verwenden können.

EWeiss 10. Jan 2017 08:31

AW: ListView TopItem
 
Ich habe es jetzt mal so versucht.
Das Problem ist mal wieder .. es geht dann wieder nicht.

Delphi-Quellcode:
procedure TSkinListView.SetTopItem(hwndLV: HWND; nItem: Integer);
var
  TopIndex: Integer;
  ItemIndex: TLVItemIndex;
  Rect: TRect;
begin

  ListView_EnsureVisible(hwndLV, nItem, true);
  TopIndex := ListView_GetTopIndex(hwndLV);
  ItemIndex.iItem := TopIndex;
  ItemIndex.iGroup := -1;
  ListView_GetItemIndexRect(hwndLV, ItemIndex, nItem, LVIR_BOUNDS, Rect);
  ListView_Scroll(hwndLV, Rect.Left, Rect.Top);
  if Visible then
    SetFocus(hwndLV);

end;
Kann jemand sehen was nicht stimmt?
Einmal ist der Eintrag unten selektiert und manchmal oben.

gruss

HolgerX 10. Jan 2017 09:17

AW: ListView TopItem
 
Hmm..

Bei allen Beispielen wurde

Delphi-Quellcode:
ListView_EnsureVisible(hwndLV, nItem, false);

(false) verwendet.

Ach, und verwende mal:

Delphi-Quellcode:
Scroll(hwndLV, 0 , R.Top - (R.Bottom - R.Top));

bra 10. Jan 2017 09:18

AW: ListView TopItem
 
Ich vermute das hängt vom Ausgangspunkt ab. Wenn er von unten anfängt zu scrollen, ist es unten markiert, von oben angefangen oben.

EWeiss 10. Jan 2017 09:29

AW: ListView TopItem
 
Zitat:

Zitat von HolgerX (Beitrag 1358549)
Hmm..

Bei allen Beispielen wurde

Delphi-Quellcode:
ListView_EnsureVisible(hwndLV, nItem, false);

(false) verwendet.

Ach, und verwende mal:

Delphi-Quellcode:
Scroll(hwndLV, 0 , R.Top - (R.Bottom - R.Top));

Ich sehe kein False.. ;)

Delphi-Quellcode:
ListView_EnsureVisible(hwndLV, nItem, true);


Oder meinst du ich sollte false verwenden?
Wenn es so ist werde ich auch das mal versuchen.

Den anderen Vorschlag werde ich mal versuchen Danke.

PS:
Hab es mal versucht keine Änderung denke da ist was Faul mit
ListView_GetItemIndexRect

gruss

EWeiss 10. Jan 2017 10:54

AW: ListView TopItem
 
Ok hier die neue funktionierende Version.
Delphi-Quellcode:
procedure TSkinListView.SetTopItem(hwndLV: HWND; nItem: Integer);
var
  lvItemsPerPage: Integer;
  lvTopIndex: Integer;
begin

   lvTopIndex := ListView_GetTopIndex(hwndLV) + 1;
   lvItemsPerPage := ListView_GetCountPerPage(hwndLV);

   if lvTopIndex > nItem then
     ListView_EnsureVisible(hwndLV, nItem, false)
   else
   if (nItem - lvTopIndex) >= lvItemsPerPage then
   begin
    if (nItem + lvItemsPerPage) > ListView_GetItemCount(hwndLV)-1 then
      ListView_EnsureVisible(hwndLV, ListView_GetItemCount(hwndLV)-1, false)
    else
    ListView_EnsureVisible(hwndLV, nItem + lvItemsPerPage - 1, false);
   end;

  if Visible then
    SetFocus(hwndLV);

end;
falls es mal jemand braucht.

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:35 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz