求助IP输入控件

小草sd 2009-08-13 09:44:16
求助IP输入控件
...全文
274 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
laowang2 2009-08-13
  • 打赏
  • 举报
回复
为Delphi/C++ Builder增添IP控件

西安交通大学

刘明华

在进行网络设置时,我们常常碰到需要填写IP地址的情况,为此Windows引入了一个专门用来接受IP地址输入的控件(如图所示)。Windows IP地址编辑控件(IP Address edit control)是随着微软的Internet Explorer 4.0的推出而引入Windows操作系统的(Windows 98和Windows 2000中都已经包含了此控件)。但是令人遗憾的是在Inprise公司最新版本的Delphi 5和C++ Builder 5中,Borland可视化控件库(Visual Component Library)中居然没有提供IP地址编辑控件。

为了让Delphi和C++ Builder开发人员更方便地使用IP控件,本文介绍如何将它包装成一个可以在Delphi和C++ Builder的IDE环境中使用的可视化Delphi控件。同时本文也为读者学习Delphi控件编写提供了一个比较好的示例;它涉及了Delphi控件编写的以下方面的知识:将Windows窗口类封装成Delphi控件,将Windows消息映射成事件属性,多个属性共享read和write方法,以及属性编辑器(Property Editor)的构造。

 



IP控件的属性、方法及事件

本文将为Delphi/C++ Builder的IP控件实现下面的属性、方法和事件。它们的简单介绍如下:

IP属性:IP控件中的IP地址值(32位整数LongWord)。为了获取IP控件的IP值,我们只需要读取此属性即可;通过对IP属性赋值,我们就能够改变IP控件的内容。

Field0..Field3属性:Field0到Field3分别为IP控件的4个部分的值。这四个属性也是为了读取和改变IP控件的IP值而设置的。

Field0Range..Field3Range 属性:Field0Range到Field3Range限制IP控件各部分的取值的范围。

Blank属性:判断IP控件的IP串是否为空,此属性为只读属性。

About属性:在Object Inspector中点击它可以显示控件的版本信息,添加此属性是为了提供一个编写属性编辑器的简单例子。

以下属性继承自TWinControl类:Font、TabOrder、TabStop、 ParentShowHint、ShowHint、Hint、及Visible。

TIPEdit的事件属性有:OnFieldChange、OnChange、OnEnter以及OnExit。

 

Clear方法:清空IP控件中的IP串。

SetFieldFocus方法:设置IP控件的输入焦点。

IP控件的实现

//文件名:IPEdit.PAS

{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

// IP address edit control for Borland Delphi 5

// Implemented by Simon Liu (simon_liu@263.net)

{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

unit IPEdit;

interface

uses Windows, Messages, SysUtils, Classes,

Forms, Controls, ComCtrls, CommCtrl, DsgnIntf;

 

type

TFieldRange = record

LowRange: Byte;

HighRange: Byte;

end;

 

TFieldChangeEvent = procedure(Sender: TObject; OldField, Value: Byte) of Object;

 

//定义TAboutProperty属性编辑器

TAboutProperty = class(TPropertyEditor)

public

procedure Edit; override;

function GetAttributes: TPropertyAttributes; override;

function GetValue: string; override;

end;

 

TIPEdit = class(TWinControl)

private

fAbout:TAboutProperty;

FIP: LongWord;

FFields:array[0..3] of Byte;

FFieldRanges: array [0..3] of TFieldRange;

FCreating: Boolean;

FOnChange: TNotifyEvent;

FOnEnter: TNotifyEvent;

FOnExit: TNotifyEvent;

FOnFieldChange: TFieldChangeEvent;

procedure SetIP(Value: LongWord);

function GetIP: LongWord;

function GetField(Index:Integer):Byte;

procedure SetField(Index:Integer; B:Byte);

function GetFieldRange(Field: Integer): TFieldRange;

procedure SetFieldRange(Field:integer; Value: TFieldRange);

procedure SetIPAddress;

function GetBlank: Boolean;

procedure WMNotifyFormat(var Message: TMessage); message WM_NOTIFYFORMAT;

//处理IP控件的通知消息IPN_FIELDCHANGED

procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;

procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;

procedure WMSetFont(var Message: TWMSetFont); message WM_SETFONT;

protected

procedure CreateParams(var Params: TCreateParams); override;

procedure CreateWnd; override;

procedure DestroyWnd; override;

public

constructor Create(AOwner: TComponent); override;

destructor Destroy; override;

//清除IP控件中的IP串

procedure Clear;

//设置IP控件的输入焦点(field的有效取值为0..3)

procedure SetFieldFocus(Field:Byte);

published

//判断IP控件的IP串是否为空

property Blank: Boolean read GetBlank;

//Field0到Field3分别为IP控件的4个部分的值

property Field0: Byte index 0 read GetField write SetField;

property Field1: Byte index 1 read GetField write SetField;

property Field2: Byte index 2 read GetField write SetField;

property Field3: Byte index 3 read GetField write SetField;

//Field0Range到Field3Range限制IP控件各部分的取值的范围

property Field0Range: TFieldRange index 0 read GetFieldRange write SetFieldRange;

property Field1Range: TFieldRange index 1 read GetFieldRange write SetFieldRange;

property Field2Range: TFieldRange index 2 read GetFieldRange write SetFieldRange;

property Field3Range: TFieldRange index 3 read GetFieldRange write SetFieldRange;

//IP地址值(32位整数LongWord)

property IP: LongWord read GetIP write SetIP;

//The About box

property About:TAboutProperty read fAbout;

//事件属性

property OnChange: TNotifyEvent read FOnChange write FOnChange;

property OnEnter: TNotifyEvent read FOnEnter write FOnEnter;

property OnExit: TNotifyEvent read FOnExit write FOnExit;

property OnFieldChange: TFieldChangeEvent read FOnFieldChange write FOnFieldChange;

//以下属性继承自TWinControl控件

property Enabled;

property TabOrder;

property TabStop;

property ParentShowHint;

property ShowHint;

property Hint;

property Visible;

end;

 

procedure Register;

 

implementation

 

{~~~~~~~~~~~~~~~~~TAboutProperty~~~~~~~~~~~~~~~~~~~~~}

procedure TAboutProperty.Edit;

begin

Application.MessageBox(

'TIPEdit for Delphi 5'#13

+'(C) 2000 by Simon Liu'#13

+'Email:simon_liu@263.net',

'About TIPEdit',MB_ICONINFORMATION);

end;

 

function TAboutProperty.GetAttributes: TPropertyAttributes;

begin

Result := [paDialog, paReadOnly];

end;

 

function TAboutProperty.GetValue: string;

begin

Result := '(Simon)';

end;

 

{~~~~~~~~~~~~~~~~~~~~~~TIPEdit~~~~~~~~~~~~~~~~~~~~~~~~}

constructor TIPEdit.Create(AOwner: TComponent);

var

i: integer;

begin

//初始化ICC_INTERNET_CLASSES类控件

CheckCommonControl(ICC_INTERNET_CLASSES);

inherited Create(AOwner);

for i:= 0 to 3 do

begin

FFieldRanges[i].LowRange:= 0;

FFieldRanges[i].HighRange:= 255;

FFields[i]:=0;

end;

FIP:=0;

Height:= 25;

Width:= 152;

TabSTop:= True;

end;

 

procedure TIPEdit.DestroyWnd;

begin

inherited DestroyWnd

end;

 

destructor TIPEdit.Destroy;

begin

inherited Destroy;

end;

 

procedure TIPEdit.CreateParams(var Params: TCreateParams);

begin

inherited CreateParams(Params);

CreateSubClass(Params, WC_IPADDRESS);

with Params do

begin

end;

end;

 

procedure TIPEdit.CreateWnd;

begin

FCreating := True;

try

inherited CreateWnd;

SetIPAddress;

finally

FCreating := False;

end;

end;

 

function TIPEdit.GetBlank: Boolean;

begin

Result:= Boolean(SendMessage(Handle, IPM_ISBLANK, 0, 0));

end;

 

procedure TIPEdit.Clear;

begin

SendMessage(Handle, IPM_CLEARADDRESS, 0, 0);

end;

 

procedure TIPEdit.SetFieldFocus(Field:Byte);

begin

SendMessage(Handle, IPM_SETFOCUS, Field, 0);

end;

 

function TIPEdit.GetFieldRange(Field: Integer): TFieldRange;

begin

Result:= FFieldRanges[Field];

end;

 

procedure TIPEdit.SetFieldRange(Field: Integer; Value: TFieldRange);

begin

if Value.LowRange > Value.HighRange then exit;

if (FFieldRanges[Field].LowRange <> Value.LowRange) or

(FFieldRanges[Field].HighRange <> Value.HighRange) then

begin

FFieldRanges[Field]:= Value;

SendMessage(Handle, IPM_SETRANGE, Field,

MakeIPRange(Value.LowRange, Value.HighRange));

end;

end;

 

function TIPEdit.GetField(Index: Integer): Byte;

begin

if (Index>=0)and(Index<=3) then Result:=FFields[Index]

else Result:=0;

end;

 

procedure TIPEdit.SetField(Index:Integer; B:Byte);

begin

if (FFields[Index] <> B)then

begin

FFields[Index]:=B;

SetIPAddress;

end;

end;

 

procedure TIPEdit.SetIPAddress;

var

i:LongWord;

begin

i:=MAKEIPADDRESS(FFields[0], FFields[1], FFields[2], FFields[3]);

SendMessage(Handle, IPM_SETADDRESS, 0, i);

FIP:=i;

end;

 

procedure TIPEdit.SetIP(Value: LongWord);

begin

if (FIP <> Value) then

begin

FFields[0]:= First_IPAddress(Value);

FFields[1]:= Second_IPAddress(Value);

FFields[2]:= Third_IPAddress(Value);

FFields[3]:= Fourth_IPAddress(Value);

SetIPAddress;

end;

end;

 

function TIPEdit.GetIP: LongWord;

begin

SendMessage(Handle, IPM_GETADDRESS, 0, Integer(@Result));

end;

 

procedure TIPEdit.WMSetFont(var Message: TWMSetFont);

begin

//不可以调用父控件的此方法

//否则,控件不能正常工作

end;

 

procedure TIPEdit.WMNotifyFormat(var Message: TMessage);

begin

with Message do

Result := DefWindowProc(Handle, Msg, WParam, LParam);

end;

 

procedure TIPEdit.CNNotify(var Message: TWMNotify);

var

pNM: PNMIPAddress;

begin

with (Message.NMHdr)^ do

begin

case Code of

IPN_FIELDCHANGED:

begin

pNM:= PNMIPADDRESS(Message.NMHdr);

if (pNM^.iField>=0)and(pNM^.iField<=3) then

FFields[pNM^.iField]:=pNM^.iValue;

if Assigned(FOnFieldChange) then

FOnFieldChange(self, pNM^.iField, pNM^.iValue);

end;

end;

end;

end;

 

procedure TIPEdit.CNCommand(var Message: TWMCommand);

begin

case Message.NotifyCode of

EN_CHANGE:

begin

if not FCreating then

if Assigned(FOnChange) then FOnChange(self);

end;

EN_KILLFOCUS: if Assigned(FOnExit) then FOnExit(self);

EN_SETFOCUS: if Assigned(FOnEnter) then FOnEnter(self);

end;

end;

 

//注册TIPEdit控件以及TAboutProperty属性编辑器

procedure Register;

begin

RegisterComponents('Simon', [TIPEdit]);

RegisterPropertyEditor(typeInfo(TAboutProperty),

TIPEdit, 'ABOUT', TAboutProperty);

end;

end.
ccrun.com 2009-08-13
  • 打赏
  • 举报
回复
文抄公来也!!!

以下代码封装了TIPAddress类,代码由cker编写,在此对cker表示感谢。
// start of TIPAddress
#include <CommCtrl.hpp>
#include <ComCtrls.hpp>
class TIPAddress;
//---------------------------------------------------------------------------
Word __fastcall MakeIPRange(Byte Low, Byte High)
{
return Word((Word(High) << 8) + Word(Low));
}
//---------------------------------------------------------------------------
unsigned __fastcall MakeIPAddress(Byte b1, Byte b2, Byte b3, Byte b4)
{
return Word((Word(b1) << 24)+(Word(b2) << 16)+(Word(b3) << 8)+(Word(b4)));
}
//---------------------------------------------------------------------------
Byte __fastcall First_IPAddress(unsigned X)
{
return Byte((X >> 24) & 0x0FF);
}
//---------------------------------------------------------------------------
Byte __fastcall Second_IPAddress(unsigned X)
{
return Byte((X >> 16) & 0x0FF);
}
//---------------------------------------------------------------------------
Byte __fastcall Third_IPAddress(unsigned X)
{
return Byte((X >> 8) & 0x0FF);
}
//---------------------------------------------------------------------------
Byte __fastcall Fourth_IPAddress(unsigned X)
{
return Byte(X & 0x0FF);
}
//---------------------------------------------------------------------------
typedef void __fastcall (__closure *TIPAddressFieldChangeEvent)
(TIPAddress* Sender, Byte OldField, Byte Value);
typedef void __fastcall (__closure *TIPAddressChangeEvent)
(TIPAddress* Sender, AnsiString IPAddress);
//---------------------------------------------------------------------------
class TIPAddress : public TWinControl
{
private:
TIPAddressChangeEvent FOnIPChange;
TIPAddressFieldChangeEvent FOnIPFieldChange;
int FMinIPAddress;
int FMaxIPAddress;
Byte FActiveField;
bool FAutoSize;
void __fastcall CNNotify(TWMNotify &Message); // CN_NOTIFY;
void __fastcall CNCommand(TWMCommand &Message); // CN_COMMAND;
protected:
virtual void __fastcall CreateParams(TCreateParams ¶ms);
AnsiString __fastcall GetMinIPAddress();
AnsiString __fastcall GetMaxIPAddress();
AnsiString __fastcall GetIPAddress();
void __fastcall SetMinIPAddress(AnsiString Value);
void __fastcall SetMaxIPAddress(AnsiString Value);
void __fastcall SetIPAddress(AnsiString Value);
bool __fastcall GetEmpty();

void __fastcall SetActiveField(Byte Value);
void __fastcall WndProc(TMessage &Message);


BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(CN_NOTIFY, TWMNotify, CNNotify);
VCL_MESSAGE_HANDLER(CN_COMMAND, TWMCommand, CNCommand);
END_MESSAGE_MAP(TWinControl);

public:
virtual __fastcall TIPAddress(TComponent* AOwner);
AnsiString __fastcall IPToString(int Ip);
int __fastcall StringToIP(AnsiString Value);
void __fastcall Clear();
__published:
__property Byte ActiveField = {read = FActiveField, write = SetActiveField};
__property bool Empty = {read = GetEmpty};
__property AnsiString MinIPAddress = {read = GetMinIPAddress, write = SetMinIPAddress};
__property AnsiString MaxIPAddress = {read = GetMaxIPAddress, write = SetMaxIPAddress};
__property AnsiString IPAddress = {read = GetIPAddress, write = SetIPAddress};
__property TIPAddressChangeEvent OnIPChange = {read = FOnIPChange, write = FOnIPChange};
__property TIPAddressFieldChangeEvent OnIPFieldChange = {read = FOnIPFieldChange, write = FOnIPFieldChange};

__property Font;
__property ParentColor;
__property ParentFont;
__property ParentShowHint;
__property PopupMenu;
__property ShowHint;
__property TabOrder;
__property TabStop;
__property Tag;
__property DragCursor;
__property DragMode;
__property HelpContext;

};
//---------------------------------------------------------------------------
void __fastcall TIPAddress::WndProc(TMessage &Message)
{
switch (Message.Msg)
{
case WM_KEYDOWN:
{
ShowMessage("aweaw");
}
break;
}
TWinControl::WndProc(Message);
}
//---------------------------------------------------------------------------
__fastcall TIPAddress::TIPAddress(TComponent* AOwner):TWinControl(AOwner)
{
if (NewStyleControls)
ControlStyle << csClickEvents << csSetCaption << csDoubleClicks << csFixedHeight;
else
ControlStyle << csClickEvents << csSetCaption << csDoubleClicks << csFixedHeight << csFramed;

ParentColor = false;
FAutoSize = true;
Width = 100;
Height = 25;
TabStop = true;
FMinIPAddress = 0;
FMaxIPAddress = 0x0FFFFFFFF;
FActiveField = 0;
FOnIPChange = NULL;
FOnIPFieldChange = NULL;
}
//---------------------------------------------------------------------------
void __fastcall TIPAddress::CreateParams(TCreateParams ¶ms)
{
InitCommonControl(ICC_INTERNET_CLASSES);
TWinControl::CreateParams(Params);
CreateSubClass(Params, WC_IPADDRESS);
}
//---------------------------------------------------------------------------
void __fastcall TIPAddress::CNCommand(TWMCommand &Message) //CN_COMMAND;
{
if ((Message.NotifyCode == EN_CHANGE) && OnIPChange)
OnIPChange(this, IPAddress);
}
//---------------------------------------------------------------------------
void __fastcall TIPAddress::CNNotify(TWMNotify &Message) //CN_NOTIFY;
{
switch(Message.NMHdr->code)
{
case IPN_FIELDCHANGED :
{
FActiveField = (PNMIPAddress(Message.NMHdr))->iField;
if (OnIPFieldChange)
{
OnIPFieldChange(this, (PNMIPAddress(Message.NMHdr))->iField,
(PNMIPAddress(Message.NMHdr))->iValue);
}
}
break;
}
}
//---------------------------------------------------------------------------
AnsiString __fastcall TIPAddress::GetIPAddress()
{
int IP = 0;
SendMessage(Handle, IPM_GETADDRESS, 0, (int)&IP);
return IPToString(IP);
}
//---------------------------------------------------------------------------
AnsiString __fastcall TIPAddress::GetMinIPAddress()
{
return IPToString(FMinIPAddress);
}
//---------------------------------------------------------------------------
void __fastcall TIPAddress::SetMinIPAddress(AnsiString Value)
{
FMinIPAddress = StringToIP(Value);
SendMessage(Handle, IPM_SETRANGE, 0, MakeIPRange(First_IPAddress(FMinIPAddress),
First_IPAddress(FMaxIPAddress)));
SendMessage(Handle, IPM_SETRANGE, 1, MakeIPRange(Second_IPAddress(FMinIPAddress),
Second_IPAddress(FMaxIPAddress)));
SendMessage(Handle, IPM_SETRANGE, 2, MakeIPRange(Third_IPAddress(FMinIPAddress),
Third_IPAddress(FMaxIPAddress)));
SendMessage(Handle, IPM_SETRANGE, 3, MakeIPRange(Fourth_IPAddress(FMinIPAddress),
Fourth_IPAddress(FMaxIPAddress)));
}
//---------------------------------------------------------------------------
AnsiString __fastcall TIPAddress::GetMaxIPAddress()
{
return IPToString(FMaxIPAddress);
}
//---------------------------------------------------------------------------
void __fastcall TIPAddress::SetMaxIPAddress(AnsiString Value)
{
FMaxIPAddress = StringToIP(Value);
SendMessage(Handle, IPM_SETRANGE, 0, MakeIPRange(First_IPAddress(FMinIPAddress),
First_IPAddress(FMaxIPAddress)));
SendMessage(Handle, IPM_SETRANGE, 1, MakeIPRange(Second_IPAddress(FMinIPAddress),
Second_IPAddress(FMaxIPAddress)));
SendMessage(Handle, IPM_SETRANGE, 2, MakeIPRange(Third_IPAddress(FMinIPAddress),
Third_IPAddress(FMaxIPAddress)));
SendMessage(Handle, IPM_SETRANGE, 3, MakeIPRange(Fourth_IPAddress(FMinIPAddress),
Fourth_IPAddress(FMaxIPAddress)));
}
//---------------------------------------------------------------------------
void __fastcall TIPAddress::SetIPAddress(AnsiString Value)
{
SendMessage(Handle, IPM_SETADDRESS, 0, StringToIP(Value));
}
//---------------------------------------------------------------------------
bool __fastcall TIPAddress::GetEmpty()
{
return (bool)(SendMessage(Handle, IPM_ISBLANK, 0, 0));
}
//---------------------------------------------------------------------------
void __fastcall TIPAddress::Clear()
{
SendMessage(Handle, IPM_CLEARADDRESS, 0, 0);
}
//---------------------------------------------------------------------------
void __fastcall TIPAddress::SetActiveField(Byte Value)
{
if(Value < 4)
{
SendMessage(Handle, IPM_SETFOCUS, WPARAM(Value), 0);
FActiveField = Value;
}
}
//---------------------------------------------------------------------------
int __fastcall TIPAddress::StringToIP(AnsiString Value)
{
Byte B[4];

B[0]= 0;
B[1]= 0;
B[2]= 0;
B[3]= 0;

int Cnt = 0;
int i = Value.Pos(".");

AnsiString Str;

while ((Value.Length() > 0) && ( Cnt < 4 ))
{
if (i == 0)
i = Value.Length() + 1;
Str = Value.SubString(1, i-1);
B[Cnt] = StrToInt(Str);
Value = Value.SubString(i+1, Value.Length());
i = Value.Pos(".");
Cnt++;
}
return MakeIPAddress(B[0], B[1], B[2], B[3]);
}
//---------------------------------------------------------------------------
AnsiString __fastcall TIPAddress::IPToString(int Ip)
{
AnsiString strTemp;
strTemp.sprintf("%d.%d.%d.%d", First_IPAddress(Ip), Second_IPAddress(Ip),
Third_IPAddress(Ip), Fourth_IPAddress(Ip));
return strTemp;
}
// end of TIPAddress

调用举例:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
TIPAddress *ip;
ip = new TIPAddress(this);
ip->Parent = this;
}

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧