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

📄 sxskinform.pas

📁 skin components for design of your applicastions
💻 PAS
📖 第 1 页 / 共 3 页
字号:
unit SXSkinForm;

////////////////////////////////////////////////////////////////////////////////
// SXSkinComponents: Skinnable Visual Controls for Delphi and C++Builder      //
//----------------------------------------------------------------------------//
// Version: 1.2.1                                                             //
// Author: Alexey Sadovnikov                                                  //
// Web Site: http://www.saarixx.info/sxskincomponents/                        //
// E-Mail: sxskincomponents@saarixx.info                                      //
//----------------------------------------------------------------------------//
// LICENSE:                                                                   //
// 1. You may freely distribute this file.                                    //
// 2. You may not make any changes to this file.                              //
// 3. The only person who may change this file is Alexey Sadovnikov.          //
// 4. You may use this file in your freeware projects.                        //
// 5. If you want to use this file in your shareware or commercial project,   //
//    you should purchase a project license or a personal license of          //
//    SXSkinComponents: http://saarixx.info/sxskincomponents/en/purchase.htm  //
// 6. You may freely use, distribute and modify skins for SXSkinComponents.   //
// 7. You may create skins for SXSkinComponents.                              //
//----------------------------------------------------------------------------//
// Copyright (C) 2006-2007, Alexey Sadovnikov. All Rights Reserved.           //
////////////////////////////////////////////////////////////////////////////////

interface

{$I Compilers.inc}

uses GR32_Image, GR32, Windows, Graphics, Classes, Messages, Forms, StdCtrls,
     ExtCtrls, SysUtils, Controls, SXSkinLibrary, Types;

{$IFNDEF COMPILER_7_UP}
 {$EXTERNALSYM WM_NCMOUSELEAVE}
 const WM_NCMOUSELEAVE = $02A2;
{$ENDIF}

type

 TSXSkinCustomForm=class(TComponent)
  private
   FSkinLibrary:TSXSkinLibrary;
   FSkinStyle:String;
   FForm:TForm;
   FCaptionHeight:Integer;
   FFormActive:Boolean;
   FCustomCaptionHeight:Integer;
   FIconRect:TRect;
   FTextRect:TRect;
   FCloseRect:TRect;
   FMaximizeRect:TRect;
   FMinimizeRect:TRect;
   FHelpRect:TRect;
   FCloseOver:Boolean;
   FMaximizeOver:Boolean;
   FMinimizeOver:Boolean;
   FHelpOver:Boolean;
   FCloseDown:Boolean;
   FMaximizeDown:Boolean;
   FMinimizeDown:Boolean;
   FHelpDown:Boolean;
   OldWindowProc:TWndMethod;
   TmpWidth:Integer;
   TmpHeight:Integer;
   ResizeTopLeftRgn:HRGN;
   ResizeTopRightRgn:HRGN;
   ResizeBottomLeftRgn:HRGN;
   ResizeBottomRightRgn:HRGN;
   ResizeLeftRgn:HRGN;
   ResizeRightRgn:HRGN;
   ResizeTopRgn:HRGN;
   ResizeBottomRgn:HRGN;
   CaptionRgn:HRGN;
   LastLeft,LastTop:Integer;
   FTextBitmap:TBitmap32;
   FIconStyle:String;
   FUseTFormIcon:Boolean;
   //
   CEID_Caption:Integer;
   CEID_LeftFrame:Integer;
   CEID_RightFrame:Integer;
   CEID_BottomFrame:Integer;
   CEID_Icon:Integer;
   CEID_Close:Integer;
   CEID_Maximize:Integer;
   CEID_Minimize:Integer;
   CEID_Help:Integer;
   CEID_Restore:Integer;
   function HasUnusualSkinStyle:Boolean;
   function HasUnusualIconStyle:Boolean;
   procedure SetSkinStyle(const Value:String);
   procedure SetSkinLibrary(Value:TSXSkinLibrary);
   procedure SetUseTFormIcon(Value:Boolean);
   procedure SetCustomCaptionHeight(Value:Integer);
   procedure NewWndProc(var Message:TMessage);
   procedure GetCurrentFState(var FState:TSXSkinFormStateParam;
              PSkinFilePath:PString=nil;PZipFilePath:PString=nil);
   function OnGetVariable(const VarName:String;var Error:Boolean):Single;
   procedure CalcResizeRegions;
   function HitTest(X,Y:Integer):Integer;
   procedure ProcessNCMouseMove;
  protected
   procedure Notification(AComponent:TComponent;Operation:TOperation); override;
  public
   constructor Create(AOwner:TComponent); override;
   destructor Destroy; override;
   procedure DrawCaptionAndBorder(Rgn:HRGN);
   procedure DrawCaptionToRect(Bitmap:TBitmap32;Rect:TRect);
   procedure ResetMaskRegion;
   procedure CalcCaptionElementsRects;
   procedure SkinChanged;
   property CustomCaptionHeight:Integer read FCustomCaptionHeight write SetCustomCaptionHeight default 0;
   property IconStyle:String read FIconStyle write FIconStyle stored HasUnusualIconStyle;
   property SkinLibrary:TSXSkinLibrary read FSkinLibrary write SetSkinLibrary;
   property SkinStyle:String read FSkinStyle write SetSkinStyle stored HasUnusualSkinStyle;
   property UseTFormIcon:Boolean read FUseTFormIcon write SetUseTFormIcon default True;
 end;

 TSXSkinForm=class(TSXSkinCustomForm)
  published
   property CustomCaptionHeight;
   property IconStyle;
   property SkinLibrary;
   property SkinStyle;
   property UseTFormIcon;
 end;

implementation

uses SXSkinRegionManager, SXMathEval, SXBitmap32Utils, SXSkinUtils;

type

 TSXForm=class(TForm);

{ TSXSkinCustomForm }

function TSXSkinCustomForm.HasUnusualIconStyle:Boolean;
begin
 Result:=SkinStyle<>'_Selective_StdIcon';
end; 

function TSXSkinCustomForm.HasUnusualSkinStyle:Boolean;
begin
 Result:=SkinStyle<>'_Form';
end;

procedure TSXSkinCustomForm.SetSkinLibrary(Value:TSXSkinLibrary);
begin
 if FSkinLibrary<>Value then
  begin
   if FSkinLibrary<>nil then
    begin
     FSkinLibrary.RemoveFreeNotification(Self);
     FSkinLibrary.RemoveSkinComponent(Self);
    end;
   FSkinLibrary:=Value;
   if FSkinLibrary<>nil then
    begin
     FSkinLibrary.FreeNotification(Self);
     FSkinLibrary.AddSkinComponent(Self);
    end;
   if not (csDestroying in ComponentState) then
    SkinChanged;
  end;
end;

procedure TSXSkinCustomForm.SetSkinStyle(const Value:String);
begin
 if FSkinStyle<>Value then
  begin
   FSkinStyle:=Value;
   SkinChanged;
  end;
end;

procedure TSXSkinCustomForm.SetUseTFormIcon(Value:Boolean);
begin
 if FUseTFormIcon<>Value then
  begin
   FUseTFormIcon:=Value;
   if FForm<>nil then
    SendMessage(FForm.Handle,WM_NCPAINT,0,0);
  end;
end;

procedure TSXSkinCustomForm.SetCustomCaptionHeight(Value:Integer);
begin
 if FCustomCaptionHeight<>Value then
  begin
   FCustomCaptionHeight:=Value;
   if FForm<>nil then
    begin
     SetWindowPos(FForm.Handle, 0, 0, 0, 0, 0, SWP_FRAMECHANGED or SWP_NOMOVE or
        SWP_NOREPOSITION or SWP_NOSIZE or SWP_NOACTIVATE);
     FForm.Invalidate;
    end;
  end;
end;

procedure TSXSkinCustomForm.Notification(AComponent:TComponent;Operation:TOperation);
begin
 inherited Notification(AComponent,Operation);
 if Operation=opRemove then
  begin
   if AComponent=FSkinLibrary then
    FSkinLibrary:=nil;
  end;
end;

procedure TSXSkinCustomForm.SkinChanged;
begin
 ResetMaskRegion;
 CalcResizeRegions;
 CalcCaptionElementsRects;
 if FForm<>nil then
  SendMessage(FForm.Handle,WM_NCPAINT,0,0);
end;

procedure TSXSkinCustomForm.GetCurrentFState(var FState:TSXSkinFormStateParam;
           PSkinFilePath:PString=nil;PZipFilePath:PString=nil);
var  A:Integer;
 Style:TSXSkinFormStyle;
begin
 Finalize(FState);
 FillChar(FState,sizeof(FState),0);
 if (SkinLibrary<>nil) and SkinLibrary.CanBeUsed and (FForm<>nil) then
  begin
   A:=SkinLibrary.Styles.GetIndexByName(SkinStyle);
   if (A>=0) and (SkinLibrary.Styles[A] is TSXSkinFormStyle) then
    begin
     Style:=TSXSkinFormStyle(SkinLibrary.Styles[A]);
     if PSkinFilePath<>nil then
      PSkinFilePath^:=Style.SkinFilePath;
     if PZipFilePath<>nil then
      PZipFilePath^:=Style.ZipFilePath;
     Style.GetCurrentFState(FState,FForm.WindowState=wsMaximized,
        FForm.WindowState=wsMinimized,FFormActive);
    end;
  end;
end;

procedure TSXSkinCustomForm.DrawCaptionToRect(Bitmap:TBitmap32;Rect:TRect);
var   FState:TSXSkinFormStateParam;
 TextRect,RR:TRect;
         W,H:Integer;
       Flags:Cardinal;

 procedure DrawStyleToRect(CElementID:Integer;const StyleName:String;X,Y,Width,Height:Integer);
 var   A:Integer;
  GStyle:TSXSkinGeneralStyle;
   ARect:TRect;
     Rgn:HRGN;
 begin
  if (Width<=0) or (Height<=0) then exit;
  if StyleName<>'' then
   begin
    A:=SkinLibrary.Styles.GetGStyleIndex(StyleName,Width,Height);
    if A>=0 then
     begin
      GStyle:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
      ARect:=Types.Rect(0,0,Width,Height);
      OffsetRect(ARect,Rect.Left,Rect.Top);
      Rgn:=CreateRectRgnIndirect(ARect);
      GStyle.DrawToBitmap(FForm,CElementID,Bitmap,X+Rect.Left,Y+Rect.Top,Width,
                          Height,ARect,Rgn,SkinLibrary);
      DeleteObject(Rgn);
     end;
   end;
 end;

 procedure DrawTextToBitmap(Bitmap:TBitmap32);
 begin
  SetDefaultFontData(FState.TextFont,FForm.Font);
  Bitmap.Font.Name:=FState.TextFont.FontName;
  Bitmap.Font.Size:=FState.TextFont.FontSize;
  Bitmap.Font.Style:=FState.TextFont.FontStyle;
  if FState.TextFont.HasShadow then
   begin
    OffsetRect(TextRect,1,1);
    if FState.TextFont.SmoothLevel=0 then
     begin
      if FState.TextFont.ShadowColor shr 24=$FF then
       begin
        Bitmap.Font.Color:=WinColor(FState.TextFont.ShadowColor);
        Bitmap.Textout(TextRect,Flags,FForm.Caption);
        end else DrawAlphaText(Bitmap,FForm.Caption,TextRect,Flags,FState.TextFont.ShadowColor);
     end else
      DrawSmoothText(Bitmap,FForm.Caption,TextRect,Flags,FState.TextFont.SmoothLevel,FState.TextFont.ShadowColor);
    OffsetRect(TextRect,-1,-1);
   end;
  if FState.TextFont.SmoothLevel=0 then
   begin
    if FState.TextFont.FontColor shr 24=$FF then
     begin
      Bitmap.Font.Color:=WinColor(FState.TextFont.FontColor);
      Bitmap.Textout(TextRect,Flags,FForm.Caption);
     end else DrawAlphaText(Bitmap,FForm.Caption,TextRect,Flags,FState.TextFont.FontColor);
   end else DrawSmoothText(Bitmap,FForm.Caption,TextRect,Flags,FState.TextFont.SmoothLevel,FState.TextFont.FontColor);
 end;

 procedure DrawButton(CElementID:Integer;const ButtonRect:TRect;
            ButtonOver,ButtonDown:Boolean;const ButtonStyle:String;ButtonEnabled:Boolean);
 var   A:Integer;
  BStyle:TSXSkinButtonStyle;
  BState:TSXSkinButtonStateParam;
 begin
  if not IsRectEmpty(ButtonRect) and (ButtonStyle<>'') then
   begin
    A:=SkinLibrary.Styles.GetIndexByName(ButtonStyle);
    if (A>=0) and (SkinLibrary.Styles[A] is TSXSkinButtonStyle) then
     begin
      BStyle:=TSXSkinButtonStyle(SkinLibrary.Styles[A]);
      BStyle.GetCurrentBState(BState,False,ButtonEnabled,ButtonOver,
                              ButtonOver and ButtonDown,ButtonDown);
      if BState.Style<>'' then
       DrawStyleToRect(CElementID,BState.Style,ButtonRect.Left,ButtonRect.Top,
            ButtonRect.Right-ButtonRect.Left,ButtonRect.Bottom-ButtonRect.Top);
     end;
   end;
 end;

begin
 if (SkinLibrary<>nil) and SkinLibrary.CanBeUsed and (FForm<>nil) then
  begin
   GetCurrentFState(FState);
   if FState.CaptionStyle<>'' then
    DrawStyleToRect(CEID_Caption,FState.CaptionStyle,0,0,FForm.Width,FCaptionHeight);
   if not IsRectEmpty(FIconRect) then
    begin
     if FUseTFormIcon then
      begin
       H:=FForm.Icon.Handle;
       if H=0 then H:=Application.Icon.Handle;
       DrawIconEx(Bitmap.Handle,FIconRect.Left+Rect.Left,FIconRect.Top+Rect.Top,H,
                  FIconRect.Right-FIconRect.Left,FIconRect.Bottom-FIconRect.Top,
                  0,0,DI_NORMAL);
      end else DrawStyleToRect(CEID_Icon,FIconStyle,FIconRect.Left,FIconRect.Top,
                   FIconRect.Right-FIconRect.Left,FIconRect.Bottom-FIconRect.Top);
    end;
   //
   DrawButton(CEID_Close,FCloseRect,FCloseOver,FCloseDown,FState.CloseButton,biSystemMenu in FForm.BorderIcons);
   if FForm.WindowState=wsMaximized then
    DrawButton(CEID_Restore,FMaximizeRect,FMaximizeOver,FMaximizeDown,FState.RestoreButton,biMaximize in FForm.BorderIcons) else
     DrawButton(CEID_Maximize,FMaximizeRect,FMaximizeOver,FMaximizeDown,FState.MaximizeButton,biMaximize in FForm.BorderIcons);
   DrawButton(CEID_Minimize,FMinimizeRect,FMinimizeOver,FMinimizeDown,FState.MinimizeButton,biMinimize in FForm.BorderIcons);
   DrawButton(CEID_Help,FHelpRect,FHelpOver,FHelpDown,FState.HelpButton,True);
   //
   if FForm.Caption<>'' then
    begin
     Flags:=DT_NOPREFIX or DT_NOCLIP or DT_TOP or DT_VCENTER or DT_SINGLELINE or
            DT_MODIFYSTRING or DT_END_ELLIPSIS;
     case FState.TextAlignment of
      taLeftJustify:  Flags:=Flags or DT_LEFT;
      taRightJustify: Flags:=Flags or DT_RIGHT;
      taCenter:       Flags:=Flags or DT_CENTER;
     end;
     TextRect:=FTextRect;
     if FState.TextFont.DoPrepaint and (FState.TextFont.SmoothLevel>0) and (FTextBitmap=nil) then
      begin
       FTextBitmap:=TBitmap32.Create;
       FTextBitmap.DrawMode:=dmBlend;

⌨️ 快捷键说明

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