📄 scombobox.pas
字号:
unit sComboBox;
{$I sDefs.inc}
{.$DEFINE LOGGED}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
{$IFDEF TNTUNICODE}TntControls, TntClasses, TntActnList, TntStdCtrls, TntGraphics, {$ENDIF}
StdCtrls, sConst, sDefaults, acSBUtils,
sCommonData{$IFDEF LOGGED}, sDebugMsgs{$ENDIF};
type
{$IFNDEF NOTFORHELP}
{$IFDEF TNTUNICODE}
TsCustomComboBox = class(TTntCustomComboBox)
{$ELSE}
TsCustomComboBox = class(TCustomComboBox)
{$ENDIF}
private
FAlignment : TAlignment;
FReadOnly: boolean;
FDisabledKind: TsDisabledKind;
FCommonData: TsCommonData;
FBoundLabel: TsBoundLabel;
FShowButton: boolean;
procedure SetAlignment(const Value: TAlignment);
procedure SetReadOnly(const Value: boolean);
procedure SetDisabledKind(const Value: TsDisabledKind);
procedure SetShowButton(const Value: boolean);
protected
lboxhandle : hwnd;
ListSW : TacScrollWnd;
OldDropcountValue : integer;
procedure PrepareCache;
procedure PaintText; virtual;
procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
procedure OurPaintHandler(iDC : hdc);
procedure DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); override;
procedure DrawSkinItem(Index: Integer; Rect: TRect; State: TOwnerDrawState);
procedure WndProc (var Message: TMessage); override;
procedure ComboWndProc(var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer); override;
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure WMLButtonDblClk(var Message: TMessage); message WM_LBUTTONDBLCLK;
public
FChildHandle: HWND;
FDefListProc: Pointer;
FDropDown : boolean;
bFormHandle : hwnd;
bFormDefProc: Pointer;
constructor Create(AOwner:TComponent); override;
destructor Destroy; override;
function IndexOf(const s : string) : integer;
procedure Invalidate; override;
function ButtonRect: TRect;
procedure PaintButton;
function ButtonHeight : integer;
procedure AfterConstruction; override;
procedure Loaded; override;
function Focused: Boolean; override;
property ShowButton : boolean read FShowButton write SetShowButton default True;
published
property Align;
property Alignment : TAlignment read FAlignment write SetAlignment; //KJS
property BoundLabel : TsBoundLabel read FBoundLabel write FBoundLabel;
property DisabledKind : TsDisabledKind read FDisabledKind write SetDisabledKind default DefDisabledKind;
property DropDownCount default 16;
property SkinData : TsCommonData read FCommonData write FCommonData;
property ReadOnly : boolean read FReadOnly write SetReadOnly default False;
end;
{$ENDIF} // NOTFORHELP
TsComboBox = class(TsCustomComboBox)
{$IFNDEF NOTFORHELP}
property Style; {Must be published before Items}
property Anchors;
{$IFDEF DELPHI7UP}
property AutoComplete;
{$ENDIF}
property BiDiMode;
property CharCase;
property Color;
property Constraints;
property Ctl3D;
property DragCursor;
property DragKind;
property DragMode;
property DropDownCount;
property Enabled;
property Font;
property ImeMode;
property ImeName;
property ItemHeight;
property ItemIndex;
property MaxLength;
property ParentBiDiMode;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
{$IFDEF TNTUNICODE}
property SelText;
property SelStart;
property SelLength;
{$ENDIF}
property ShowHint;
property Sorted;
property TabOrder;
property TabStop;
property Text;
property Visible;
{$IFDEF DELPHI6UP}
property OnCloseUp;
property OnSelect;
{$ENDIF}
property OnChange;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnDrawItem;
property OnDropDown;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMeasureItem;
property OnStartDock;
property OnStartDrag;
property Items; { Must be published after OnMeasureItem }
{$ENDIF} // NOTFORHELP
property BoundLabel;
property DisabledKind;
property SkinData;
property ReadOnly;
end;
implementation
uses sStyleSimply, sSkinProps, sVCLUtils, sMessages, sAlphaGraph,
acntUtils, sGraphUtils, sSkinManager;
var
bFlag : boolean = False;
function IsOwnerDraw(Ctrl : TsCustomComboBox) : boolean;
begin
Result := (Ctrl.Style in [csOwnerDrawFixed, csOwnerDrawVariable]) and Assigned(Ctrl.OnDrawItem)
end;
{ TsCustomComboBox }
procedure TsCustomComboBox.AfterConstruction;
begin
inherited AfterConstruction;
FCommonData.Loaded;
end;
function TsCustomComboBox.ButtonHeight: integer;
begin
if FCommonData.Skinned and (FCommonData.SkinManager.ConstData.ComboGlyph > -1)
then Result := HeightOf(FCommonData.SkinManager.ma[FCommonData.SkinManager.ConstData.ComboGlyph].R) div (1 + FCommonData.SkinManager.ma[FCommonData.SkinManager.ConstData.ComboGlyph].MaskType)
else Result := 16;
end;
function TsCustomComboBox.ButtonRect: TRect;
const
iMargin = 2;
var
w : integer;
begin
if (Style <> csSimple) and FShowButton then w := GetSystemMetrics(SM_CXVSCROLL) else w := 0;
if UseRightToLeftAlignment then Result.Left := iMargin else Result.Left := Width - w - iMargin;
Result.Top := iMargin;
Result.Right := Result.Left + w;
Result.Bottom := Height - iMargin;
end;
procedure TsCustomComboBox.CNDrawItem(var Message: TWMDrawItem);
var
b1, b2 : boolean;
ds : TDrawItemStruct;
begin
ds := Message.DrawItemStruct^;
b1 := (ds.itemState and ODS_COMBOBOXEDIT = 0);
b2 := ((ds.itemState and ODS_FOCUS <> 0) and not DroppedDown);
if not SkinData.Skinned or b1 or b2 or DroppedDown then inherited else begin
with Message.DrawItemStruct^ do BitBlt(hDC, 0, 0, Width, Height, FCommonData.FCacheBmp.Canvas.Handle, 0, 0, SRCCOPY);
end;
end;
procedure TsCustomComboBox.ComboWndProc(var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer);
var
ps : TPaintStruct;
begin
{$IFDEF LOGGED}
// AddToLog(Message);
{$ENDIF}
if ReadOnly then begin
case Message.Msg of
WM_KEYDOWN, WM_CHAR, WM_KEYUP, WM_SYSKEYUP, CN_KEYDOWN, CN_CHAR, CN_SYSKEYDOWN,
CN_SYSCHAR, WM_PASTE, WM_CUT, WM_CLEAR, WM_UNDO: Exit
else
{$IFDEF TNTUNICODE}
// if not TntCombo_ComboWndProc(Self, Message, ComboWnd, ComboProc, DoEditCharMsg) then
{$ENDIF}
end
end;
{$IFDEF TNTUNICODE}
// if not TntCombo_ComboWndProc(Self, Message, ComboWnd, ComboProc, DoEditCharMsg) then
{$ENDIF}
begin
if FCommonData.Skinned then case Message.Msg of
WM_ERASEBKGND, WM_NCPAINT : if (Style <> csSimple) and (not (Focused or FCommonData.FFocused) or not Enabled or ReadOnly) then begin
Message.Result := 1;
Exit;
end;
WM_PAINT : if (Style <> csSimple) and (not (Focused or FCommonData.FFocused) or not Enabled or ReadOnly) then begin
BeginPaint(ComboWnd, PS);
{ if not FCommonData.BGChanged then begin
DC := GetWindowDC(ComboWnd);
if DroppedDown then
BitBlt(DC, 0, 0, Width - 6, FCommonData.FCacheBmp.Height - 6, FCommonData.FCacheBmp.Canvas.Handle, 3, 3, SRCCOPY);
ReleaseDC(ComboWnd, DC);
end;}
EndPaint(ComboWnd, PS);
Exit;
end;
end;
inherited;
end;
end;
constructor TsCustomComboBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
DropDownCount := 16;
FCommonData := TsCommonData.Create(Self, True);
FCommonData.COC := COC_TsEdit;
if FCommonData.SkinSection = '' then FCommonData.SkinSection := s_ComboBox;
FDisabledKind := DefDisabledKind;
FBoundLabel := TsBoundLabel.Create(Self, FCommonData);
FDropDown := False;
// Canvas.Handle := 0;
FReadOnly := False;
FShowButton := True;
FDefListProc := nil;
end;
destructor TsCustomComboBox.Destroy;
begin
if lBoxHandle <> 0 then begin
SetWindowLong(lBoxHandle, GWL_STYLE, GetWindowLong(lBoxHandle, GWL_STYLE) and not WS_THICKFRAME or WS_BORDER);
UninitializeACScroll(lBoxHandle, True, False, ListSW);
lBoxHandle := 0;
end;
FreeAndNil(FBoundLabel);
if Assigned(FCommonData) then FreeAndNil(FCommonData);
inherited Destroy;
end;
procedure TsCustomComboBox.DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
Offset : integer;
begin
if FCommonData.Skinned and (odComboBoxEdit in State) then begin
Canvas.Font.Assign(Font);
BitBlt(Canvas.Handle, 0, 0, Width, Height, FCommonData.FCacheBmp.Canvas.Handle, 0, 0, SRCCOPY);
if not Enabled or ReadOnly then Exit;
if DroppedDown then begin
if (odComboBoxEdit in State) then begin
Canvas.Font.Color := Font.Color;
Canvas.Brush.Style := bsClear;
end
else begin
Canvas.Brush.Style := bsSolid;
if not DroppedDown then begin
Canvas.Font.Color := clHighLightText;
Canvas.Brush.Color := clHighLight;
Canvas.FillRect(Rect);
end
else begin
Canvas.Font.Color := Font.Color;
if FCommonData.Skinned or not (odComboBoxEdit in State) then Canvas.Brush.Style := bsClear else begin
Canvas.Brush.Color := ColorToRGB(Color);
Canvas.FillRect(Rect);
end;
end;
end;
if Assigned(OnDrawItem) then OnDrawItem(Self, Index, Rect, State) else begin
TControlCanvas(Canvas).UpdateTextFlags;
if Text <> '' then begin
Offset := integer(Style <> csDropDown);
{$IFDEF TNTUNICODE}
WideCanvasTextOut(Canvas, Rect.Left + Offset, Rect.Top + Offset, Items[Index]);
{$ELSE}
Canvas.TextRect(Rect, Rect.Left + Offset, Rect.Top + Offset, Items[Index]);
{$ENDIF}
end;
end;
if odFocused in State then Canvas.DrawFocusRect(Rect);
end
else begin
Canvas.Brush.Style := bsSolid;
if IsOwnerDraw(Self) then begin
if (odFocused in State) then begin
Canvas.Font.Color := clHighLightText;
Canvas.Brush.Color := clHighLight;
end
else begin
Canvas.Font.Color := Font.Color;
Canvas.Brush.Color := Color;
end;
if Index > -1 then OnDrawItem(Self, Index, Rect, State);
end
else begin
if not ((odSelected in State) or (odFocused in State) or FCommonData.FFocused or Focused) then Exit;
Canvas.Font.Color := clHighLightText;
Canvas.Brush.Color := clHighLight;
Canvas.FillRect(Rect);
TControlCanvas(Canvas).UpdateTextFlags;
if Text <> '' then begin
Offset := integer(Style <> csDropDown);
{$IFDEF TNTUNICODE}
WideCanvasTextOut(Canvas, Rect.Left + Offset, Rect.Top + Offset, Items[Index]);
{$ELSE}
Canvas.TextRect(Rect, Rect.Left + Offset, Rect.Top + Offset, Items[Index]);
{$ENDIF}
end;
end;
end;
end
else begin
Canvas.Font.Assign(Font);
if ((odSelected in State) or (odFocused in State)) then begin
Canvas.Font.Color := clHighLightText;
Canvas.Brush.Color := clHighLight;
Canvas.Brush.Style := bsSolid;
if not IsOwnerDraw(Self) then Canvas.FillRect(Rect);
end
else begin
if Enabled then Canvas.Font.Color := Font.Color else Canvas.Font.Color := clBtnShadow;
Canvas.Brush.Color := ColorToRGB(Color);
Canvas.Brush.Style := bsSolid;
Canvas.FillRect(Rect);
end;
if Assigned(OnDrawItem) then OnDrawItem(Self, Index, Rect, State) else begin
TControlCanvas(Canvas).UpdateTextFlags;
if Text <> '' then begin
Offset := integer(Style <> csDropDown);
{$IFDEF TNTUNICODE}
WideCanvasTextOut(Canvas, Rect.Left + Offset, Rect.Top + Offset, Items[Index]);
{$ELSE}
Canvas.TextRect(Rect, Rect.Left + Offset, Rect.Top + Offset, Items[Index]);
{$ENDIF}
end;
end;
end;
end;
procedure TsCustomComboBox.DrawSkinItem(Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
R : TRect;
Flags : Cardinal;
begin
FCommonData.FCacheBmp.Canvas.Font.Assign(Font);
if (odFocused in State) then begin
FCommonData.FCacheBmp.Canvas.Font.Color := ColorToRGB(clHighlightText);
FCommonData.FCacheBmp.Canvas.Brush.Color := ColorToRGB(clHighlight);
FCommonData.FCacheBmp.Canvas.Brush.Style := bsSolid;
FCommonData.FCacheBmp.Canvas.FillRect(Rect);
end
else begin
FCommonData.FCacheBmp.Canvas.Font.Color := Font.Color;
FCommonData.FCacheBmp.Canvas.Brush.Color := Color;
FCommonData.FCacheBmp.Canvas.Brush.Style := bsClear;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -