首页 > 代码库 > 自定义组件-IPEdit
自定义组件-IPEdit
输入IP用的.....支持windows风格显示
unit HSIPEdit;// ***************************************************************************//// IPEdit//// 版本: 1.1// 作者: 刘志林// 修改日期: 2016-07-12// QQ: 17948876// E-mail: lzl_17948876@hotmail.com// 博客: http://www.cnblogs.com/hs-kill///// !!! 若有修改,请通知作者,谢谢合作 !!!//// ---------------------------------------------------------------------------//// 修改历史:// 1.1// 增加对IPV6的支持//// ***************************************************************************interfaceuses Messages, Windows, SysUtils, Classes, Controls, Forms, Graphics, StdCtrls, ExtCtrls, Themes;const {激活下一列, WParam: 列序号 LParam: 是否全选 0-不选 1-选} WM_IPFIELD_ACTIVE = WM_USER + $4;type THSIPField = class(TCustomEdit) private { Private declarations } FMin, FMax: Word; FIndex: Byte; FIPV6: Boolean; FIsSetValue: Boolean; function GetError: Boolean; function GetValue: Word; procedure SetMin(AValue: Word); procedure SetMax(AValue: Word); procedure SetValue(AValue: Word); procedure SetIPV6(AValue: Boolean); function GetCurrentPosition: Integer; procedure SetCurrentPosition(Value: Integer); procedure WMKeyDown(var Message: TWMKey); message WM_KEYDOWN; procedure CreateParams(var Params: TCreateParams); override; procedure KeyPress(var Key: Char); override; protected { Protected declarations } procedure Change; override; procedure SetValueStr(AValue: string); procedure ActiveField(ANext, ASel: Boolean); constructor Create(AOwner: TComponent); override; destructor Destroy; override; property IPV6: Boolean read FIPV6 write SetIPV6; property CurrentPosition: integer read GetCurrentPosition write SetCurrentPosition; property ReadOnly stored False; property Index: Byte read FIndex; published { Published declarations } property Min: Word read FMin write SetMin default 0; property Max: Word read FMax write SetMax default 255; property Value: Word read GetValue write SetValue default 0; property Error: Boolean read GetError; end; THSIPEdit = class(TCustomControl) private FUpdatting: Boolean; FIPV6: Boolean; {如果IPV4则使用后4位} FFields: array[0..7] of THSIPField; FFullRepaint: Boolean; FOnChange: TNotifyEvent; procedure CreateParams(var Params: TCreateParams); override; function GetFieldCount: Byte; function GetFieldValue(Index: Byte): Integer; function GetMin(nIndex: Byte): Word; procedure SetMin(nIndex: Byte; Value: Word); function GetMax(nIndex: Byte): Word; procedure SetMax(nIndex: Byte; Value: Word); function GetIPString: string; procedure SetIPString(Value: string); function GetTabStop: Boolean; procedure SetTabStop(AValue: Boolean); procedure SetReadOnly(AValue: Boolean); function GetReadOnly: Boolean; function FocusIndex: Integer; function GetFields(AIndex: Integer): THSIPField; function GetCursor(): TCursor; procedure SetCursor(AValue: TCursor); function GetError: Boolean; procedure SetIPV6(const Value: Boolean); procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED; procedure WMSize(var Message: TWMSize); message WM_SIZE; procedure CMEnter(var Message: TCMEnter); message CM_ENTER; procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN; procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED; procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED; procedure WMIPFIELDACTIVE(var Message: TMessage); message WM_IPFIELD_ACTIVE; procedure DoChange(Sender: TObject); protected procedure ArrangeFields; procedure Paint; override; property FullRepaint: Boolean read FFullRepaint write FFullRepaint default True; property Fields[index: Integer]: THSIPField read GetFields;(* function GetAddr: integer; procedure SetAddr(value: integer);*) {暂时不开放设置} property Min[index: Byte]: Word read GetMin write SetMin; property Max[index: Byte]: Word read GetMax write SetMax; public constructor Create(AOwner: TComponent); override; destructor Destroy; override;(* property Addr: integer read GetAddr write SetAddr;*) property FieldCount: Byte read GetFieldCount; property FieldValue[Index: Byte]: Integer read GetFieldValue; property Error: Boolean read GetError; published property Align; property Anchors; property IPString: string read GetIPString write SetIPString; property BevelEdges; property BevelInner; property BevelKind default bkNone; property BevelOuter; property Color; property Cursor: TCursor Read GetCursor write SetCursor; property Ctl3D; property Font; property Enabled; property ParentColor default False; property ParentFont default True; property ParentShowHint; property PopupMenu; property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False; property IPV6: Boolean read FIPV6 write SetIPV6 default False; property ShowHint; property TabOrder; property TabStop: Boolean read GetTabStop write SetTabStop default True; property Visible; property OnChange: TNotifyEvent read FOnChange write FOnChange; property OnEnter; property OnExit; end;implementationconst _DefWidthIPV4 = 161; _DefWidthIPV6 = 361; { TIPFieldEdit }procedure THSIPField.SetMin(AValue: Word);begin if (not FIPV6) and (AValue > 255) then AValue := 255; FMin := AValue; if FMax < FMin then FMax := FMin;end;procedure THSIPField.SetValueStr(AValue: string);var nValue, nCode: Integer;begin FIsSetValue := True; try if FIPV6 then AValue := ‘$‘ + AValue; Val(AValue, nValue, nCode); if (nCode <> 0) then AValue := ‘‘ else begin if (nValue < FMin) then nValue := FMin else if (nValue > FMax) then nValue := FMax; if FIPV6 then AValue := IntToHex(nValue, 2) else AValue := IntToStr(nValue); end; if AValue <> Text then Text := AValue; if (Length(Text) = MaxLength) and (CurrentPosition = MaxLength) then ActiveField(True, True); finally FIsSetValue := False; end;end;procedure THSIPField.SetMax(AValue: Word);begin if (not FIPV6) and (AValue > 255) then AValue := 255; FMax := AValue; if FMin > FMax then FMin := FMax;end;procedure THSIPField.SetValue(AValue: Word);begin if FIPV6 then SetValueStr(IntToHex(AValue, 2)) else SetValueStr(IntToStr(AValue));end;procedure THSIPField.KeyPress(var Key: Char);begin if FIPV6 and (Key in [‘0‘..‘9‘, ‘A‘..‘F‘]) then begin inherited; end else if (Key in [‘0‘..‘9‘]) then begin inherited; end else begin if (Key = ‘.‘) and (SelLength = 0) and (Text <> ‘‘) then ActiveField(True, True); if Key <> #8 then Key := #0 else if CurrentPosition = 0 then ActiveField(False, False); end;end;procedure THSIPField.CreateParams(var Params: TCreateParams);begin inherited CreateParams(Params); Params.Style := Params.Style or (ES_CENTER);end;procedure THSIPField.ActiveField(ANext, ASel: Boolean);begin if ANext then SendMessage(Parent.Handle, WM_IPFIELD_ACTIVE, FIndex + 1, MakeLParam(Byte(ASel), 0)) else SendMessage(Parent.Handle, WM_IPFIELD_ACTIVE, FIndex - 1, MakeLParam(Byte(ASel), 1));end;procedure THSIPField.Change;begin if not FIsSetValue then SetValueStr(Text); inherited Change;end;constructor THSIPField.Create(AOwner: TComponent);begin inherited Create(AOwner); Text := ‘‘; FMin := 0; FMax := 255; FIPV6 := False; FIsSetValue := False; MaxLength := 3; ParentFont := True; ParentColor := True; BorderStyle := bsNone;end;destructor THSIPField.Destroy;begin inherited Destroy;end;function THSIPField.GetCurrentPosition: Integer;{Get character position of cursor within line}begin Result := SelStart - SendMessage(Handle, EM_LINEINDEX, (SendMessage(Handle, EM_LINEFROMCHAR, SelStart, 0)), 0);end;function THSIPField.GetError: Boolean;var nV: Integer;begin if FIPV6 then Result := not TryStrToInt(‘$‘ + Text, nV) else Result := not TryStrToInt(Text, nV);end;function THSIPField.GetValue: Word;begin if FIPV6 then Result := StrToIntDef(‘$‘ + Text, 0) else Result := StrToIntDef(Text, 0);end;procedure THSIPField.SetCurrentPosition(Value: Integer);var nPos: Integer;begin {Value must be within range} nPos := Value; if nPos < 0 then nPos := 0; if nPos > Length(Text) then nPos := Length(Text); {Put cursor in selected position} SelStart := SendMessage(Handle, EM_LINEINDEX, 0, 0) + nPos;end;procedure THSIPField.SetIPV6(AValue: Boolean);var nV: string;begin if FIPV6 <> AValue then begin FIPV6 := AValue; if FIPV6 then begin MaxLength := 4; FMax := $FFFF; nV := IntToHex(StrToIntDef(Text, 0), 2); end else begin MaxLength := 3; FMax := 255; nV := IntToStr(StrToIntDef(‘$‘ + Text, 0)); end; SetMax(FMax); SetMin(FMin); SetValueStr(nV); end; Visible := False;//FIPV6 or (FIndex > 3);end;procedure THSIPField.WMKeyDown(var Message: TWMKey);begin with Message do if (CharCode = VK_RIGHT) and (CurrentPosition >= Length(Text)) then begin SelLength := 0; ActiveField(True, False); Result := 1; end else if (CharCode = VK_LEFT) and (CurrentPosition = 0) then begin SelLength := 0; ActiveField(False, False); Result := 1; end else inherited;end;{ TIPEdit }constructor THSIPEdit.Create(AOwner: TComponent);var i: integer;begin inherited Create(AOwner); ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents, csSetCaption, csOpaque, csDoubleClicks, csReplicatable]; if NewStyleControls then ControlStyle := ControlStyle else ControlStyle := ControlStyle + [csFramed]; ParentFont := True; FUpdatting := True; FIPV6 := False; for i := 0 to 7 do begin FFields[i] := THSIPField.Create(Self); with FFields[i] do begin FIndex := i; Parent := Self; FIPV6 := Self.FIPV6; OnChange := DoChange; end; end;// Cursor := crIBeam; Width := 161; Height := 21; BevelKind := bkFlat; TabStop := True; ParentColor := False; ArrangeFields; FUpdatting := False;end;destructor THSIPEdit.Destroy;var i: integer;begin for i := 0 to 7 do FFields[i].Free; inherited;end;procedure THSIPEdit.DoChange(Sender: TObject);begin if Assigned(FOnChange) then FOnChange(Self);end;procedure THSIPEdit.CreateParams(var Params: TCreateParams);const ReadOnlys: array[Boolean] of DWORD = (0, ES_READONLY);begin inherited CreateParams(Params); with Params do begin Style := Style or ReadOnlys[ReadOnly]; WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW); end;end;procedure THSIPEdit.CMColorChanged(var Message: TMessage);begin // inherited; Invalidate;end;procedure THSIPEdit.CMFontChanged(var Message: TMessage);begin // inherited; if not FUpdatting then ArrangeFields; Invalidate;end;procedure THSIPEdit.CMCtl3DChanged(var Message: TMessage);begin inherited;end;procedure THSIPEdit.Paint;var nRect: TRect; nTop, i: Integer; nFSize: TSize;begin// inherited; nRect := GetClientRect; Canvas.Brush.Color := Color; Canvas.FillRect(nRect); nFSize := Canvas.TextExtent(‘a‘); nTop := nRect.Top + (nRect.Bottom - nRect.Top - nFSize.cy) div 2; if FIPV6 then begin for i := 1 to 7 do Canvas.TextOut(FFields[i].Left - nFSize.cx - 2, nTop, ‘:‘); end else begin for i := 5 to 7 do Canvas.TextOut(FFields[i].Left - nFSize.cx - 2, nTop, ‘.‘); end;end;function THSIPEdit.GetCursor(): TCursor;begin Result := inherited Cursor;end;function THSIPEdit.GetError: Boolean;var i, m: Integer;begin Result := False; if FIPV6 then m := 0 else m := 4; for i := m to 7 do if FFields[i].Error then begin Result := True; Break; end;end;procedure THSIPEdit.SetCursor(AValue: TCursor);var i: integer;begin inherited Cursor := AValue; for i := 0 to 7 do FFields[i].Cursor := AValue;end;procedure THSIPEdit.ArrangeFields;var i: integer; nW, nH, nL, nT, nB: Integer; nFSize: TSize; nRC: TRect;begin if not Assigned(Parent) then Exit; nRC := ClientRect; nFSize := Canvas.TextExtent(‘a‘); nL := nRC.Left + 2; nH := nFSize.cy + 2; nT := nRc.Top + (nRC.Bottom - nRC.Top - nH) div 2 + 1; nB := nFSize.cx + 4; if FIPV6 then begin nW := (ClientWidth - 4 - nB * 7) div 8; for i := 0 to 7 do begin FFields[i].SetBounds(nL, nT, nW, nH); Inc(nL, nW + nB); end; end else begin nW := (ClientWidth - 4 - nB * 3) div 4; for i := 0 to 3 do FFields[i].SetBounds(nL, nT, nW, nH); for i := 4 to 7 do begin FFields[i].SetBounds(nL, nT, nW, nH); Inc(nL, nW + nB); end; end;end;function THSIPEdit.GetMin(nIndex: Byte): Word;begin Result := FFields[nIndex].Min;end;procedure THSIPEdit.SetMin(nIndex: Byte; Value: Word);begin FFields[nIndex].Min := Value;end;function THSIPEdit.GetMax(nIndex: Byte): Word;begin Result := FFields[nIndex].Max;end;procedure THSIPEdit.SetMax(nIndex: Byte; Value: Word);begin FFields[nIndex].Max := Value;end;function THSIPEdit.GetIPString: string;begin if GetError then Result := ‘‘ else if FIPV6 then Result := Format(‘%.4x:%.4x:%.4x:%.4x:%.4x:%.4x:%.4x:%.4x‘, [FFields[0].Value, FFields[1].Value, FFields[2].Value, FFields[3].Value, FFields[4].Value, FFields[5].Value, FFields[6].Value, FFields[7].Value]) else Result := Format(‘%d.%d.%d.%d‘, [FFields[4].Value, FFields[5].Value, FFields[6].Value, FFields[7].Value]);end;procedure THSIPEdit.SetIPString(Value: string);var i, nF: integer;begin if FIPV6 then nF := 0 else nF := 4; with TStringList.Create do try if FIPV6 then Delimiter := ‘:‘ else Delimiter := ‘.‘; DelimitedText := Value; {暂不支持IPV6缩写模式 如: 0::FF:0} if Count <> (8 - nF) then for i := nF to 7 do FFields[i].SetValueStr(‘‘) else for i := nF to 7 do FFields[i].SetValueStr(Strings[i - nF]); finally Free; end;end;procedure THSIPEdit.SetIPV6(const Value: Boolean);var i: Integer;begin if FIPV6 <> Value then begin FUpdatting := True; FIPV6 := Value; for i := 0 to 7 do FFields[i].IPV6 := FIPV6; if FIPV6 then begin if Width = _DefWidthIPV4 then Width := _DefWidthIPV6; end else begin if Width = _DefWidthIPV6 then Width := _DefWidthIPV4; end; FUpdatting := False; ArrangeFields; Invalidate; end;end;(*function THSIPEdit.GetAddr: integer;type DWORDSTRUCT = Record case integer of 0: (b: array [0..3] of Byte); 1: (w: array [0..1] of word); 2: (d: Integer); end;var v: DWORDSTRUCT; i: integer;begin if Error then Result := 0 else begin for i := 0 to 3 do v.b[i] := FFields[i].Value; Result := v.d; end;end;procedure THSIPEdit.SetAddr(value: integer);type DWORDSTRUCT = Record case integer of 0: (b: array [0..3] of Byte); 1: (w: array [0..1] of word); 2: (d: integer); end;var v: DWORDSTRUCT; i: integer;begin v.d := value; for i := 0 to 3 do begin FFields[i].Value := v.b[i]; end;end;*)function THSIPEdit.FocusIndex: Integer;var i: Integer;begin Result := -1; for i := 0 to 7 do if FFields[i].Focused then Result := i;end;procedure THSIPEdit.WMSize(var Message: TWMSize);begin inherited; if not FUpdatting then ArrangeFields; Invalidate;end;procedure THSIPEdit.WMIPFIELDACTIVE(var Message: TMessage);var nF: integer; nSel: Boolean;begin if FIPV6 then nF := 0 else nF := 4; with Message do begin if (WParam < nF) or (WParam > 7) then Exit; nSel := Boolean(Byte(LParamLo)); if nSel then FFields[WParam].SelectAll else if LParamHi = 0 then FFields[WParam].CurrentPosition := 0 else FFields[WParam].CurrentPosition := Length(FFields[WParam].Text); FFields[WParam].SetFocus; end;end;procedure THSIPEdit.WMLButtonDown(var Message: TWMLButtonDown);begin inherited; if FocusIndex < 0 then if FIPV6 then FFields[0].SetFocus else FFields[4].SetFocus;end;function THSIPEdit.GetFieldCount: Byte;begin if FIPV6 then Result := 8 else Result := 4;end;function THSIPEdit.GetFields(AIndex: Integer): THSIPField;begin Result := FFields[AIndex];end;function THSIPEdit.GetFieldValue(Index: Byte): Integer;begin Result := 0; if FIPV6 then begin if Index > 7 then Exit; if FFields[Index].Error then Exit; Result := FFields[Index].Value; end else begin if Index > 3 then Exit; if FFields[Index + 4].Error then Exit; Result := FFields[Index + 4].Value; end;end;function THSIPEdit.GetTabStop: Boolean;begin Result := inherited TabStop;end;procedure THSIPEdit.SetTabStop(AValue: Boolean);var i: integer;begin if AValue <> inherited TabStop then begin inherited TabStop := AValue; for i := 0 to 7 do FFields[i].TabStop := AValue; end;end;procedure THSIPEdit.SetReadOnly(AValue: Boolean);var i: integer;begin if ReadOnly <> AValue then for i := 0 to 7 do FFields[i].ReadOnly := AValue;end;function THSIPEdit.GetReadOnly: Boolean;begin Result := FFields[0].ReadOnly;end;procedure THSIPEdit.CMEnter(var Message: TCMEnter);begin if IPV6 then FFields[0].SetFocus else FFields[4].SetFocus; inherited;end;end.
自定义组件-IPEdit
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。