cxheader.pas
来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,754 行 · 第 1/4 页
PAS
1,754 行
ATextRect.Left := Result.Left + AImages.Width + ImageTextOffset;
taRightJustify:
begin
Result.Left := ATextRect.Right - ATextWidth - AImages.Width - ImageTextOffset;
if Result.Left < ATextRect.Left then
begin
Result.Left := ATextRect.Left;
Inc(ATextRect.Left, AImages.Width + ImageTextOffset);
AHeaderItemInfo.SectionAlignment := taLeftJustify
end;
end;
taCenter:
begin
Result.Left := ATextRect.Left + ((ATextRect.Right - ATextRect.Left) -
AImages.Width - ImageTextOffset - ATextWidth) div 2;
if Result.Left < ATextRect.Left then
begin
Result.Left := ATextRect.Left;
AHeaderItemInfo.SectionAlignment := taLeftJustify
end;
Inc(ATextRect.Left, AImages.Width + ImageTextOffset);
end;
end;
end;
var
ANormalContentRect, ATextRect, AImageRect: TRect;
AClipRegion: TcxRegion;
ASavedBrushColor: TColor;
AItemCount: Integer;
AHeaderRect: TRect;
AHeaderItemInfo: THeaderItemInfo;
begin
AItemCount := Header_GetItemCount(AHeaderHandle);
GetWindowRect(AHeaderHandle, AHeaderRect);
AHeaderRect := Rect(0, 0, AHeaderRect.Right - AHeaderRect.Left,
AHeaderRect.Bottom - AHeaderRect.Top);
if AItemCount = 0 then
begin
ACanvas.FillRect(AHeaderRect);
Exit;
end;
SendGetStructMessage(AHeaderHandle, CM_GETHEADERITEMINFO, AIndex, AHeaderItemInfo);
if (AIndex = AItemCount) then
AHeaderItemInfo.Rect.Right := AHeaderRect.Right + 10
else
if not ALookAndFeel.NativeStyle and (ALookAndFeel.Kind = lfUltraFlat) then
Inc(AHeaderItemInfo.Rect.Right);
ANormalContentRect := ALookAndFeel.Painter.HeaderControlSectionContentBounds(AHeaderItemInfo.Rect, cxbsNormal);
ATextRect := GetTextRect(ANormalContentRect, AHeaderItemInfo.SortOrder);
if Assigned(AImages) and (AHeaderItemInfo.ImageIndex >= 0) then
AImageRect := GetImageRect(ATextRect, AHeaderItemInfo);
ASavedBrushColor := ACanvas.Brush.Color;
AClipRegion := ACanvas.GetClipRegion;
try
ACanvas.SetClipRegion(TcxRegion.Create(AHeaderItemInfo.Rect), roIntersect);
ALookAndFeel.Painter.DrawHeaderControlSection(ACanvas, AHeaderItemInfo.Rect, ATextRect,
[nRight], cxBordersAll, AHeaderItemInfo.State, AHeaderItemInfo.SectionAlignment, vaCenter, False,
True, AHeaderItemInfo.Text, ACanvas.Font, ACanvas.Font.Color, ACanvas.Brush.Color);
ACanvas.SetClipRegion(TcxRegion.Create(ANormalContentRect), roIntersect);
if Assigned(AImages) and (AHeaderItemInfo.ImageIndex >= 0) then
ACanvas.DrawImage(AImages, AImageRect.Left, AImageRect.Top +
(AImageRect.Bottom - AImageRect.Top - AImages.Height) div 2,
AHeaderItemInfo.ImageIndex);
DrawSortingMark(AHeaderItemInfo.Rect, AHeaderItemInfo.SortOrder);
finally
ACanvas.SetClipRegion(AClipRegion, roSet);
ACanvas.Brush.Color := ASavedBrushColor;
end;
end;
function SendGetStructMessage(Handle: HWND; Msg: UINT; WParam: WPARAM;
var LParam): LRESULT;
begin
Result := SendMessage(Handle, Msg, WParam, Integer(@LParam));
end;
function GetNextSortOrder(ASortOrder: TcxHeaderSortOrder;
ADeleteSorting: Boolean): TcxHeaderSortOrder;
begin
if ADeleteSorting then
Result := soNone
else
if ASortOrder = soAscending then
Result := soDescending
else
Result := soAscending;
end;
{ TcxCustomHeader }
procedure TcxCustomHeader.CMBiDiModeChanged(var Message: TMessage);
var
I: Integer;
begin
inherited;
if HandleAllocated then
for I := 0 to Sections.Count - 1 do
if Sections[I].ParentBiDiMode then
Sections[I].ParentBiDiModeChanged;
end;
procedure TcxCustomHeader.CMEnabledChanged(var Message: TMessage);
begin
inherited;
Invalidate;
end;
constructor TcxCustomHeader.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := [];
DoubleBuffered := True;
Height := 17;
Width := 117;
FAllowSort := True;
FResizeUpdate := True;
FSectionStream := nil;
FSelectedSectionIndex := -1;
FSizedSectionIndex := -1;
FUnderMouseSectionIndex := -1;
FHotSectionIndex := -1;
FSections := TcxHeaderSections.Create(Self);
FImagesChangeLink := TChangeLink.Create;
FImagesChangeLink.OnChange := ImageListChange;
end;
destructor TcxCustomHeader.Destroy;
begin
EndMouseTracking(Self);
FreeAndNil(FSections);
FreeAndNil(FImagesChangeLink);
FreeAndNil(FSectionStream);
FreeAndNil(FBrush);
inherited Destroy;
end;
procedure TcxCustomHeader.CalcSectionWidths(AHeaderWidth: Integer;
out AWidths: TcxHeaderSectionWidths);
var
ANewSectionWidth, APrevNonFixedWidthSectionCount, ARemainedWidth: Integer;
ASectionWidth, ATempWidth, AWorkWidth, I: Integer;
ANonFixedWidthSections: TList;
ASection: TcxHeaderSection;
begin
ANonFixedWidthSections := TList.Create;
try
SetLength(AWidths, Sections.Count);
AWorkWidth := AHeaderWidth;
for I := 0 to Sections.Count - 1 do
begin
ASection := Sections[I];
if ASection.AutoSize then
ANonFixedWidthSections.Add(ASection)
else
begin
Dec(AWorkWidth, ASection.Width);
AWidths[I] := ASection.Width;
end;
end;
if ANonFixedWidthSections.Count > 0 then
repeat
APrevNonFixedWidthSectionCount := ANonFixedWidthSections.Count;
ATempWidth := AWorkWidth div APrevNonFixedWidthSectionCount;
ARemainedWidth := AWorkWidth mod APrevNonFixedWidthSectionCount;
for I := APrevNonFixedWidthSectionCount - 1 downto 0 do
begin
ASection := TcxHeaderSection(ANonFixedWidthSections[I]);
ASectionWidth := ATempWidth;
if I = APrevNonFixedWidthSectionCount - 1 then
Inc(ASectionWidth, ARemainedWidth);
ANewSectionWidth := Max(ASectionWidth, ASection.MinWidth);
ANewSectionWidth := Min(ANewSectionWidth, ASection.MaxWidth);
AWidths[ASection.Index] := ANewSectionWidth;
if ASectionWidth <> ANewSectionWidth then
begin
ANonFixedWidthSections.Remove(ASection);
Dec(AWorkWidth, ANewSectionWidth);
end;
end;
until (ANonFixedWidthSections.Count = 0) or
(ANonFixedWidthSections.Count = APrevNonFixedWidthSectionCount);
finally
ANonFixedWidthSections.Free;
end;
end;
procedure TcxCustomHeader.FlipChildren(AllLevels: Boolean);
var
I, AFirstSectionWidth, ALastSectionWidth: Integer;
ASectionList: TcxHeaderSections;
begin
if HandleAllocated and (Sections.Count > 0) then
begin
ALastSectionWidth := ClientWidth;
AFirstSectionWidth := Sections[0].Width;
for I := 0 to Sections.Count - 2 do
Dec(ALastSectionWidth, Sections[I].Width);
ASectionList := TcxHeaderSections.Create(Self);
try
for I := 0 to Sections.Count - 1 do
with ASectionList.Add do
Assign(Sections[I]);
for I := 0 to Sections.Count - 1 do
Sections[I].Assign(ASectionList[Sections.Count - I - 1]);
finally
ASectionList.Free;
end;
if Sections.Count > 1 then
begin
Sections[Sections.Count - 1].Width := AFirstSectionWidth;
Sections[0].Width := ALastSectionWidth;
end;
UpdateSections;
end;
end;
function TcxCustomHeader.GetAutoHeight: Integer;
var
AContentHeight: Integer;
begin
Canvas.Font.Assign(Font);
Canvas.Font.Style := [fsBold, fsUnderline];
AContentHeight := Canvas.TextHeight('Wq');
if (Images <> nil) and (AContentHeight < Images.Height) then
AContentHeight := Images.Height;
Result := AContentHeight +
2 * (LookAndFeel.Painter.HeaderControlSectionBorderSize(cxbsNormal) +
cxHeaderSectionTextTopBottomIndent);
end;
procedure TcxCustomHeader.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
Style := Style and not(CS_HREDRAW or CS_VREDRAW);
end;
function TcxCustomHeader.CreateSection: TcxHeaderSection;
begin
Result := TcxHeaderSection.Create(Sections);
end;
procedure TcxCustomHeader.CreateWnd;
procedure ReadSections;
var
AReader: TReader;
begin
Sections.Clear;
AReader := TReader.Create(FSectionStream, 1024);
try
AReader.ReadValue;
AReader.ReadCollection(Sections);
finally
AReader.Free;
end;
FreeAndNil(FSectionStream);
end;
begin
inherited CreateWnd;
if FSectionStream <> nil then
ReadSections
else
UpdateSections;
end;
procedure TcxCustomHeader.DestroyWnd;
var
AWriter: TWriter;
begin
if FSectionStream = nil then
FSectionStream := TMemoryStream.Create;
AWriter := TWriter.Create(FSectionStream, 1024);
try
AWriter.WriteCollection(FSections);
finally
AWriter.Free;
FSectionStream.Position := 0;
end;
inherited DestroyWnd;
end;
procedure TcxCustomHeader.LookAndFeelChanged(Sender: TcxLookAndFeel;
AChangedValues: TcxLookAndFeelValues);
begin
inherited LookAndFeelChanged(Sender, AChangedValues);
Invalidate;
end;
procedure TcxCustomHeader.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = Images) then
Images := nil;
end;
procedure TcxCustomHeader.SetSections(Value: TcxHeaderSections);
begin
FSections.Assign(Value);
end;
procedure TcxCustomHeader.UpdateSection(Index: Integer);
begin
InvalidateRect(GetSectionRect(Index), False);
end;
procedure TcxCustomHeader.UpdateSections;
begin
InvalidateRect(ClientRect, False);
end;
procedure TcxCustomHeader.AllocateSplitLineDC;
begin
FLineDC := GetDCEx(Parent.Handle, 0, DCX_CACHE or DCX_CLIPSIBLINGS or DCX_LOCKWINDOWUPDATE);
if not ResizeUpdate then
begin
if not Assigned(FBrush) then
begin
FBrush := TBrush.Create;
{$IFDEF DELPHI4}
FBrush.Bitmap := AllocPatternBitmap(clBlack, clWhite);
{$ENDIF}
end;
FPrevBrush := SelectObject(FLineDC, FBrush.Handle);
end;
end;
procedure TcxCustomHeader.DrawSplitLine(XPos: Integer);
begin
FLineVisible := not FLineVisible;
FLastDrawPosOnMove := XPos;
PatBlt(FLineDC, Self.Left + XPos, 1, 1, Parent.Height - 1, DSTINVERT);
end;
procedure TcxCustomHeader.ReleaseSplitLine;
begin
if FLineVisible then DrawSplitLine(FLastDrawPosOnMove);
if FPrevBrush <> 0 then SelectObject(FLineDC, FPrevBrush);
ReleaseDC(Parent.Handle, FLineDC);
if FBrush <> nil then FreeAndNil(FBrush);
end;
procedure TcxCustomHeader.InitResize(XPos: Integer);
begin
FLineVisible := False;
AllocateSplitLineDC;
if not ResizeUpdate then DrawSplitLine(XPos);
end;
procedure TcxCustomHeader.ChangeSectionSortOrder(ASection: TcxHeaderSection;
ANewSortOrder: TcxHeaderSortOrder; ADeleteOtherSorting: Boolean);
procedure DeleteOtherSorting;
var
I: Integer;
begin
for I := 0 to Sections.Count - 1 do
if Sections[I] <> ASection then
ChangeSectionSortOrder(Sections[I], soNone, False);
end;
begin
if not AllowSort or (ANewSortOrder = ASection.SortOrder) then
Exit;
if ADeleteOtherSorting then
DeleteOtherSorting;
if DoSectionChangingSortOrder(ASection, ANewSortOrder) then
begin
ASection.SortOrder := ANewSortOrder;
DoSectionChangedSortOrder(ASection);
end;
end;
function TcxCustomHeader.DoSectionChangingSortOrder(ASection: TcxHeaderSection;
ANewSortOrder: TcxHeaderSortOrder): Boolean;
begin
Result := True;
if Assigned(FOnSectionChangingSortOrder) then
FOnSectionChangingSortOrder(Self, ASection, ASection.SortOrder,
ANewSortOrder, Result);
end;
procedure TcxCustomHeader.DoSectionChangedSortOrder(ASection: TcxHeaderSection);
begin
if Assigned(FOnSectionChangedSortOrder) then
FOnSectionChangedSortOrder(Self, ASection, ASection.SortOrder);
end;
function TcxCustomHeader.DoSectionDrag(FromSection,
ToSection: TcxHeaderSection): Boolean;
begin
Result := True;
DoSectionDragEvent(FromSection, ToSection, Result);
end;
procedure TcxCustomHeader.DoSectionEndDrag;
var
AIndexFrom: Integer;
begin
if UnderMouseSectionIndex <> -1 then
begin
AIndexFrom := SelectedSectionIndex;
SelectedSectionIndex := -1;
HotSectionIndex := -1;
Sections[AIndexFrom].Index := UnderMouseSectionIndex;
HotSectionIndex := UnderMouseSectionIndex;
end;
DoSectionEndDragEvent;
end;
procedure TcxCustomHeader.DrawSection(SectionIndex: Integer);
begin
if IsSectionIndex(SectionIndex) and Assigned(FOnDrawSection) then
FOnDrawSection(Self, FSections[SectionIndex], GetSectionRect(SectionIndex),
FSections[SectionIndex].State = cxbsPressed)
else
DrawHeaderSection(Handle, SectionIndex, Canvas, LookAndFeel, Images);
end;
procedure TcxCustomHeader.ImageListChange(Sender: TObject);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?