Windows提供了两个API函数,InitCommonControls和InitCommonControlsEx,用来初始化自定义控制库。从名字我们不难看出这两个API函数的关系:后者是前者的增强。如果你希望在程序中使用IP控件,你必须用InitCommonControlsEx来完成对自定义控制库以及类的初始化。函数InitCommonControlsEx的原型如下(Pascal语法):
type
tagINITCOMMONCONTROLSEX = packed record
dwSize: DWORD; // size of this structure
dwICC: DWORD; // flags indicating which classes to be initialized
end;
TInitCommonControlsEx = tagINITCOMMONCONTROLSEX;
function InitCommonControlsEx(var ICC: TInitCommonControlsEx): Bool;
IP控件属于ICC_INTERNET_CLASSES类别的控件,如果要使用该控件,你应该在程序中包含如下的初始化代码:
var
ICC: TInitCommonControlsEx;
begin
ICC.dwSize := SizeOf(TInitCommonControlsEx);
ICC.dwICC := ICC_INTERNET_CLASSES;
If not InitCommonControlsEx(ICC)
then begin
//初始化失败
end;
end;
创建IP控件
Windows API函数CreateWindow或者CreateWindowEx都可以用来创建一个IP控件实例。IP控件的窗口类名为“SysIPAddress32”,Delphi的commctrl.pas单元为其定义了一个符号常量WC_IPADDRESS。下面这条语句将在Form1上创建一个IP控件。
ipEdit:=CreateWindow(WC_IPADDRESS, nil, WS_CHILD or WS_VISIBLE, 91,88,130,23, Form1.Handle,0, hInstance,nil);
使用IP控件
在程序中,我们通过向IP控件发送消息来与它通讯。IP控件可以响应的消息有以下6个,这些消息及它们的含义见下表:
消息常量
消息值
作用
参数及返回值
IPM_CLEARADDRESS
WM_USER+100
清除IP控件中的IP串
参数无
IPM_SETADDRESS
WM_USER+101
设置IP控件的IP串
Lparam为32位的IP 值
IPM_GETADDRESS
WM_USER+102
获取IP控件中的IP串所对应的IP值(32位整数)
Lparam为一个指向Integer变量的指针。返回值等于IP控件中非控的字段数目;获取到的IP值存放在lparam 所指向的Integer变量中。
IPM_SETRANGE
WM_USER+103
设置IP控件4个部分的其中一个的IP取值范围
Wparam指明要设置取值范围的部分;lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。
IPM_SETFOCUS
WM_USER+104
设输入焦点
Wparam指明哪个部分获取焦点
IPM_ISBLANK
WM_USER+105
IP串是否为空
参数无。返回值:若为空,返回非0;不为空,返回0
㈠清空IP串(IPM_CLEARADDRESS)
SendMessage(ipEdit,IPM_CLEARADDRESS,0,0);
㈡设置IP串(IPM_SETADDRESS)
var ip: Integer;
...
ip:=MAKEIPADDRESS(202,117,17,25);
SendMessage(ipEdit,IPM_SETADDRESS,0,ip);
此例将IP控件的内容设为“202.117.17.25”,其中MAKEIPADDRESS是一个Win32宏,定义在commctrl.h头文件中,它用来合成一个32位的IP值:
#define MAKEIPADDRESS(b1,b2,b3,b4) ((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4))))
由于在Delphi中,没有宏的概念,所以在对应的Delphi单元commctrl.pas文件中,它是作为一个函数实现的:
function MAKEIPADDRESS(b1, b2, b3, b4: DWORD): LPARAM;
begin
Result := (b1 shl 24) + (b2 shl 16) + (b3 shl 8) + b4;
end;
㈢获取IP值(IPM_GETADDRESS)
var ip: Integer;
...
SendMessage(ipEdit,IPM_GETADDRESS,0,Integer(@ip));
//Inc(ip);
//SendMessage(ipEdit,IPM_SETADDRESS,0,ip);
若想要获取IP控件中IP串所对应的IP值,你应该向IP控件发送IPM_GETADDRESS消息,并且需要把一个32位整数的地址作为SendMessage的最后一个参数。
㈣设置取值范围(IPM_SETRANGE)
SendMessage (ipEdit, IPM_SETRANGE, 0, 203 shl 8 or 100);
此语句将IP控件的第一部分的范围限制为100..203。在IPM_SETRANGE消息中,Wparam指明要设置的字段, 而lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。
㈤设置输入焦点(IPM_SETFOCUS)
SendMessage(ipEdit,IPM_SETFOCUS,3,0);
//将输入焦点设在IP控件的第四部分。
㈥判断IP串是否为空(IPM_ISBLANK)
if SendMessage(ipEdit,IPM_ISBLANK,0,0)<>0
then //IP控件中的IP串为空
else // IP控件中的IP串至少有一部分不是空的
IP控件的通知消息
当IP串被改动后或者输入焦点发生了转移,IP控件就会向它的父窗口发送通知消息IPN_FIELDCHANGED。在大多数情况下,我们都可以忽略此通知消息。以下是处理通知消息IPN_FIELDCHANGED的一个示例:
procedure Tform1.WndProc(var Msg: TMessage);
var p
NMHDR;
begin
inherited;
if Msg.Msg=WM_NOTIFY
then begin
p:=Pointer(Msg.lParam);
if p^.code=IPN_FIELDCHANGED
then begin
{...
处理IP控件的IPN_FIELDCHANGED通知消息
...}
end;
end;
end;