• TEdit扩展:做成多按钮的Edit,可用作浏览器地址栏


    TEdit是经常使用的组件,但其功能不能满足开发要求,虽然高版本的Delphi已经提供一个TButtonEdit组件,但这个组件提供的按钮数量较少,于是本人模仿这个组件,做了一个支持4个按钮的TEdit扩展组件,在Delphi XE下测试通过。

    主要代码如下:

    unit UWSIEAddress;

    interface

    uses
      SysUtils, Classes, Controls, StdCtrls,ImgList,Messages,Menus,themes,Forms,
      Windows,Dialogs,RegularExpressions,Registry,ShellAPI;

    const
      AltID=111;
      ShiftID=1001;
      CtrlID=11117;
      ASID=1112;
      ACID=11228;
      SCID=12118;
      ASCID=12229;

    //这些值是随机定义的,用于判断那些辅助键按下

    type
      TOnUrlSelectedEvent = procedure(Sender: TObject; Url: WideString; var Cancel: boolean) of object;

      TCustomUWSIEAddress = class;

      TEditButton = class(TPersistent)
      strict private
        type
          TButtonState = (bsNormal, bsHot, bsPushed);
          TGlyph = class(TCustomControl)
          private
            FButton: TEditButton;
            FState: TButtonState;
          protected
            procedure Click; override;
            procedure CreateWnd; override;
            procedure Paint; override;
            procedure WndProc(var Message: TMessage); override;
            procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW;
          public
            constructor Create(AButton: TEditButton); reintroduce; virtual;
          end;
      protected
        type
          TButtonPosition = (bpLeft, bpRightRight,bpRightMiddle,bpRightLeft);
      strict private
        FDisabledImageIndex: TImageIndex;
        FDropDownMenu: TPopupMenu;
        FEditControl: TCustomUWSIEAddress;
        FGlyph: TGlyph;
        FHotImageIndex: TImageIndex;
        FImageIndex: TImageIndex;
        FPosition: TButtonPosition;
        FPressedImageIndex: TImageIndex;
        function GetEnabled: Boolean;
        function GetCustomHint: TCustomHint;
        function GetHint: string;
        function GetImages: TCustomImageList;
        function GetVisible: Boolean;
        procedure SetDisabledImageIndex(const Value: TImageIndex);
        procedure SetEnabled(const Value: Boolean);
        procedure SetCustomHint(const Value: TCustomHint);
        procedure SetHint(const Value: string);
        procedure SetHotImageIndex(const Value: TImageIndex);
        procedure SetImageIndex(const Value: TImageIndex);
        procedure SetPressedImageIndex(const Value: TImageIndex);
        procedure SetVisible(const Value: Boolean);
      protected
        function GetOwner: TPersistent; override;
        procedure UpdateBounds; dynamic;
        property EditControl: TCustomUWSIEAddress read FEditControl;
        property Glyph: TGlyph read FGlyph;
        property Images: TCustomImageList read GetImages;
        property Position: TButtonPosition read FPosition;
      public
        constructor Create(EditControl: TCustomUWSIEAddress; APosition: TButtonPosition); reintroduce; virtual;
        destructor Destroy; override;
        property Visible: Boolean read GetVisible ;
      published
        property CustomHint: TCustomHint read GetCustomHint write SetCustomHint;
        property DisabledImageIndex: TImageIndex read FDisabledImageIndex write SetDisabledImageIndex default -1;
        property DropDownMenu: TPopupMenu read FDropDownMenu write FDropDownMenu;
        property Enabled: Boolean read GetEnabled write SetEnabled default True;
        property Hint: string read GetHint write SetHint;
        property HotImageIndex: TImageIndex read FHotImageIndex write SetHotImageIndex default -1;
        property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1;
        property PressedImageIndex: TImageIndex read FPressedImageIndex write SetPressedImageIndex default -1;
      end;


      TEditButtonClass = class of TEditButton;

      TCustomUWSIEAddress = class(TCustomEdit)
      private
        { Private declarations }
        FShiftKeyID:Integer;
        FCanvas: TControlCanvas;
        FImages: TCustomImageList;
        FImageChangeLink: TChangeLink;
        FLeftButton: TEditButton;
        FRightButtonRight: TEditButton;
        FRightButtonMiddle: TEditButton;
        FRightButtonLeft: TEditButton;
        FFavIconsSavePath:String;
        FOneKeyAddressFile:String;
        FAddressAutoFixFile:String;
        FOneKeyAddress:TStrings;
        FAddressAutoFix:TStrings;
        FTypedUrls:TStringList;
        FOnUrlSelected: TOnUrlSelectedEvent;
        function GetOneKeyAddress: TStrings;
        function GetAddressAutoFix: TStrings;
        function AdjustTextHint(Margin: Integer; const Value: string): string;
        procedure SetOneKeyAddress(Value: TStrings);
        procedure SetAddressAutoFix(Value: TStrings);
        procedure ImageListChange(Sender: TObject);
        procedure SetImages(const Value: TCustomImageList);
        function GetOnLeftButtonClick: TNotifyEvent;
        function GetOnRightButtonRightClick: TNotifyEvent;
        function GetOnRightButtonMiddleClick: TNotifyEvent;
        function GetOnRightButtonLeftClick: TNotifyEvent;
        procedure SetLeftButton(const Value: TEditButton);
        procedure SetOnLeftButtonClick(const Value: TNotifyEvent);
        procedure SetRightButtonRight(const Value: TEditButton);
        procedure SetOnRightButtonRightClick(const Value: TNotifyEvent);
        procedure SetRightButtonMiddle(const Value: TEditButton);
        procedure SetOnRightButtonMiddleClick(const Value: TNotifyEvent);
        procedure SetRightButtonLeft(const Value: TEditButton);
        procedure SetOnRightButtonLeftClick(const Value: TNotifyEvent);
        function GetOneKeyAddressUrl(Key:String):string;
        function GetFixUrl(SrcKey,Key:String):string;
        procedure GetTypedUrls;
      protected
        { Protected declarations }
        procedure DoSetTextHint(const Value: string); override;
        function GetEditButtonClass: TEditButtonClass; dynamic;
        procedure Notification(AComponent: TComponent; Operation: TOperation); override;
        procedure UpdateEditMargins; dynamic;
        procedure WndProc(var Message: TMessage); override;
        procedure KeyDown(var Key: Word; Shift: TShiftState); override;
        procedure KeyUp(var Key: Word; Shift: TShiftState); override;
      public
        { Public declarations }
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
        procedure LoadOneKeyAddressList;
        procedure LoadAddressAutoFixList;
        procedure SaveOneKeyAddressList;
        procedure SaveAddressAutoFixList;
        procedure DefaultHandler(var Message); override;
        procedure UpdateTypedUrls;
        function GetShellIcons:Cardinal;
        property Images: TCustomImageList read FImages write SetImages;
        property LeftButton: TEditButton read FLeftButton write SetLeftButton;
        property RightButtonRight: TEditButton read FRightButtonRight write SetRightButtonRight;
        property RightButtonMiddle: TEditButton read FRightButtonMiddle write SetRightButtonMiddle;
        property RightButtonLeft: TEditButton read FRightButtonLeft write SetRightButtonLeft;
        property OnLeftButtonClick: TNotifyEvent read GetOnLeftButtonClick write SetOnLeftButtonClick;
        property OnRightButtonRightClick: TNotifyEvent read GetOnRightButtonRightClick write SetOnRightButtonRightClick;
        property OnRightButtonMiddleClick: TNotifyEvent read GetOnRightButtonMiddleClick write SetOnRightButtonMiddleClick;
        property OnRightButtonLeftClick: TNotifyEvent read GetOnRightButtonLeftClick write SetOnRightButtonLeftClick;
        property FavIconsSavePath:String read FFavIconsSavePath write FFavIconsSavePath;
        property OneKeyAddressFile:String read FOneKeyAddressFile write FOneKeyAddressFile;
        property AddressAutoFixFile:String read FAddressAutoFixFile write FAddressAutoFixFile;
        Property OneKeyAddress:TStrings read GetOneKeyAddress  write SetOneKeyAddress;
        Property AddressAutoFix:TStrings read GetAddressAutoFix  write SetAddressAutoFix;
        property OnUrlSelected: TOnUrlSelectedEvent read FOnUrlSelected write FOnUrlSelected;
        property  TypedUrls:TStringList read FTypedUrls;
      published
        { Published declarations }
      end;

     TUWSIEAddress=class(TCustomUWSIEAddress )
     private

     protected

     public


     published
        property Align;
        property Alignment;
        property Anchors;
        property AutoSelect;
        property AutoSize;
        property BevelEdges;
        property BevelInner;
        property BevelKind default bkNone;
        property BevelOuter;
        property BevelWidth;
        property BiDiMode;
        property BorderStyle;
        property CharCase;
        property Color;
        property Constraints;
        property Ctl3D;
        property DoubleBuffered;
        property DragCursor;
        property DragKind;
        property DragMode;
        property Enabled;
        property Font;
        property HideSelection;
        property Images;
        property ImeMode;
        property ImeName;
        property LeftButton;
        property MaxLength;
        property OEMConvert;
        property NumbersOnly;
        property ParentBiDiMode;
        property ParentColor;
        property ParentCtl3D;
        property ParentDoubleBuffered;
        property ParentFont;
        property ParentShowHint;
        property PasswordChar;
        property PopupMenu;
        property ReadOnly;
        property RightButtonRight;
        property RightButtonMiddle;
        property RightButtonLeft;
        property ShowHint;
        property TabOrder;
        property TabStop;
        property Text;
        property TextHint;
        property Touch;
        property Visible;
        property OnChange;
        property OnClick;
        property OnContextPopup;
        property OnDblClick;
        property OnDragDrop;
        property OnDragOver;
        property OnEndDock;
        property OnEndDrag;
        property OnEnter;
        property OnExit;
        property OnKeyDown;
        property OnKeyPress;
        property OnKeyUp;
        property OnGesture;
        property OnLeftButtonClick;
        property OnMouseActivate;
        property OnMouseDown;
        property OnMouseEnter;
        property OnMouseLeave;
        property OnMouseMove;
        property OnMouseUp;
        property OnRightButtonRightClick;
        property OnRightButtonMiddleClick;
        property OnRightButtonLeftClick;
        property OnStartDock;
        property OnStartDrag;

        property FavIconsSavePath;
        property OneKeyAddressFile;
        property AddressAutoFixFile;
        Property OneKeyAddress;
        Property AddressAutoFix;
        property OnUrlSelected;
     end;


    procedure Register;

    implementation

    procedure Register;
    begin
      RegisterComponents('Unruly Wolf Soft', [TUWSIEAddress]);
    end;

    function CtrlDown : Boolean;
    var
      State : TKeyboardState;
    begin
      GetKeyboardState(State) ;
      Result := ((State[vk_Control] And 128) <> 0) ;
    end;

    function ShiftDown : Boolean;
    var
      State : TKeyboardState;
    begin
      GetKeyboardState(State) ;
      Result := ((State[vk_Shift] and 128) <> 0) ;
    end;

    function AltDown : Boolean;
    var
      State : TKeyboardState;
    begin
      GetKeyboardState(State) ;
      Result := ((State[vk_Menu] and 128) <> 0) ;
    end;

    { TEditButton.TGlyph }

    constructor TEditButton.TGlyph.Create(AButton: TEditButton);
    begin
      inherited Create(AButton.FEditControl);
      FButton := AButton;
      FState := bsNormal;
      Parent := FButton.FEditControl;
      Visible := True;
      ShowHint:=True;
    end;

    procedure TEditButton.TGlyph.Click;
    begin
      // Replicate from TControl to set Sender to owning TButtonedEdit control
      if Assigned(OnClick) and (Action <> nil) and not DelegatesEqual(@OnClick, @Action.OnExecute) then
        OnClick(FButton.EditControl)
      else if not (csDesigning in ComponentState) and (ActionLink <> nil) then
        ActionLink.Execute(FButton.EditControl)
      else if Assigned(OnClick) then
        OnClick(FButton.EditControl);
      FState := bsNormal;
    end;

    procedure TEditButton.TGlyph.CreateWnd;
    begin
      inherited;
      if Visible then
        FButton.FEditControl.UpdateEditMargins;
    end;

    procedure TEditButton.TGlyph.Paint;
    var
      LIndex: Integer;
    begin
      inherited;
      if (FButton.Images <> nil) and Visible then
      begin
        LIndex := FButton.ImageIndex;
        if Enabled then
        begin
          case FState of
            bsHot:
              if FButton.HotImageIndex <> -1 then
                LIndex := FButton.HotImageIndex;
            bsPushed:
              if FButton.PressedImageIndex <> -1 then
                LIndex := FButton.PressedImageIndex;
          end;
        end
        else
          if FButton.DisabledImageIndex <> -1 then
            LIndex := FButton.DisabledImageIndex;
        if LIndex <> -1 then
          FButton.Images.Draw(Canvas, 0, 0, LIndex);
      end;
    end;

    procedure TEditButton.TGlyph.WndProc(var Message: TMessage);
    var
      LPoint: TPoint;
    begin
      if (Message.Msg = WM_CONTEXTMENU) and (FButton.EditControl.PopupMenu = nil) then
      begin
          FState := bsNormal;
          Exit;
      end;

      inherited;
      case Message.Msg of
        CM_MOUSEENTER: FState := bsHot;
        CM_MOUSELEAVE: FState := bsNormal;
        WM_LBUTTONDOWN:
        begin
            if FButton.FDropDownMenu <> nil then
            begin
              if not (csDesigning in Parent.ComponentState) then
              begin
                LPoint := ClientToScreen(Point(0, FButton.EditControl.Height));
                FButton.FDropDownMenu.Popup(LPoint.X, LPoint.Y);
                if Assigned(OnClick) and (Action <> nil) and not DelegatesEqual(@OnClick, @Action.OnExecute) then
                OnClick(FButton.EditControl)
                else if not (csDesigning in ComponentState) and (ActionLink <> nil) then
                ActionLink.Execute(FButton.EditControl)
                else if Assigned(OnClick) then
                OnClick(FButton.EditControl);
              end;
            end
            else
            FState := bsPushed;
        end;
        WM_LBUTTONUP: FState := bsNormal;
        WM_RBUTTONUP:
        begin
          if FButton.FDropDownMenu <> nil then
            begin
              if not (csDesigning in Parent.ComponentState) then
              begin
                LPoint := ClientToScreen(Point(0, FButton.EditControl.Height));
                FButton.FDropDownMenu.Popup(LPoint.X, LPoint.Y);
                FState := bsNormal;
              end;
            end;
        end;
        CM_VISIBLECHANGED: FButton.UpdateBounds;
      else
        Exit;
      end;
      Invalidate;
    end;

    procedure TEditButton.TGlyph.CMHintShow(var Message: TCMHintShow);
    begin
      if Hint<>''  then
      Message.HintInfo^.HintStr := Hint
    end;

    { TEditButton }

    constructor TEditButton.Create(EditControl: TCustomUWSIEAddress; APosition: TButtonPosition);
    begin
      inherited Create;
      FEditControl := EditControl;
      FGlyph := TGlyph.Create(Self);
      FHotImageIndex := -1;
      FImageIndex := -1;
      FPosition := APosition;
      FPressedImageIndex := -1;
      FDisabledImageIndex := -1;
    end;

    destructor TEditButton.Destroy;
    begin
      FGlyph.Parent.RemoveControl(FGlyph);
      FGlyph.Free;
      inherited;
    end;

    function TEditButton.GetEnabled: Boolean;
    begin
      Result := FGlyph.Enabled;
    end;

    function TEditButton.GetCustomHint: TCustomHint;
    begin
      Result := FGlyph.CustomHint;
    end;

    function TEditButton.GetHint: string;
    begin
      Result := FGlyph.Hint;
    end;

    function TEditButton.GetImages: TCustomImageList;
    begin
      Result := FEditControl.Images;
    end;

    function TEditButton.GetOwner: TPersistent;
    begin
      Result := FEditControl;
    end;

    function TEditButton.GetVisible: Boolean;
    begin
      Result := FGlyph.Visible;
    end;

    procedure TEditButton.SetDisabledImageIndex(const Value: TImageIndex);
    begin
      if Value <> FDisabledImageIndex then
      begin
        FDisabledImageIndex := Value;
        if not Enabled then
          FGlyph.Invalidate;
      end;
    end;

    procedure TEditButton.SetEnabled(const Value: Boolean);
    begin
      if Value <> FGlyph.Enabled then
      begin
        FGlyph.Enabled := Value;
        FGlyph.Invalidate;
      end;
    end;

    procedure TEditButton.SetCustomHint(const Value: TCustomHint);
    begin
      if Value <> FGlyph.CustomHint then
        FGlyph.CustomHint := Value;
    end;

    procedure TEditButton.SetHint(const Value: string);
    begin
      if Value <> FGlyph.Hint then
        FGlyph.Hint := Value;
    end;

    procedure TEditButton.SetHotImageIndex(const Value: TImageIndex);
    begin
      if Value <> FHotImageIndex then
      begin
        FHotImageIndex := Value;
        if FGlyph.FState = bsHot then
          FGlyph.Invalidate;
      end;
    end;

    procedure TEditButton.SetImageIndex(const Value: TImageIndex);
    begin
      if Value <> FImageIndex then
      begin
        FImageIndex := Value;
        if FGlyph.FState = bsNormal then
          FGlyph.Invalidate;
      end;
    end;

    procedure TEditButton.SetPressedImageIndex(const Value: TImageIndex);
    begin
      if Value <> FPressedImageIndex then
      begin
        FPressedImageIndex := Value;
        if FGlyph.FState = bsPushed then
          FGlyph.Invalidate;
      end;
    end;

    procedure TEditButton.SetVisible(const Value: Boolean);
    begin
      if Value <> FGlyph.Visible then
      begin
        FGlyph.Visible := Value;
        FEditControl.UpdateEditMargins;
      end;
    end;

    procedure TEditButton.UpdateBounds;
    var
      EdgeSize, NewLeft: Integer;
    begin
      if FGlyph <> nil then
      begin
        if Images <> nil then
        begin
          FGlyph.Width := Images.Width;
          FGlyph.Height := Images.Height;
        end
        else
        begin
          FGlyph.Width := 0;
          FGlyph.Height := 0;
        end;
        FGlyph.Top := (FEditControl.Height-FGlyph.Height) div 2-1;
        NewLeft := FGlyph.Left;

        if not ThemeServices.ThemesEnabled then
          FGlyph.Top :=(FEditControl.Height-FGlyph.Height) div 2;

        case FPosition of
          bpLeft:
            begin
              if ThemeServices.ThemesEnabled then
                NewLeft := 0
              else
                NewLeft := 1;
            end;
          bpRightRight:
            begin
              NewLeft := FEditControl.Width - FGlyph.Width-2;
              if FEditControl.BorderStyle <> bsNone then
                Dec(NewLeft, 4);
              if FEditControl.BevelKind <> bkNone then
              begin
                EdgeSize := 0;
                if FEditControl.BevelInner <> bvNone then
                  Inc(EdgeSize, FEditControl.BevelWidth);
                if FEditControl.BevelOuter <> bvNone then
                  Inc(EdgeSize, FEditControl.BevelWidth);
                if beRight in FEditControl.BevelEdges then
                  Dec(NewLeft, EdgeSize);
                if beLeft in FEditControl.BevelEdges then
                  Dec(NewLeft, EdgeSize);
              end;
              if not ThemeServices.ThemesEnabled then
                Dec(NewLeft);
            end;
          bpRightMiddle:
            begin
              NewLeft := FEditControl.Width - FGlyph.Width*2-4;
              if FEditControl.BorderStyle <> bsNone then
                Dec(NewLeft, 4);
              if FEditControl.BevelKind <> bkNone then
              begin
                EdgeSize := 0;
                if FEditControl.BevelInner <> bvNone then
                  Inc(EdgeSize, FEditControl.BevelWidth);
                if FEditControl.BevelOuter <> bvNone then
                  Inc(EdgeSize, FEditControl.BevelWidth);
                if beRight in FEditControl.BevelEdges then
                  Dec(NewLeft, EdgeSize);
                if beLeft in FEditControl.BevelEdges then
                  Dec(NewLeft, EdgeSize);
              end;
              if not ThemeServices.ThemesEnabled then
                Dec(NewLeft);
            end;

            bpRightLeft:
              begin
                NewLeft := FEditControl.Width - FGlyph.Width*3-8;
                if FEditControl.BorderStyle <> bsNone then
                Dec(NewLeft, 4);
                if FEditControl.BevelKind <> bkNone then
                begin
                  EdgeSize := 0;
                  if FEditControl.BevelInner <> bvNone then
                  Inc(EdgeSize, FEditControl.BevelWidth);
                  if FEditControl.BevelOuter <> bvNone then
                  Inc(EdgeSize, FEditControl.BevelWidth);
                  if beRight in FEditControl.BevelEdges then
                  Dec(NewLeft, EdgeSize);
                  if beLeft in FEditControl.BevelEdges then
                  Dec(NewLeft, EdgeSize);
                end;
                if not ThemeServices.ThemesEnabled then
                Dec(NewLeft);
            end;
        end;

        if (not FEditControl.Ctl3D) and (FEditControl.BorderStyle <> bsNone) then
        begin
          FGlyph.Top := (FEditControl.Height-FGlyph.Height) div 2;
          Inc(NewLeft, 2);
        end;

        FGlyph.Left := NewLeft;

        if (csDesigning in FEditControl.ComponentState) and not Visible then
          FGlyph.Width := 0;
      end;
    end;


    constructor TCustomUWSIEAddress.Create(AOwner: TComponent);
    begin
      inherited;
      FCanvas := TControlCanvas.Create;
      FCanvas.Control := Self;
      FImageChangeLink := TChangeLink.Create;
      FImageChangeLink.OnChange := ImageListChange;
      FLeftButton := GetEditButtonClass.Create(Self, bpLeft);
      FRightButtonRight := GetEditButtonClass.Create(Self, bpRightRight);
      FRightButtonMiddle := GetEditButtonClass.Create(Self, bpRightMiddle);
      FRightButtonLeft := GetEditButtonClass.Create(Self, bpRightLeft);
      font.Size:=12;
      FShiftKeyID:=0;
      FFavIconsSavePath:='';
      FOneKeyAddressFile:='';
      FAddressAutoFixFile:='';

      FOneKeyAddress:=TStringlist.Create ;
      FAddressAutoFix:=TStringlist.Create ;
      FTypedUrls:=TStringlist.Create ;

      LoadOneKeyAddressList;
      LoadAddressAutoFixList;
      GetTypedUrls;
    end;

    destructor TCustomUWSIEAddress.Destroy;
    begin
      FreeAndNil(FCanvas);
      FreeAndNil(FImageChangeLink);
      FreeAndNil(FLeftButton);
      FreeAndNil(FRightButtonRight);
      FreeAndNil(FRightButtonMiddle);
      FreeAndNil(FRightButtonLeft);

      SaveOneKeyAddressList;
      SaveAddressAutoFixList;
      FOneKeyAddress.Free ;
      FAddressAutoFix.Free;
      FTypedUrls.Free ;
      inherited;
    end;

    function TCustomUWSIEAddress.AdjustTextHint(Margin: Integer; const Value: string): string;
    var
      LWidth, Count: Integer;
    begin
      if (Margin = 0) or (Win32MajorVersion >= 6) then
        inherited DoSetTextHint(Value)
      else
      begin
        // This is a hack!! Due to a presumed bug in Windows XP any text hint
        // set with EM_SETCUEBANNER does not respect left margins set with
        // EM_SETMARGINS. The following works around the issue.
        FCanvas.Font := Font;
        LWidth := FCanvas.TextWidth(' '); // do not localize
        Count := Margin div LWidth;
        if (Margin mod LWidth) > 0 then
          Inc(Count);
        inherited DoSetTextHint(StringOfChar(' ', Count) + Value);
      end;
    end;

    procedure TCustomUWSIEAddress.DoSetTextHint(const Value: string);
    begin
      AdjustTextHint(0, Value);
    end;

    function TCustomUWSIEAddress.GetEditButtonClass: TEditButtonClass;
    begin
      Result := TEditButton;
    end;

    function TCustomUWSIEAddress.GetOnLeftButtonClick: TNotifyEvent;
    begin
      Result := LeftButton.Glyph.OnClick;
    end;

    function TCustomUWSIEAddress.GetOnRightButtonRightClick: TNotifyEvent;
    begin
      Result := RightButtonRight.Glyph.OnClick;
    end;

    function TCustomUWSIEAddress.GetOnRightButtonMiddleClick: TNotifyEvent;
    begin
      Result := RightButtonMiddle.Glyph.OnClick;
    end;

    function TCustomUWSIEAddress.GetOnRightButtonLeftClick: TNotifyEvent;
    begin
      Result := RightButtonLeft.Glyph.OnClick;
    end;

    procedure TCustomUWSIEAddress.ImageListChange(Sender: TObject);
    begin
      if HandleAllocated then
      begin
        FLeftButton.UpdateBounds;
        FRightButtonRight.UpdateBounds;
        FRightButtonMiddle.UpdateBounds;
        FRightButtonLeft.UpdateBounds;
        UpdateEditMargins;
      end;
    end;

    procedure TCustomUWSIEAddress.DefaultHandler(var Message);
    {$IF DEFINED(CLR)}
    var
      LMessage: TMessage;
    {$IFEND}
    begin
      inherited;
    {$IF DEFINED(CLR)}
      LMessage := UnwrapMessage(TObject(Message));
      case LMessage.Msg of
    {$ELSE}
      case TMessage(Message).Msg of
    {$IFEND}
        CN_CTLCOLOREDIT:
          begin
            FLeftButton.Glyph.Invalidate;
            FRightButtonRight.Glyph.Invalidate;
            FRightButtonMiddle.Glyph.Invalidate;
            FRightButtonLeft.Glyph.Invalidate;
          end;
        WM_SIZE:
          begin
            FRightButtonRight.UpdateBounds;
            FRightButtonMiddle.UpdateBounds;
            FRightButtonLeft.UpdateBounds;
          end;
      end;
    end;

    procedure TCustomUWSIEAddress.Notification(AComponent: TComponent; Operation: TOperation);
    begin
      inherited Notification(AComponent, Operation);
      if Operation = opRemove then
      begin
        if AComponent = FImages then
        begin
          FImages := nil;
          FLeftButton.UpdateBounds;
          FRightButtonRight.UpdateBounds;
          FRightButtonMiddle.UpdateBounds;
          FRightButtonLeft.UpdateBounds;
          UpdateEditMargins;
        end
        else if (LeftButton <> nil) and (AComponent = LeftButton.DropDownMenu) then
          LeftButton.DropDownMenu := nil
        else if (RightButtonRight <> nil) and (AComponent = RightButtonRight.DropDownMenu) then
          RightButtonRight.DropDownMenu := nil
        else if (RightButtonMiddle <> nil) and (AComponent = RightButtonMiddle.DropDownMenu) then
          RightButtonMiddle.DropDownMenu := nil
        else if (RightButtonLeft <> nil) and (AComponent = RightButtonLeft.DropDownMenu) then
          RightButtonLeft.DropDownMenu := nil;
      end;
    end;

    procedure TCustomUWSIEAddress.SetImages(const Value: TCustomImageList);
    begin
      if Value <> FImages then
      begin
        if FImages <> nil then
          FImages.UnRegisterChanges(FImageChangeLink);
        FImages := Value;
        if FImages <> nil then
        begin
          FImages.RegisterChanges(FImageChangeLink);
          FImages.FreeNotification(Self);
        end;
        FLeftButton.UpdateBounds;
        FRightButtonRight.UpdateBounds;
        FRightButtonMiddle.UpdateBounds;
        FRightButtonLeft.UpdateBounds;
        UpdateEditMargins;
      end;
    end;

    procedure TCustomUWSIEAddress.SetLeftButton(const Value: TEditButton);
    begin
      FLeftButton.Assign(Value);
    end;

    procedure TCustomUWSIEAddress.SetOnLeftButtonClick(const Value: TNotifyEvent);
    begin
      LeftButton.Glyph.OnClick := Value;
    end;

    procedure TCustomUWSIEAddress.SetOnRightButtonRightClick(const Value: TNotifyEvent);
    begin
      RightButtonRight.Glyph.OnClick := Value;
    end;

    procedure TCustomUWSIEAddress.SetOnRightButtonMiddleClick(const Value: TNotifyEvent);
    begin
      RightButtonMiddle.Glyph.OnClick := Value;
    end;

    procedure TCustomUWSIEAddress.SetOnRightButtonLeftClick(const Value: TNotifyEvent);
    begin
      RightButtonLeft.Glyph.OnClick := Value;
    end;

    procedure TCustomUWSIEAddress.SetRightButtonRight(const Value: TEditButton);
    begin
      FRightButtonRight.Assign(Value);
    end;

    procedure TCustomUWSIEAddress.SetRightButtonMiddle(const Value: TEditButton);
    begin
      FRightButtonMiddle.Assign(Value);
    end;

    procedure TCustomUWSIEAddress.SetRightButtonLeft(const Value: TEditButton);
    begin
      FRightButtonLeft.Assign(Value);
    end;

    procedure TCustomUWSIEAddress.UpdateEditMargins;
    var
      LMargin, RMargin: Integer;
    begin
      if HandleAllocated then
      begin
        LMargin := 0;
        RMargin := 0;
        if (Images <> nil) then
        begin
          if LeftButton.Visible then
            LMargin := Images.Width + 2;
          if RightButtonLeft.Visible then
            RMargin := 3*Images.Width+16;
        end;
        SendMessage(Handle, EM_SETMARGINS, EC_LEFTMARGIN or EC_RIGHTMARGIN, MakeLong(LMargin, RMargin));
        AdjustTextHint(LMargin, TextHint);
        Invalidate;
      end;
    end;

    procedure TCustomUWSIEAddress.WndProc(var Message: TMessage);
    var
      LLeft, LTop: Integer;
    begin
      case Message.Msg of
        CN_CTLCOLORSTATIC,
        CN_CTLCOLOREDIT:
          if FImages <> nil then
          begin
            if LeftButton.Visible then
            begin
              LLeft := LeftButton.Glyph.Left;
              LTop := (Height-LeftButton.Glyph.Height) div 2-1;
              if ThemeServices.ThemesEnabled and Ctl3D then
              begin
                Inc(LLeft);
                Inc(LTop);
              end;
              ExcludeClipRect(Message.WParam, LLeft + 1, LTop + 1,
                LeftButton.Glyph.Width + LeftButton.Glyph.Left, LeftButton.Glyph.Height);
            end;

            if RightButtonRight.Visible then
            begin
              LTop := (Height-RightButtonRight.Glyph.Height) div 2-1;
              if ThemeServices.ThemesEnabled and Ctl3D then
                Inc(LTop);
              ExcludeClipRect(Message.WParam, RightButtonRight.Glyph.Left, LTop + 1,
                RightButtonRight.Glyph.Width + RightButtonRight.Glyph.Left, RightButtonRight.Glyph.Height);
            end;

            if RightButtonMiddle.Visible then
            begin
              LTop := (Height-RightButtonMiddle.Glyph.Height) div 2-1;
              if ThemeServices.ThemesEnabled and Ctl3D then
                Inc(LTop);
              ExcludeClipRect(Message.WParam, RightButtonMiddle.Glyph.Left, LTop + 1,
                RightButtonMiddle.Glyph.Width + RightButtonMiddle.Glyph.Left, RightButtonMiddle.Glyph.Height);
            end;

            if RightButtonLeft.Visible then
            begin
              LTop :=(Height-RightButtonLeft.Glyph.Height) div 2-1;
              if ThemeServices.ThemesEnabled and Ctl3D then
                Inc(LTop);
              ExcludeClipRect(Message.WParam, RightButtonLeft.Glyph.Left, LTop + 1,
                RightButtonLeft.Glyph.Width + RightButtonLeft.Glyph.Left, RightButtonLeft.Glyph.Height);
            end;
          end;
      end;

      inherited;

      case Message.Msg of
        CM_BORDERCHANGED,
        CM_CTL3DCHANGED:
          begin
            if not (csLoading in ComponentState) then
            begin
              LeftButton.UpdateBounds;
              RightButtonRight.UpdateBounds;
              RightButtonMiddle.UpdateBounds;
              RightButtonLeft.UpdateBounds;
            end;
          end;
        CM_FONTCHANGED:
          if not (csLoading in ComponentState) then
            UpdateEditMargins;
      end;
    end;

    function TCustomUWSIEAddress.GetOneKeyAddress: TStrings;
    begin
      Result:=FOneKeyAddress;
    end;

    function TCustomUWSIEAddress.GetAddressAutoFix: TStrings;
    begin
        Result:=FAddressAutoFix;
    end;

    procedure TCustomUWSIEAddress.SetOneKeyAddress(Value: TStrings);
    begin
      FOneKeyAddress.Assign(Value);
    end;

    procedure TCustomUWSIEAddress.SetAddressAutoFix(Value: TStrings);
    begin
      FAddressAutoFix.Assign(Value);
    end;

    procedure TCustomUWSIEAddress.LoadOneKeyAddressList;
    begin
        if (csDesigning in ComponentState) then Exit;
        if FOneKeyAddressFile='' then
        FOneKeyAddressFile:=Format('%s\OneKeyAddress.dat',[ExtractFileDir(Application.ExeName)]);
        if fileExists(FOneKeyAddressFile) then
        FOneKeyAddress.LoadFromFile(FOneKeyAddressFile);
        if FOneKeyAddress.Count=0 then
        begin
           FOneKeyAddress.Add('123=www.hao123.com');
           FOneKeyAddress.Add('d123=123.duba.net');
           FOneKeyAddress.Add('baidu=www.baidu.com');
           FOneKeyAddress.Add('b=www.baidu.com');
           FOneKeyAddress.Add('百度=www.baidu.com');
           FOneKeyAddress.Add('g=www.google.com');
           FOneKeyAddress.Add('google=www.google.com');
           FOneKeyAddress.Add('谷歌=www.google.com');
           FOneKeyAddress.Add('k=www.kingsoft.com');
           FOneKeyAddress.Add('kingsoft=www.kingsoft.com');
           FOneKeyAddress.Add('金山=www.kingsoft.com');
           FOneKeyAddress.Add('i=www.ijinshan.com');
           FOneKeyAddress.Add('duba=www.ijinshan.com');
           FOneKeyAddress.Add('毒霸=www.ijinshan.com');
           FOneKeyAddress.Add('金山毒霸=www.ijinshan.com');
           FOneKeyAddress.Add('金山卫士=www.ijinshan.com');
           FOneKeyAddress.Add('卫士=www.ijinshan.com');
           FOneKeyAddress.Add('wps=www.wps.cn');
           FOneKeyAddress.Add('q=www.qq.com');
           FOneKeyAddress.Add('sina=www.sina.com');
           FOneKeyAddress.Add('新浪=www.sina.com');
        end;
    end;

    procedure TCustomUWSIEAddress.LoadAddressAutoFixList;
    begin
        if (csDesigning in ComponentState) then Exit;
        if FAddressAutoFixFile='' then
        FAddressAutoFixFile:=Format('%s\AddressAutoFix.dat',[ExtractFileDir(Application.ExeName)]);
        if FileExists(FAddressAutoFixFile) then
        FAddressAutoFix.LoadFromFile(FAddressAutoFixFile);
        if FAddressAutoFix.Count=0 then
        begin
          FAddressAutoFix.Add('Ctrl+Enter=www. .com');
          FAddressAutoFix.Add('Alt+Enter=www. .cn');
          FAddressAutoFix.Add('Shift+Enter=www. .com.cn');
          FAddressAutoFix.Add('Ctrl+Alt+Enter=www. .net');
          FAddressAutoFix.Add('Ctrl+Shift+Enter=www. .org');
          FAddressAutoFix.Add('Alt+Shift+Enter=www. .cc');
          FAddressAutoFix.Add('Ctrl+Shift+Alt+Enter=http://www.baidu.com/s?wd=');
        end;
    end;

    procedure TCustomUWSIEAddress.SaveOneKeyAddressList;
    begin
        if FOneKeyAddressFile='' then
        FOneKeyAddressFile:=Format('%s\OneKeyAddress.dat',[ExtractFileDir(Application.ExeName)]);
        FOneKeyAddress.SavetoFile(FOneKeyAddressFile);
    end;

    procedure TCustomUWSIEAddress.SaveAddressAutoFixList;
    begin
        if FAddressAutoFixFile='' then
        FAddressAutoFixFile:=Format('%s\AddressAutoFix.dat',[ExtractFileDir(Application.ExeName)]);
        FAddressAutoFix.SavetoFile(FAddressAutoFixFile);
    end;

    function TCustomUWSIEAddress.GetOneKeyAddressUrl(Key:String):string;
    begin
       Result:=Key;
       if (FOneKeyAddress.Count>0) and (Key<>'') then
       begin
          Result:=FOneKeyAddress.Values[Key];
          if Result='' then
          Result:=Key ;
       end;
    end;

    function TCustomUWSIEAddress.GetFixUrl(SrcKey,Key:String):string;
    var
      SubUrlList:TStringList;
      I,K:Integer;
      SubUrls:TArray<string>;
      SubUrl,TempResult:string;
    begin
       Result:=key;
       if (SrcKey<>'') and (Key<>'') then
       begin
         SubUrlList:=TStringList.Create ;
         try
           SubUrls:=TRegEx.Split(SrcKey,'[  ]');
           for SubUrl in SubUrls do
           SubUrlList.Add(SubUrl);
           K:=SubUrlList.Count;
           if k>0 then
           begin
              TempResult:=SubUrlList[0]+Key;
              if K>1 then
              TempResult:=TempResult+SubUrlList[1];
           end
           else
           TempResult:=Key ;
         finally
           SubUrlList.Free ;
         end;
         Result:=TempResult ;
       end;
    end;

    procedure TCustomUWSIEAddress.GetTypedUrls;
    var
      Reg:TRegistry;
      Urls:TStringList;
      I:Integer ;
      TmpUrl:string;
    begin
       Reg:=TRegistry.Create;
       Urls:=TStringList.Create;
       try
         Reg.RootKey:=HKEY_CURRENT_USER;
         if Reg.OpenKey('Software\Microsoft\Internet Explorer\TypedURLs', False) then
         begin
            Reg.GetValueNames(Urls);
            if Urls.Count>0 then
            for I:=0 to Urls.Count-1 do
            begin
              TmpUrl:=Reg.ReadString(Urls[I]);
              TmpUrl:=Trim(TmpUrl);
              if (TmpUrl<>'') and (FTypedUrls.IndexOf(TmpUrl)=-1) then
              FTypedUrls.Add(TmpUrl);
            end;
            Reg.CloseKey ;
         end;
         if Reg.OpenKey('Software\Microsoft\Internet Explorer\TypedAddress', false) then
         begin
            Reg.GetValueNames(Urls);
            if Urls.Count>0 then
            for I:=0 to Urls.Count-1 do
            begin
              TmpUrl:=Reg.ReadString(Urls[I]);
              TmpUrl:=Trim(TmpUrl);
              if (TmpUrl<>'') and (FTypedUrls.IndexOf(TmpUrl)=-1) then
              FTypedUrls.Add(TmpUrl);
            end;
            Reg.CloseKey ;
         end;
       finally
         Reg.Free;
         Urls.Free;
       end;
    end;

    procedure TCustomUWSIEAddress.UpdateTypedUrls;
    var
      reg:TRegistry ;
    begin
       GetTypedUrls ;
       if Text='' then Exit;
       if FTypedUrls.IndexOf(Text)=-1 then
       begin
         reg:=TRegistry.Create ;
         try
           if Reg.OpenKey('Software\Microsoft\Internet Explorer\TypedURLs', False) then
           begin
              reg.WriteString(Format('url%d',[FTypedUrls.Count+1]),Text);
           end;
           reg.CloseKey ;
         finally
           reg.Free;
         end;
       end;
    end;

    function TCustomUWSIEAddress.GetShellIcons:Cardinal;
    var
     sfi: TShFileInfo;
     aHandle: Cardinal;
    begin
      Result:=0;
      aHandle := ShGetFileInfo('', 0, sfi, sizeOf(sfi), SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
      if (aHandle <> 0) then
      Result:= aHandle;
    end;

    procedure TCustomUWSIEAddress.KeyDown(var Key: Word; Shift: TShiftState);
    begin
      FShiftKeyID:=0;
      if CtrlDown then
      FShiftKeyID:=FShiftKeyID+ctrlID;
      if ShiftDown then
      FShiftKeyID:=FShiftKeyID+ShiftID;
      if AltDown then
      FShiftKeyID:=FShiftKeyID+AltID;

      inherited;
    end;

    procedure TCustomUWSIEAddress.KeyUp(var Key: Word; Shift: TShiftState);
    var
      SrcKey:string;
      bCancel:Boolean ;
    begin
      bCancel:=False ;
      if Key=13 then
      begin
        case FShiftKeyID of
          0:begin
              Text:=GetOneKeyAddressUrl(Text);
            end;
          CtrlID:begin
                   SrcKey:=FAddressAutoFix.Values['Ctrl+Enter'];
                   Text:=GetFixUrl(SrcKey,Text);
                 end;
          AltID:begin
                  SrcKey:=FAddressAutoFix.Values['Alt+Enter'];
                  Text:=GetFixUrl(SrcKey,Text);
                end;
          ShiftID:begin
                    SrcKey:=FAddressAutoFix.Values['Shift+Enter'];
                    Text:=GetFixUrl(SrcKey,Text);
                  end;
          ACID:begin
                 SrcKey:=FAddressAutoFix.Values['Ctrl+Alt+Enter'];
                 Text:=GetFixUrl(SrcKey,Text);
               end;
          SCID:begin
                 SrcKey:=FAddressAutoFix.Values['Ctrl+Shift+Enter'];
                 Text:=GetFixUrl(SrcKey,Text);
               end;
          ASID:begin
                 SrcKey:=FAddressAutoFix.Values['Alt+Shift+Enter'];
                 Text:=GetFixUrl(SrcKey,Text);
               end;
          ASCID:begin
                  SrcKey:=FAddressAutoFix.Values['Ctrl+Shift+Alt+Enter'];
                  Text:=GetFixUrl(SrcKey,Text);
                end;
        end;
        if Text='' then
        Text:='about:blank'
        {else if (Pos('.',Text)=0) and (not FileExists(Text)) and
           (not DirectoryExists(Text)) then
        Text:='http://www.baidu.com/s?wd='+Text};
        UpdateTypedUrls;
        if Assigned(FOnUrlSelected) then
        FOnUrlSelected(Self, Text, bCancel);
      end;
      FShiftKeyID:=0;

      inherited;
    end;

    end.

    代码没有整理,习惯没养好

    实际应用案例图

    完整组件这里下载

    https://files.cnblogs.com/uws2056/UWSIEAddress.rar

  • 相关阅读:
    暑期学习录
    08管道命名符
    07输入输出重定向
    06grep与find命令详解
    05tar命令详解
    04文件目录管理命令
    03工作目录切换命令与文本文件编辑命令
    02系统状态检测命令
    01常用系统工作命令
    vue2.0细节剖析
  • 原文地址:https://www.cnblogs.com/uws2056/p/2316437.html
Copyright © 2020-2023  润新知