中国最大的web开发资源网站及技术社区,
borland的c# builder是一个基于c#语言的编程工具,c# builder允许开发者用java或corba工具开发,c# builder同时也具有从多种数据库中读取数据的能力,可以混合和适应不同开发标准的能力。本文向大家介绍怎样用borland c# builder编写一个信箱监视程序, 程序主要是通过winsock来进行网络通信。要实现这个程序,应对pop3协议有一定的了解,下面是对pop3协议的一个粗略的介绍,读者可以参看rfc 1225更为详细地了解该协议。
一、pop3协议简单介绍
pop3服务器程序通常在tcp端口110提供服务。当客户想要使用服务时,它便与服务器建立一个tcp连接。一旦连接建立,pop3服务器就向客户发送一条欢迎消息。然后客户开始给服务器发送命令,服务器则给出相应的回答。pop3的命令由一个关键词或者关键词加参数组成。每个命令以回车换行(0xd0xa)作为结束标志。对于所有的命令,pop3服务器都会提供一个回答。服务器的回答由一个状态标志加一些附加信息组成。目前使用的两个标志是“+ok”和“-err”,分别表示客户的命令是否合法。所有的回答也是以回车换行结束。与本文讨论的话题相关的四个pop3命令是user、pass、stat和quit。
user命令
格式user name
其中name是用户在该pop3服务器上的用户标识。客户应该在接到服务器的欢迎消息后或者在上一个user或者pass失败之后可以发送此命令。
pass命令
格式pass string
其中string为该用户的密码。客户在发送了user命令并且收到了+ok的回答之后方可发送此命令。如果用户名和密码都正确,服务器回答+ok,否则-err。
stat命令
格式stat
stat命令来查看邮箱的情况。stat命令的回应中有两个数字,分别表示邮件的数量和邮件的大小。
quit命令
从pop3服务器上退出登录。
二、pop3信箱的监视程序分析
我们准备的做的程序要实现以下功能:
1.托盘图标,程序一运行,只显示一托盘图标,右键点击托盘图标可弹出菜单。
2.获取邮件数量,根据pop3协议,得到邮件的数量。
3.读取和写注册表,注册表中保存服务器、用户名、密码等设置。
4.用户提示信息,这里我们做一个与msn一样的提示窗口。
三、程序实现
下面我们就不妨着手我们的程序。首先,打开borland c# builder,新建一个项目,菜单 file->c# applicaion 项目的名称不妨设为"chkpop3",图示如下:
[ 相关贴图 ]
设计主窗口,如下图:
[ 相关贴图 ]
主要包括五个文本框,五个标签,三个按钮,一个选择框和一个timer。
winform设置如下:
text:收取邮件
startposition:centerscreen
maximizebox:false
三个按钮:
最小化按钮:最小化窗口,这里就是隐藏主窗口。
取邮件按钮:实现取得pop3信箱中的邮件数量,并用信息窗口提示。
应用按钮:保存设置到注册表中
timer1的功能:完成在一定时间间隔内取pop3信箱中邮件数量。
1.托盘的实现:
从tool palette选择组件contextmenu(加两个菜单项,设置和退出)、notifyicon(text设为:邮箱检测,图标icon选择一个16x16的小图标即可,contextmenu设为前面加入的contextmenu1,visible设为true) 这样一个完整的托盘程序就设好了。
2.用户提示信息的实现:
新建一窗口winform1,把窗体的formborderstyle属性设置为none(无边框模式),然后把topmost属性(总在最上方)属性设置为true,把showintaskbar属性(是否在 windows 任务栏中显示窗体)设置为false,并在窗体上加上一文字标签,将窗体的背景设置为你想要的图片和合适的大小。最后再放上三个timer控件,其中,timer1控制窗体滚出的动画,timer2控制窗体停留时间,timer3控制窗体的滚入动画,将它们的interval属性设置为10,如图:
[ 相关贴图 ]
winform1代码如下:
using system;
using system.drawing;
using system.collections;
using system.componentmodel;
using system.windows.forms;
using system.data;
namespace pop3
{
/// <summary>
/// summary description for winform1.
/// </summary>
public class winform1 : system.windows.forms.form
{
/// <summary>
/// required designer variable.
/// </summary>
private system.componentmodel.icontainer components;
private system.windows.forms.timer timer1;
private system.windows.forms.timer timer2;
private system.windows.forms.timer timer3;
private system.windows.forms.linklabel linklabel1;
public string str_num;
public winform1()
{
//
// required for windows form designer support
//
initializecomponent();
//
// todo: add any constructor code after initializecomponent call
//
}
/// <summary>
/// clean up any resources being used.
/// </summary>
protected override void dispose (bool disposing)
{
if (disposing)
{
if (components != null)
{
components.dispose();
}
}
base.dispose(disposing);
}
#region windows form designer generated code
/// <summary>
/// required method for designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void initializecomponent()
{
this.components = new system.componentmodel.container();
system.resources.resourcemanager resources = new system.resources.resourcemanager(typeof(winform1));
this.timer1 = new system.windows.forms.timer(this.components);
this.timer2 = new system.windows.forms.timer(this.components);
this.timer3 = new system.windows.forms.timer(this.components);
this.linklabel1 = new system.windows.forms.linklabel();
this.suspendlayout();
//
// timer1
//
this.timer1.interval = 10;
this.timer1.tick += new system.eventhandler(this.timer1_tick);
//
// timer2
//
this.timer2.interval = 10;
this.timer2.tick += new system.eventhandler(this.timer2_tick);
//
// timer3
//
this.timer3.interval = 10;
this.timer3.tick += new system.eventhandler(this.timer3_tick);
//
// linklabel1
//
this.linklabel1.autosize = true;
this.linklabel1.backcolor = system.drawing.color.whitesmoke;
this.linklabel1.location = new system.drawing.point(56, 56);
this.linklabel1.name = "linklabel1";
this.linklabel1.size = new system.drawing.size(79, 17);
this.linklabel1.tabindex = 0;
this.linklabel1.tabstop = true;
this.linklabel1.text = "您有新邮件!";
//
// winform1
//
this.autoscalebasesize = new system.drawing.size(6, 14);
this.backcolor = system.drawing.systemcolors.info;
this.backgroundimage = ((system.drawing.image)(resources.getobject("$this.backgroundimage")));
this.clientsize = new system.drawing.size(194, 122);
this.controls.add(this.linklabel1);
this.formborderstyle = system.windows.forms.formborderstyle.none;
this.name = "winform1";
this.showintaskbar = false;
this.text = "信息提示";
this.topmost = true;
this.load += new system.eventhandler(this.winform1_load);
this.activated += new system.eventhandler(this.winform1_activated);
this.resumelayout(false);
}
#endregion
private void winform1_load(object sender, system.eventargs e)
{
screen[] screens = screen.allscreens;
screen screen = screens[0];
this.location = new point(screen.workingarea.width - 200, screen.workingarea.height - 30);
this.timer2.interval = 5000;
}
private void scrollup()
{
if(height < 122)
{
this.height += 3;
this.location = new point(this.location.x, this.location.y - 3);
}
else
{
this.timer1.enabled = false;
this.timer2.enabled = true;
}
}
private void scrolldown()
{
if(height > 3)
{
this.height -= 3;
this.location = new point(this.location.x, this.location.y + 3);
}
else
{
this.timer3.enabled = false;
this.close();
}
}
private void timer1_tick(object sender, system.eventargs e)
{
scrollup();
}
private void timer2_tick(object sender, system.eventargs e)
{
timer2.enabled = false;
timer3.enabled = true;
}
private void timer3_tick(object sender, system.eventargs e)
{
scrolldown();
}
public void scrollshow()
{
this.width = 194;
this.height = 0;
this.show();
this.timer1.enabled = true;
}
private void winform1_activated(object sender, system.eventargs e)
{
linklabel1.text="您有"+str_num+"封新邮件!";
}
}
}
具体的实现,可以参考一下网上的一篇文章:《用vc#编写仿msn messager的滚动提示窗口》,已经记不清出处了,可以通过这个网http://yousoft.hi.com.cn/article_view.asp?id=6595浏览。
3.获取邮件数量的实现,代码见下:
string str_server;
if ((tb_server.text!="") && (tb_user.text!="") && (tb_pwd.text!=""))
{
tcpclient tcpc = new tcpclient(tb_server.text,110);
byte[] outbytes;
string input;
networkstream ns = null;
try{
ns = tcpc.getstream();
streamreader sr = new streamreader(ns);
tb_status.text=sr.readline();
input = "user " + tb_user.text + "/r/n";
outbytes = system.text.encoding.ascii.getbytes(input.tochararray());
ns.write(outbytes,0,outbytes.length)
tb_status.text=tb_status.text+"/r/n"+sr.readline();
input = "pass " + tb_pwd.text + "/r/n";
outbytes = system.text.encoding.ascii.getbytes(input.tochararray());
ns.write(outbytes,0,outbytes.length)
tb_status.text=tb_status.text+"/r/n"+sr.readline();
input = "stat" + "/r/n";
outbytes = system.text.encoding.ascii.getbytes(input.tochararray());
ns.write(outbytes,0,outbytes.length)
str_server=sr.readline();
str_num="";
if (str_server.startswith("+ok")){
str_num=str_server.split(' ')[1];
} else str_num="";
tb_status.text=tb_status.text+"/r/n"+"a:"+str_server;
input = "quit" + "/r/n";
outbytes = system.text.encoding.ascii.getbytes(input.tochararray());
ns.write(outbytes,0,outbytes.length)
tb_status.text=tb_status.text+"/r/n"+"b:"+sr.readline();
}
catch(invalidoperationexception ioe){
tb_status.text="could not connect to mail server";
}
if (str_num!="") {
winform1 form = new winform1();
form.str_num=str_num;
form.scrollshow();
}
程序与邮件服务器建立一个tcp连接,然后发送pop3的一些命令,取到服务器传回的信息,得到邮件的数量。
stat命令的回应中有两个数字,分别表示邮件的数量和邮件的大小。一般格式是这样的“+ok 数量 大小”
所以,只要根据服务器返回的信息,提取+ok,然后再按空格分隔得到数量。代码见上。
4.注册表的读写:
我们知道,要实现程序在开机后自己运行,可以通过写注册表hkey_current_user/software/microsoft/windows/currentversion/run实现
另外,为了方便用户,我们把邮件服务器,用户,密码等信息存入注册表,不用每次都再输一次。
保存信息代码如下:
registrykey rk;
registry.currentuser.createsubkey("software//yousoft");
rk=registry.currentuser.opensubkey("software//yousoft",true);
rk.setvalue("server",tb_server.text);
rk.setvalue("user",tb_user.text);
rk.setvalue("pwd",tb_pwd.text);
rk.setvalue("interval",tb_mins.text);
if (cb_autorun.checked) {
rk=registry.currentuser.opensubkey("software//microsoft//windows//currentversion//run",true);
rk.setvalue("chkmail",application.executablepath);
} else
{
rk=registry.currentuser.opensubkey("software//microsoft//windows//currentversion//run",true);
rk.deletevalue("chkmail");
}
rk.close();
启动程序时读入信息:
private void winform_load(object sender, system.eventargs e)
{
registrykey rk;
rk=registry.currentuser.opensubkey("software//yousoft",false);
object srv=rk.getvalue("server");
if (srv!=null) tb_server.text=srv.tostring();
object usr=rk.getvalue("user");
if (usr!=null) tb_user.text=usr.tostring();
object pwd=rk.getvalue("pwd");
if (pwd!=null) tb_pwd.text=pwd.tostring();
object mins=rk.getvalue("interval");
if (mins!=null) tb_mins.text=mins.tostring();
rk.close();
}
winform的完整代码如下:
using system;
using system.drawing;
using system.collections;
using system.componentmodel;
using system.windows.forms;
using system.data;
using system.net.sockets;
using system.io;
using system.net;
using microsoft.win32;
namespace pop3
{
/// <summary>
/// summary description for winform.
/// </summary>
public class winform : system.windows.forms.form
{
/// <summary>
/// required designer variable.
/// </summary>
private system.componentmodel.icontainer components;
private system.windows.forms.button button1;
private system.windows.forms.label label1;
private system.windows.forms.label label2;
private system.windows.forms.label label3;
private system.windows.forms.textbox tb_server;
private system.windows.forms.textbox tb_user;
private system.windows.forms.textbox tb_pwd;
private system.windows.forms.textbox tb_status;
private system.windows.forms.notifyicon notifyicon1;
private system.windows.forms.contextmenu contextmenu1;
private system.windows.forms.menuitem menuitem1;
private system.windows.forms.menuitem menuitem2;
private system.windows.forms.menuitem menuitem3;
private bool f_open=true;
private string str_num="";
private system.windows.forms.button button2;
private system.windows.forms.timer timer1;
private system.windows.forms.textbox tb_mins;
private system.windows.forms.label label4;
private system.windows.forms.label label5;
private system.windows.forms.button button3;
private system.windows.forms.checkbox cb_autorun;
public winform()
{
//
// required for windows form designer support
//
initializecomponent();
//
// todo: add any constructor code after initializecomponent call
//
}
/// <summary>
/// clean up any resources being used.
/// </summary>
protected override void dispose (bool disposing)
{
if (disposing)
{
if (components != null)
{
components.dispose();
}
}
base.dispose(disposing);
}
#region windows form designer generated code
/// <summary>
/// required method for designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void initializecomponent()
{
this.components = new system.componentmodel.container();
system.resources.resourcemanager resources = new system.resources.resourcemanager(typeof(winform));
this.button1 = new system.windows.forms.button();
this.label1 = new system.windows.forms.label();
this.label2 = new system.windows.forms.label();
this.label3 = new system.windows.forms.label();
this.tb_server = new system.windows.forms.textbox();
this.tb_user = new system.windows.forms.textbox();
this.tb_pwd = new system.windows.forms.textbox();
this.tb_status = new system.windows.forms.textbox();
this.notifyicon1 = new system.windows.forms.notifyicon(this.components);
this.contextmenu1 = new system.windows.forms.contextmenu();
this.menuitem1 = new system.windows.forms.menuitem();
this.menuitem2 = new system.windows.forms.menuitem();
this.menuitem3 = new system.windows.forms.menuitem();
this.button2 = new system.windows.forms.button();
this.timer1 = new system.windows.forms.timer(this.components);
this.tb_mins = new system.windows.forms.textbox();
this.label4 = new system.windows.forms.label();
this.label5 = new system.windows.forms.label();
this.button3 = new system.windows.forms.button();
this.cb_autorun = new system.windows.forms.checkbox();
this.suspendlayout();
//
// button1
//
this.button1.location = new system.drawing.point(152, 176);
this.button1.name = "button1";
this.button1.tabindex = 0;
this.button1.text = "取邮件";
this.button1.click += new system.eventhandler(this.button1_click);
//
// label1
//
this.label1.location = new system.drawing.point(24, 32);
this.label1.name = "label1";
this.label1.size = new system.drawing.size(80, 23);
this.label1.tabindex = 1;
this.label1.text = "邮件服务器:";
//
// label2
//
this.label2.location = new system.drawing.point(48, 64);
this.label2.name = "label2";
this.label2.size = new system.drawing.size(56, 23);
this.label2.tabindex = 2;
this.label2.text = "用户名:";
//
// label3
//
this.label3.location = new system.drawing.point(58, 96);
this.label3.name = "label3";
this.label3.size = new system.drawing.size(48, 23);
this.label3.tabindex = 3;
this.label3.text = "密码:";
//
// tb_server
//
this.tb_server.location = new system.drawing.point(112, 24);
this.tb_server.name = "tb_server";
this.tb_server.size = new system.drawing.size(176, 21);
this.tb_server.tabindex = 4;
this.tb_server.text = "";
this.tb_server.textchanged += new system.eventhandler(this.tb_pwd_textchanged);
//
// tb_user
//
this.tb_user.location = new system.drawing.point(112, 60);
this.tb_user.name = "tb_user";
this.tb_user.size = new system.drawing.size(176, 21);
this.tb_user.tabindex = 5;
this.tb_user.text = "";
this.tb_user.textchanged += new system.eventhandler(this.tb_pwd_textchanged);
//
// tb_pwd
//
this.tb_pwd.location = new system.drawing.point(112, 91);
this.tb_pwd.name = "tb_pwd";
this.tb_pwd.passwordchar = '*';
this.tb_pwd.size = new system.drawing.size(176, 21);
this.tb_pwd.tabindex = 6;
this.tb_pwd.text = "";
this.tb_pwd.textchanged += new system.eventhandler(this.tb_pwd_textchanged);
//
// tb_status
//
this.tb_status.location = new system.drawing.point(16, 208);
this.tb_status.multiline = true;
this.tb_status.name = "tb_status";
this.tb_status.size = new system.drawing.size(328, 80);
this.tb_status.tabindex = 7;
this.tb_status.text = "";
//
// notifyicon1
//
this.notifyicon1.contextmenu = this.contextmenu1;
this.notifyicon1.icon = ((system.drawing.icon)(resources.getobject("notifyicon1.icon")));
this.notifyicon1.text = "邮件检测";
this.notifyicon1.visible = true;
//
// contextmenu1
//
this.contextmenu1.menuitems.addrange(new system.windows.forms.menuitem[] {
this.menuitem1,
this.menuitem2,
this.menuitem3});
//
// menuitem1
//
this.menuitem1.index = 0;
this.menuitem1.text = "设置&s";
this.menuitem1.click += new system.eventhandler(this.menuitem1_click);
//
// menuitem2
//
this.menuitem2.index = 1;
this.menuitem2.text = "-";
//
// menuitem3
//
this.menuitem3.index = 2;
this.menuitem3.text = "退出&q";
this.menuitem3.click += new system.eventhandler(this.menuitem3_click);
//
// button2
//
this.button2.location = new system.drawing.point(48, 176);
this.button2.name = "button2";
this.button2.tabindex = 8;
this.button2.text = "最小化";
this.button2.click += new system.eventhandler(this.button2_click);
//
// timer1
//
this.timer1.interval = 5000;
this.timer1.tick += new system.eventhandler(this.timer1_tick);
//
// tb_mins
//
this.tb_mins.location = new system.drawing.point(112, 124);
this.tb_mins.name = "tb_mins";
this.tb_mins.size = new system.drawing.size(144, 21);
this.tb_mins.tabindex = 10;
this.tb_mins.text = "20000";
this.tb_mins.textchanged += new system.eventhandler(this.tb_pwd_textchanged);
//
// label4
//
this.label4.location = new system.drawing.point(32, 128);
this.label4.name = "label4";
this.label4.size = new system.drawing.size(72, 23);
this.label4.tabindex = 9;
this.label4.text = "时间间隔:";
//
// label5
//
this.label5.location = new system.drawing.point(264, 129);
this.label5.name = "label5";
this.label5.size = new system.drawing.size(40, 16);
this.label5.tabindex = 11;
this.label5.text = "毫秒";
//
// button3
//
this.button3.location = new system.drawing.point(264, 176);
this.button3.name = "button3";
this.button3.tabindex = 12;
this.button3.text = "应用";
this.button3.click += new system.eventhandler(this.button3_click);
//
// cb_autorun
//
this.cb_autorun.location = new system.drawing.point(112, 152);
this.cb_autorun.name = "cb_autorun";
this.cb_autorun.size = new system.drawing.size(160, 24);
this.cb_autorun.tabindex = 13;
this.cb_autorun.text = "启动时自动执行";
//
// winform
//
this.autoscalebasesize = new system.drawing.size(6, 14);
this.clientsize = new system.drawing.size(368, 301);
this.controls.add(this.cb_autorun);
this.controls.add(this.button3);
this.controls.add(this.label5);
this.controls.add(this.tb_mins);
this.controls.add(this.label4);
this.controls.add(this.button2);
this.controls.add(this.tb_status);
this.controls.add(this.tb_pwd);
this.controls.add(this.tb_user);
this.controls.add(this.tb_server);
this.controls.add(this.label3);
this.controls.add(this.label2);
this.controls.add(this.label1);
this.controls.add(this.button1);
this.icon = ((system.drawing.icon)(resources.getobject("$this.icon")));
this.maximizebox = false;
this.name = "winform";
this.startposition = system.windows.forms.formstartposition.centerscreen;
this.text = "收取邮件";
this.load += new system.eventhandler(this.winform_load);
this.activated += new system.eventhandler(this.winform_activated);
this.resumelayout(false);
}
#endregion
/// <summary>
/// the main entry point for the application.
/// </summary>
[stathread]
static void main()
{
application.run(new winform());
}
private void button1_click(object sender, system.eventargs e)
{
string str_server;
if ((tb_server.text!="") && (tb_user.text!="") && (tb_pwd.text!=""))
{
tcpclient tcpc = new tcpclient(tb_server.text,110);
byte[] outbytes;
string input;
networkstream ns = null;
try{
ns = tcpc.getstream();
streamreader sr = new streamreader(ns);
tb_status.text=sr.readline();
input = "user " + tb_user.text + "/r/n";
outbytes = system.text.encoding.ascii.getbytes(input.tochararray());
ns.write(outbytes,0,outbytes.length)
tb_status.text=tb_status.text+"/r/n"+sr.readline();
input = "pass " + tb_pwd.text + "/r/n";
outbytes = system.text.encoding.ascii.getbytes(input.tochararray());
ns.write(outbytes,0,outbytes.length)
tb_status.text=tb_status.text+"/r/n"+sr.readline();
input = "stat" + "/r/n";
outbytes = system.text.encoding.ascii.getbytes(input.tochararray());
ns.write(outbytes,0,outbytes.length)
str_server=sr.readline();
str_num="";
if (str_server.startswith("+ok")){
str_num=str_server.split(' ')[1];
} else str_num="";
tb_status.text=tb_status.text+"/r/n"+str_server;
input = "quit" + "/r/n";
outbytes = system.text.encoding.ascii.getbytes(input.tochararray());
ns.write(outbytes,0,outbytes.length)
tb_status.text=tb_status.text+"/r/n"+sr.readline();
}
catch(invalidoperationexception ioe){
tb_status.text="could not connect to mail server";
}
if (str_num!="") {
winform1 form = new winform1();
form.str_num=str_num;
form.scrollshow();
}
}
}
private void winform_activated(object sender, system.eventargs e)
{
if (f_open) {
this.hide();
f_open=false;
}
}
private void menuitem3_click(object sender, system.eventargs e)
{
this.close();
}
private void menuitem1_click(object sender, system.eventargs e)
{
this.show();
this.focus();
}
private void button2_click(object sender, system.eventargs e)
{
this.hide();
}
private void timer1_tick(object sender, system.eventargs e)
{
button1_click(sender,e);
}
private void tb_pwd_textchanged(object sender, system.eventargs e)
{
timer1.enabled=false;
if ((tb_server.text!="") && (tb_user.text!="") && (tb_pwd.text!=""))
{
timer1.interval=system.convert.toint32(tb_mins.text);
timer1.enabled=true;
} else
{
timer1.enabled=false;
}
}
private void button3_click(object sender, system.eventargs e)
{
registrykey rk;
registry.currentuser.createsubkey("software//yousoft");
rk=registry.currentuser.opensubkey("software//yousoft",true);
rk.setvalue("server",tb_server.text);
rk.setvalue("user",tb_user.text);
rk.setvalue("pwd",tb_pwd.text);
rk.setvalue("interval",tb_mins.text);
if (cb_autorun.checked) {
rk=registry.currentuser.opensubkey("software//microsoft//windows//currentversion//run",true);
rk.setvalue("chkmail",application.executablepath);
} else
{
rk=registry.currentuser.opensubkey("software//microsoft//windows//currentversion//run",true);
rk.deletevalue("chkmail");
}
rk.close();
}
private void winform_load(object sender, system.eventargs e)
{
registrykey rk;
rk=registry.currentuser.opensubkey("software//yousoft",false);
object srv=rk.getvalue("server");
if (srv!=null) tb_server.text=srv.tostring();
object usr=rk.getvalue("user");
if (usr!=null) tb_user.text=usr.tostring();
object pwd=rk.getvalue("pwd");
if (pwd!=null) tb_pwd.text=pwd.tostring();
object mins=rk.getvalue("interval");
if (mins!=null) tb_mins.text=mins.tostring();
rk.close();
}
}
}