cxheader.pas

来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,754 行 · 第 1/4 页

PAS
1,754
字号
begin
  UpdateSections;
end;

procedure TcxCustomHeader.RestoreScreenCursor;
begin
  if FScreenCursorSaved then
  begin
    FScreenCursorSaved := False;
    Screen.Cursor := FScreenCursor;
  end;
end;

procedure TcxCustomHeader.SetScreenCursor(ACursor: TCursor);
begin
  if not FScreenCursorSaved then
  begin
    FScreenCursor := Screen.Cursor;
    FScreenCursorSaved := True;
  end;
  Screen.Cursor := ACursor;
end;

procedure TcxCustomHeader.WMSize(var Message: TWMSize);
begin
  inherited;
  FitToClientWidth;
end;

procedure TcxCustomHeader.WMWindowPosChanged(var Message: TWMWindowPosChanged);
begin
  inherited;
  Invalidate;
end;

procedure TcxCustomHeader.HDMGetItemCount(var Message: TMessage);
begin
  Message.Result := Sections.Count;
end;

procedure TcxCustomHeader.HDMGetItemInfo(var Message: TCMHeaderItemInfo);

  function GetState(AIndex: Integer): TcxButtonState;
  begin
    if not Enabled then
      Result := cxbsDisabled
    else
      if IsSectionIndex(AIndex) then
        Result := FSections[AIndex].State
      else
        Result := cxbsNormal;
  end;

var
  AIndex: Integer;
  AHeaderItemInfo: PHeaderItemInfo;
begin
  AIndex := Message.Index;
  AHeaderItemInfo := Message.HeaderItemInfo;
  ZeroMemory(AHeaderItemInfo, SizeOf(THeaderItemInfo));
  AHeaderItemInfo.ImageIndex := -1;
  AHeaderItemInfo.State := GetState(AIndex);
  AHeaderItemInfo.Rect := GetSectionRect(AIndex);
  if IsSectionIndex(AIndex) then
  begin
    AHeaderItemInfo.Text := FSections[AIndex].Text;
    AHeaderItemInfo.SectionAlignment := FSections[AIndex].FAlignment;
    AHeaderItemInfo.ImageIndex := FSections[AIndex].ImageIndex;
    AHeaderItemInfo.SortOrder := FSections[AIndex].SortOrder;
  end;
  Message.HeaderItemInfo := AHeaderItemInfo;
end;

procedure TcxCustomHeader.SetImages(Value: TCustomImageList);
begin
  cxSetImageList(Value, FImages, FImagesChangeLink, Self);
end;

procedure TcxCustomHeader.DoSectionClickEvent(Section: TcxHeaderSection);
begin
  if Assigned(FOnSectionClick) then FOnSectionClick(Self, Section);
end;

procedure TcxCustomHeader.DoSectionChange;
begin
  if Assigned(OnSectionChange) then
    OnSectionChange(Self);
end;

procedure TcxCustomHeader.DoSectionsChange;
begin
  if Assigned(OnSectionsChange) then
    OnSectionsChange(Self);
end;

procedure TcxCustomHeader.DoSectionDragEvent(FromSection, ToSection: TcxHeaderSection;
  var AllowDrag: Boolean);
begin
  if Assigned(FOnSectionDrag) then
    FOnSectionDrag(Self, FromSection, ToSection, AllowDrag);
  FSectionDragged := AllowDrag;
end;

procedure TcxCustomHeader.DoSectionEndDragEvent;
begin
  if Assigned(FOnSectionEndDrag) then FOnSectionEndDrag(Self);
end;

procedure TcxCustomHeader.DoSectionResizeEvent(Section: TcxHeaderSection);
begin
  if Assigned(FOnSectionResize) then FOnSectionResize(Self, Section);
end;

procedure TcxCustomHeader.DoSectionEndResizeEvent(Section: TcxHeaderSection);
begin
  if Assigned(FOnSectionEndResize) then
    FOnSectionEndResize(Self, Section);
  if not FSectionsFitCalculating then
    FitToClientWidth;
end;

procedure TcxCustomHeader.DoSectionTrackEvent(Section: TcxHeaderSection;
  Width: Integer; State: TcxSectionTrackState);
begin
  if Assigned(FOnSectionTrack) then FOnSectionTrack(Self, Section, Width, State);
end;

procedure TcxCustomHeader.Paint;
var
  I: Integer;
begin
  inherited Paint;

  Canvas.Font.Assign(Font);
  Canvas.Brush.Color := Self.Color;

  if (FSections.Count = 0) and not IsInnerControl and IsDesigning then
  begin
    Canvas.Pen.Style := psDash;
    Windows.Rectangle(Canvas.Handle, ClientRect.Left, ClientRect.Top,
      ClientRect.Right, ClientRect.Bottom);
  end
  else
    for I := 0 to FSections.Count do
      DrawSection(I);
end;

function TcxCustomHeader.GetSectionRect(Index: Integer): TRect;
var
  ASectionWidths: TcxHeaderSectionWidths;
  I: Integer;
begin
  SetLength(ASectionWidths, Sections.Count);
  for I := 0 to Sections.Count - 1 do
    ASectionWidths[I] := Sections[I].Width;
  Result := GetSectionRectBySectionWidths(Width, ASectionWidths, Index);
end;

function TcxCustomHeader.GetSectionRectBySectionWidths(AHeaderWidth: Integer;
  const ASectionWidths: TcxHeaderSectionWidths; AIndex: Integer): TRect;
var
  I: Integer;
begin
  Result := cxEmptyRect;
  if (AIndex >= 0) and (AIndex <= Sections.Count) then
  begin
    for I := 0 to AIndex - 1 do
      Inc(Result.Left, ASectionWidths[I]);
    if AIndex = Sections.Count then
      Result.Right := AHeaderWidth
    else
      Result.Right := Result.Left + ASectionWidths[AIndex];
    Result.Bottom := Height;
  end;
end;

procedure TcxCustomHeader.WMCaptureChanged(var Message: TMessage);
begin
  if (FState = hsNone) then
    Exit;

  case FState of
    hsSized:
      begin
        if not ResizeUpdate then
          ReleaseSplitLine;
        UpdateSizedSection;
      end;
    hsDragged:
      begin
        DoSectionEndDragEvent;
        RestoreScreenCursor;
      end;
  end;
  FState := hsNone;
  SelectedSectionIndex := -1;
end;

procedure TcxCustomHeader.WMLButtonDown(var Message: TWMLButtonDown);
begin
  inherited;
  if csDesigning in ComponentState then
    Exit;

  MouseCapture := True;
  if MouseOnSizer then
  begin
    FState := hsSized;
    if not ResizeUpdate then
      InitResize(SizedSection.Right);
    DoSectionTrackEvent(SizedSection, SizedSection.Width, tsTrackBegin);
    FPrevMousePos := Message.XPos;
  end
  else
  begin
    if (UnderMouseSectionIndex <> -1) and UnderMouseSection.AllowClick then
    begin
      FState := hsPressed;
      HotSectionIndex := -1;
      SelectedSectionIndex := UnderMouseSectionIndex;
    end;
  end;
end;

procedure TcxCustomHeader.WMMouseMove(var Message: TWMMouseMove);
var
  ACalcNewWidth: Integer;
begin
  inherited;
  if csDesigning in ComponentState then
    Exit;

  UpdateUnderMouseSection;

  case FState of
    hsSized:
      begin
        ACalcNewWidth := SizedSection.Width + Message.XPos - FPrevMousePos;
        if ACalcNewWidth < SizedSection.MinWidth then
          ACalcNewWidth := SizedSection.MinWidth
        else
          if ACalcNewWidth > SizedSection.MaxWidth then
            ACalcNewWidth := SizedSection.MaxWidth;

        if not ResizeUpdate then
        begin
          if FLastDrawPosOnMove <> ( SizedSection.Left + ACalcNewWidth) then
          begin
            DrawSplitLine(FLastDrawPosOnMove);
            DrawSplitLine(SizedSection.Left + ACalcNewWidth);
          end;
        end
        else
        begin
          FPrevMousePos := FPrevMousePos + ACalcNewWidth - SizedSection.Width;
          SizedSection.Width := ACalcNewWidth;
          DoSectionTrackEvent(SizedSection, SizedSection.Width, tsTrackMove);
        end;

        DoSectionResizeEvent(SizedSection);
      end;
    hsPressed:
      begin
        if FDragReorder then
        begin
          FSectionDragged := False;
          FState := hsDragged;
          UpdateDraggedSection;
        end
        else
          UpdatePressedSection;
      end;
    hsDragged:
      begin
        UpdateDraggedSection;
        if SelectedSectionIndex <> UnderMouseSectionIndex then
          HotSectionIndex := UnderMouseSectionIndex
        else
          HotSectionIndex := -1;
      end;
    hsNone:
      begin
        UpdateSizedSection;
        if MouseOnSizer then
          HotSectionIndex := -1
        else
          HotSectionIndex := UnderMouseSectionIndex;
      end;
  end;

  BeginMouseTracking(Self, ClientRect, Self);
end;

procedure TcxCustomHeader.WMLButtonUp(var Message: TWMLButtonUp);
var
  ASection: TcxHeaderSection;
  AState: TShiftState;
begin
  inherited;
  if IsDesigning then
    Exit;

  case FState of
    hsSized:
      begin
        if not ResizeUpdate then
        begin
          SizedSection.Width := FLastDrawPosOnMove - SizedSection.Left;
          ReleaseSplitLine;
        end;
        DoSectionTrackEvent(SizedSection, SizedSection.Width, tsTrackEnd);
        UpdateSizedSection;
      end;
    hsDragged:
      begin
        if FSectionDragged then
          DoSectionEndDrag;
        RestoreScreenCursor;
        UpdateSections;
      end;
    hsPressed:
      begin
        if UnderMouseSectionIndex = SelectedSectionIndex then
        begin
          AState := KeysToShiftState(Message.Keys);
          ASection := SelectedSection;
          DoSectionClickEvent(ASection);
          ChangeSectionSortOrder(ASection,
            GetNextSortOrder(ASection.SortOrder, ssCtrl in AState),
            [ssCtrl, ssShift] * AState = []);
        end;
      end;
  end;
  FState := hsNone;
  MouseCapture := False;
  SelectedSectionIndex := -1;
end;

function TcxCustomHeader.GetSectionIndexAtPos(X, Y: Integer; AIncludeNonSectionPart: Boolean): Integer;
var
  I: Integer;
  ACount: Integer;
begin
  Result := -1;
  if AIncludeNonSectionPart then
    ACount := FSections.Count
  else
    ACount := FSections.Count - 1;
  for I := 0 to ACount do
    if PtInRect(GetSectionRect(I), Point(X, Y)) and PtInRect(ClientRect, Point(X, Y)) then
    begin
      Result := I;
      Break;
    end;
end;

function TcxCustomHeader.GetSelectedSection: TcxHeaderSection;
begin
  Result := FSections[SelectedSectionIndex];
end;

function TcxCustomHeader.GetSizedSection: TcxHeaderSection;
begin
  Result := FSections[SizedSectionIndex];
end;

function TcxCustomHeader.GetUnderMouseSection: TcxHeaderSection;
begin
  Result := FSections[UnderMouseSectionIndex];
end;

function TcxCustomHeader.IsSectionIndex(AIndex: Integer): Boolean;
begin
  Result := (AIndex >= 0) and (AIndex < FSections.Count);
end;

procedure TcxCustomHeader.HeaderMouseLeave;
begin
  Perform(CM_MOUSELEAVE, 0, 0);
end;

procedure TcxCustomHeader.SetHotSectionIndex(Value: Integer);
begin
  if (FHotSectionIndex <> Value) then
  begin
    SetSectionState(FHotSectionIndex, cxbsNormal);
    FHotSectionIndex := Value;
    SetSectionState(FHotSectionIndex, cxbsHot);
  end;
end;

procedure TcxCustomHeader.SetMouseOnSizer(Value: Boolean);
begin
  if FMouseOnSizer <> Value then
  begin
    FMouseOnSizer := Value;
    if FMouseOnSizer then
      SetScreenCursor(crHSplit)
    else
      RestoreScreenCursor;
  end;
end;

procedure TcxCustomHeader.SetSectionState(AIndex: Integer; AState: TcxButtonState);
begin
  if (Sections.Count > 0) and (AIndex >= 0) and (AIndex < Sections.Count) then
    FSections[AIndex].State := AState;
end;

procedure TcxCustomHeader.SetSelectedSectionIndex(Value: Integer);
begin
  if Value <> -1 then
    SetSectionState(Value, cxbsPressed)
  else
    SetSectionState(FSelectedSectionIndex, cxbsNormal);
  FSelectedSectionIndex := Value;
end;

procedure TcxCustomHeader.SetSizedSectionIndex(Value: Integer);
begin
  FSizedSectionIndex := Value;
  if FSizedSectionIndex = -1 then
    MouseOnSizer := False
  else
    MouseOnSizer := True;
end;

procedure TcxCustomHeader.SetUnderMouseSectionIndex(Value: Integer);
begin
  FUnderMouseSectionIndex := Value;
end;

procedure TcxCustomHeader.UpdateDraggedSection;
begin
  if UnderMouseSectionIndex <> -1 then
  begin
    SetScreenCursor(crDrag);
    DoSectionDrag(SelectedSection, UnderMouseSection);
  end

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?