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

📄 scustomcomboedit.pas

📁 Alpha Controls.v5.46b Source
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit sCustomComboEdit;
{$I sDefs.inc}
{.$DEFINE LOGGED}

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Mask, acntUtils, buttons, menus, sCalcUnit, sConst, sSpeedButton,
  sGraphUtils, sCommonData, sDefaults, sMaskEdit, sSkinProps, sBitBtn,
  sGlyphUtils{$IFDEF DELPHI6}, Variants{$ENDIF};

type
{$IFNDEF NOTFORHELP}
  TCloseUpEvent = procedure (Sender: TObject; Accept: Boolean) of object;
  TsCustomComboEdit = class;

  TsEditButton = class(TsSpeedButton)
  private
    FOwner : TsCustomComboEdit;
  public
    constructor Create(AOwner: TComponent); override;
    procedure DrawStandardGlyph;
    procedure PaintTo(DC : hdc; R : TPoint);
    procedure PrepareCache; override;
    procedure DrawGlyph; reintroduce;
    procedure Paint; override;
    function GlyphWidth : integer; override;
    function GlyphHeight : integer; override;
  end;
{$ENDIF} // NOTFORHELP

  TsCustomComboEdit = class(TsMaskEdit)
{$IFNDEF NOTFORHELP}
  private
    FButton: TsEditButton;
    FClickKey: TShortCut;
    FReadOnly: Boolean;
    FDirectInput: Boolean;
    FAlignment: TAlignment;
    FPopupWindowAlign: TPopupWindowAlign;
    FGlyphMode: TsGlyphMode;
    FPopupWidth: integer;
    FDisabledKind: TsDisabledKind;
    FShowButton: boolean;
    procedure EditButtonClick(Sender: TObject);
    procedure EditButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure EditButtonMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    function GetDroppedDown: Boolean;
    procedure SetDirectInput(Value: Boolean);
    procedure SetReadOnly(Value: Boolean);
    procedure SetAlignment(Value: TAlignment);
    procedure CMCancelMode(var Message: TCMCancelMode); message CM_CANCELMODE;
    procedure WMPaste(var Message: TWMPaste); message WM_PASTE;
    procedure WMCut(var Message: TWMCut); message WM_CUT;
    procedure CMFocuseChanged(var Message: TCMFocusChanged); message CM_FOCUSCHANGED;
    procedure SetPopupWidth(const Value: integer);
    procedure SetDisabledKind(const Value: TsDisabledKind);
    procedure SetShowButton(const Value: boolean);
  protected
    FOnButtonClick: TNotifyEvent;
    procedure SetEditRect; override;
    function IsActive : boolean; override;
    procedure PaintBorder(DC : hdc); override;
    procedure PaintText; override;
    procedure OurPaintHandler(DC : hdc); override;

    function GetReadOnly: Boolean; virtual;
    procedure KeyPress(var Key: Char); override;

    procedure PopupWindowShow; virtual;
    procedure PopupWindowClose; virtual;
    procedure CreateParams(var Params: TCreateParams); override;

    procedure Change; override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure ButtonClick; dynamic;
    property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
    property PopupAlign: TPopupWindowAlign read FPopupWindowAlign write FPopupWindowAlign default pwaRight;
  public
    FDefBmpName : string;
    FPopupWindow: TWinControl;
    constructor Create(AOwner: TComponent); override;
    procedure CreateWnd; override;
    destructor Destroy; override;
    procedure Invalidate; override;
    procedure AfterConstruction; override;
    procedure Loaded; override;

    procedure WndProc (var Message: TMessage); override;
    procedure DoClick;
    procedure SelectAll; virtual;
    property Button: TsEditButton read FButton;
    property DroppedDown: Boolean read GetDroppedDown;
    property PopupWidth : integer read FPopupWidth write SetPopupWidth default 197;
{$ENDIF} // NOTFORHELP
  published
{$IFNDEF NOTFORHELP}
    property Align;             // KJS
    property Anchors;           // KJS
    property AutoSelect;
    property DragCursor;
    property DragMode;
    property EditMask;
    property Enabled;
    property Font;
    property HideSelection;
    property ImeMode;
    property ImeName;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Text;
    property Visible;
    property OnChange;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDrag;
    property OnContextPopup;
{$ENDIF} // NOTFORHELP
    {:@event}
    property OnButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
    property ShowButton : boolean read FShowButton write SetShowButton default True;
    property ClickKey: TShortCut read FClickKey write FClickKey default scAlt + vk_Down;
    property DisabledKind : TsDisabledKind read FDisabledKind write SetDisabledKind default DefDisabledKind;
    property GlyphMode : TsGlyphMode read FGlyphMode write FGlyphMode;
    property DirectInput: Boolean read FDirectInput write SetDirectInput default True;
    property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
  end;

implementation

uses sStyleSimply, sCurrencyEdit{$IFDEF CHECKXP}, UxTheme, Themes{$ENDIF}, sMaskData,
  sVCLUtils, sMessages, sAlphaGraph, sSkinManager
  {$IFDEF LOGGED}, sDebugMsgs{$ENDIF};

constructor TsEditButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FOwner := TsCustomComboEdit(AOwner);
  SkinData.SkinSection := s_SPEEDBUTTON;
{$IFDEF CHECKXP}
  Flat := True;
{$ENDIF}
  Cursor := crArrow;
  Align := alRight;
  Width := 22; 
  ShowCaption := False;
end;

{ TsCustomComboEdit }

constructor TsCustomComboEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  SkinData.COC := COC_TsComboEdit;
  FDisabledKind := DefDisabledKind;

  FDefBmpName := '';
  FGlyphMode := TsGlyphMode.Create(Self);

  AutoSize := False;
  FDirectInput := True;
  FClickKey := scAlt + vk_Down;
  FPopupWindowAlign := pwaRight;
  FShowButton := True;

  FButton := TsEditButton.Create(Self);
  FButton.Parent := Self;
  FButton.Visible := True;
  FButton.OnClick := EditButtonClick;
  FButton.OnMouseDown := EditButtonMouseDown;
  FButton.OnMouseUp := EditButtonMouseUp;

  Height := 21;
  FPopupWidth := 197;
end;

destructor TsCustomComboEdit.Destroy;
begin
  OnKeyDown := nil;
  if Assigned(FGlyphMode) then FreeAndNil(FGlyphMode);
  if Assigned(FButton) then FButton.OnClick := nil;
  inherited Destroy;
end;

procedure TsCustomComboEdit.PopupWindowShow;
var
  P: TPoint;
  Y: Integer;
begin
  if (FPopupWindow <> nil) and not (ReadOnly or DroppedDown) then begin
    FPopupWindow.Visible := False;
    FPopupWindow.Width := FPopupWidth;
    P := Parent.ClientToScreen(Point(Left, Top));
    Y := P.Y + Height;

    if Y + FPopupWindow.Height > Screen.DesktopHeight then Y := P.Y - FPopupWindow.Height;
    case FPopupWindowAlign of
      pwaRight: begin
        Dec(P.X, FPopupWindow.Width - Width);
        if P.X < Screen.DesktopLeft then Inc(P.X, FPopupWindow.Width - Width);
      end;
      pwaLeft: begin
        if P.X + FPopupWindow.Width > Screen.DesktopWidth then Dec(P.X, FPopupWindow.Width - Width);
      end;
    end;
    if P.X < Screen.DesktopLeft
      then P.X := Screen.Desktopleft
      else if P.X + FPopupWindow.Width > Screen.DesktopWidth then P.X := Screen.DesktopWidth - FPopupWindow.Width;

    SetWindowPos(FPopupWindow.Handle, HWND_TOPMOST, P.X, Y, FPopupWindow.Width, FPopupWindow.Height, {SWP_NOACTIVATE or }SWP_SHOWWINDOW);
    FPopupWindow.Visible := True;
  end;
end;

procedure TsCustomComboEdit.Change;
begin
  if not DroppedDown then inherited Change;
end;

procedure TsCustomComboEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
  if (FClickKey = ShortCut(Key, Shift)) and (GlyphMode.Width > 0) then begin
    EditButtonClick(Self);
    Key := 0;
  end;
  SetEditRect
end;

procedure TsCustomComboEdit.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if not RestrictDrawing then SkinData.BGChanged := True;
  inherited MouseDown(Button, Shift, X, Y);
  if DroppedDown then PopupWindowClose;
  SetEditRect
end;

procedure TsCustomComboEdit.SetEditRect;
var
  Loc: TRect;
begin
  if Parent = nil then Exit;
  SendMessage(Handle, EM_GETRECT, 0, LongInt(@Loc));
  Loc.Bottom := ClientHeight;
  Loc.Right := ClientWidth - FButton.Width;// - 2;
  Loc.Top := 0;
  Loc.Left := 0;
  SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@Loc));
  SendMessage(Handle, EM_GETRECT, 0, LongInt(@Loc));  {debug}
end;

function TsCustomComboEdit.GetDroppedDown : Boolean;
begin
  Result := (FPopupWindow <> nil) and FPopupWindow.Visible;
end;

procedure TsCustomComboEdit.CMCancelMode(var Message: TCMCancelMode);
begin
  if (Message.Sender <> Self) and
       (Message.Sender <> FPopupWindow) and
         (Message.Sender <> FButton) and
           ((FPopupWindow <> nil) and
             not FPopupWindow.ContainsControl(Message.Sender)) then PopupWindowClose;
end;

procedure TsCustomComboEdit.EditButtonClick(Sender: TObject);
begin
  if not FReadOnly then ButtonClick;
end;

procedure TsCustomComboEdit.DoClick;
begin
  EditButtonClick(Self);
end;

procedure TsCustomComboEdit.ButtonClick;
begin
  if Assigned(FOnButtonClick) then FOnButtonClick(Self);
  if DroppedDown then PopupWindowClose else begin
    if CanFocus then SetFocus;
    PopupWindowShow;
  end;
end;

procedure TsCustomComboEdit.SelectAll;
begin
  if {DirectInput and} (Text <> '') then //inherited SelectAll;
    SendMessage(Handle, EM_SETSEL, 0, -1);//Length(Text)); // v4.44
end;

procedure TsCustomComboEdit.SetDirectInput(Value: Boolean);
begin
  inherited ReadOnly := not Value or FReadOnly;
  FDirectInput := Value;
end;

procedure TsCustomComboEdit.WMPaste(var Message: TWMPaste);
begin
  if not FDirectInput or ReadOnly then Exit;
  inherited;
end;

procedure TsCustomComboEdit.WMCut(var Message: TWMCut);
begin
  if not FDirectInput or ReadOnly then Exit;
  inherited;
end;

procedure TsCustomComboEdit.SetReadOnly(Value: Boolean);
begin
  if Value <> FReadOnly then begin
    FReadOnly := Value;
    inherited ReadOnly := Value or not FDirectInput;
//     if Assigned(Button) then Button.Enabled := not FReadOnly; for future???
  end;
end;

procedure TsCustomComboEdit.SetAlignment(Value: TAlignment);
begin
  if FAlignment <> Value then begin
    FAlignment := Value;
    SkinData.Invalidate;
  end;
end;

procedure TsCustomComboEdit.WndProc(var Message: TMessage);
begin
{$IFDEF LOGGED}
  AddToLog(Message);
{$ENDIF}
  case Message.Msg of

⌨️ 快捷键说明

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