中國最大的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();
}
}
}