ksskinitems.pas

来自「小区水费管理系统源代码水费收费管理系统 水费收费管理系统」· PAS 代码 · 共 508 行

PAS
508
字号
{==============================================================================

  SkinEngine's Items
  Copyright (C) 2000-2002 by Evgeny Kryukov
  All rights reserved

  All conTeThements of this file and all other files included in this archive
  are Copyright (C) 2002 Evgeny Kryukov. Use and/or distribution of
  them requires acceptance of the License Agreement.

  See License.txt for licence information

  $Id: KsSkinItems.pas,v 1.5 2002/10/28 21:04:21 Evgeny Exp $

===============================================================================}

unit KsSkinItems;

{$I se_define.inc}
{$T-,W-,X+,P+}

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, CommCtrl, Menus, ActnList, ImgList, se_controls, KsSkinObjects,
  KsSkinSource, KsSkinEngine;

type

{ TSeSkinItem }

  TSeSkinItem = class(TSeCustomItem)
  private
    FSkinEngine: TSeSkinEngine;
    FSkinMenuBar: TseSkinObject;
    FSkinPopupMenu: TseSkinObject;
    FSkinMenuBarItem: TseSkinObject;
    FSkinPopupMenuItem: TseSkinObject;
    FSkinPopupMenuSep: TseSkinObject;

    procedure SetSkinEngine(const Value: TSeSkinEngine);
  protected
    function UseSkin: boolean;
    { Overrides }
    function CreatePopupWindowClass: TClass; override;
    { VCL protected  }
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    procedure CalcSize(Canvas: TCanvas; View: TSeItemView; var AWidth,
      AHeight: integer); override;
    procedure DrawItem(Canvas: TCanvas; View: TSeItemView; Rect: TRect;
      Active, Hover: boolean); override;
    procedure DrawScrollButton(Canvas: TCanvas; View: TSeItemView; Rect: TRect;
      Button: TSeMenuScrollButton; Active: boolean); override;

    property SkinEngine: TSeSkinEngine read FSkinEngine write SetSkinEngine;
  published
    property Checked;
    property Enabled;
    property Caption;
    property ImageIndex;
    property Images;
    property ShortCut;
    property Visible;
    property OnClick;
    property OnBeforeDropDown;
  end;

implementation {===============================================================}

uses KsSkinMenuForm;

{ TSeSkinItem }

constructor TSeSkinItem.Create(AOwner: TComponent);
begin
  inherited;
end;

destructor TSeSkinItem.Destroy;
begin
  inherited;
end;

{ Skin support }

function TSeSkinItem.UseSkin: boolean;
begin
  if (csDestroying in ComponentState) or (csLoading in ComponentState) then
    Result := false
  else
    if (FSkinEngine <> nil) and (FSkinEngine.SkinSource <> nil) and
       (not FSkinEngine.SkinSource.IsChanging) and
       (FSkinEngine.SkinSource.Count > 0) and
       (FSkinMenuBar <> nil) and
       (FSkinPopupMenu <> nil)
    then
      Result := true
    else
      Result := false;
end;

procedure TSeSkinItem.CalcSize(Canvas: TCanvas; View: TSeItemView;
  var AWidth, AHeight: integer);
begin
  if UseSkin then
  begin
    if (View.IsMenuBar) then
    begin
      if FSkinMenuBarItem = nil then
      begin
        inherited ;
        Exit;
      end;

      Canvas.Font.Assign(FSkinMenuBarItem.Font);

      with FSkinMenuBarItem do
        AWidth := TextWidth(Canvas, Caption) + TextMarginLeft + TextMarginRight;

      AHeight := FSkinMenuBarItem.Height;

      if MDIItemKind <> mikNone then
        AWidth := AHeight;
    end
    else
    begin
      if FSkinPopupMenuItem = nil then
      begin
        inherited ;
        Exit;
      end;

      Canvas.Font.Assign(FSkinPopupMenuItem.Font);

      AWidth := GetGlyphSize + TextWidth(Canvas, Caption) + ItemStep + TextWidth(Canvas, ShortCutToText(ShortCut)) + SubMenuWidth;
      AHeight := FSkinPopupMenuItem.Height;

      if (Caption <> '-') and (AHeight < GetGlyphSize - 4) then
        AHeight := GetGlyphSize + 4;

      Exit;
    end;
  end
  else
    inherited ;
end;

procedure TSeSkinItem.DrawItem(Canvas: TCanvas; View: TSeItemView;
  Rect: TRect; Active, Hover: boolean);
const
  CheckMarkPoints: array[0..11] of TPoint = (
    { Black }
    (X: -2; Y: -2), (X: 0; Y:  0), (X:  4; Y: -4),
    (X:  4; Y: -3), (X: 0; Y:  1), (X: -2; Y: -1),
    (X: -2; Y: -2),
    { White }
    (X: -3; Y: -2), (X: -3; Y: -1), (X: 0; Y: 2),
    (X:  5; Y: -3), (X:  5; Y: -5));
var
  R: TRect;
  Points: array[0..11] of TPoint;
  i, X, Y: integer;
  B: TBitmap;
  Flags: integer;
  IHandle, IHandle2 : HICON;
  IconX, IconY : integer;
  ID: boolean;
  SkinObject: TSeSkinObject;
begin
  if UseSkin then
  begin
    if (View.IsMenuBar) and (FSkinMenuBar <> nil) and (FSkinMenuBarItem <> nil) then
    begin

      { MDI Items }
      if (MDIItemKind <> mikNone) and (MDIItemKind <> mikSysMenu) then
      begin
        { Draw SysIcon }
        case MDIItemKind of
          mikMinimize: begin
            SkinObject := FSkinMenuBar.FindObjectByName('Min');
            if SkinObject <> nil then
            begin
              { Set State }
              if Active then
                if Hover then SkinObject.State := ssHot
                else SkinObject.State := ssFocused
              else
                SkinObject.State := ssNormal;
              { Draw }
              R := SkinObject.BoundsRect;
              RectCenter(R, Rect);
              SkinObject.BoundsRect := R;
              SkinObject.Draw(Canvas);
            end;
          end;
          mikRestore: begin
            SkinObject := FSkinMenuBar.FindObjectByName('Restore');
            if SkinObject <> nil then
            begin
              { Set State }
              if Active then
                if Hover then SkinObject.State := ssHot
                else SkinObject.State := ssFocused
              else
                SkinObject.State := ssNormal;
              { Draw }
              R := SkinObject.BoundsRect;
              RectCenter(R, Rect);
              SkinObject.BoundsRect := R;
              SkinObject.Draw(Canvas);
            end;
          end;
          mikClose: begin
            SkinObject := FSkinMenuBar.FindObjectByName('Close');
            if SkinObject <> nil then
            begin
              { Set State }
              if Active then
                if Hover then SkinObject.State := ssHot
                else SkinObject.State := ssFocused
              else
                SkinObject.State := ssNormal;
              { Draw }
              R := SkinObject.BoundsRect;
              RectCenter(R, Rect);
              SkinObject.BoundsRect := R;
              SkinObject.Draw(Canvas);
            end;
          end;
        end;

        Exit;
      end;

      Canvas.Font.Assign(FSkinMenuBarItem.Font);
      FSkinMenuBarItem.BoundsRect := Rect;
      FSkinMenuBarItem.Text := Caption;

      { Set state }
      if Active then
        if Hover then FSkinMenuBarItem.State := ssHot
        else FSkinMenuBarItem.State := ssFocused
      else
        FSkinMenuBarItem.State := ssNormal;

      if not Enabled then FSkinMenuBarItem.Enabled := false
      else FSkinMenuBarItem.Enabled := true;

      { Draw }
      FSkinMenuBarItem.Draw(Canvas);

      { Draw MDI system menu icon }
      if MDIItemKind = mikSysMenu then
      begin
        ID := false;
        if TForm((ActiveMDIForm as TSeCustomForm).Form).Icon.Handle <> 0 then
          IHandle := TForm((ActiveMDIForm as TSeCustomForm).Form).Icon.Handle
        else
          if Application.Icon.Handle <> 0 then
            IHandle := Application.Icon.Handle
          else
          begin
            IHandle := LoadIcon(0, IDI_APPLICATION);
            ID := true;
          end;
        IconX := GetSystemMetrics(SM_CXSMICON);
        if IconX = 0 then IconX := GetSystemMetrics(SM_CXSIZE);
        IconY := GetSystemMetrics(SM_CYSMICON);
        if IconY = 0 then IconY := GetSystemMetrics(SM_CYSIZE);
        IHandle2 := CopyImage(IHandle, IMAGE_ICON, IconX, IconY, LR_COPYFROMRESOURCE);

        R := Classes.Rect(0, 0, 16, 16);
        RectCenter(R, Rect);
        DrawIconEx(Canvas.Handle, R.Left, R.Top, IHandle2, 0, 0, 0, 0, DI_NORMAL);

        DestroyIcon(IHandle2);
        if ID then DestroyIcon(IHandle);
      end;

      Exit;
    end;

    if not View.IsMenuBar and (FSkinPopupMenu <> nil) and (FSkinPopupMenuItem <> nil) then
    begin
      Canvas.Font.Assign(FSkinPopupMenuItem.Font);
      FSkinPopupMenuItem.BoundsRect := Rect;
      FSkinPopupMenuItem.Text := Caption;

      { Set state }
      if Active then
        if Hover then FSkinPopupMenuItem.State := ssHot
        else FSkinPopupMenuItem.State := ssFocused
      else
        FSkinPopupMenuItem.State := ssNormal;

      if Caption = '-' then
      begin
        FSkinPopupMenuItem.State := ssNormal;
        if FSkinPopupMenuSep <> nil then
        begin
          { Draw Separator Object }
          FSkinPopupMenuSep.BoundsRect := Rect;
          FSkinPopupMenuSep.State := ssNormal;
          FSkinPopupMenuSep.Draw(Canvas);
          Exit;
        end;
        FSkinPopupMenuItem.Draw(Canvas);
        Exit;
      end;

      if not Enabled then FSkinPopupMenuItem.Enabled := false
      else FSkinPopupMenuItem.Enabled := true;

      { Set Shortcut Text }
      if ShortCut <> 0 then
        FSkinPopupMenuItem.RightText := ShortCutToText(ShortCut)
      else
        FSkinPopupMenuItem.RightText := '';

      { Draw }
      if FSkinPopupMenuItem.TextMarginLeft < GetGlyphSize then
        FSkinPopupMenuItem.TextMarginLeft :=  FSkinPopupMenuItem.TextMarginLeft + (GetGlyphSize - FSkinPopupMenuItem.TextMarginLeft);

      FSkinPopupMenuItem.Draw(Canvas);

      { Draw Image and Checked }
      if (Checked) or ((ImgList <> nil) and (ImageIndex >= 0)) then
      begin
        { Draw Glyph }
        R := Rect;
        R.Right := R.Left + GetGlyphSize;
        if (ImgList <> nil) and (ImageIndex >= 0) then
        begin
          { Draw Image }
          ImgList.Draw(Canvas,
            R.Left + ((R.Right - R.Left) - ImgList.Width) div 2,
            R.Top + ((R.Bottom - R.Top) - ImgList.Height) div 2,
            ImageIndex, Enabled);
        end
        else
        begin
          { Draw CheckBox }
          X := (R.Left + R.Right) div 2 - 2;
          Y := (R.Top + R.Bottom) div 2 + 1;
          System.Move(CheckMarkPoints, Points, 12 * SizeOf(TPoint));
          for i := Low(Points) to High(Points) do begin
            Inc (Points[I].X, X);
            Inc (Points[I].Y, Y);
          end;
          Canvas.Pen.Color := Canvas.Font.Color;
          Polyline(Canvas.Handle, Points[0], 7);
          Canvas.Pen.Color := Canvas.Font.Color;
          Polyline(Canvas.Handle, Points[7], 5);
        end;
      end;

      { Draw Submenu Arrow }
      if Count > 0 then
      begin
        R := Rect;
        R.Left := R.Right - SubMenuWidth;
        
        B := TBitmap.Create;
        try
          B.Width := RectWidth(R);
          B.Height := RectHeight(R);
          { Draw to B }
          DrawFrameControl(B.Canvas.Handle, Classes.Rect(0, 0, RectWidth(R),
            RectHeight(R)), DFC_MENU, DFCS_MENUARROW);
          { Copy to Buffer }
          for X := 0 to B.Width-1 do
            for Y := 0 to B.Height-1 do
              if B.Canvas.Pixels[X, Y] = clBlack then
                Canvas.Pixels[R.Left + X, R.Top + Y] := Canvas.Font.Color;
        finally
          B.Free;
        end;
      end;

      Exit;
    end;

    inherited ;
  end
  else
    inherited;
end;

procedure TSeSkinItem.DrawScrollButton(Canvas: TCanvas; View: TSeItemView;
  Rect: TRect; Button: TSeMenuScrollButton; Active: boolean);
var
  SkinObject: TSeSkinObject;
  R: TRect;
begin
  if UseSkin then
  begin
    SkinObject := FSkinPopupMenuItem.CreateCopy(nil);
    SkinObject.BoundsRect := Rect;
    SkinObject.Text := '';

    { Set state }
    if Active then
      SkinObject.State := ssFocused
    else
      SkinObject.State := ssNormal;

    { Draw }
    SkinObject.Draw(Canvas);

    SkinObject.State := ssNormal;
    Canvas.Font.Assign(SkinObject.Font);
    SkinObject.Free;
    { Draw Arrow }
    if Button = ksbUp then
    begin
      R := Classes.Rect(0, 0, 7, 4);
      RectCenter(R, Rect);

      Canvas.Pen.Style := psSolid;
      Canvas.Pen.Color := Canvas.Font.Color;
      Canvas.Brush.Style := bsSolid;
      Canvas.Brush.Color := Canvas.Font.Color;
      with R do
        Canvas.Polygon([Point(Left, Bottom - 1),
          Point(Right - 1, Bottom - 1),
          Point((Right - 1 + Left) div 2, Top)]);
    end;

    if Button = ksbDown then
    begin
      R := Classes.Rect(0, 0, 7, 4);
      RectCenter(R, Rect);

      Canvas.Pen.Style := psSolid;
      Canvas.Pen.Color := Canvas.Font.Color;
      Canvas.Brush.Style := bsSolid;
      Canvas.Brush.Color := Canvas.Font.Color;
      with R do
        Canvas.Polygon([Point(Left, Top),
          Point(Right - 1, Top),
          Point((Right - 1 + Left) div 2, Bottom - 1)]);
    end;
  end
  else
    inherited;
end;

{ Override }

function TSeSkinItem.CreatePopupWindowClass: TClass;
begin
  Result := TSeSkinPopupWindow;
end;

procedure TSeSkinItem.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited;
  if (Operation = opRemove) and (AComponent = FSkinEngine) then FSkinEngine := nil;
end;

procedure TSeSkinItem.SetSkinEngine(const Value: TSeSkinEngine);
var
  i: integer;
begin
  FSkinEngine := Value;

  if (FSkinEngine <> nil) and (FSkinEngine.SkinSource <> nil) and
     (not FSkinEngine.SkinSource.IsChanging) and
     (FSkinEngine.SkinSource.Count > 0) then
  begin
    FSkinMenuBar := FSkinEngine.SkinSource.GetObjectByName('MenuBar');
    FSkinPopupMenu := FSkinEngine.SkinSource.GetObjectByName('PopupMenu');
    if FSkinMenuBar <> nil then
      if IsToolbar then
        FSkinMenuBarItem := FSkinMenuBar.FindObjectByName('ToolbarItem')
      else
        FSkinMenuBarItem := FSkinMenuBar.FindObjectByName('Item');
    if FSkinPopupMenu <> nil then
    begin
      FSkinPopupMenuItem := FSkinPopupMenu.FindObjectByName('Item');
      FSkinPopupMenuSep := FSkinPopupMenu.FindObjectByName('Separator');
    end;
  end
  else
  begin
    FSkinPopupMenu := nil;
    FSkinMenuBar := nil;
    FSkinMenuBarItem := nil;
    FSkinPopupMenuItem := nil;
  end;

  for i := 0 to Count-1 do
    if Items[i] is TSeSkinItem then
      TSeSkinItem(Items[i]).SkinEngine := Value;
end;

initialization
  RegisterClasses([TSeSkinItem]);
finalization
end.

⌨️ 快捷键说明

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