打造人性化的通讯录软件
编程爱好者
本期为大家介绍的这个生活实用程序名叫《通讯录》,它除了能记录下好友的详细联系方式外,还能以更人性化的方式提醒我们节日等重要事件,同时兼具闹钟功能,使我们能更好地把握时间。
软件的主要功能包括:
1.通讯录的查询;
2.区号的查询;
3.按电话号码查询;
4.节日查询;
5.闹钟服务。
功能特点:软件的查询功能采用了模糊查询方式,另外当它启动之后可以最小化到系统托盘区。该软件采用PowerBuilder8.0编写。
一、简单的操作
如图1,点击“录入”按钮后就会在数据窗口区追加一条新记录,同时输入区全部清空等待录入,把必要信息录入完毕后就可以点击“保存”按钮来保存数据。“锁定”按钮可以把数据窗口中的数据锁定而避免误修改。“升序”按钮是一个排序的按钮,当需要按哪个字段进行排序时可以先选中该字段的数据区,然后再点击“升序”按钮来排序,当然也可以按“降序”来排,只要再点击一次此按钮即可。“查询”按钮是一个比较关键的按钮,利用它可以完成所有数据记录的查询,在本程序中都是利用的模糊查询方式,只要输入关键字就可以查询到所需的数据记录,如图1所示的每一个字段的信息都可以作为关键字。“隐藏”按钮就是把本程序最小化到系统托盘区,如果要使用“节日提醒”功能和“闹钟服务”可以把程序最小化到系统托盘区,而不能关闭它。

二、制作难点
1.防止同时运行多个实例
本程序是一个数据库系统,如果同时运行多个实例就可能会在操作数据时,产生数据的不一致,为此,在本程序中进行了限制,只允许应用程序运行一次。为此在应用对象“dhgl”的“open”事件中加入了下面的代码:
long ll_winhandle1,ll_winhandle2,ll_winhandle3,ll_winhandle4,ll_winhandle5,ll_winhandle6
ll_winhandle1=FindWindowA(0,"通讯录")
ll_winhandle2=FindWindowA(0,"区号查询")
ll_winhandle3=FindWindowA(0,"办公电话查询")
ll_winhandle4=FindWindowA(0,"家庭电话查询")
ll_winhandle5=FindWindowA(0,"节日查询")
ll_winhandle6=FindWindowA(0,"闹钟服务")
If ll_winhandle1>0 or ll_winhandle2>0 or ll_winhandle3>0 or &
ll_winhandle4>0 or ll_winhandle5>0 or ll_winhandle6>0 Then
messagebox("提示","本程序已经运行了!")
Return
End If
Open(w_main)
在这段代码中FindWindowA()是一个关键函数,用于判断本程序是否已经运行,如果运行了那么就会弹出对话框进行提示,如果没有运行则运行。FindWindowA()函数的声明如下:
Function Ulong FindWindowA(Ulong classname, String windowname) Library "user32.dll"
2.同时删除多条记录
在如图2所示窗口的数据窗口中可以看出有几行记录被选中成为了反白显示,这时如果点击“删除”按钮,确认后被选中的记录将会被删除掉,这就是同时删除多条记录。为此可以在数据窗口控件的clicked事件中写入下面代码:

long therow,startrow,endrow
If KeyDown(KeyControl!) Then
If row>0 Then
this.SelectRow(row,TRUE)
Else
return
End If
ElseIf KeyDown(KeyShift!) Then
startrow=this.GetRow()
endrow=row
If startrow>endrow Then
For therow=startrow To endrow Step -1
this.SelectRow(therow,TRUE)
Next
Else
For therow=startrow To endrow
this.SelectRow(therow,TRUE)
Next
End If
Else
this.SelectRow(0,False)
End If
这样就可以通过按住Shift或Ctrl功能键来选中如图2所示数据窗口中的多行记录了。再来看“删除”按钮的代码:
integer i,m
m=0
long therow
IF dw_1.GetSelected
Row(0)<>0 THEN
Do
therow=dw_1.GetSelectedRow(therow - 1)
IF therow<>0 THEN
m=1
dw_1.DeleteRow(therow)
END IF
Loop While therow<>0
END IF
IF m=0 THEN
dw_1.DeleteRow(0)
END IF
可以看出第一个IF语句中使用了一个Do…Loop While循环来删除所有被选中的记录,而第二个IF语句则用来删除一条记录。
3.节日提醒和闹钟服务
要使用节日和闹钟的功能首先要对节日和时间作一些设置,好比是给闹钟定一个时;其次是本程序要一直处于运行状态,当然如果不用时可以把它最小化到系统托盘区,而不必关闭程序。这样当有提醒信息满足条件时就会有提醒窗口跳到桌面的最外层来显示了,同时程序会播放一个提示音,这个提示音是可以改变的,但在本程序中现在只支持WAV格式的声音文件。如果有兴趣的话还可以制作出自己的个性提示音来,比如:语音提醒。此功能的实现是通过窗口的timer事件来完成的,执行此事件的时间间隔写在了dhgl.ini文件中,如下:
[dhgl]
ycxs=0
time=58
58就是执行timer事件的时间间隔,它是以秒计算的,当然这个数不能大于60,如果大于60就可能会错过触发时间而导致提醒失效。
if string(today(),"mm/dd")=string(trim(s_yr),"@@/@@") and minute(now())=0 and mod(hour(now()),2)=0 then
openwithparm(w_tixing,"今天是: "+string(today(),"yyyy年mm月dd日")+"~r~n"+s_jr)
end if
minute(now())=0和mod(hour(now()),2)=0语句就限定了在日期满足的条件下还要在非奇数的整点触发,这一点读者可以根据自己的实际情况,制作出符合自己的提醒触发时间点。
另外,在制作此功能时还使用了PB中的数据存储,其代码如下:
long i,i_jr
string s_yr,s_jr
datastore lds_jr
lds_jr=Create datastore //建立数据存储
lds_jr.dataobject="d_jr"
lds_jr.Settransobject(SQLCA)
i_jr=lds_jr.Retrieve()
for i=1 to i_jr
s_yr=lds_jr.Getitemstring(i,"月日")
s_jr=lds_jr.Getitemstring(i,"节日")
if string(today(),"mm/dd")=string(trim(s_yr),"@@/@@") and minute(now())=0 and mod(hour(now()),2)=0 then
openwithparm(w_tixing,"今天是: "+string(today(),"yyyy年mm月dd日")+"~r~n"+" "+s_jr)
end if
next
destroy lds_jr
从这段程序可以看出,数据存储好像是一个不可视的数据窗口,定义之后和数据窗口控件一样也是把数据窗口对象赋予它,然后通过事务对象的数据库连接属性来访问和操作数据库中的数据。在这个地方也可以用数据窗口控件来实现上述功能,但可能会多占用系统资源,而使用数据存储后可以用destroy语句来删除数据存储以释放数据存储所占用的系统资源。
以上软件下载地址:http://www.cpcw.com/xz/45shenghuo.rar(由于下载用户过多,建议使用下载软件下载)
本程序可以最小化到系统托盘区功能的实现主要是使用了Windows系统中的API函数,具体的实现方法读者可以参看源程序代码。