⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmlabel.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
              SetDepth(0,1);
              SetDepth(1,1);
           end;
           lsSunken:
           begin
              SetDirection(0,ldDownRight);
              SetDirection(1,ldUpLeft);
              SetDepth(0,1);
              SetDepth(1,1);
           end;
           lsShadow:
           begin
              SetDirection(0,ldNone);
              SetDirection(1,ldDownRight);
              SetDepth(0,0);
              SetDepth(1,2);
              SetAsButton(False);
           end;
           lsFlying:
           begin
              SetDirection(0,ldDownRight);
              SetDirection(1,ldDownRight);
              SetDepth(0,1);
              SetDepth(1,5);
              SetColor(0,clGray);  { Flying has two shadows }
              SetAsButton(False);
           end;
           lsNone:
           begin
              SetDirection(0,ldNone);
              SetDirection(1,ldNone);
              SetDepth(0,0);
              SetDepth(1,0);
              SetAsButton(False);
           end;
      else SetAsButton(False);
      Refresh;
    end;
    FChangingStyle := False;   { So further changes set style to custom }
  end;
end;

{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.SetAsButton(aValue: Boolean);
begin
   if (FAsButton <> aValue) then
   begin
      FAsButton := aValue;
      { If not already raised, raise it }
      if aValue then SetEffect(lsRaised);
   end;
end;

{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.SetAngle(aValue: TMMAngle);
begin
   if (FAngle <> aValue) then
   begin
      FAngle := aValue;
      DCosAngle := Cos(FAngle * DDegToRad);  { Calculate values for later use }
      DCosSquared := DCosAngle * DCosAngle;
      DSinAngle := Sin(FAngle * DDegToRad);
      DSinSquared := DSinAngle * DSinAngle;
      if FAngle <> 0 then Alignment := taLeftJustify;  { Cannot align when rotated }
      Invalidate;
   end;
end;

{------------------------------------------------------------------------}
procedure GetRGB(Color: TColor; var IR, IG, IB: Byte);
begin
   IR := GetRValue(Color);
   IG := GetGValue(Color);
   IB := GetBValue(Color);
end;

{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.SetTextAngle(Canvas: TCanvas; aValue: TMMAngle);
var
   FntLogRec: TLogFont;    { Storage area for font information }

begin
   { Get the current font information. We only want to modify the angle }
   GetObject(Canvas.Font.Handle, SizeOf(FntLogRec), Addr(FntLogRec));

   { Modify the angle. "The angle, in tenths of a degrees, between the base
     line of a character and the x-axis." (Windows API Help file.)}
   FntLogRec.lfEscapement := aValue * 10;
   FntLogRec.lfOutPrecision := OUT_TT_ONLY_PRECIS;  { Request TrueType precision }

   { Delphi will handle the deallocation of the old font handle }
   Canvas.Font.Handle := CreateFontIndirect(FntLogRec);
end;

{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.MouseDown(Button: TMouseButton; ssShift: TShiftState; X, Y: Integer);
begin
   if AsButton then
   begin    { If left button and label isn't sunken }
      if (Button = mbLeft) and (EffectStyle <> lsSunken) and Enabled then
         SetEffect(lsSunken);
   end;
   inherited MouseDown(Button, ssShift, X, Y);
end;

{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.MouseMove(ssShift: TShiftState; X, Y: Integer);
begin
   if AsButton then
   begin
      if ssShift = [ssLeft] then  { Left mouse button down }
      begin                       { If within label's client area }
         if  (X >= 0) and (X <= ClientWidth) and (Y >= 0) and (Y <= ClientHeight) then
             SetEffect(lsSunken)
      else
         SetEffect(lsRaised);
    end;
  end;
  inherited MouseMove(ssShift, X, Y);
end;

{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.MouseUp(Button: TMouseButton; ssShift: TShiftState; X, Y: Integer);
begin
   if AsButton then
   begin    { If within label's client area }
      if (X >= 0) and (X <= ClientWidth) and (Y >= 0) and (Y <= ClientHeight) then
         SetEffect(lsRaised);
   end;
   inherited MouseUp(Button, ssShift, X, Y);
end;

{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.Paint;
const
  WAlignments: array [TAlignment] of word = (DT_LEFT, DT_RIGHT, DT_CENTER);
var
  IMinOffset, IMaxOffset: Integer;
  RctTemp: TRect;
  StrText: array [0..255] of char;
  I, IMid, IH, IW, IX, IY, ILimit: Integer;
  I1, I2, I3, I4, IAdj: Integer;
  P1, P2, P3, P4: TPoint;
  IFromR, IFromG, IFromB: Byte;
  RAdjustR, RAdjustG, RAdjustB: Real;
  BmpTemp, BmpWork: TBitmap;
  CnvWork: TCanvas;
  OldPalette: HPalette;

begin
  { Find minimum and maximum of all offsets (including font itself) }
  IMinOffset := Min(Min(Min(Min(IOffsets[DirectionHighlight, drX] * DepthHighlight,
                IOffsets[DirectionShadow, drX] * DepthShadow),
                IOffsets[DirectionHighlight, drY] * DepthHighlight),
                IOffsets[DirectionShadow, drY] * DepthShadow), 0);
  IMaxOffset := Max(Max(Max(Max(IOffsets[DirectionHighlight, drX] * DepthHighlight,
                IOffsets[DirectionShadow, drX] * DepthShadow),
                IOffsets[DirectionHighlight, drY] * DepthHighlight),
                IOffsets[DirectionShadow, drY] * DepthShadow), 0);
  case Alignment of
    taLeftJustify:  IAdj := 0;
    taCenter:       IAdj := (IMaxOffset - IMinOffset) div 2;
    taRightJustify: IAdj := IMaxOffset - IMinOffset;
  end;

  { Create temporary drawing surfaces }
  BmpTemp := TBitmap.Create;
  BmpWork := TBitmap.Create;
  try
    BmpTemp.Height := Self.Height;
    BmpTemp.Width := Self.Width;
    BmpTemp.Canvas.Font := Self.Font;
    BmpWork.Height := BmpTemp.Height;
    BmpWork.Width := BmpTemp.Width;
    BmpWork.Canvas.Font := Self.Font;        { Ensure canvas font is set }
    BmpWork.Canvas.CopyRect(ClientRect, Canvas, ClientRect);
    if (Angle <> 0) then               { Need to generate an angled font }
    begin
      SetTextAngle(BmpTemp.Canvas, Angle);
      SetTextAngle(BmpWork.Canvas, Angle);
    end;

    with BmpWork.Canvas do
    begin
      { Set starting point for text - IX, IY }
      if Angle = 0 then
      begin
        IX := 0;
        IY := 0;
      end
      else
      begin
        IW := TextWidth(Caption);
        IH := TextHeight(Caption);
        IMid := TextWidth(Caption+'   ') div 2;
        IX := IMid - Trunc(IW / 2 * DCosAngle) - Trunc(IH / 2 * DSinAngle);
        IY := IMid + Trunc(IW / 2 * DSinAngle) - Trunc(IH / 2 * DCosAngle);

        IMid := IMid + (IMaxOffset - IMinOffset + 4) div 2;
        IW := IW + IMaxOffset + IMinOffset + 4;
        IH := IH + IMaxOffset + IMinOffset + 4;
        I1 := Trunc(IW / 2 * DCosAngle);
        I2 := Trunc(IH / 2 * DSinAngle);
        I3 := Trunc(IW / 2 * DSinAngle);
        I4 := Trunc(IH / 2 * DCosAngle);
        P1 := Point(IMid - I1 - I2 + 2, IMid + I3 - I4 + 2);
        P2 := Point(IMid + I1 - I2 + 2, IMid - I3 - I4 + 2);
        P3 := Point(IMid + I1 + I2 + 2, IMid - I3 + I4 + 2);
        P4 := Point(IMid - I1 + I2 + 2, IMid + I3 + I4 + 2);
      end;

      if not Transparent then                { Fill in background }
      begin
        Brush.Color := Self.Color;
        Brush.Style := bsSolid;
        if Angle = 0 then
          FillRect(ClientRect)               { Original label canvas }
        else
          Polygon([P1, P2, P3, P4]);
      end;
      Brush.Style := bsClear;         { Don't overwrite background above }
    end;

    GetTextBuf(StrText, SizeOf(StrText));  { Get label's caption }

    { Prepare for extruding shadow, if requested }
    GetRGB(ColourShadow, IFromR, IFromG, IFromB);
    RAdjustR := 0; RAdjustG := 0; RAdjustB := 0;

    if (StyleShadow <> loNormal) and (DepthShadow > 1) then
    begin
      ILimit := 1;
    end
    else ILimit := DepthShadow;

    CnvWork := BmpWork.Canvas;        { Work directly on label's canvas }

    { Process for each copy of the shadow - several if extruding }
    for I := DepthShadow downto ILimit do
    begin
      CnvWork.Font.Color := RGB(IFromR+Round(RAdjustR*(DepthShadow-i)),
                                IFromG+Round(RAdjustG*(DepthShadow-i)),
                                IFromB+Round(RAdjustB*(DepthShadow-i)));
      if Angle = 0 then
      begin
        { Create a rect that is offset for the shadow }
        RctTemp:= Rect(ClientRect.Left - IMinOffset -IAdj + IOffsets[DirectionShadow, drX] * I,
                       ClientRect.Top - IMinOffset + IOffsets[DirectionShadow, drY] * I,
                       ClientRect.Right - IMinOffset - IAdj + IOffsets[DirectionShadow, drX] * I,
                       ClientRect.Bottom - IMinOffset + IOffsets[DirectionShadow, drY] * I);

        { Draw shadow text with alignment }
        DrawText(CnvWork.Handle, StrText, StrLen(StrText), RctTemp,
                 DT_EXPANDTABS or DT_WORDBREAK or WAlignments[Alignment]);
      end
      else
        { Draw angled shadow text without alignment }
        CnvWork.TextOut(IX - IMinOffset + IOffsets[DirectionShadow, drX] * I,
                        IY - IMinOffset + IOffsets[DirectionShadow, drY] * I,
                        Caption);
    end;

    { Prepare for extruding highlight, if requested }
    GetRGB(ColourHighlight, IFromR, IFromG, IFromB);
    RAdjustR := 0; RAdjustG := 0; RAdjustB := 0;

    if (StyleHighlight <> loNormal) and (DepthHighlight > 1) then
    begin
      ILimit := 1;
    end
    else ILimit := DepthHighlight;

    CnvWork := BmpWork.Canvas;      { Work directly on label's canvas }

    { Process for each copy of the highlight - several if extruding }
    for I := DepthHighlight downto ILimit do
    begin
      CnvWork.Font.Color := RGB(IFromR+Round(RAdjustR*(DepthHighlight-i)),
                                IFromG+Round(RAdjustG*(DepthHighlight-i)),
                                IFromB+Round(RAdjustB*(DepthHighlight-i)));
      if Angle = 0 then
      begin
        { Create a rect that is offset for the highlight }
        RctTemp:= Rect(ClientRect.Left - IMinOffset - IAdj + IOffsets[DirectionHighlight, drX] * I,
                       ClientRect.Top - IMinOffset + IOffsets[DirectionHighlight, drY] * I,
                       ClientRect.Right - IMinOffset - IAdj + IOffsets[DirectionHighlight, drX] * I,
                       ClientRect.Bottom - IMinOffset + IOffsets[DirectionHighlight, drY] * I);

        { Draw highlight text with alignment }
        DrawText(CnvWork.Handle, StrText, StrLen(StrText), RctTemp,
                 DT_EXPANDTABS or DT_WORDBREAK or WAlignments[Alignment]);
      end
      else
        { Draw angled highlight text without alignment }
        CnvWork.TextOut(IX - IMinOffset + IOffsets[DirectionHighlight, drX] * I,
                        IY - IMinOffset + IOffsets[DirectionHighlight, drY] * I,
                        Caption);
    end;

    if not FBitmap.Empty then
    begin
        { Fill the bitmap with white }
        CnvWork := BmpTemp.Canvas;
        CnvWork.Brush.Color := clWhite;
        CnvWork.FillRect(Rect(0,0,BmpTemp.Width,BmpTemp.Height));
        { text color to black }
        CnvWork.Font.Color := clBlack;
    end
    else
    begin
       CnvWork := BmpWork.Canvas;
       { Restore original font colour }
       CnvWork.Font.Color := Font.Color;
    end;

    if Angle = 0 then
    begin
      { Create a rect that is offset for the original text }
      RctTemp:= Rect(ClientRect.Left - IMinOffset - IAdj,
                     ClientRect.Top - IMinOffset,
                     ClientRect.Right - IMinOffset - IAdj,
                     ClientRect.Bottom - IMinOffset);
      { Draw original text with alignment }
      DrawText(CnvWork.Handle, StrText, StrLen(StrText), RctTemp,
               DT_EXPANDTABS or DT_WORDBREAK or WAlignments[Alignment]);
    end
    else
      { Draw angled original text without alignment }
      CnvWork.TextOut(IX - IMinOffset, IY - IMinOffset, Caption);

    if not FBitmap.Empty then
    begin
       { combine original canvas with bitmap (invert) }
       TileBlt(BmpWork.Canvas.Handle,FBitmap.Handle,
               Rect(0,0,BmpWork.Width, BmpWork.Height),SRCINVERT);

       { now draw black white font }
       BitBlt(BmpWork.Canvas.Handle,0,0,BmpTemp.Width, BmpTemp.Height,
              BmpTemp.Canvas.Handle,0,0,SRCAND);

       { combine original canvas with bitmap (invert again) }
       TileBlt(BmpWork.Canvas.Handle,FBitmap.Handle,
               Rect(0,0,BmpWork.Width, BmpWork.Height),SRCINVERT);

       if (GetPalette <> 0) then
       begin
          OldPalette := SelectPalette(Canvas.Handle, GetPalette, True);
          RealizePalette(Canvas.Handle);
       end;
    end;

    { Paint the bevel }
    Bevel.PaintBevel(BmpWork.Canvas, ClientRect, True);

    { now copy to screen }
    BitBlt(Canvas.Handle, 0, 0, Width ,Height,
           BmpWork.Canvas.Handle, 0, 0, SRCCOPY);

    if (GetPalette <> 0) then
    begin
       SelectPalette(Canvas.Handle, OldPalette, True);
       RealizePalette(Canvas.Handle);
    end;

  finally
    BmpTemp.Free;
    BmpWork.Free;
  end;
end;

end.

⌨️ 快捷键说明

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