cxeditutils.pas

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

PAS
862
字号
            Inc(P1.Y);
            Inc(P2.Y);
          end;
        end
        else
        begin
          Inc(P2.Y);
          if P1.X > P2.X then
          begin
            Inc(P1.X);
            Inc(P2.X);
          end;
        end;
        cxEditFillRect(ACanvas.Handle, Rect(P1.X, P1.Y, P2.X, P2.Y), ABrush);
      end;
      with Points[High(Points)] do
        cxEditFillRect(ACanvas.Handle, Rect(X, Y, X + 1, Y + 1), ABrush);
    end
    else
    begin
      Pen.Color := AColor;
      Polyline(Points);
      with Points[High(Points)] do
        Pixels[X, Y] := AColor;
    end;
end;

function VerifyBitmap(ABitmap: TBitmap): Boolean;
begin
  with ABitmap do
    Result := (ABitmap <> nil) and (not Empty) and (Width > 0) and (Height > 0);
end;

function VerifyImages(AImages: TCustomImageList): Boolean;
begin
  with AImages do
    Result := (AImages <> nil) and (Width > 0) and (Height > 0);
end;

function CalculateEditDefaultButtonWidth(ACanvas: TcxCanvas; AViewInfo: TcxEditButtonViewInfo): Integer;

  function GetEditButtonTotalBorderExtent: Integer;
  var
    ATheme: TdxTheme;
    R, CR: TRect;
  begin
    with AViewInfo do
      if Data.NativeStyle then
      begin
        R := Rect(0, 0, 100, 100);
        if Data.ComboBoxStyle then
        begin
          ATheme := OpenTheme(totComboBox);
          GetThemeBackgroundContentRect(ATheme, ACanvas.Handle, CP_DROPDOWNBUTTON,
            CBXS_NORMAL, R, CR);
        end else
        begin
          ATheme := OpenTheme(totButton);
          GetThemeBackgroundContentRect(ATheme, ACanvas.Handle, BP_PUSHBUTTON,
            PBS_NORMAL, R, CR);
        end;
        Result := CR.Left + (R.Right - R.Left - CR.Right);
      end
      else
        Result := cxEditButtonMaxBorderWidth * 2;
  end;

var
  AButtonTotalBorderExtent: Integer;
  ACaptionWidth: Integer;
begin
  with AViewInfo do
  begin
    if Data.NativeStyle then
      if Data.ComboBoxStyle then
        Data.NativeStyle := AreVisualStylesMustBeUsed(Data.NativeStyle, totComboBox)
      else
        Data.NativeStyle := AreVisualStylesMustBeUsed(Data.NativeStyle, totButton);
    AButtonTotalBorderExtent := GetEditButtonTotalBorderExtent;
    if Width > 0 then
      if Width < AButtonTotalBorderExtent then
        Result := AButtonTotalBorderExtent
      else
        Result := Width
    else
      if (Data.Kind = bkGlyph) and VerifyBitmap(Glyph) then
        Result := Glyph.Width + GetEditButtonTotalBorderExtent
      else
      begin
        if Data.Kind = bkText then
          ACaptionWidth := ACanvas.TextWidth(Data.VisibleCaption) + AButtonTotalBorderExtent + 2 + 1
        else
          ACaptionWidth := 0;
        Result := GetSystemMetrics(SM_CYHSCROLL);
        if ACaptionWidth > Result then
          Result := ACaptionWidth;
      end;
  end;
end;

function cxEditGetBorderWidthBySkinPainter(ABorderStyle: TcxEditBorderStyle;
  ASkinPainter: TcxCustomLookAndFeelPainterClass): Integer;
const
  SkinBordersWidth: array [Boolean] of Integer = (1, cxContainerMaxBorderWidth);
begin
  if ASkinPainter = nil then
    Result := GetContainerBorderWidth(TcxContainerBorderStyle(ABorderStyle))
  else
    Result := SkinBordersWidth[ABorderStyle = ebsThick];
end;

procedure cxEditFillRect(ACanvas: TCanvas; const R: TRect; AColor: TColor);
begin
  Windows.FillRect(ACanvas.Handle, R, GetSolidBrush(AColor));
end;

procedure cxEditFillRect(ACanvas: TcxCanvas; const R: TRect; AColor: TColor);
begin
  Windows.FillRect(ACanvas.Handle, R, GetSolidBrush(AColor));
end;

procedure cxEditFillRect(ACanvasHandle: TcxEditCanvasHandle; const R: TRect;
  ABrush: TBrushHandle);
begin
  Windows.FillRect(ACanvasHandle, R, ABrush);
end;

function cxOffsetRect(var ARect: TRect; AOffset: TPoint): Boolean;
begin
  Result := OffsetRect(ARect, AOffset.X, AOffset.Y);
end;

procedure ConvertFlag(AInputFlags: DWORD; var AOutputFlags: Integer;
  AInputFlag: DWORD; AOutputFlag: Integer);
begin
  if AInputFlags and AInputFlag <> 0 then
    AOutputFlags := AOutputFlags or AOutputFlag;
end;

function cxTextOutFlagsToDrawTextFlags(AFlags: DWORD): Integer;
begin
  Result := 0;
  ConvertFlag(AFlags, Result, CXTO_LEFT, cxAlignLeft);
  ConvertFlag(AFlags, Result, CXTO_CENTER_HORIZONTALLY, cxAlignHCenter);
  ConvertFlag(AFlags, Result, CXTO_RIGHT, cxAlignRight);
  ConvertFlag(AFlags, Result, CXTO_TOP, cxAlignTop);
  ConvertFlag(AFlags, Result, CXTO_CENTER_VERTICALLY, cxAlignVCenter);
  ConvertFlag(AFlags, Result, CXTO_BOTTOM, cxAlignBottom);
  ConvertFlag(AFlags, Result, CXTO_SINGLELINE, cxSingleLine);
  ConvertFlag(AFlags, Result, CXTO_WORDBREAK, cxWordBreak);
end;

function DrawTextFlagsTocxTextOutFlags(AFlags: DWORD): Integer;
begin
  Result := 0;
  ConvertFlag(AFlags, Result, cxAlignLeft, CXTO_LEFT);
  ConvertFlag(AFlags, Result, cxAlignHCenter, CXTO_CENTER_HORIZONTALLY);
  ConvertFlag(AFlags, Result, cxAlignRight, CXTO_RIGHT);
  ConvertFlag(AFlags, Result, cxAlignTop, CXTO_TOP);
  ConvertFlag(AFlags, Result, cxAlignVCenter, CXTO_CENTER_VERTICALLY);
  ConvertFlag(AFlags, Result, cxAlignBottom, CXTO_BOTTOM);
  ConvertFlag(AFlags, Result, cxSingleLine, CXTO_SINGLELINE);
  ConvertFlag(AFlags, Result, cxWordBreak, CXTO_WORDBREAK);
end;

procedure InternalFillRect(ACanvas: TcxCanvas; const AOuterRect, AInternalRect: TRect;
  ABrush: TBrushHandle);
begin
  if IsRectEmpty(AOuterRect) or EqualRect(AOuterRect, AInternalRect) then
    Exit;
  if IsRectEmpty(AInternalRect) then
    cxEditFillRect(ACanvas.Handle, AOuterRect, ABrush)
  else
  begin
    cxEditFillRect(ACanvas.Handle, Rect(AOuterRect.Left, AOuterRect.Top,
      AInternalRect.Left, AOuterRect.Bottom), ABrush);
    cxEditFillRect(ACanvas.Handle, Rect(AInternalRect.Left, AOuterRect.Top,
      AInternalRect.Right, AInternalRect.Top), ABrush);
    cxEditFillRect(ACanvas.Handle, Rect(AInternalRect.Right, AOuterRect.Top,
      AOuterRect.Right, AOuterRect.Bottom), ABrush);
    cxEditFillRect(ACanvas.Handle, Rect(AInternalRect.Left, AInternalRect.Bottom,
      AInternalRect.Right, AOuterRect.Bottom), ABrush);
  end;
end;

procedure DrawCustomEdit(ACanvas: TcxCanvas; AViewInfo: TcxCustomEditViewInfo;
  ADrawBackground: Boolean; ABackgroundStyle: TcxEditBackgroundPaintingStyle);

  procedure FillEditBorderRect(ABackgroundBrush: TBrushHandle);
  begin
    if not AViewInfo.Transparent then
      cxEditFillRect(ACanvas.Handle, AViewInfo.BorderRect, ABackgroundBrush);
  end;

  procedure FillContentOffsetRegion(ABackgroundBrush: TBrushHandle);
  begin
    with AViewInfo do
    begin
      if Transparent or not AViewInfo.HasContentOffsets then
        Exit;
      cxEditFillRect(ACanvas.Handle, Rect(Bounds.Left, Bounds.Top, BorderRect.Left,
        Bounds.Bottom), ABackgroundBrush);
      cxEditFillRect(ACanvas.Handle, Rect(BorderRect.Left, Bounds.Top,
        BorderRect.Right, BorderRect.Top), ABackgroundBrush);
      cxEditFillRect(ACanvas.Handle, Rect(BorderRect.Left, BorderRect.Bottom,
        BorderRect.Right, Bounds.Bottom), ABackgroundBrush);
      cxEditFillRect(ACanvas.Handle, Rect(BorderRect.Right, Bounds.Top,
        Bounds.Right, Bounds.Bottom), ABackgroundBrush);
    end;
  end;

  procedure DrawEditBordersBySkinPainter(const R1: TRect; ABorderWidth: Integer;
    APainter: TcxCustomLookAndFeelPainterClass);
  begin
    with AViewInfo do
    begin
      if not (Transparent and IsInplace) then
        cxDrawTransparentControlBackground(Edit, ACanvas, R1, False);
      ACanvas.FrameRect(R1, BorderColor, ABorderWidth);
    end;
  end;

  procedure DrawUsualEditBackground(ABackgroundBrush: TBrushHandle);
  var
    R, R1: TRect;
    ABorderWidth: Integer;
  begin
    with AViewInfo do
    begin
      R := BorderRect;
      ABorderWidth := cxEditGetBorderWidthBySkinPainter(BorderStyle, Painter);
      Dec(R.Left, ABorderWidth);
      Dec(R.Top, ABorderWidth);
      if bRight in Edges then Inc(R.Right, ABorderWidth);
      if bBottom in Edges then Inc(R.Bottom, ABorderWidth);
      if Shadow then
        DrawContainerShadow(ACanvas, R);
      if not(bRight in Edges) then Inc(R.Right, ABorderWidth);
      if not(bBottom in Edges) then Inc(R.Bottom, ABorderWidth);
      if BorderStyle <> ebsNone then
      begin
        R1 := R;
        if AViewInfo.Painter <> nil then
          DrawEditBordersBySkinPainter(R1, ABorderWidth, AViewInfo.Painter)
        else
          case BorderStyle of
            ebsSingle, ebsThick:
              ACanvas.FrameRect(R1, BorderColor, ABorderWidth);
            ebsFlat:
              begin
                ACanvas.DrawEdge(R1, True, True, Edges);
                InflateRect(R1, -1, -1);
                ACanvas.FrameRect(R1, clBtnFace);
              end;
            ebs3D:
              begin
                ACanvas.DrawEdge(R1, True, True, Edges);
                InflateRect(R1, -1, -1);
                ACanvas.DrawComplexFrame(R1, cl3DDkShadow, cl3DLight, Edges);
              end;
          end;
      end;
      if IsInplace then
      begin
        if not Transparent then
          if ADrawBackground then
            cxEditFillRect(ACanvas.Handle, Bounds, ABackgroundBrush)
          else
            FillContentOffsetRegion(ABackgroundBrush);
      end
      else
        if ADrawBackground then
          FillEditBorderRect(ABackgroundBrush);
    end;
  end;

  procedure DrawEditBackground(ABackgroundBrush: TBrushHandle);
  begin
    if not AViewInfo.DrawBackground(ACanvas) then
      if AViewInfo.NativeStyle then
        AViewInfo.DrawNativeStyleEditBackground(ACanvas, ADrawBackground,
          ABackgroundStyle, ABackgroundBrush)
      else
        DrawUsualEditBackground(ABackgroundBrush);
  end;

var
  AVisibleButtonsCount: Integer;
  I: Integer;
  ASavedDC: Integer;
begin
  AVisibleButtonsCount := Length(AViewInfo.ButtonsInfo);
  ASavedDC := 0;
  if (AVisibleButtonsCount > 0) and not AViewInfo.ButtonsInfo[0].Data.BackgroundPartiallyTransparent then
  begin
    ASavedDC := SaveDC(ACanvas.Handle);
    for I := 0 to AVisibleButtonsCount - 1 do
      ACanvas.ExcludeClipRect(AViewInfo.ButtonsInfo[I].VisibleBounds);
  end;
  DrawEditBackground(GetSolidBrush(ACanvas, AViewInfo.BackgroundColor));

  if ASavedDC <> 0 then
    RestoreDC(ACanvas.Handle, ASavedDC);
  AViewInfo.DrawButtons(ACanvas);
end;

function GetArrowSize(const AContentSize: TSize; AArrowDirection: TcxArrowDirection): TSize;
var
  AMinContentSize: Integer;
  ATempVar: Longint;
begin
  AMinContentSize := AContentSize.cx;
  if AMinContentSize > AContentSize.cy then
    AMinContentSize := AContentSize.cy;

  Result.cx := (AMinContentSize - 1) div 2;
  if not Odd(Result.cx) then
    Result.cx := Result.cx + 1;
  Result.cy := Result.cx div 2 + 1;
  if AArrowDirection in [adLeft, adRight] then
  begin
    ATempVar := Result.cx;
    Result.cx := Result.cy;
    Result.cy := ATempVar;
  end;
end;

function GetEditButtonsContentVerticalOffset(ACanvas: TcxCanvas;
  AButtonsStyle: TcxEditButtonStyle; ANativeStyle: Boolean): Integer;
var
  ATheme: TdxTheme;
  CR, R: TRect;
begin
  if ANativeStyle then
  begin
    R := Rect(0, 0, 100, 100);
    ATheme := OpenTheme(totButton);
    GetThemeBackgroundContentRect(ATheme, ACanvas.Handle, BP_PUSHBUTTON,
      PBS_NORMAL, R, CR);
    Result := CR.Top + R.Bottom - CR.Bottom;
  end
  else
    Result := cxEditButtonContentVerticalOffset[AButtonsStyle];
end;

function GetHotTrackColor: TColor;
begin
  if FIsWin98Or2000 then
    Result := GetSysColor({$IFDEF DELPHI5}COLOR_HOTLIGHT{$ELSE}26{$ENDIF})
  else
    Result := clBlue;
end;

function GetNativeInnerTextEditContentHeightCorrection(
  AProperties: TcxCustomEditProperties; AIsInplace: Boolean): Integer;
begin
  Result := Integer(AIsInplace and (AProperties.Buttons.Count > 0));
end;

function GetEditButtonRegion(ACanvas: TcxCanvas; AViewInfo: TcxEditButtonViewInfo): TcxRegion;
var
  ATheme: TdxTheme;
  ARgn1, ARgn2: HRGN;
begin
  with AViewInfo do
    if Data.NativeState <> TC_NONE then
    begin
      if Data.ComboBoxStyle then
      begin
        ATheme := OpenTheme(totComboBox);
        GetThemeBackgroundRegion(ATheme, ACanvas.Handle, CP_DROPDOWNBUTTON,
          Data.NativeState, @Bounds, ARgn1);
      end else
      begin
        ATheme := OpenTheme(totButton);
        GetThemeBackgroundRegion(ATheme, ACanvas.Handle, Data.NativePart,
          Data.NativeState, @Bounds, ARgn1);
      end;
      ARgn2 := CreateRectRgnIndirect(Bounds);
      CombineRgn(ARgn1, ARgn1, ARgn2, RGN_AND);
      DeleteObject(ARgn2);
      Result := TcxRegion.Create(ARgn1);
    end
    else
      Result := TcxRegion.Create(Bounds);
end;

function GetEditBorderHighlightColor(
  AIsOffice11Style: Boolean): TColor;
begin
  if AIsOffice11Style then
    Result := dxOffice11SelectedBorderColor
  else
    Result := clHighlight;
end;

function GetEditButtonHighlightColor(APressed: Boolean;
  AIsOffice11Style: Boolean): TColor;
var
  APainterClass: TcxCustomLookAndFeelPainterClass;
begin
  if AIsOffice11Style then
    APainterClass := TcxOffice11LookAndFeelPainter
  else
    APainterClass := TcxUltraFlatLookAndFeelPainter;
  if APressed then
    Result := APainterClass.ButtonColor(cxbsPressed)
  else
    Result := APainterClass.ButtonColor(cxbsHot);
end;

function IsShadowDrawingNeeded(AViewData: TcxCustomEditViewData): Boolean;
begin
  Result := AViewData.Style.Shadow and not AViewData.IsNativeStyle(AViewData.Style.LookAndFeel);
end;

procedure RestoreCanvasFont(ACanvas: TcxCanvas; const ASavedLogFont: TLogFont);
begin
  ACanvas.Font.Handle := CreateFontIndirect(ASavedLogFont);
end;

procedure SaveCanvasFont(ACanvas: TcxCanvas; out ALogFont: TLogFont);
begin
  cxGetFontData(ACanvas.Font.Handle, ALogFont);
end;

initialization
  RetrieveWindowsVersion;

end.

⌨️ 快捷键说明

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