Q&A

  • stringrid 로 title 클릭시 정렬시키는 컴포넌트를 만들려고 하느데요?
TstringGrid 를 상속받아서 그리드의 title 를 클릭시 title에 정렬를 하게 하려고 하거든요
어떻게 하면 좋을까요
1  COMMENTS
  • Profile
    히히 2003.12.09 03:51
    예전에 그런 방식으로 정렬을 했던 경험이 있어서 관련 소스를
    적어 드립니다.

    소트는 TList의 Sort메소드를 이용하면 편합니다.
    코딩도 의외로 간결하죠...

    procedure TSEHStringGrid.Sort(SortCol: integer);
    type
      PStrList = ^AStrList;
      AStrList = record
        AKeyItem : string;
        AKeyItemN : integer;
        AItemRecord: TStrings;
      end;

    var
      StrList: TList;
      AItem: PStrList;
      i: integer;
      TempStrList: array of TStringList;
      DataType : Char;

    function  StrCompareList(Item1,Item2:Pointer):Integer;
    var
    stTemp1, stTemp2 :PStrList;
    begin
      stTemp1:= Item1;
      stTemp2:= Item2;
      if stTemp1^.AKeyItem < stTemp2^.AKeyItem then Result:= -1
      else
        if stTemp1^.AKeyItem = stTemp2^.AKeyItem then Result:= 0
        else
          Result:= 1;
    end;

    function  NumberCompareList(Item1,Item2:Pointer):Integer;
    var
    stTemp1, stTemp2 :PStrList;
    begin
      stTemp1:= Item1;
      stTemp2:= Item2;
      if stTemp1^.AKeyItemN < stTemp2^.AKeyItemN then Result:= -1
      else
        if stTemp1^.AKeyItemN = stTemp2^.AKeyItemN then Result:= 0
        else
          Result:= 1;
    end;

    begin
      DataType := FDisplayFormat[SortCol + 1];
      if FixedRows <= 0 then begin
         MessageBox(Parent.Handle, 'FixedRow가 0보다 커야합니다','확장 스트링그리드',MB_OK);
         exit;
      end;
      StrList := TList.Create;
      try
        for i := 1 to RowCount - 1 do begin
            New(AItem);
            if DataType = 'N' then begin
               if IsNumber(Cells[SortCol, i]) then
                 AItem^.AKeyItemN := StrToInt(Cells[SortCol, i])
               else
                 AItem^.AKeyItemN := 0;
               AItem^.AKeyItem := '';
            end
            else begin
              AItem^.AKeyItemN := 0;
              AItem^.AKeyItem := Cells[SortCol, i];
            end;
            AItem^.AItemRecord :=  Rows[i];
            StrList.Add(AItem);
        end;
        if DataType = 'N' then
          StrList.Sort(@NumberCompareList)
        else
          StrList.Sort(@StrCompareList);
        SetLength(TempStrList, StrList.Count);
        for i := 0 to (StrList.Count - 1) do begin
          TempStrList[i] := TStringList.Create;
          TempStrList[i].AddStrings(PStrList(StrList.Items[i])^.AItemRecord);
        end;
    //    ZapGrid;
        for i := 0 to (StrList.Count - 1) do begin
          Rows[i+1] := TempStrList[i];
        end;
      finally
        for i := 0 to (StrList.Count - 1) do
        begin
          AItem := StrList.Items[i];
          Dispose(AItem);
          TempStrList[i].Free;
        end;
        StrList.Free;
      end;
    end;

    procedure DrawRaisedInner(hd: THandle; Rect: TRect);
    begin
    DrawEdge(hd, Rect, BDR_RAISEDINNER, BF_RIGHT or BF_BOTTOM);
    DrawEdge(hd, Rect, BDR_RAISEDINNER, BF_LEFT or BF_TOP);
    end;

    procedure DrawSunkenOuter(hd: THandle; Rect: TRect);
    begin
    DrawEdge(hd, Rect, BDR_SUNKENOUTER, BF_RIGHT or BF_BOTTOM);
    DrawEdge(hd, Rect, BDR_SUNKENOUTER, BF_LEFT or BF_TOP);
    end;

    procedure TSEHStringGrid.MouseDown(Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      inherited;
      if Not FSortEnabled then exit;
      FCurrent := MouseCoord(X, Y);
      FRect := CellRect(FCurrent.X, FCurrent.Y);
      if (FCurrent.Y >= 0) and (FCurrent.Y < FixedRows) and (FCurrent.X >= 0) then
      begin
        FMouseDown := True;
        DrawSunkenOuter(Canvas.Handle, FRect);
      end;
    end;

    procedure TSEHStringGrid.MouseMove(Shift: TShiftState; X, Y: Integer);
    begin
      inherited;
      if Not FSortEnabled then exit;
      if not FMouseDown then exit;
      if PtInRect(FRect, Point(X, Y)) then
        DrawSunkenOuter(Canvas.Handle, FRect)
      else
        DrawRaisedInner(Canvas.Handle, FRect);
    end;

    //Title에서 마우스를 업하면...해당 칼럼을 기준으로 소팅한다
    procedure TSEHStringGrid.MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer);
    var
      HeaderStore : TStringList;
    begin
      inherited;
      HeaderStore := TStringList.Create;
      try
        if Not FSortEnabled then exit;
        if not FMouseDown then exit;
        FMouseDown := False;
        HeaderStore.AddStrings(Rows[0]);
        DrawRaisedInner(Canvas.Handle, FRect);
        if (FCurrent.Y >= 0) and (FCurrent.Y < FixedRows) and (FCurrent.X >= 0) then
           Sort(FCurrent.X);
        Rows[0] := HeaderStore;
      finally
        HeaderStore.Free;
      end;
    end;