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

📄 spagecontrol.pas

📁 Alpha Controls.v5.46b Source
💻 PAS
📖 第 1 页 / 共 4 页
字号:
      end;
    end;
  end
  else case Message.Msg of
    WM_WINDOWPOSCHANGING, CM_INVALIDATE : ArrangeButtons;
  end;
end;

procedure TsPageControl.UpdateUpDownRgn;
var
  Bmp : TBitmap;
  mi : integer;
  rgn : hrgn;
begin
Exit;//v5.46
  if (UpDown <> nil) and (UpDown.ButtonSkin = s_Button) then begin
    mi := SkinData.SkinManager.GetMaskIndex(UpDown.ButtonSkin, s_BordersMask);
    if SkinData.SkinManager.IsValidImgIndex(mi) then begin
      Bmp := CreateBmp24(UpDown.Width div 2, UpDown.Height);
      FillDC(Bmp.Canvas.Handle, Rect(0, 0, Bmp.Width, Bmp.Height), clFuchsia + 1);
      CtrlParentColor := clFuchsia + 1;
      UpDown.DrawBtn(Bmp, sbkLeft);
      CtrlParentColor := clFuchsia;
      Bmp.Width := UpDown.Width;
      BitBlt(Bmp.Canvas.Handle, UpDown.Width div 2, 0, UpDown.Width div 2, UpDown.Height, Bmp.Canvas.Handle, 0, 0, SRCCOPY);
      GetRgnFromBmp(rgn, Bmp, clFuchsia + 1);
      if Rgn <> 0 then SetWindowRgn(UpDown.Handle, Rgn, Repaint);
      FreeAndNil(Bmp);
    end;
  end;
end;

procedure TsPageControl.ArrangeButtons;
var
  i : integer;
  Page : TsTabSheet;
  rTab : TRect;
  function TabHeight : integer; begin
    case TabPosition of
      tpTop, tpBottom : Result := HeightOf(rTab)
      else Result := WidthOf(rTab);
    end;
  end;
begin
  if FShowCloseBtns and not SkinData.Skinned then begin
    for i := 0 to PageCount - 1 do begin
      Page := TsTabSheet(Pages[i]);
      if Page.Btn <> nil then Page.Btn.Visible := Page.TabVisible;
      if not Page.TabVisible or not Page.UseCloseBtn then Continue;
      rTab := TabRect(Page.TabIndex);
      if Page.Btn = nil then begin
        Page.Btn := TsTabBtn.Create(Self);
        Page.Btn.OnClick := CloseClick;
        Page.Btn.Page := Page;
        Page.Btn.Visible := False;
        Page.Btn.Height := iBtnHeight;
        Page.Btn.Width := iBtnWidth;
        Page.Btn.Parent := Self;
      end;
      case TabPosition of
        tpTop, tpBottom : begin
          Page.Btn.Left := rTab.Right - Page.Btn.Width - BtnOffs;
          Page.Btn.Top := rTab.Top + BtnOffs;
        end;
        tpLeft : begin
          Page.Btn.Left := rTab.Left + BtnOffs;
          Page.Btn.Top := rTab.Top + BtnOffs;
        end
        else begin
          Page.Btn.Left := rTab.Right - Page.Btn.Width - BtnOffs;
          Page.Btn.Top := rTab.Top + BtnOffs;
        end
      end;
      Page.Btn.Visible := True;
    end;
  end
  else for i := 0 to PageCount - 1 do begin
    if TsTabSheet(Pages[i]).Btn <> nil then FreeAndNil(TsTabSheet(Pages[i]).Btn);
  end;
end;

procedure TsPageControl.SetShowCloseBtns(const Value: boolean);
begin
  if FShowCloseBtns <> Value then begin
    FShowCloseBtns := Value;
    if SkinData.Skinned and Value then UpdateBtnData;
    ArrangeButtons;
    if SkinData.Skinned then FCommonData.Invalidate;
  end;
end;

procedure TsPageControl.CloseClick(Sender: TObject);
var
  ToClose : boolean;
  Act : TacCloseAction;
begin
  ToClose := True;
  Act := acaFree;
  if Assigned(OnCloseBtnClick) then OnCloseBtnClick(Self, TsTabBtn(Sender).Page.TabIndex, ToClose, Act);
  if ToClose then begin
    if Act = acaFree then FreeAndNil(TsTabBtn(Sender).Page) else TsTabBtn(Sender).Page.TabVisible := False;
    TsTabBtn(Sender).Visible := False;
    ArrangeButtons;
    RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_UPDATENOW);
  end;
end;

procedure TsPageControl.PaintButton(DC: hdc; TabRect: TRect; State: integer; BG : hdc = 0);
Const
  sx = 'X';
var
  BtnRect : TRect;
  TmpBmp : TBitmap;
  x, y : integer;
begin
  if BtnIndex < 0 then Exit;
  BtnRect.Left := TabRect.Right - BtnWidth - BtnOffs;
  BtnRect.Top := TabRect.Top + BtnOffs;
  BtnRect.Right := TabRect.Right - BtnOffs;
  BtnRect.Bottom := TabRect.Top + BtnHeight + BtnOffs;

  TmpBmp := CreateBmp24(BtnWidth, BtnHeight);
  if BG = 0
    then BitBlt(TmpBmp.Canvas.Handle, 0, 0, BtnWidth, BtnHeight, FCommonData.FCacheBmp.Canvas.Handle, BtnRect.Left, BtnRect.Top, SRCCOPY)
    else BitBlt(TmpBmp.Canvas.Handle, 0, 0, BtnWidth, BtnHeight, BG, WidthOf(TabRect) - BtnWidth - BtnOffs, BtnOffs, SRCCOPY);

  if CloseBtnSkin = '' then DrawSkinGlyph(TmpBmp, Point(0, 0), State, 1, FCommonData.SkinManager.ma[BtnIndex]) else begin
    GlobalCacheInfo := MakeCacheInfo(FCommonData.FCacheBmp, BtnRect.Left, BtnRect.Top);

    PaintItem(BtnIndex, CloseBtnSkin, GlobalCacheInfo, True, State, Rect(0, 0, TmpBmp.Width, TmpBmp.Height),
      Point(0, 0), TmpBmp, SkinData.SkinManager);

    TmpBmp.Canvas.Brush.Style := bsClear;
    TmpBmp.Canvas.Font.Style := [fsBold];
    TmpBmp.Canvas.Font.Color := clRed;
    x := (iBtnWidth - TmpBmp.Canvas.TextWidth(sx)) div 2;
    y := (iBtnHeight - TmpBmp.Canvas.TextHeight(sx)) div 2;
    TmpBmp.Canvas.TextOut(x + integer(State = 2), y + integer(State = 2), 'X');
  end;

  BitBlt(DC, BtnRect.Left, BtnRect.Top, BtnWidth, BtnHeight, TmpBmp.Canvas.Handle, 0, 0, SRCCOPY);
  FreeAndNil(TmpBmp);
end;

procedure TsPageControl.PaintButtons(DC: hdc);
var
  i, j : integer;
begin
  if not FShowCloseBtns then Exit;
//  if Skindata.Skinned then begin // !!!
//  end; 
  j := 0;
  for i := 0 to PageCount - 1 do if Pages[i].TabVisible then begin
    if TsTabSheet(Pages[i]).UseCloseBtn
      then PaintButton(DC, SkinTabRect(j, Pages[i] = ActivePage), 2 * integer(Pages[i] = ActivePage));
    inc(j);
  end;
end;

procedure TsPageControl.UpdateBtnData;
begin
  if CloseBtnSkin <> '' then begin
    BtnIndex := FCommonData.SkinManager.GetSkinIndex(CloseBtnSkin);
    if BtnIndex > -1 then begin
      BtnWidth := iBtnWidth;
      BtnHeight := iBtnWidth;
    end;
  end
  else begin
    BtnIndex := FCommonData.SkinManager.GetMaskIndex(FCommonData.SkinManager.ConstData.IndexGlobalInfo, s_GlobalInfo, s_SmallIconClose);
    if BtnIndex < 0 then BtnIndex := FCommonData.SkinManager.GetMaskIndex(FCommonData.SkinManager.ConstData.IndexGlobalInfo, s_GlobalInfo, s_BorderIconClose);
    if BtnIndex > -1 then begin
      BtnWidth := WidthOf(FCommonData.SkinManager.ma[BtnIndex].R) div FCommonData.SkinManager.ma[BtnIndex].ImageCount;
      BtnHeight := HeightOf(FCommonData.SkinManager.ma[BtnIndex].R) div (1 + FCommonData.SkinManager.ma[BtnIndex].MaskType);
    end;
  end;
end;

function TsPageControl.BtnRect(TabIndex: integer): TRect;
var
  R : TRect;
begin
  if SkinData.Skinned or (TabIndex < 0) then begin
    R := SkinTabRect(TabIndex, Pages[TabIndex] = ActivePage);
    Result := Rect(R.Right - BtnWidth - BtnOffs, R.Top + BtnOffs, R.Right - BtnOffs, R.Top + BtnHeight + BtnOffs);
  end
  else Result := Rect(0, 0, 0, 0)
end;

procedure TsPageControl.PaintButtonEx(TabIndex : integer; BtnState: integer; TabState : integer);
var
  DC : hdc;
  R : TRect;
  TmpBmp : TBitmap;
begin
  if (TabIndex < 0) or not FShowCloseBtns or not TsTabSheet(Pages[TabIndex]).UseCloseBtn then Exit;
  R := SkinTabRect(Pages[TabIndex].TabIndex, Pages[TabIndex] = ActivePage);
  TmpBmp := CreateBmp24(WidthOf(R), HeightOf(R));

  DrawSkinTab(TabIndex, TabState, TmpBmp, Point(-R.Left, -R.Top));
  if TabState <> 2 then begin
    BitBlt(TmpBmp.Canvas.Handle, 0, TmpBmp.Height - 5, TmpBmp.Width, 5, FCommonData.FCacheBmp.Canvas.Handle, R.Left, R.Bottom - 5, SRCCOPY);
  end;

  DC := GetDC(Handle);
  PaintButton(DC, R, BtnState, TmpBmp.Canvas.Handle);
  ReleaseDC(Handle, DC);

  FreeAndNil(TmpBmp);
end;

procedure TsPageControl.SetCloseBtnSkin(const Value: TsSkinSection);
begin
  if FCloseBtnSkin <> Value then begin
    FCloseBtnSkin := Value;
    FCommonData.Invalidate;
  end;
end;

{ TsTabSheet }

constructor TsTabSheet.Create(AOwner: TComponent);
begin
  inherited;
  FCommonData := TsTabSkinData.Create;
  Btn := nil;
  FUseCloseBtn := True;
end;

procedure TsTabSheet.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params.WindowClass do style := style and not (CS_HREDRAW or CS_VREDRAW);
end;

destructor TsTabSheet.Destroy;
begin
  FreeAndNil(FCommonData);
  inherited;
end;

procedure TsTabSheet.SetButtonSkin(const Value: TsSkinSection);
begin
  if FButtonSkin <> Value then begin
    FButtonSkin := Value;
    if PageControl <> nil then TsPageControl(PageControl).SkinData.Invalidate;
  end;
end;

procedure TsTabSheet.SetTabSkin(const Value: TsSkinSection);
begin
  if FTabSkin <> Value then begin
    FTabSkin := Value;
    if PageControl <> nil then TsPageControl(PageControl).SkinData.Invalidate;
  end;
end;

procedure TsTabSheet.SetUseCloseBtn(const Value: boolean);
begin
  if FUseCloseBtn <> Value then begin
    FUseCloseBtn := Value;
    if PageControl <> nil then TsPageControl(PageControl).SkinData.Invalidate;
  end;
end;

procedure TsTabSheet.WMPaint(var Message: TWMPaint);
var
  DC, SavedDC : hdc;
  PS : TPaintStruct;
begin
  if not (csDestroying in ComponentState) and TsPageControl(PageControl).SkinData.Skinned and Showing then begin
    BeginPaint(Handle, PS);
    try
      TsPageControl(PageControl).SkinData.Updating := TsPageControl(PageControl).SkinData.Updating;
      if not TsPageControl(PageControl).SkinData.Updating then begin
        SavedDC := 0;
        if Message.DC = 0 then begin
          DC := GetDC(Handle);
          SavedDC := SaveDC(DC);
        end
        else DC := Message.DC;
        try
          CopyWinControlCache(Self, TsPageControl(PageControl).SkinData, Rect(Left, Top, 0, 0), Rect(0, 0, Width, Height), DC, False);
          sVCLUtils.PaintControls(DC, Self, True, Point(0, 0));
          SetParentUpdated(Self);
        finally
          if Message.DC = 0 then begin
            RestoreDC(DC, SavedDC);
            ReleaseDC(Handle, DC);
          end;
        end;
      end
    finally
      EndPaint(Handle, PS);
    end;
  end
  else inherited;
end;

procedure TsTabSheet.WndProc(var Message: TMessage);
begin
{$IFDEF D_LOGGED}
//  AddToLog(Message);
{$ENDIF}
  if PageControl <> nil then begin
    if (Message.Msg = SM_ALPHACMD) then case Message.WParamHi of
      AC_CTRLHANDLED : begin Message.LParam := 1; Exit end; // AlphaSkins supported
      AC_GETAPPLICATION : begin Message.Result := longint(Application); Exit end;
      AC_REMOVESKIN : begin
        if Message.LParam = LongInt(TsPageControl(PageControl).SkinData.SkinManager) then Repaint;
        AlphaBroadCast(Self, Message);
      end;
      AC_SETNEWSKIN : begin
        AlphaBroadCast(Self, Message);
      end;
      AC_REFRESH : begin
        if (Message.LParam = LongInt(TsPageControl(PageControl).SkinData.SkinManager)) and Visible then Repaint;
        AlphaBroadCast(Self, Message);
      end;
      AC_GETCACHE : if TsPageControl(PageControl).SkinData.Skinned then begin
        SendAMessage(PageControl, AC_GETCACHE);
        GlobalCacheInfo.X := Left;
        GlobalCacheInfo.Y := Top;
      end;
      AC_GETCONTROLCOLOR : if TsPageControl(PageControl).SkinData.Skinned then begin
        SendMessage(PageControl.Handle, SM_ALPHACMD, MakeWParam(0, AC_GETCONTROLCOLOR), 0)
      end;
      AC_PREPARING : if TsPageControl(PageControl).SkinData.Skinned then begin
        Message.LParam := integer(GetBoolMsg(PageControl, AC_PREPARING));
        Exit;
      end;
      AC_CHILDCHANGED : if TsPageControl(PageControl).SkinData.Skinned then begin
        Message.LParam := integer((TsPageControl(PageControl).SkinData.SkinManager.gd[TsPageControl(PageControl).SkinData.SkinIndex].GradientPercent + TsPageControl(PageControl).SkinData.SkinManager.gd[TsPageControl(PageControl).SkinData.SkinIndex].ImagePercent > 0) or TsPageControl(PageControl).SkinData.RepaintIfMoved);
        Message.Result := Message.LParam;
        Exit;
      end;
    end
    else if TsPageControl(PageControl).SkinData.Skinned then case Message.Msg of
      WM_MOUSEMOVE : if not (csDesigning in ComponentState) then begin
        if (DefaultManager <> nil) and not (csDesigning in DefaultManager.ComponentState) then DefaultManager.ActiveControl := 0;
      end;
      WM_PARENTNOTIFY : if (Message.WParam and $FFFF = WM_CREATE) or (Message.WParam and $FFFF = WM_DESTROY) then begin
        inherited;
        if Message.WParamLo = WM_CREATE then AddToAdapter(Self);
        exit;
      end;
      WM_ERASEBKGND : begin
        Message.Result := 1;
        Exit
      end;
    end;
  end;
  inherited;
end;

{ TsTabSkinData }

procedure TsTabSkinData.SetCustomColor(const Value: boolean);
begin
  FCustomColor := Value;
end;

procedure TsTabSkinData.SetCustomFont(const Value: boolean);
begin
  FCustomFont := Value;
end;

procedure TsTabSkinData.SetSkinSection(const Value: string);
begin
  FSkinSection := Value;
end;

{ TsTabBtn }

constructor TsTabBtn.Create(AOwner: TComponent);
begin
  inherited;
  Flat := True;
  UpdateGlyph;
end;

procedure TsTabBtn.UpdateGlyph;
begin
  Caption := 'X';
  Font.Style := [fsBold];
  Font.Color := clRed;
end;

end.

⌨️ 快捷键说明

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