📄 fcframe.pas
字号:
unit fcframe;
{$i fcIfDef.pas}
interface
uses classes, Windows, controls, stdctrls, graphics, forms, Messages, typinfo;
type
// TfcComboButtonStyle = (cbsEllipsis, cbsDownArrow, cbsCustom);
TfcButtonEffects = class(TPersistent)
private
FTransparent: boolean;
FFlat: boolean;
procedure SetTransparent(val: boolean);
procedure SetFlat(val: boolean);
protected
Procedure Refresh; virtual;
public
Control: TControl;
Button: TControl;
constructor Create(Owner: TComponent; AButton: TControl);
class Function Get(Control: TControl): TfcButtonEffects;
Procedure Assign(Source: TPersistent); override;
published
property Transparent: boolean read FTransparent write SetTransparent default false;
property Flat: boolean read FFlat write SetFlat default false;
end;
TfcEditFocusStyle = (efsFrameBox, efsFrameSunken, efsFrameRaised, efsFrameEtched,
efsFrameBump, efsFrameSingle);
TfcEditFrameEnabledType = (efLeftBorder, efTopBorder, efRightBorder, efBottomBorder);
TfcEditFrameEnabledSet = set of TfcEditFrameEnabledType;
TfcEditFrame = class(TPersistent)
private
Control: TWinControl;
FEnabled: boolean;
FNonFocusBorders: TfcEditFrameEnabledSet;
FFocusBorders: TfcEditFrameEnabledSet;
FFocusStyle: TfcEditFocusStyle;
FNonFocusStyle: TfcEditFocusStyle;
FNonFocusTextOffsetX: integer;
FNonFocusTextOffsetY: integer;
FTransparent: boolean;
FTransparentClearsBackground: boolean;
FMouseEnterSameAsFocus:boolean;
FAutoSizeHeightAdjust: integer;
FNonFocusTransparentFontColor: TColor;
FNonFocusColor: TColor;
FNonFocusFontColor: TColor;
procedure SetFocusBorders(val: TfcEditFrameEnabledSet);
procedure SetNonFocusBorders(val: TfcEditFrameEnabledSet);
procedure SetNonFocusStyle(val: TfcEditFocusStyle);
procedure SetEnabled(val: boolean);
procedure SetTransparent(val: boolean);
procedure CheckParentClipping;
// procedure AdjustEditRect;
public
CreateTransparent: boolean;
function IsSingleBorderStyle(Style: TfcEditFocusStyle): boolean;
constructor Create(Owner: TComponent);
procedure GetEditRectForFrame(var Loc: TRect);
procedure RefreshTransparentText(InvalidateBorders: boolean=False; UseEditRect: boolean = True);
procedure RefreshControl;
procedure AdjustHeight;
Function IsFrameEffective: boolean;
procedure GetFrameTextPosition(
var Left, Indent: integer;
Focused: boolean = False); virtual;
class Function Get(Control: TControl): TfcEditFrame;
Procedure Assign(Source: TPersistent); override;
property TransparentClearsBackground: boolean
read FTransparentClearsBackground write FTransparentClearsBackground default False;
published
property Enabled: boolean read FEnabled write SetEnabled default False;
property Transparent: boolean read FTransparent write SetTransparent default False;
property AutoSizeHeightAdjust: integer read FAutoSizeHeightAdjust write FAutoSizeHeightAdjust default 0;
property FocusBorders : TfcEditFrameEnabledSet read FFocusBorders write SetFocusBorders
default [efLeftBorder, efTopBorder, efRightBorder, efBottomBorder];
property NonFocusBorders : TfcEditFrameEnabledSet read FNonFocusBorders write SetNonFocusBorders
default [efBottomBorder];
property FocusStyle: TfcEditFocusStyle read FFocusStyle write FFocusStyle default efsFrameBox;
property NonFocusStyle: TfcEditFocusStyle read FNonFocusStyle write SetNonFocusStyle default efsFrameBox;
property NonFocusTextOffsetX: integer read FNonFocusTextOffsetX write FNonFocusTextOffsetX default 0;
property NonFocusTextOffsetY: integer read FNonFocusTextOffsetY write FNonFocusTextOffsetY default 0;
// Obsolete
property NonFocusTransparentFontColor: TColor read FNonFocusTransparentFontColor write FNonFocusTransparentFontColor default clNone;
property NonFocusColor: TColor read FNonFocusColor write FNonFocusColor default clNone;
property NonFocusFontColor: TColor read FNonFocusFontColor write FNonFocusFontColor default clNone;
property MouseEnterSameAsFocus: boolean
read FMouseEnterSameAsFocus write FMouseEnterSameAsFocus default False;
end;
procedure fcDrawEdge(
Control: TWinControl;
Frame: TfcEditFrame;
Canvas: TCanvas;
Focused: boolean);
procedure fcInvalidateTransparentArea(control : TControl);
function fcIsTransparentParent(control : TControl): boolean;
implementation
uses fccommon, grids;
Function fcSetBorder(ctrl: TControl; val: boolean): boolean;
var PropInfo: PPropInfo;
intval: integer;
begin
Result:= False;
PropInfo:= Typinfo.GetPropInfo(ctrl.ClassInfo, 'BorderStyle');
if (PropInfo<>Nil) then begin
if val then intval:= ord(bsSingle)
else intval:= ord(bsNone);
SetOrdProp(Ctrl, PropInfo, intval);
result:= True;
end
end;
function fcTransparent(Control: TControl): boolean;
var PropInfo: PPropInfo;
begin
Result:= False;
PropInfo:= Typinfo.GetPropInfo(Control.ClassInfo,'Transparent');
if PropInfo<>Nil then result:= Boolean(GetOrdProp(Control, PropInfo));
end;
function fcIsTransparentParent(control : TControl): boolean;
var OrigStyle: longint;
pc: TControl;
begin
result:= false;
pc:= control;
// If parent is not transparent then just return
if (fcIsClass(pc.Parent.ClassType, 'TfcPanel') or
fcIsClass(pc.Parent.ClassType, 'TfcGroupBox')) and
fcTransparent(pc.Parent) then
begin
result:= True;
exit;
end;
if (pc.parent is TWinControl) and
TWinControl(pc.parent).HandleAllocated then
begin
OrigStyle:= Windows.GetWindowLong(TWinControl(pc.parent).handle, GWL_EXSTYLE);
result:= (OrigStyle and WS_EX_TRANSPARENT)<>0;
end;
end;
constructor TfcEditFrame.Create(Owner: TComponent);
begin
inherited Create;
Enabled:= false;
FNonFocusBorders:= [efBottomBorder];
FFocusBorders:= [efLeftBorder, efTopBorder, efRightBorder, efBottomBorder];
if Owner is TWinControl then
control:= TWinControl(Owner)
else
control:= nil;
FFocusStyle := efsFrameBox;
FNonFocusStyle:= efsFrameBox;
FNonFocusTextOffsetX:=0;
FNonFocusTextOffsetX:=0;
FNonFocusTransparentFontColor:= clNone;
FNonFocusColor:= clNone;
FNonFocusFontcolor:= clNone;
FMouseEnterSameAsFocus := False;
end;
procedure TfcEditFrame.SetNonFocusBorders(val: TfcEditFrameEnabledSet);
begin
FNonFocusBorders:= val;
if control is TCustomEdit then
begin
RefreshControl;
end
// control.invalidate;
end;
procedure TfcEditFrame.SetFocusBorders(val: TfcEditFrameEnabledSet);
begin
FFocusBorders:= val;
if control is TCustomEdit then
begin
control.invalidate;
end
end;
procedure TfcEditFrame.SetNonFocusStyle(val: TfcEditFocusStyle);
begin
if val<>FNonFocusStyle then
begin
FNonFocusStyle:= val;
if control is TCustomEdit then
begin
control.invalidate;
end
end
end;
procedure TfcEditFrame.SetEnabled(val: boolean);
Function wwGetAutoSize(ctrl: TControl): boolean;
var PropInfo: PPropInfo;
begin
Result:= False;
PropInfo:= Typinfo.GetPropInfo(ctrl.ClassInfo,'AutoSize');
if PropInfo<>Nil then result:= Boolean(GetOrdProp(Ctrl, PropInfo));
end;
begin
if val<>FEnabled then
begin
FEnabled:= val;
if control is TCustomEdit then
begin
if val then fcSetBorder(control, False);
if wwGetAutoSize(control) then AdjustHeight;
control.invalidate;
end
end
end;
procedure fcDrawEdge(
Control: TWinControl;
Frame: TfcEditFrame;
Canvas: TCanvas;
Focused: boolean);
var cr: TRect;
// StateFlags: Word;
Flags: integer;
focusStyle: TfcEditFocusStyle;
begin
cr:= Control.ClientRect;
if Focused then begin
if not (efRightBorder in Frame.FocusBorders) and
frame.transparent then cr.right:= cr.right-2;
flags:= 0;
if efLeftBorder in Frame.FocusBorders then flags:= flags + bf_left;
if efBottomBorder in Frame.FocusBorders then flags:= flags + bf_bottom;
if efTopBorder in Frame.FocusBorders then flags:= flags + bf_top;
if efRightBorder in Frame.FocusBorders then flags:= flags + bf_right;
focusStyle:= Frame.FocusStyle;
end
else begin
if not (efRightBorder in Frame.NonFocusBorders) and
frame.transparent then cr.right:= cr.right-2;
flags:= 0;
if efLeftBorder in Frame.NonFocusBorders then flags:= flags + bf_left;
if efBottomBorder in Frame.NonFocusBorders then flags:= flags + bf_bottom;
if efTopBorder in Frame.NonFocusBorders then flags:= flags + bf_top;
if efRightBorder in Frame.NonFocusBorders then flags:= flags + bf_right;
focusStyle:= Frame.NonFocusStyle;
end;
if (FocusStyle=efsFrameSingle) then
begin
DrawEdge(Canvas.Handle, cr, BDR_SUNKENOUTER, flags or bf_mono );
end
else if (FocusStyle=efsFrameBox) then
begin
DrawEdge(Canvas.Handle, cr, EDGE_SUNKEN, flags or bf_mono);
end
else if (FocusStyle=efsFrameSunken) then
begin
DrawEdge(Canvas.Handle, cr, EDGE_SUNKEN, flags);
end
else if (FocusStyle=efsFrameRaised) then
begin
DrawEdge(Canvas.Handle, cr, EDGE_RAISED, flags);
end
else if (FocusStyle=efsFrameEtched) then
begin
DrawEdge(Canvas.Handle, cr, EDGE_ETCHED, flags);
end
else if (FocusStyle=efsFrameBump) then
begin
DrawEdge(Canvas.Handle, cr, EDGE_BUMP, flags);
end;
end;
procedure TfcEditFrame.CheckParentClipping;
var OldStyle: longint;
begin
if FTransparent and IsFrameEffective and (Control<>nil) and
not (csDesigning in Control.ComponentState) then
begin
if Control.HandleAllocated then
begin
OldStyle:= GetWindowLong(Control.Parent.Handle, GWL_STYLE);
if OldStyle and (NOT WS_CLIPCHILDREN)<>OldStyle then
begin
SendMessage(Control.Handle, CM_RECREATEWND, 0, 0);
end
end
end
end;
procedure TfcEditFrame.SetTransparent(val: boolean);
begin
if val<>FTransparent then
begin
CreateTransparent:= val;
FTransparent:= val;
CheckParentClipping;
end;
{ if (Control<>nil) and Control.HandleAllocated and
fcIsClass(Control.ClassType, 'TfcCustomRichEdit') and (Control<>nil) then
begin
SendMessage(control.handle, cm_recreatewnd, 0, 0);
end;;
}
end;
procedure TfcEditFrame.RefreshTransparentText(InvalidateBorders: boolean=False; UseEditRect: boolean = True);
var r,tempeditrect:TRect;
dc: HDC;
brush: HBRUSH;
begin
r:= Control.BoundsRect;
if not InvalidateBorders then
begin
SendMessage(Control.handle,em_getrect, 0, Integer(@tempeditrect));
if not useEditRect then begin
InflateRect(r,-2,-2);
if not (efLeftBorder in nonFocusBorders) then dec(r.Left,2);
end
else if (TEdit(Control).BorderStyle=bsNone) then
begin
InflateRect(r,-2,-2);
if not (efLeftBorder in nonFocusBorders) then dec(r.Left,2);
r.Right := r.Left+tempeditrect.Right+1;
end
end;
{ If imager not in background, then need to explicitly clear background }
if fcIsTransparentParent(Control) { or True } then
fcInvalidateTransparentArea(Control)
else if (Control.Parent.ControlAtPos( Point(Control.Left, Control.Top), True)=nil) then
begin
DC := GetDC(Control.Handle);
brush:= 0;
try
brush:= CreateSolidBrush(ColorToRGB(TEdit(Control.parent).color));
SelectObject(DC, brush);
if not InvalidateBorders then
begin
InflateRect(tempEditRect, 1, 1);
{ 11/22/99 - Fix problem where far left pixels are not cleared }
if not (efLeftBorder in nonFocusBorders) then
begin
dec(tempEditRect.Left,1);
if tempEditRect.Left<0 then tempEditRect.left:= 0;
end;
Windows.FillRect(DC, tempEditRect, brush);
end
else begin
r:= Control.ClientRect;
Windows.FillRect(DC, r, brush);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -