Einzelnen Beitrag anzeigen

MathiasSimmack
(Gast)

n/a Beiträge
 
#4

Re: ListView Elemente Gruppieren: Terminierung der IDs?!

  Alt 2. Mär 2005, 22:05
So funktioniert das nicht. Halte mir bitte zugute, dass ich den Beitrag damals geschrieben habe, um zu zeigen, wie die Gruppierung funktioniert. Ich glaube in den Win32-API-Tutorials müsste es vollständiger drin stehen. Speziell der Befehl "ListView_RemoveAllGroups" sollte erwähnt werden.

Wie auch immer, im angesprochenen MovieOrganizer von Chakotay habe ich eine einzige Prozedur, die für die Gruppierung sorgt:
Delphi-Quellcode:
resourcestring
  ONEMEDIA = 'One medium';
  TWOMEDIA = 'Two media';
  MULTIMEDIA = 'Multi media';

  SINGLECOPY = 'Unique copy';
  MULTICOPY = 'Multi copies';

  PIC1A = 'excellent picture';
  PIC1 = 'very good picture';
  PIC2 = 'good picture';
  PIC3 = 'acceptable picture';
  PIC4 = 'lousy picture';
  PIC5 = 'Did you see something?';
  PIC6 = 'more snow than anything else';

  SND1A = 'excellent sound';
  SND1 = 'very good sound';
  SND2 = 'good sound';
  SND3 = 'this bass is acceptable';
  SND4 = 'What does he say?';
  SND5 = 'Louder!';
  SND6 = 'Is this a silent movie?';

  AVAIL = 'available@location';
  LENT = 'lent to';

  NOCOMMENT = 'no comment';
  OTHER = 'other titles';


procedure RebuildGroups(const hLV: HWND; iSubItem: integer;
  fEnableView: boolean);
const
  MIN_GROUP_ID = 2000;
var
  i : integer;
  j : integer;
  fFound : boolean;
  buf : string;
  wbuf : array[0..MAX_PATH]of widechar;
  gi : integer;
  group : TLVGroup;
  lvi : TLVItem60;
begin
  if(not WinXP) then exit;
  if(ListView_GetItemCount(hLV) = 0) then exit;

  // remove all groups
  ListView_RemoveAllGroups(hLV);

  for i := 0 to ListView_GetItemCount(hLV) - 1 do begin
    // get item's caption
    SetLength(buf,MAX_PATH); ZeroMemory(@buf[1],MAX_PATH);
    ListView_GetItemText(hLV,i,iSubItem,@buf[1],MAX_PATH);

    // something to do?
    if(buf <> '') then begin
      fFound := false;
      ZeroMemory(@wbuf,sizeof(wbuf));

      case iSubItem of
        // Type groups, & Sound format groups
        1,
        2:
          lstrcpyW(wbuf,pwidechar(widestring(buf)));
        // Media groups
        3:
          begin
            j := StrToIntDef(buf,1);
            if(j = 1) then lstrcpyW(wbuf,pwidechar(widestring(ONEMEDIA)))
              else if(j = 2) then lstrcpyW(wbuf,pwidechar(widestring(TWOMEDIA)))
                else lstrcpyW(wbuf,pwidechar(widestring(MULTIMEDIA)));
          end;
        // Copy groups
        4:
          begin
            j := StrToIntDef(buf,1);
            if(j = 1) then lstrcpyW(wbuf,pwidechar(widestring(SINGLECOPY)))
                else lstrcpyW(wbuf,pwidechar(widestring(MULTICOPY)));
          end;
        // Quality group (pic)
        5:
          begin
            if(lstrcmp(pchar(buf),'1+') = 0) then
              lstrcpyW(wbuf,pwidechar(widestring(PIC1A)))
            else if(buf[1] = '1') then
              lstrcpyW(wbuf,pwidechar(widestring(PIC1)))
            else if(buf[1] = '2') then
              lstrcpyW(wbuf,pwidechar(widestring(PIC2)))
            else if(buf[1] = '3') then
              lstrcpyW(wbuf,pwidechar(widestring(PIC3)))
            else if(buf[1] = '4') then
              lstrcpyW(wbuf,pwidechar(widestring(PIC4)))
            else if(buf[1] = '5') then
              lstrcpyW(wbuf,pwidechar(widestring(PIC5)))
            else
              lstrcpyW(wbuf,pwidechar(widestring(PIC6)));
          end;
        // Quality group (sound)
        6:
          begin
            if(lstrcmp(pchar(buf),'1+') = 0) then
              lstrcpyW(wbuf,pwidechar(widestring(SND1A)))
            else if(buf[1] = '1') then
              lstrcpyW(wbuf,pwidechar(widestring(SND1)))
            else if(buf[1] = '2') then
              lstrcpyW(wbuf,pwidechar(widestring(SND2)))
            else if(buf[1] = '3') then
              lstrcpyW(wbuf,pwidechar(widestring(SND3)))
            else if(buf[1] = '4') then
              lstrcpyW(wbuf,pwidechar(widestring(SND4)))
            else if(buf[1] = '5') then
              lstrcpyW(wbuf,pwidechar(widestring(SND5)))
            else
              lstrcpyW(wbuf,pwidechar(widestring(SND6)))
          end;
        // "Lent to" groups
        7:
          begin
            if(buf[1] = #0) then lstrcpyW(wbuf,pwidechar(widestring(AVAIL)))
              else lstrcpyW(wbuf,pwidechar(widestring(LENT)));
          end;
        // Comment groups
        8:
          begin
            if(buf[1] = #0) then
              lstrcpyW(wbuf,pwidechar(widestring(NOCOMMENT)))
            else
              lstrcpyW(wbuf,pwidechar(widestring(OTHER)))
          end;
        // Title groups
        else begin
          SetLength(buf,1); buf[1] := UPCASE(buf[1]);
          if(buf[1] in['A'..'Z']) then
            lstrcpyW(wbuf,pwidechar(widestring(buf)))
          else
            lstrcpyW(wbuf,pwidechar(widestring(OTHER)));
        end;
      end;

      // does the group's name exist?
      gi := 0;
      while(true) do begin
        ZeroMemory(@group,sizeof(TLVGroup));
        group.cbSize := sizeof(TLVGroup);
        group.mask := LVGF_HEADER;

        // upps!
        if(ListView_GetGroupInfo(hLV,
          MIN_GROUP_ID+gi,group) = -1) then break;

        // yes
        if(lstrcmpiW(wbuf,group.pszHeader) = 0) then begin
          fFound := true;
          break;
        end;

        inc(gi);
      end;

      // name not found, create group
      if(not fFound) then begin
        ZeroMemory(@group,sizeof(TLVGroup));

        group.cbSize := sizeof(TLVGroup);
        group.mask := LVGF_HEADER or LVGF_GROUPID;
        group.iGroupId := MIN_GROUP_ID + gi;
        group.pszHeader := wbuf;
        group.cchHeader := lstrlenW(wbuf);
        group.uAlign := LVGA_HEADER_CENTER;

        ListView_InsertGroup(hLV,-1,group);
      end;

      // send the item to this group
      ZeroMemory(@lvi,sizeof(lvi));
      lvi.mask := LVIF_GROUPID;
      lvi.iItem := i;
      lvi.iGroupId := MIN_GROUP_ID + gi;
      SendMessage(hLV,LVM_SETITEM,0,LPARAM(@lvi));
    end;
  end;

  // enable Group view?
  ListView_EnableGroupView(hLV,fEnableView);
end;
Und so wird sie bspw. im "OnColumnClick"-Ereignis der List-View aufgerufen:
Delphi-Quellcode:
procedure TMO18Form.MovieListColumnClick(Sender: TObject;
  Column: TListColumn);
begin
  ColumnToSort := Column.Index; (Sender as tCustomListView).AlphaSort;

  if(WinXP) then begin
    ListView_SetSelectedColumn(MovieList.Handle,ColumnToSort);
    RebuildGroups(MovieList.Handle,ColumnToSort,IDM_GROUPING.Checked);
  end;
end;
Je nach angeklickter Spalte erstellt sie dabei neue Gruppen. Mehr ist nicht nötig.
  Mit Zitat antworten Zitat