关于作者

姓名:

性别:男

出生日期:--

地区:

联系电话:

QQ:--

婚否:保密
用户名:cyber2005
笔名:cyber2005
地区:
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

在线留言



朋友的blog

黑客安全网站

编程指导网站

jsp 网站

下载

项目

web2.0网站

IT业界网站

访问统计:
文章个数:209
评论个数:26
留言条数:6




Powered by BlogDriver 2.1

逸屋老鬼(QQ:84055177)的博客

 

欢迎访问逸屋老鬼(QQ:84055177)的博客

文章

出售各类smartphone,手机开发程序源码,价格面议

出售各类windows mobile程序,手机开发程序源码,价格面议

例如:ppc的签名程序,拍照录音,列表控件,gis,图表等开发代码 ,欢迎定购。价格面议:QQ:84055177

tel:13980565638

- 作者: cyber2005 2008年01月15日, 星期二 23:49  回复(0) |  引用(1) 加入博采

[MS Smartphone] Connection Manager Sample Code
/**********************************************************************************
*Function:GPRSConnect()
**Description:If there is active CMNET connection,no need to create CMNET connection again.
*If no active connection,then create a CMNET connection,
*Input:N/A
*Output:N/A
*Return:BOOL,TRUE-Success FALSE-FAILURE
*Others:None
***********************************************************************************/


BOOL GPRSConnect()
{

 int ret=CloseRasGPRSConnections();
 if(1==ret)
  return TRUE;
 else if(0==ret)
  return GPRSCmnetConnect();
 else
     return FALSE;
}

/**********************************************************************************
*Function:GPRSCmnetConnect()
*Description:Create CMNET GPRS connection
*Input:N/A
*Output:N/A
*Return:BOOL,TRUE-Success FALSE-FAILURE
*Others:None
***********************************************************************************/


BOOL GPRSCmnetConnect()
{
 HANDLE hConnection = NULL;

 DWORD   dwIndex  = 0;
 DWORD   dwResult = 0;
 DWORD   dwStatus = 0;
 BOOL   tResult   = FALSE;
 CONNMGR_CONNECTIONINFO sCI = { 0 };
 HRESULT hResult = S_OK;
   
 sCI.cbSize           = sizeof(sCI);
 sCI.dwParams         = CONNMGR_PARAM_GUIDDESTNET;
 sCI.dwFlags          = CONNMGR_FLAG_PROXY_HTTP | CONMGR_FLAG_PROXY_WAP | CONNMGR_FLAG_PROXY_SOCKS4 | CONNMGR_FLAG_PROXY_SOCKS5;      
 sCI.dwPriority       = CONNMGR_PRIORITY_USERINTERACTIVE;
 sCI.guidDestNet      = IID_DestNetInternet;

 if (FAILED(ConnMgrEstablishConnectionSync(&sCI, &hConnection, 30000, &dwStatus)))
 {
     return FALSE;
 }

 return TRUE;
}

/**********************************************************************************
*Function:ClosRasGPRSConnections()
*Description:If there is active CMNET connection,don't close it,because we need
*CMNET connection in our program.If there is active CMWAP connection,we disconnect it.
*Input:N/A
*Output:N/A
*Return:DWORD,0-no active connection(CMWAP),1-cmnet is active,-1-error happened
*Others:None
***********************************************************************************/

DWORD CloseRasGPRSConnections()
{
 int index; // An integer index
 DWORD dwError, dwRasConnSize, dwNumConnections; // Number of connections found
 RASCONN RasConn[20]; // Buffer for connection state data,Assume the maximum number of entries is 20.

 TCHAR CMNET[64]=_T("GPRS连接互联网");
 TCHAR CMWAP[64]=_T("移动梦网(GPRS)");


 // Assume no more than 20 connections.
 RasConn[0].dwSize = sizeof (RASCONN);
 dwRasConnSize = 20 * sizeof (RASCONN);

 

 // Find all connections.
 if (dwError = RasEnumConnections (RasConn, &dwRasConnSize,&dwNumConnections))
 {
  return -1;
 }

 
 // If there are no connections, return zero.
 if (!dwNumConnections)
 {
  return 0;
 }


 // Terminate all of the remote access connections.
 for (index = 0; index < (int)dwNumConnections; ++index)
 {
  
  if(!wcscmp(RasConn[index].szEntryName,CMWAP))
  {
   if (dwError = RasHangUp (RasConn[index].hrasconn))
    return -1;
   else
    return 0;  //successfully disconnect cmwap;
 
  }

  if(wcscmp(RasConn[index].szEntryName,CMNET)==0){
   return 1;
 
  }

 }

 return 0;
}



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=416676

- 作者: cyber2005 2007年03月7日, 星期三 15:54  回复(1) |  引用(0) 加入博采

如何读取smartphone 手机中的数据,比如短信,或电话簿等hdw191(小不懂)
如何读取smartphone 手机中的数据,比如短信,或电话簿等

我有别人的源代码, 但是他那个没有注释和文档,看得不怎么懂,在网上搜也搜不到,不知那位高人有没有这方面的资料借小弟看一下呀~ 他用的是这个COM接口: IPOutlookApp,IPOutlookItemCollection,还有IFloder等....有人知道么?

无聊客(yzx0023) 得分10

SDK 下面有sample的啊,文档看MSDN

小不懂(hdw191) 得分0

不是很想看msdn....汗...

雨霖(songtitan) 得分40

POOM API

自己去GOOGLE吧

小不懂(hdw191) 得分0

谢谢songtitan(雨霖)

知道了

- 作者: cyber2005 2007年03月6日, 星期二 15:25  回复(0) |  引用(1) 加入博采

Windows mobile 下读取手机SIM卡信息
最近在忙一个移动警务的项目,需要获取SIM卡的信息,来做身份的验证。考虑到获取:国际移动设备识别码(IMEI:International Mobile Equipment Identification Number)和国际移动用户识别码(IMSI:International Mobile Subscriber Identification Number),读取这两个号码用到TAPI的lineGetGeneralInfo()函。在新版的OpenNetCF里没有发现对这个函数的封装(也许我没找到),于是到网上找了找,找到一个以前版本OpenNetCF里的:TapiLib.dll,包含对Windows ce phone api 的封装(TAPI),综合网上的一些资料,实现代码如下:

public struct GeneralInfo
    {
        public string Manufacturer;
        public string Model;
        public string Revision;
        public string SerialNumber;
        public string SubscriberNumber;
    }
 
    /// <summary>
    /// Tapi控制类
    /// </summary>
    public class ControlTapi
    {
 
        [DllImport("cellcore.dll")]
        private static extern int lineGetGeneralInfo(IntPtr hLigne,byte[]lpLineGeneralInfo );
 
        /// <summary>
        /// 调用cellcore.dll获取sim卡的综合信息
        /// </summary>
        /// <param name="l"></param>
        /// <returns></returns>
        private  GeneralInfo GetGeneralInfo(Line l)
        {
            GeneralInfo lgi = new GeneralInfo();
            byte[] buffer = new byte[512];
            BitConverter.GetBytes(512).CopyTo(buffer, 0);
 
            if (lineGetGeneralInfo(l.hLine, buffer) != 0)
            {
                throw new System.ComponentModel.Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error(), "TAPI Error: " + System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString("X"));
            }
 
            int subscsize = BitConverter.ToInt32(buffer, 44);
            int subscoffset = BitConverter.ToInt32(buffer, 48);
            lgi.SubscriberNumber = System.Text.Encoding.Unicode.GetString(buffer, subscoffset, subscsize).ToString();
            lgi.SubscriberNumber = lgi.SubscriberNumber.Replace("\0", "");
            return lgi;
 
        }
 
       
 
        /// <summary>
        /// 获取sim卡的IMSI
        /// </summary>
        /// <returns></returns>
        public static string  GetIMSINumber()
        {
            string result = "";
            try
            {
                Tapi t = new Tapi();
                t.Initialize();
                Line l = t.CreateLine(0, LINEMEDIAMODE.INTERACTIVEVOICE, OpenNETCF.Tapi.LINECALLPRIVILEGE.MONITOR);
                ControlTapi ctapi = new ControlTapi();
                GeneralInfo gi = ctapi.GetGeneralInfo(l);
              
                result =  gi.SubscriberNumber;
                l.Dispose();
                t.Shutdown();
 
            }
            catch// (Exception ex)
            {
                result = "";
            }
 
            return result;
 
        }
 
        /// <summary>
        /// 获取IMEI的号码
        /// </summary>
        /// <returns></returns>
        public static string GetIMEINumber()
        {
            string result = "";
       &nbs;    try
            {
                Tapi t = new Tapi();
                t.Initialize();
                Line l = t.CreateLine(0, LINEMEDIAMODE.INTERACTIVEVOICE, OpenNETCF.Tapi.LINECALLPRIVILEGE.MONITOR);
                ControlTapi ctapi = new ControlTapi();
                GeneralInfo gi = ctapi.GetGeneralInfo(l);
                result = gi.SerialNumber;
                l.Dispose();
                t.Shutdown();
 
            }
            catch// (Exception ex)
            {
                result = "";
            }
 
            return result;
        }

    }

vb 的代码你可以去看看这里:http://www.peterfoot.net/RetrieveIMEIThroughTAPI.aspx

另:
1、环境:在vs2005+windows mobile 5.0 +多普达818测试通过。
2、
关于获取SIM卡的本机号码,你可以用:http://www.microsoft.com/china/msdn/archives/library/dnnetcomp/html/netcfPhoneAPI.asp,这里 提供的方法,不过这个方法需要安全认证,比较麻烦,具体认证的方式见:http://www.microsoft.com/china/MSDN/library/Mobility/pocketpc/2k3smartphonesecurity.mspx?pf=true
3、TapiLib.dll的下载地址:http://www.cnblogs.com/Files/xjb/TapiLib.rar
4、参考资料:
http://hucgy.bokee.com/3328836.html

- 作者: cyber2005 2007年03月6日, 星期二 14:51  回复(0) |  引用(1) 加入博采

前段时间看到有人问.net 2005怎么做.cab文件
本地MSDN 连接 ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_evtuv/html/36a418e2-ef99-4608-9258-11004c877891.htm

本演练演示如何使用 Visual Studio 2005 将应用程序及其资源打包到一个 CAB 文件中,以便可以将它部署到最终用户的智能设备上。

注意
显示的对话框和菜单命令可能会与帮助中的描述不同,具体取决于您的当前设置或版本。若要更改设置,请在“工具”菜单上选择“导入和导出设置”。有关更多信息,请参见 Visual Studio 设置。


在本演练中,您可以从任何用 Visual Basic 2005、Visual C# 2005 或 Visual C++ 2005 编写的智能设备解决方案开始。有关更多信息,请参见演练:创建简单应用程序。

本演练演示如何执行下列操作:

将一个 CAB 项目添加到解决方案中。

更改产品名称。

更改输出路径。

用应用程序的主输出填充 CAB 文件。

在必要时添加依赖项。

创建应用程序的快捷方式。

编辑注册表项。

先决条件
一个现有的智能设备解决方案。对于本打包演练,可以考虑创建并生成一个简单的项目,例如,演练:创建用于设备的 Windows 窗体应用程序中介绍的项目。

注意
显示的对话框和菜单命令可能会与帮助中的描述不同,具体取决于您的当前设置或版本。若要更改设置,请在“工具”菜单上选择“导入和导出设置”。有关更多信息,请参见 Visual Studio 设置。


安装 CAB 项目
为解决方案添加智能设备 CAB 项目
打开现有的智能设备项目,并确保“解决方案资源管理器”可见。

在“文件”菜单上指向“添加”,然后单击“新建项目”。

出现“添加新项目”对话框。

在左侧的“项目类型”窗格中展开“其他项目类型”节点,再单击“安装和部署”。

在右侧的“模板”窗格下选择“智能设备 CAB 项目”。

这是唯一可用于智能设备的 CAB 项目类型。其他项目类型仅用于桌面解决方案。

在“名称”框中,键入 CABProject,然后单击“确定”。

此 CAB 项目即会添加到您的解决方案,并显示在“解决方案资源管理器”中。现在显示“文件系统编辑器”的两个窗格。

自定义 CAB 项目
更改产品名称和其他项目属性
在“解决方案资源管理器”中选择“CABProject”(如果尚未选定)。

在“视图”菜单上单击“属性窗口”,或打开“属性”窗口。

在属性网格的“ProductName”字段中,将值更改为“MyProduct”。

“ProductName”属性的值决定了在文件夹名称和“添加/删除程序”对话框中为应用程序显示的名称。

还可以使用此窗口更改制造商的名称,以及指定允许的最低和最高操作系统版本。

可以将“OSVersionMin”属性设置为 4.21,以指示您的 Pocket PC 应用程序具有屏幕方向感知功能。但是,将此属性设置为 4.21 会阻止应用程序安装到基于 Windows Mobile 2003 或更早版本的 Pocket PC 上。若要允许在此类设备上安装该程序,并通知较新的设备该程序具有屏幕方向感知功能,则必须手动编辑 .inf 文件,将“BuildMax”属性设置为下列值之一:

0xA0000000,指示应用程序支持方形屏幕(240x240 像素)

0xC0000000,指示应用程序支持屏幕旋转

- 或 -

0xE0000000,指示应用程序支持方形屏幕和屏幕旋转。

有关更多信息,请参见 MSDN 白皮书“Developing Screen Orientation-Aware Applications”(开发识别屏幕方向的应用程序)。

对于基于 Windows Mobile 2003SE 和更早版本的 Pocket PC 解决方案,“Compress”属性和“NoUninstall Device Deployment”属性必须为 False。请注意,对于配备了 Compact Framework 2.0 的设备,此选项可以设置为 true。有关更多信息,请参见“智能设备 Cab 项目”->“属性”窗口。

如果您使用的是 Windows CE 安装程序 DLL,使用此属性网格可以指定文件名和位置。有关 Windows CE 安装程序 DLL 的更多信息,请参见 Pocket PC 或 Smartphone SDK 文档。

更改 CAB 文件的名称并添加身份验证
在“解决方案资源管理器”中右击“CABProject”,然后单击“属性”。

出现 CAB 项目的“属性页”对话框。在“输出文件名”框中,将 CAB 文件的名称和路径更改为 Debug\MyApp.cab,然后单击“确定”。

还可以使用此属性页为项目添加身份证。身份验证对于 Smartphone 解决方案是必需的,但是在基于 Windows Mobile 2003 SE 和更早版本的 Pocket PC 解决方案上,身份验证不受支持。有关更多信息,请参见设备项目中的安全性。

为 CAB 项目添加设备项目应用程序
在“文件系统编辑器”的左窗格中,选择“应用程序文件夹”节点,以指定下列步骤中选择的文件将安装到目标设备上的此文件夹中。

如果“文件系统”编辑器不可见,请在“解决方案资源管理器”中右击 CAB 项目名称,选择“视图”,再单击“文件系统”。

在 Visual Studio 中的“操作”菜单上指向“添加”,然后单击“项目输出”。

在“添加项目输出组”对话框中,从“项目”下拉列表中选择您的智能设备项目。

从输出列表中选择“主输出”,然后单击“确定”。

注意
为使用 C++ 编写的应用程序创建智能设备 CAB 项目时,如果要动态链接到 DLL,必须手动向 CAB 项目添加所有依赖项,如 atl80.dll、mfc80U.dll 和/或 msvcrt.dll。但是,为了减少 MFC/ATL DLL 的依赖项,强烈建议您使用静态链接。如果采用的是静态链接,则无需随同应用程序一起重新发布 DLL。如果采用的是动态链接,并需要在 CAB 中重新发布 DLL,请不要将 DLL 安装到设备上的系统目录(如 \windows)中,而应将 DLL 安装到本地应用程序目录中。如果重新发布一个应用程序套件,而套件中的所有应用程序都动态地链接到 ATL/MFC 运行库,建议您将所有应用程序和运行库 DLL 安装到一个单独的应用程序目录中,并为可以放置在其自己的文件夹中的应用程序提供快捷方式。这样可以避免发生系统目录中的 DLL 在以后被替换,从而破坏动态链接到这些 DLL 的任何应用程序的危险,同时还可以节省一些空间。


向 CAB 项目中添加依赖项(仅限 C++ 项目)
在“解决方案资源管理器”中右击 CAB 项目的名称,指向“添加”,再单击“文件”。

导航至 <Visual Studio 安装文件夹>\VC\ce\dll\armv4。

选择要添加的文件。

对于 MFC 项目,请按 Ctrl,再单击 MFC80U.DLL、atl80.dll 和 msvcrt80.dll。如果应用程序需要特定于 MFC 语言的资源,您可能还需要单击一个或多个特定于语言的 DLL。

对于 ATL 项目,请按 Ctrl,再单击 atl80.dll 和 msvcrt80.dll。如果 ATL 解决方案支持 MFC,还需要单击 MFC80U.DLL。

对于 Win32 项目,请单击 msvcrt80.dll。

在“添加文件”对话框中单击“打开”,将文件添加到 CAB 项目中。

在“文件系统编辑器”的左窗格中,右击“目标计算机上的文件系统”。

单击“添加特殊文件夹”,然后单击“Windows 文件夹”。

在“文件系统编辑器”的左窗格中,单击包含主输出的文件夹。默认情况下,DLL 已添加到与主输出相同的文件夹中。若要将这些 DLL 移动到 Windows 文件夹中,请在“文件系统编辑器”的中间窗格中选择这些文件,然后将它们拖到“Windows 文件夹”图标上。

使用相同的过程添加解决方案需要的其他任何依赖项。可以将依赖项添加到任何文件夹中;而不必将它们添加到“Windows”文件夹。

为设备项目应用程序创建快捷方式
在“文件系统编辑器”的右窗格中,选择“<your application project name> 的主输出”。

在“操作”菜单上选择“创建 <your application project name> 的主输出的快捷方式”。

此命令将在“输出”项的下面添加一个快捷方式项。

右击该快捷方式项,单击“重命名”,将此快捷方式重命名为适用于快捷方式的内容。

添加注册表项
在“解决方案资源管理器”中选择 CAB 项目。

在“视图”菜单上指向“编辑器”,然后单击“注册表”。

在“注册表编辑器”中,右击 HKEY_CURRENT_USER,然后单击快捷菜单上的“新建项”。

当“注册表编辑器”中显示“新建项”项时,将其重命名为“SOFTWARE”。

右击此新项,指向“新建”,然后单击“项”。

当“注册表编辑器”中显示“新建项”项时,将其重命名为“MyCompany”。

右击“MyCompany”项,再单击快捷菜单上的“属性窗口”。

“名称”值已更改为“MyCompany”。

生成和部署 CAB 文件
生成 CAB 文件
在“生成”菜单上单击“生成 CABProject”。

- 或 -

在“解决方案资源管理器”中右击“CABProject”,再单击“生成”。

在“文件”菜单上单击“全部保存”。

Smartphone 解决方案的 CAB 文件在部署到最终用户的设备上之前必须进行数字签名。基于 Windows Mobile 2003SE 和更早版本的 Pocket PC 解决方案不支持数字签名。有关更多信息,请参见如何:对 CAB 文件进行签名(设备)。

将 CAB 文件部署到设备上
在“Windows 资源管理器”中定位到存储此解决方案的文件夹。可以在解决方案的“CABProject\Release”文件夹中找到此 CAB 文件。

将 CAB 文件复制到与 ActiveSync 4.0 或更高版本连接的设备上。

当用户在设备上的“资源管理器”中点击此 CAB 文件名时,Windows CE 将解开该 CAB,并将应用程序安装到设备上。

有关更多信息,请参见 Smartphone 和 Pocket PC SDK 文档。

- 作者: cyber2005 2007年02月7日, 星期三 11:18  回复(0) |  引用(1) 加入博采

监视来到的短消息例子。

这个例子是按照监视来到的短消息,然后按照提取短消息的内容,我们可以按照里面的内容
让程序做些动作,本个例子是发送你的未读的SMS,MAIL,MMS的数量,由此可以推开得到一些
其他的应用。。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.WindowsMobie.PocketOutlook;
using Microsoft.WindowsMobile;
using Microsoft.WindowsMobile.Telephony;
using Microsoft.WindowsMobile.PocketOutlook.MessageInterception;
using Microsoft.WindowsMobile.Status;
//using Microsoft.WindowsMobile.Status.SystemState;

namespace AppDemo
{
public partial class Form1 : Form
{
private OutlookSession AppSession;
private OutlookSession SmsSession;
private AppointmentCollection AppAppts;
private ListViewItem lviAppt;
private ListViewItem smsItem;
private MessageInterceptor interceptor;
public Form1()
{
InitializeComponent();
interceptor
= new MessageInterceptor(InterceptionAction.Notify);
interceptor.MessageReceived
+= new MessageInterceptorEventHandler(interceptor_MessageReceived);
}


private void button1_Click(object sender, EventArgs e)
{
AppSession
= new OutlookSession();
AppAppts
= AppSession.Appointments.Items;
foreach (Appointment appt in AppAppts)
{
lviAppt
= new ListViewItem();
lviAppt.Text
= appt.Start.ToShortDateString();
lviAppt.SubItems.Add(appt.Start.ToShortTimeString());
lviAppt.SubItems.Add(appt.Subject);
lvAppt.Items.Add(lviAppt);
}

AppSession.Dispose();
}


private void button2_Click(object sender, EventArgs e)
{
Phone phone
= new Phone();
try
{
phone.Talk(
13425173242);
}

catch
{
MessageBox.Show(
Can’t Dailing…);
}

}


private void button3_Click(object sender, EventArgs e)
{
SmsSession
= new OutlookSession();

//SmsAccount sms ;
smsItem = new ListViewItem();
smsItem.Text
= (String)SmsSession.SmsAccount.Name;
lvAppt.Items.Add(smsItem);
}


private void button4_Click(object sender, EventArgs e)
{
if (btnActivate.Text.IndexOf(Activate) != -1)
{
interceptor
= new MessageInterceptor(InterceptionAction.Notify);
interceptor.MessageReceived
+= new MessageInterceptorEventHandler(interceptor_MessageReceived);
btnActivate.Text
= Deactivate;
}


if (btnActivate.Text.IndexOf(Deactivate) != -1)
{
interceptor.Dispose();
interceptor
= null;
btnActivate.Text
= Activate;
}

interceptor_MessageReceived((
object)sender ,( MessageInterceptorEventArgs )e );
}




void interceptor_MessageReceived(object sender, MessageInterceptorEventArgs e)
{
SmsMessage sms
= (SmsMessage)e.Message;
string strFrom = sms.From.Address;
string strMessageText = sms.Body.Trim().ToLower();
bool bGotCommand = false;
string strReplyMessage = “”;

switch (strMessageText)
{
case getunreadsms:
strReplyMessage
= Unread SMS: +SystemState.MessagingSmsUnread;
bGotCommand
= true;
break;

case getunreademail:
strReplyMessage
= Unread Email: +SystemState.MessagingTotalEmailUnread;
bGotCommand
= true;
break;

case getunreadmms:
strReplyMessage
= Unread MMS: +SystemState.MessagingMmsUnread;
bGotCommand
= true;
break;
}


if (bGotCommand == true)
{
SmsMessage replySMS
= new SmsMessage();
replySMS.To.Add(
new Recipient(strFrom));
replySMS.Body
= strReplyMessage;
replySMS.Send();
}

}


}


}

- 作者: cyber2005 2007年02月7日, 星期三 11:03  回复(0) |  引用(1) 加入博采

共享一段自己琢磨着写的发送短消息的源码
以下是VC# 源码,我的编译环境是 VS2005 中文版本. Windows Mobile 5.0 Pocket PC



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////





using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.WindowsMobile.PocketOutlook;

namespace PhoneTools
{
    public partial class Smsform : Form
    {
        //创建新的邮件服务
        OutlookSession m_outlookSession;

        public Smsform()
        {
            InitializeComponent();

            m_outlookSession = new OutlookSession();
        }

        private void m_txtMesage_TextChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                //创建新的短消息服务
                SmsMessage hobirSms = new SmsMessage(
                    "13999999999",
                    m_txtMesage.Text);
                // 使用OutlookSession中的SMS帐户进行发送
                m_outlookSession.SmsAccount.Send(hobirSms);

                //向用户提示发送成功信息
                MessageBox.Show(
                    "Your message has been sent.",
                    "Send",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Asterisk,
                    MessageBoxDefaultButton.Button1);

                //关闭当前窗口
                Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    String.Format("Error: {0}", ex.Message),
      nbsp;             "Send",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Hand,
                    MessageBoxDefaultButton.Button1);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //清空文本
            m_txtMesage.Text = String.Empty;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //关闭该窗口
            Close();
        }
    }
}

- 作者: cyber2005 2007年02月7日, 星期三 10:54  回复(0) |  引用(1) 加入博采

NHibernate简介

什么是NHibernate?
NHibernate是一个基于.Net,用于关系数据库的对象持久化类库.它是著名的Hibernate的.Net版本.
NHibernate用于把你的.Net对象持久化到底层的关系数据库中.你完全不用自己编写Sql语句去操作这些对象,NH会代替你做.你的代码里面只需要关心这些对象,NH生成sql语句并能为你取到正确的东西.
开发过程
HNibernate将会有一些工具帮助你,如:生成schema,根据映射文件(Mapping file)生成类,并更新schema(一个新开发者的建议).然而,在本文档中,前提是你已经手动的数据库的创建喝.Net类的编写...
这里是我们要做的:
 
1.       在数据库中创建把.Net类持久化的对应表.
2.       创建需要被持久化的.Net类.
3.       创建映射文件,以告诉NH怎样持久化这些类的属性.
4.       创建NH的配置文件,以告诉NH怎样连接数据库.
5.       使用NH提供的API.
 
步骤1:创建数据库表
我们正在做的是一个非常简单的NH示例.在这个例子里面,我们实现一个基本的用户管理子系统.我们将会使用一个user表(sql server 2000):
 
use NHibernate
go
 
CREATE TABLE users (
  LogonID varchar(20) NOT NULL default '0',
  Name varchar(40) default NULL,
  Password varchar(20) default NULL,
  EmailAddress varchar(40) default NULL,
  LastLogon datetime default NULL,
  PRIMARY KEY  (LogonID)
)
go
 
我使用的是MS Sql Server 2000,但是如果你找到一个任何数据库的.net Data Provider驱动,你可以使用任何数据库.
 
步骤2:创建.Net类:
当我们这样一堆的用户的时候,我们需要某种对象来保存.NH是通过reflection对象的属性来工作的,所以我们给需要持久化的对象添加属性.一个对应于上面数据库结构的类可以写成这个样子:
 
using System;
 
namespace NHibernate.Demo.QuickStart
{
       public class User
       {
              private string id;
              private string userName;
              private string password;
              private string emailAddress;
              private DateTime lastLogon;
 
 
              public User()
              {
              }
 
              public string Id 
              {
                     get { return id; }
                     set { id = value; }
              }
 
              public string UserName 
              {
                     get { return userName; }
                     set { userName = value; }
              }
 
              public string Password 
              {
                     get { return password; }
                     set { password = value; }
              }
 
              public string EmailAddress 
              {
       &nbp;             get { return emailAddress; }
                     set { emailAddress = value; }
              }
 
              public DateTime LastLogon 
              {
                     get { return lastLogon; }
                     set { lastLogon = value; }
              }
              
       }
}
 
在上面的代码里面,我们把属性和构造函数写成了public-NH并不要求一定要这样做.你可以使用public,protected,internal或者干脆private来标记你的属性.
 
步骤3:编写映射文件(Mapping File)
现在我们有了数据库表和.Net类,我们还需要告诉NH怎样在数据库和类之间映射.这就需要映射文件了.最简捷(也是可维护性最好的)方法就是为每一个类编写一个映射文件,如果你把命名为"XXX.hbm.xml"的映射文件和XXX类文件放在同一目录下,NH会很让 一切变得很轻松.这儿,我们的User.hbm.xml可能会像这样:
<?xml version="1.0" encoding="utf-8" ?> 


<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">


    <class name="NHibernate.Demo.QuickStart.User, NHibernate.Demo.QuickStart" table="users">

              <id name="Id" column="LogonId" type="String(20)">

                     <generator class="assigned" />

              </id>

              <property name="UserName" column="Name" type="String(40)"/>

              <property name="Password" type="String(20)"/>

              <property name="EmailAddress" type="String(40)"/>

              <property name="LastLogon" type="DateTime"/>

       </class>

</hibernate-mapping>
让我们来看看这个有趣的映射文件:第一个tag是class,这里我们把类型名(类名和Assembly名)映射到数据库中的user表(这里和hibernate有些不同,我们必须告诉NH这个类从哪儿来的.这个差异是由.Net和Java Reflect机制的不同引起的-zyyang).这种情况下,我们是从Assembly NHibernate.Demo.QuickStart中载入NHibernate.Demo.QuickStart.User类..NH遵守.Net Framework使用Reflection载入类型的规则-所以遇到什么疑惑,就去查查.NET Framework SDK. 
让我们暂时跳过"id" tag,先说property节点."name"属性值就是我们写的.Net类中的属性,column属性值就是在数据库中与'Net类属性对应的字段名.type属性是可选的(如果你没有标明,NH会给出一个最适合的),但是推荐的做法是带上这个属性.hibernate用户会注意到,在type属性值里,我们给出了长度值,这是因为ADO.NET需要这样做.
让我们返回到"id" tag,你可能会猜想这个tag和映射到表的Primary Key有关.正确.ID  tag的格式和Property tag的相似.我们从Property(name)映射到目标数据库的字段(colume).
这些嵌入的Generator标记告诉NH怎样生成Primary Key(NH很方便的就能给你生成一个,不管是什么类型的,只要你告诉它怎样去做).在我们举的例子中,把它设置成"assigned",意思是"我们的对象将自己生成key"(User对象将总是需要一个UserID),如果你乐意让NH代替你生成,你会对uuid.hex和uuid.string类感兴趣的(参看chm文档).
Tip:如果你使用vs.net编译,设置Build Action,把User.hbm.xml文件作为资源绑定到Asssembly,这样映射文件就成了Asssembly的一部分了.后面我们会明白这个步骤的重要性.
 
步骤4:创建数据库配置文件
目前为止,我们还没有告诉NH到哪儿去找数据库.最直接的方法就是在你程序的配置文件中给NH一个部分,就是这样:
<?xml version="1.0" encoding="utf-8" ?>

<configuration>

     <configSections>

               <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />

       </configSections>

       <nhibernate>

              <add key="hibernate.connection.provider"value="NHibernate.Connection.DriverConnectionProvider" />

              <add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect" />

              <add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />

              <add key="hibernate.connection.connection_string" value="Server=localhost;initial catalog=nhibernate;User ID=someuser;Password=somepwd;Min Pool Size=2" />

       </nhibernate>

</configuration>
上面的例子中使用SqlClient驱动,连接到本地的nhibernate数据库,并且使用提供的用户和密码.还会有其他的配置项,你可以参看文档.
 
步骤5:开始体验NHibernate的神奇
所有艰苦的工作已经做完了.如果所有的工作完成后,你将会有这些成果:
æ         User.cs - 需要持久化的.Net类.
æ         User.hbm.xml - 映射文件
æ         app.config - 带有Ado.net连接信息的配置文件(你也可以在代码中指定的)
æ         一个叫做user的数据库表.
 
在代码里面使用NHibernate是很简单的事情:
1.       创建一个Configuration对象.
2.       告诉Configuration你想要持久化哪一种对象.
3.       创建一个Session连接到你设定的数据库.
4.       载入,保存和查询你的对象.
5.       Flush()你的Session
 
好,让我们来看看一些代码:
 
创建一个Configuration对象....
Configuration对象知道所有在.Net类和后端数据库之间的映射关系,
 
Configuration cfg = new Configuration();
cfg.AddAssembly("NHibernate.Demo.QuickStart");
 
Configuration对象会查找这个Assembly中所有以.hbm.xml结尾的文件.也有其他的方法添加映射文件这个可能是最简单的一个.
 
创建一个Session对象.......
ISession对象代表着一个到后端数据库连接,ITransaction代表一个NHibernate管理的事务(Transaction).
 
ISessionFactory factory = cfg.BuildSessionFactory();
ISession session = factory.OpenSession();
ITransaction transaction = session.BeginTransaction();
 
载入,保存和查询你的对象......
 
现在你可以以.net的方式对待这些对象.想在数据库中保存一个新的user?只需要:
 
User newUser = new User();
newUser.Id = "joe_cool";
newUser.UserName = "Joseph Cool";
newUser.Password = "abc123";
newUser.EmailAddress = "joe@cool.com";
newUser.LastLogon = DateTime.Now;
              
// Tell NHibernate that this object should be saved
session.Save(newUser);
 
// commit all of the changes to the DB and close the ISession
transaction.Commit();
session.Close();
 
这就是NH的好处,大部分时间内你只用关心你的业务对象(BO).
 
假如你需要根据已经知道的user ID查询一个对象,如果session是open的,你只需要一行:
 
// open another session to retrieve the just inserted user
session = factory.OpenSession();
User joeCool = (User)session.Load(typeof(User), "joe_cool");
 
这样你又会得到这个对象,设置一下对象的属性,它会在下一次Flush()方法出现的时候被持久化到数据库.
 
// set Joe Cool's Last Login property
joeCool.LastLogon = DateTime.Now;
 
// flush the changes from the Session to the Database
session.Flush();
 
让NH去写入你对对象作出的修改,你只需要Flush Session就可以了.
 
更好的是,你可以从数据库中查询到一个System.Collections.IList:
 
IList userList = session.CreateCriteria(typeof(User)).List();
foreach(User user in userList)
{
       Console.WriteLine(user.Id + " last logged in at " + user.LastLogon);
}
 
这个查询会返回整个表的内容.尤其是当你想要更多的控制时候--像类出所有在March 14, 2004 10:00 PM之后登陆过的用户,你可以:
 
IList recentUsers = session.CreateCriteria(typeof(User)).Add(Expression.Gt("LastLogon", new DateTime(2004, 03, 14, 20, 0, 0))).List();
foreach(User user in recentUsers)
{
       Console.WriteLine(user.Id + " last logged in at " + user.LastLogon);
}
 
文档里还有很多的查询选项,但是以上这些足够让你看出Hinernate的力量了.
不要忘记了,最后要关掉你的Session.
 
// tell NHibernate to close this Session
session.Close();

- 作者: cyber2005 2007年02月7日, 星期三 10:50  回复(0) |  引用(1) 加入博采

认识Web.config文件

认识Web.config文件

Web.config文件是一个XML文本文件,它用来储存 ASP.NET Web 应用程序的配置信息(如最常用的设置ASP.NET Web 应用程序的身份验证方式),它可以出现在应用程序的每一个目录中。当你通过.NET新建一个Web应用程序后,默认情况下会在根目录自动创建一个默认的
Web.config文件,包括默认的配置设置,所有的子目录都继承它的配置设置。如果你想修改子目录的配置设置,你可以在该子目录下新建一个Web.config文件。它可以提供除从父目录继承的配置信息以外的配置信息,也可以重写或修改父目录中定义的设置。

在运行时对Web.config文件的修改不需要重启服务就可以生效(注:<processModel> 节例外)。当然Web.config文件是可以扩展的。你可以自定义新配置参数并编写配置节处理程序以对它们进行处理。

web.config文件详解

web.config配置文件(默认的配置设置)以下所有的代码都应该位于

<configuration>
<system.web>

</system.web>
</configuration>

之间,出于学习的目的下面的示例都省略了这段XML标记。

1、<authentication> 节
作用:配置 ASP.NET 身份验证支持(为Windows、Forms、PassPort、None四种)。该元素只能在计算机、站点或应用程序级别声明。<authentication> 元素必需与<authorization> 节配合使用。
示例:
以下示例为基于窗体(Forms)的身份验证配置站点,当没有登陆的用户访问需要身份验证的网页,网页自动跳转到登陆网页。

<authentication mode="Forms" >
<forms loginUrl="logon.aspx" name=".FormsAuthCookie"/>
</authentication>

其中元素loginUrl表示登陆网页的名称,name表示Cookie名称。

2、<authorization> 节
作用:控制对 URL 资源的客户端访问(如允许匿名用户访问)。此元素可以在任何级别(计算机、站点、应用程序、子目录或页)上声明。必需与<authentication> 节配合使用。
示例:以下示例禁止匿名用户的访问

<authorization>
  <deny users="?"/>
</authorization>

注:你可以使用user.identity.name来获取已经过验证的当前的用户名;可以使用
web.Security.FormsAuthentication.RedirectFromLoginPage方法将已验证的用户重定向到用户刚才请求的页面.具体的实例请参考:
Forms验证 http://www.fanvb.net/websample/dataauth.aspx

3、<compilation>节
作用:配置 ASP.NET 使用的所有编译设置。默认的debug属性为“True”.在程序编译完成交付使用之后应将其设为False(Web.config文件中有详细说明,此处省略示例)

4、<customErrors>
作用:为 ASP.NET 应用程序提供有关自定义错误信息的信息。它不适用于 XML Web services 中发生的错误。
示例:当发生错误时,将网页跳转到自定义的错误页面。

<customErrors defaultRedirect="ErrorPage.aspx" mode="RemoteOnly">
</customErrors>

其中元素defaultRedirect表示自定义的错误网页的名称。mode元素表示:对不在本地 Web 服务器上运行的用户显示自定义(友好的)信息。

5、<httpRuntime>节
作用:配置 ASP.NET HTTP 运行库设置。该节可以在计算机、站点、应用程序和子目录级别声明。
示例:控制用户上传文件最大为4M,最长时间为60秒,最多请求数100

<httpRuntime maxRequestLength="4096" executionTimeout="60" appRequestQueueLimit="100"/>

6、 <pages>
作用:标识特定于页的配置设置(如是否启用会话状态、视图状态,是否检测用户的输入等)。<pages>可以在计算机、站点、应用程序和子目录级别声明。
示例:不检测用户在浏览器输入的内容中是否存在潜在的危险数据(注:该项默认是检测,如果你使用了不检测,一要对用户的输入进行编码或验证),在从客户端回发页时将检查加密的视图状态,以验证视图状态是否已在客户端被篡改。(注:该项默认是不验证)

<pages buffer="true" enableViewStateMac="true" validateRequest="false"/>

7、<sessionState>
作用:为当前应用程序配置会话状态设置(如设置是否启用会话状态,会话状态保存位置)。
示例:

<sessionState mode="InProc" cookieless="true" timeout="20"/>
</sessionState>

注:
mode="InProc"表示:在本地储存会话状态(你也可以选择储存在远程服务器或SAL服务器中或不启用会话状态)
cookieless="true"表示:如果用户浏览器不支持Cookie时启用会话状态(默认为False)
timeout="20"表示:会话可以处于空闲状态的分钟数

8、<trace>
作用:配置 ASP.NET 跟踪服务,主要用来程序测试判断哪里出错。
示例:以下为Web.config中的默认配置:

<trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />

注:
enabled="false"表示不启 用跟踪;
requestLimit="10"表示指定在服务器上存储的跟踪请求的数目
pageOutput="false"表示只能通过跟踪实用工具访问跟踪输出;
traceMode="SortByTime"表示以处理跟踪的顺序来显示跟踪信息
localOnly="true" 表示跟踪查看器 (trace.axd) 只用于宿主 Web 服务器

自定义Web.config文件配置

自定义Web.config文件配置节过程分为两步。
1.在在配置文件顶部 <configSections> 和 </configSections>标记之间声明配置节的名称和处理该节中配置数据的 .NET Framework 类的名称。
2.是在 <configSections> 区域之后为声明的节做实际的配置设置。
示例:创建一个节存储数据库连接字符串

<configuration>
  <configSections>
  <section name="appSettings" type="System.Configuration.NameValueFileSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</configSections>
  <appSettings>
   <add key="scon" value="server=a;database=northwind;uid=sa;pwd=123"/>
  </appSettings>
  <system.web>
   ......
  </system.web>
</configuration>

访问Web.config文件

你可以通过使用ConfigurationSettings.AppSettings 静态字符串集合来访问 Web.config 文件示例:获取上面例子中建立的连接字符串。例如:

protected static string Isdebug = ConfigurationSettings.AppSettings["debug"]



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=624798

- 作者: cyber2005 2007年02月1日, 星期四 10:41  回复(0) |  引用(0) 加入博采

C#实现对Word、Excel等的模版定制
C#实现对Word文件读写

        手头上的一个项目报表相对比较简单,所以报表打印采用VBA引擎,通过定制Word模版,然后根据模版需要填充数据,然后OK,打印即可。

实现方法:首先需要引用VBA组建,我用的是Office2003 Professional,Dll版本号为Microsoft Word11.0


另外当然还需要引用Interop.Word.Dll.

代码如下:
///#region 打开Word文档,并且返回对象wDoc,wDoc
/// 
/// 打开Word文档,并且返回对象wDoc,wDoc
/// 
/// 完整Word文件路径+名称 
/// 返回的Word.Document wDoc对象
/// 返回的Word.Application对象
public static void CreateWordDocument(string FileName,ref Word.Document wDoc,ref Word.Application WApp)
{
if(FileName == ""return;
Word.Document thisDocument 
= null;
Word.FormFields formFields 
= null;
Word.Application thisApplication 
= new Word.ApplicationClass();
thisApplication.Visible 
= true;
thisApplication.Caption 
= "";
thisApplication.Options.CheckSpellingAsYouType 
= false;
thisApplication.Options.CheckGrammarAsYouType 
= false;

Object filename 
= FileName;
Object ConfirmConversions 
= false;
Object ReadOnly 
= true;
Object AddToRecentFiles 
= false;

Object PasswordDocument 
= System.Type.Missing;
Object PasswordTemplate 
= System.Type.Missing;
Object Revert 
= System.Type.Missing;
Object WritePasswordDocument 
= System.Type.Missing;
Object WritePasswordTemplate 
= System.Type.Missing;
Object Format 
= System.Type.Missing;
Object Encoding 
= System.Type.Missing;
Object Visible 
= System.Type.Missing;
Object OpenAndRepair 
= System.Type.Missing;
Object DocumentDirection 
= System.Type.Missing;
Object NoEncodingDialog 
= System.Type.Missing;
Object XMLTransform 
= System.Type.Missing;

try
{
Word.Document wordDoc 
=
thisApplication.Documents.Open(
ref filename, ref ConfirmConversions,
ref ReadOnly, ref AddToRecentFiles, ref PasswordDocument, ref PasswordTemplate,
ref Revert,ref WritePasswordDocument, ref WritePasswordTemplate, ref Format,
ref Encoding, ref Visible, ref OpenAndRepair, ref DocumentDirection,
ref NoEncodingDialog, ref XMLTransform );

thisDocument 
= wordDoc;
wDoc 
= wordDoc;
WApp 
= thisApplication;
formFields 
= wordDoc.FormFields;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}

}
#endregion

调用上面静态方法,打开目标文件并且把DataGrid中数据填充到对应Word标签中去
///#region Word填充数据(For Example)
/// 
/// Word填充数据
/// 
private void WordLoadData()
{
Word.Document wDoc
=null;
Word.Application wApp
=null;
sysFun.CreateWordDocument(
"E:\\监测报告(new).dot",ref wDoc,ref wApp);

//对标签"C"进行填充
object bkmC="C";
if(wApp.ActiveDocument.Bookmarks.Exists("C"== true{
wApp.ActiveDocument.Bookmarks.get_Item
(
ref bkmC).Select();
}
wApp.Selection.TypeText(
this.txt1.Text);
object bkmG = "TWaterTable3";
object unit; 
object count; //移动数
object extend; 


extend 
= Word.WdMovementType.wdExtend;
unit 
= Word.WdUnits.wdCell;
//把DataGrid中数据填充到标签TWaterTable3上
if(wApp.ActiveDocument.Bookmarks.Exists("TWaterTable3"== true)
{
wApp.ActiveDocument.Bookmarks.get_Item
(
ref bkmG).Select();

for(int i=0;i {
if(i==0)
{
count
=1;
}
else
{
count
=0;
}
//需填充5列数据
wApp.Selection.Move(ref unit,ref count);
wApp.Selection.TypeText(gridEX1.GetRow(i).Cells[
0].Text);
count
=1;

wApp.Selection.Move(
ref unit,ref count);
wApp.Selection.TypeText(gridEX1.GetRow(i).Cells[
1].Text);

wApp.Selection.Move(
ref unit,ref count);
wApp.Selection.TypeText(gridEX1.GetRow(i).Cells[
2].Text);

wApp.Selection.Move(
ref unit,ref count);
wApp.Selection.TypeText(gridEX1.GetRow(i).Cells[
3].Text);

wApp.Selection.Move(
ref unit,ref count);
wApp.Selection.TypeText(gridEX1.GetRow(i).Cells[
4].Text);
//换行
wApp.Selection.MoveRight(ref unit,ref count,ref extend);
}
}
}
#endregion

然后就OK了,在对标签表控制要注意列循环和换行.

C#操作Excel(导入导出)

 

有很多朋友说需要C#导出到Excel的代码,现共享给大家

/// 
/// 读取Excel文档
/// 
/// 文件名称
/// 返回一个数据集
public DataSet ExcelToDS(string Path)
{
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" +"Data Source="+ Path +";"+"Extended Properties=Excel 8.0;";
OleDbConnection conn 
= new OleDbConnection(strConn);
conn.Open(); 
string strExcel = ""
OleDbDataAdapter myCommand 
= null;
DataSet ds 
= null;
strExcel
="select * from [sheet1$]";
myCommand 
= new OleDbDataAdapter(strExcel, strConn);
ds 
= new DataSet();
myCommand.Fill(ds,
"table1"); 
return ds;
}


/// 
/// 写入Excel文档
/// 
/// 文件名称
public bool SaveFP2toExcel(string Path)
{
try
{
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" +"Data Source="+ Path +";"+"Extended Properties=Excel 8.0;";
OleDbConnection conn 
= new OleDbConnection(strConn);
conn.Open(); 
System.Data.OleDb.OleDbCommand cmd
=new OleDbCommand ();
cmd.Connection 
=conn;
//cmd.CommandText ="UPDATE [sheet1$] SET 姓名='2005-01-01' WHERE 工号='日期'";
//cmd.ExecuteNonQuery ();
for(int i=0;i {
if(fp2.Sheets [0].Cells[i,0].Text!="")
{
cmd.CommandText 
="INSERT INTO [sheet1$] (工号,姓名,部门,职务,日期,时间) VALUES('"+fp2.Sheets [0].Cells[i,0].Text+ "','"+
fp2.Sheets [
0].Cells[i,1].Text+"','"+fp2.Sheets [0].Cells[i,2].Text+"','"+fp2.Sheets [0].Cells[i,3].Text+
"','"+fp2.Sheets [0].Cells[i,4].Text+"','"+fp2.Sheets [0].Cells[i,5].Text+"')";
cmd.ExecuteNonQuery ();
}
}
conn.Close ();
return true;
}
catch(System.Data.OleDb.OleDbException ex)
{
System.Diagnostics.Debug.WriteLine (
"写入Excel发生错误:"+ex.Message );
}
return false;
}

导出到Excel的时候,创建一个Excel文件

object misvalueExcel = System.Reflection.Missing.Value;
Excel.ApplicationClass exApp = new Excel.ApplicationClass();
exApp.DisplayAlerts = false;
Excel.Workbook book = exApp.Workbooks.Add(misvalueExcel);
book.SaveAs(fileName,misvalueExcel,misvalueExcel,misvalueExcel,misvalueExcel,misvalueExcel,Excel.XlSaveAsAccessMode.xlShared,misvalueExcel,misvalueExcel,misvalueExcel,misvalueExcel,misvalueExcel);
book.Close(misvalueExcel,misvalueExcel,misvalueExcel);
exApp.Quit();



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=623643

- 作者: cyber2005 2007年02月1日, 星期四 10:40  回复(0) |  引用(0) 加入博采

WebService中实现 上传下载文件

/*上传文件的WebService*/

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using System.IO;

/// <summary>
/// Upload 的摘要说明。
/// </summary>
[WebService(Namespace = "http://tempuri.org/",
   Description = "在Web Services里利用.NET框架进上载文件。")]
public class UploadFile : System.Web.Services.WebService
{
    public UploadFile()
    {
    }

    [WebMethod(Description = "Web 服务提供的方法,返回是否文件上载成功与否。")]
    public string Upload(byte[] fs, string fileType)
    {
        string FileName = System.DateTime.Now.ToString("yyyyMMddHHmmssms") +"." +fileType;
        try
        {
            ///定义并实例化一个内存流,以存放提交上来的字节数组。
            MemoryStream m = new MemoryStream(fs);
            ///定义实际文件对象,保存上载的文件。
            FileStream f = new FileStream(Server.MapPath(".") + "\\UploadFile\\"
             + FileName, FileMode.Create);
            ///把内内存里的数据写入物理文件
            m.WriteTo(f);
            m.Close();
            f.Close();
            f = null;
            m = null;
            return FileName;
        }
        catch (Exception ex)
        {
            return null;
        }
    }

    [WebMethod(Description = "Web 服务提供的方法,删除指定文件")]
    public void Delete(string fileName)
    {
        string filePath = Server.MapPath(".") + "\\UploadFile\\" + fileName;      
        File.Delete(filePath);
    }
}

 

/*下载文件*/

using System;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.IO;

/// <summary>
/// GetBinaryFile 的摘要说明。
/// Web Services名称:GetBinaryFile
/// 功能:返回服务器上的一个文件对象的二进制字节数组。
/// </summary>
[WebService(Namespace = "http://tempuri.org/",
Description = "在Web Services里利用.NET框架进行传递二进制文件。")]
public class GetBinaryFile : System.Web.Services.WebService
{
    /// <summary>
    /// Web 服务提供的方法,返回给定文件的字节数组。
    /// </summary>
    [WebMethod(Description = "Web 服务提供的方法,返回给定文件的字节数组")]
    public byte[] GetFile(string requestFileName)
    {
        string fileName = Server.MapPath(".") + "\\UploadFile\\" + requestFileName;
        return getBinaryFile(fileName);
    }

    /// <summary>
    /// getBinaryFile:返回所给文件路径的字节数组。
    /// </summary>
    /// <param name="filename"></param>
    /// <returns></returns>
    public byte[] getBinaryFile(string filename)
    {
        if (File.Exists(filename))
        {
            try
            {
                ///打开现有文件以进行读取。
                FileStream s = File.OpenRead(filename);
                return ConvertStreamToByteBuffer(s);
                s.Close();
            }
            catch (Exception e)
            {
                return new byte[0];
            }
        }
        else
        {
            return new byte[0];
        }
    }

    /// <summary>
    /// ConvertStreamToByteBuffer:把给定的文件流转换为二进制字节数组。
    /// </summary>
    /// <param name="theStream"></param>
    /// <returns></returns>
    public byte[] ConvertStreamToByteBuffer(System.IO.Stream theStream)
    {
        int b1;
        System.IO.MemoryStream tempStream = new System.IO.MemoryStream();
        while ((b1 = theStream.ReadByte()) != -1)
        {
            tempStream.WriteByte(((byte)b1));
        }
        return tempStream.ToArray();

    }

    [WebMethod(Description = "Web 服务提供的方法,返回给定文件类型。")]
    public string GetImageType()
    {
        ///这里只是测试,您可以根据实际的文件类型进行动态输出
        return "image/jpg";
    }
}

/*调用上传*/

string filePath = "c:\test.jpg";
FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate,
FileAccess.Read);
// Read the Data into the Byte Array
byte[] fileByte = new byte[fs.Length];
fs.Read(fileByte, 0, (int)fs.Length);

UploadFile uploadfile = new UploadFile();
int indexof = filePath.LastIndexOf(".")+1;
string fileExt = filePath.Substring(indexof, filePath.Length - indexof);
string filename = uploadfile.Upload(fileByte, fileExt);

 



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=673981


- 作者: cyber2005 2007年02月1日, 星期四 10:39  回复(0) |  引用(0) 加入博采

使用 Windows Mobile 5.0 中的图片、视频和照相机

代码演练

本部分将为您介绍示例客户端方案的一些源代码。您将看到如何在托管代码和本机代码中使用选择图片对话框和照相机捕获对话框。不过,本文的附带源代码中不包括本机代码示例。然后,您将看到如何使用其他包含媒体的应用程序,以及如何将媒体存储到数据库中。

选择图片(托管代码)

要将多媒体与企业应用程序集成,最重要的是能够使用已经存储在文件系统中的图片(包括照片)和视频。如果该设备没有配备内置照相机,您仍然可以使用该方法集成多媒体。例如,您可能使用单独的数字照相机来拍照或者捕获视频,然后使用红外线端口或蓝牙将照片或视频传输到 Pocket PC。为了满足该需要,Windows Mobile 5.0 平台中包括了一个现成的对话框,该对话框可以在托管 (.NET Compact Framework) 代码中作为"Microsoft.WindowsMobile.Forms"命名空间中的 SelectPictureDialog 类使用。

要创建前面图 9 中显示的文件选择屏幕,可以使用以下代码示例。

private void fromFileMenuItem_Click(object sender, EventArgs e)
{
  SelectPictureDialog selectPictureDialog = new SelectPictureDialog();
  selectPictureDialog.Owner = this;
  selectPictureDialog.Title = "Select Exhibit Photo or Video";
  selectPictureDialog.CameraAccess = false;
  selectPictureDialog.Filter = "All files|*.*";
  if(selectPictureDialog.ShowDialog() == DialogResult.OK &&

    selectPictureDialog.FileName.Length > 0)
  {
    fileExtension = Path.GetExtension(selectPictureDialog.FileName);
    File.Copy(selectPictureDialog.FileName, fileName());
    if(fileExtension.ToLower() == ".jpg")
      pictureBox.Image = new Bitmap(fileName());
    else
    {
      ComponentResourceManager resources =
        new ComponentResourceManager(typeof(ExhibitForm));
      pictureBox.Image = ((System.Drawing.Image)
        (resources.GetObject("pictureBox.Image")));
    }
  }
}

在上面的代码中,您可以看到该对话框的所有者设置为具有该标题的当前窗口。CameraAccess 属性指示照相机是否应该从该对话框窗口使用。如果该属性设置为 true 且照相机可用,则可以在文件列表中看到照相机符号。当选择照相机符号时,将显示一个 CameraCaptureDialog 对话框,这样就可以照相或者制作视频记录。请注意,因为 SelectPictureDialog 对话框能够链接到 CameraCaptureDialog 对话框(虽然该示例中未显示它),所以这的确就是从文件系统和内置照相机中启用包含的媒体而需进行的最小集成。

Filter 属性定义当应用程序显示文件列表时将应用的搜索筛选器。该属性的默认值为"Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF"。

上述代码中接下来要发生的是对话框的实际呈现。呈现通过 ShowDialog 方法进行,该方法直至对话框关闭时才停止执行。通常,ShowDialog 方法返回一个值,指示对话框的关闭方式。如果用户按设备上的 Action 键或点击 OK,该对话框返回 DialogResult.OK。如果选择一张图片,则 FileName 属性包括所选文件的名称。如果这两个条件都满足,则保存所选文件的扩展名,将该文件复制到示例的媒体文件夹。如果所选文件是照片(在本示例中,只有 JPEG 文件可用于照片),使用所选图片更新 Exhibit 屏幕上的图片框 (pictureBox)。如果所选文件是视频,默认图像(图 12 显示的放大的媒体播放器文档符号)从应用程序资源加载。

fileName 方法的代码如下所示。

private string fileName()
{
  return Common.Values.MediaPath + Path.DirectorySeparatorChar +
      exhibitID.ToString() + fileExtension;
}

上述代码创建了展示的完整文件名,该文件名是展示的标识(唯一标识符)和所选文件的文件扩展名的组合。所有媒体文件都存储在一个公共文件夹 (Common.Values.MediaPath) 中。

图 15 显示 SelectPictureDialog 类的完整定义。


15. SelectPictureDialog

因为 Filter 属性可以包括多个筛选器,所以可以使用 FilterIndex 属性设置默认筛器索引。例如,如果 Filter 属性设置为"Bitmap Files|*.bmp|JPEG Files|*.jpg|GIF Files|*.gif",FilterIndex 设置为 1,则该对话框将搜索 JPEG 文件。

除了已经提到的属性,还可以用 InitialDirectory 属性选择一个初始文件夹来搜索图片。可以将 LockDirectory 属性设置为 true 以防止用户更改文件夹。可以使用 SortOrder 属性设置找到的文件的初始排序,还可以将该属性设置为根据日期、名称或大小按升序和降序进行排序。可以使用 ShowDrmContent 属性指定受数字版权管理(Digital Rights Management,DRM)保护的文件是否应该显示在对话框中。如果受 DRM 保护的文件得到保护,则它们不会被转发,只有当 ShowForwardLockedContent 属性设置为 true 时,它们才会显示在该对话框中。

选择图片(本机代码)

要在本机代码中使用上一部分中描述的对话框,可以使用具有 OPENFILENAMEEX 结构的 GetOpenFileNameEx 函数,如下所示。

TCHAR szFile[MAX_PATH];
OPENFILENAMEEX ofnex = {0};

ofnex.lStructSize     = sizeof(ofnex);
ofnex.hwndOwner       = g_hWnd;
ofnex.lpstrFile       = szFile;
ofnex.nMaxFile        = sizeof(szFile) / sizeof(szFile[0]);
ofnex.lpstrFilter     = TEXT("All Files (*.*)\0*.*\0");
ofnex.lpstrTitle      = TEXT("Select Exhibit Photo or Video");
ofnex.ExFlags         = OFN_EXFLAG_THUMBNAILVIEW;
ofnex.lpstrInitialDir = NULL;

if(GetOpenFileNameEx(&ofnex))
{
  // The selected file name is in szFile
}

上述代码中的所有者窗口是主应用程序窗口(全局定义为 g_hWnd)。请注意,筛选器的各部分用 NULL 字符分隔。使用 OFN_EXFLAG_THUMBNAILVIEW 以缩略图格式显示 ListView 控件,ExFlags 成员可以包括 OFN_EXFLAG_DETAILSVIEW 标志以详细信息格式显示 ListView。其他选项是 OFN_EXFLAG_HIDEDRMPROTECTEDOFN_EXFLAG_HIDEDRMFORWARDLOCKED,前者用于排除受 DRM 保护的文件的显示,后者用于排除无法转发的受 DRM 保护的文件。

捕获照片和视频(托管代码)

尽管许多移动设备早已配备了内置照相机,但刚开始时缺乏对使用这些照相机的开发支持。几乎没有制造商制造可以从托管代码使用的照相机,甚至本机 API 都难以找到。对于那些希望将媒体集成到应用程序中的企业开发人员而言,唯一可用的选择是进行文件级集成(如前面图片选择对话框的讨论中描述的那样)。

有了 Windows Mobile 5.0 软件,所有一切都改变了。现在定义了设备制造商将支持的通用照相机 API。此外,为了满足那些使用 .NET Compact Framework 构建应用程序的企业开发人员的需要,Windows Mobile 5.0 软件还包括了一个现成的对话框。该对话框名为 CameraCaptureDialog,可在"Microsoft.WindowsMobile.Forms"命名空间中找到它。

要创建前面图 14 中显示的照片捕获屏幕,可以使用以下代码示例。

private void photoMenuItem_Click(object sender, EventArgs e)
{
  CameraCaptureDialog cameraCaptureDialog = new CameraCaptureDialog();
  cameraCaptureDialog.Owner = this;
  cameraCaptureDialog.Title = "Take Exhibit Photo";
  cameraCaptureDialog.Mode = CameraCaptureMode.Still;
  if(cameraCaptureDialog.ShowDialog() == DialogResult.OK &&

    cameraCaptureDialog.FileName.Length > 0)
  {
    fileExtension = Path.GetExtension(cameraCaptureDialog.FileName);
    File.Copy(cameraCaptureDialog.FileName, fileName());
    pictureBox.Image = new Bitmap(fileName());
  }
}

CameraCaptureDialog 类的工作方式与前面讨论的 SelectPictureDialog 类非常类似。在上述代码中,该对话框的所有者设置为具有该标题的当前窗口。Mode 属性指示照相机捕获对话框应该用于拍照还是进行视频录制。在本例中,用户需要一张照片 (CameraCaptureMode.Still)。对话框通过 ShowDialog 方法显示,该方法返回一个指示对话框关闭方式的值。如果用户点击 OK,则对话框返回 DialogResult.OK。如果拍了一张照片,FileName 属性包括新建的图片(照片)文件的名称。如果这两个条件都满足,则保存所选文件的扩展名,将该文件复制到示例的媒体文件夹,使用所选图片更新 Exhibit 屏幕上的图片框 (pictureBox)。

要使用同一个对话框捕获视频,使用以下代码示例。

private void videoMenuItem_Click(object sender, EventArgs e)
{
  CameraCaptureDialog cameraCaptureDialog = new CameraCaptureDialog();
  cameraCaptureDialog.Owner = this;
  cameraCaptureDialog.Title = "Take Exhibit Video";
  cameraCaptureDialog.Mode = CameraCaptureMode.VideoWithAudio;
  if(cameraCaptureDialog.ShowDialog() == DialogResult.OK &&

    cameraCaptureDialog.FileName.Length > 0)
  {
    fileExtension = Path.GetExtension(cameraCaptureDialog.FileName);
    File.Copy(cameraCaptureDialog.FileName, fileName());
    ComponentResourceManager resources =
      new ComponentResourceManager(typeof(ExhibitForm));
    pictureBox.Image = ((System.Drawing.Image)
      (resources.GetObject("pictureBox.Image"))); ;
  }
}

请注意,上面的代码与捕获照片的代码非常类似,但是 Mode 属性却设置为捕获带有声音的视频记录 (CameraCaptureMode.VideoWithAudio)。Mode 属性也可以设置为捕获没有声音的视频 (CameraCaptureMode.VideoOnly)。此外,默认图像(图 12 中显示的放大的媒体播放器文档符号)从该应用程序的资源加载到图片框中。

图 16 显示 CameraCaptureDialog 类的完整定义。


16. CameraCaptureDialog

除了已经提到的属性,如果在使用 ShowDialog 方法显示该对话框之前设置 DefaultFileName 属性,该名称将用作新照片或视频的文件名。可以使用 InitialDirectory 属性指定捕获的文件(照片或视频)将存储到何处。要请求捕获的照片或视频的分辨率,将 Resolution 属性设置为一个 Size 实例,如下所示。

cameraCaptureDialog.Resolution = new Size(320, 240);

使用 StillQuality 属性设置该照片的压缩级别。在 CameraCaptureStillQuality 枚举中,High 选项意味着低压缩率用于保持照片的高质量。Low 选项与其相反(结果产生具有较低质量的高压缩)。Normal 选项产生介于 HighLow 选项之间的质量。

使用 VideoTimeLimit 属性设置新视频的最大记录时间。默认值为零,即没有时间限制。

最后一个属性是 VideoTypes,它可用于选择要捕获哪种类型的视频。基本上,在基于 Windows Mobile 5.0 的设备上,可以使用两种不同的视频类型 - 多媒体消息传递服务(Multimedia Messaging Service,MMS)和 Windows Media Video (WMV)。CameraCaptureVideoTypes 枚举提供可能的值。使用 Messaging 录制 MMS 视频,使用 Standard 录制 WMV 视频。还有一个 All 枚举值,用于使 Resolution 属性确定要录制的视频类型。如果使用 All 选项且 Resolution 高度和宽度为零,则再次使用上次使用的分辨率。您还需要设置 MessagingStandard 枚举值的 Resolution 属性。

捕获照片和视频(本机代码)

如果想在本机代码中使用相同的对话框(如前所述),可以使用具有 SHCAMERACAPTURE 结构的 SHCameraCapture 函数,如下所示。

HRESULT hResult;
SHCAMERACAPTURE shcc;
ZeroMemory(&shcc, sizeof(shcc));

shcc.cbSize     = sizeof(shcc);
shcc.hwndOwner  = g_hWnd;
shcc.pszTitle   = TEXT("Take Exhibit Video");
shcc.Mode       = CAMERACAPTURE_MODE_VIDEOWITHAUDIO;
shcc.VideoTypes = CAMERACAPTURE_VIDEOTYPE_ALL;

if(S_OK == SHCameraCapture(&shcc))
{
  // The selected file name is in shcc.szFile
}

上述代码中的所有者窗口是主应用程序窗口(全局定义为 g_hWnd)。Mode 成员的其他值是针对照片的 CAMERACAPTURE_MODE_STILL(默认值)和针对无声音视频的 CAMERACAPTURE_MODE_VIDEOONLYVideoTypes 成员的其他值是针对 WMV 视频的 CAMERACAPTURE_VIDEOTYPE_STANDARD 以及针对 MMS 视频的 CAMERACAPTURE_VIDEOTYPE_MESSAGING。当使用后两个值之一时,nResolutionWidthnResolutionHeight 成员均不能为零。

查看照片和视频

要打开前面图 11(图片查看器)和图 13(媒体播放器)中显示的屏幕,可以使用以下代码。

private void viewMenuItem_Click(object sender, EventArgs e)
{
  Process process = new Process();
  process.StartInfo.FileName = fileName();
  process.StartInfo.Verb = "Open";
  process.StartInfo.UseShellExecute = tue;
  process.Start();
}

使用"System.Diagnostics"命名空间的 Process 类为特定文件新建一个进程。请注意,如果 UseShellExecute 属性设置为 true,文件名可以是与具有默认打开操作的可执行文件相关联的任何文件类型。在基于 Windows Mobile 5.0 的 Pocket PC 上,.jpg 扩展名与图片和视频查看器可执行文件 (pimg.exe) 相关联,.wmv 扩展名与媒体播放器可执行文件 (wmplayer.exe) 相关联。

将媒体保存到数据库

在前面的示例中,媒体保存在一个文件中,该文件复制到特定的(媒体)文件夹以便稍后与服务器同步。媒体(文件)信息也可以通过如下代码示例的方式存储在数据库中。

FileStream fs = File.Open(fileName(), FileMode.Open);
byte[] imageData = new byte[fs.Length];
fs.Read(imageData, 0, imageData.Length);
fs.Close();

SqlCeCommand cmd = cn.CreateCommand();
cmd.CommandText = "UPDATE Exhibit SET Media=?" +
  " WHERE ExhibitID='" + exhibitID + "'";
SqlCeParameter param = cmd.Parameters.Add("p0", SqlDbType.Image);
param.Value = imageData;
cmd.ExecuteNonQuery();

将文件读入一个字节数组,然后该数组用于更新数据库中正确的展示行。在上述代码中,保存媒体数据的数据库列 (Media) 被假定为 image 类型。请注意,要使用外部程序(pimg.exe 和 wmplayer.exe)播放媒体,需要将媒体再次写入到一个文件中,然后才能调用外部程序。

将媒体文件存储在文件系统中还是存储在数据库中,这取决于应用程序的要求。这两项技术都有优缺点。将媒体文件存储在文件系统中可以使录制、播放和操作更简单,并且能更容易地分离数据和媒体的存储。例如,数据库可以位于设备上较快的内存中从而提高访问性能,而媒体则存储在存储卡上,这样就可以存储更多信息,但访问速度较慢。然而,当这些文件需要与服务器同步时,就需要自定义解决方案(如 HTTP 上载和 XML Web 服务的附件)。如果媒体存储在数据库中,那么每次需要播放或操作时,都需要将媒体提取到一个文件中。但是这一同步操作较容易,因为数据库同步(如 Microsoft SQL Server Mobile Edition 中的远程数据访问和合并复制)和 XML Web 服务同步(SOAP 上的 DataSet)都支持该数据传输。任何情况下,您都应该考虑在设备上本地压缩媒体,以及当媒体在设备和服务器间传输时压缩媒体这两方面。

多媒体之外的代码重点

既然已经演练了示例应用程序中实现的多媒体功能,那么您可以再演练其他一些代码,因为从企业应用程序角度看,这是值得研究一下的。例如,使用 .NET Compact Framework 2.0 命名空间"Microsoft.Win32"中的 Registry 类获取注册表设置,如下代码示例所示。

string registryKey = @"SOFTWARE\Microsoft\MsdnSamples\Inspection";
RegistryKey key = Registry.LocalMachine.CreateSubKey(registryKey);
string userName = key.GetValue("UserName", "<default>").ToString();

要保存相同的注册表设置,使用以下代码。

RegistryKey key = Registry.LocalMachine.OpenSubKey(registryKey, true);
key.SetValue("UserName", userName);

该代码示例的另一个非常有趣的部分是数据访问。首先是用户界面实现,接着是用来填充 Type 组合框的代码(如前面的图 5 所示)。

try
{
  DataTable dt;
  using(InspectionHandler inspectionHandler = new InspectionHandler())
    dt = inspectionHandler.GetAllTypes().Tables[0];
  DataRow dr = dt.NewRow();
  dr["TypeName"] = "<All types>";
  dr["InspectionTypeID"] = Guid.Empty;
  dt.Rows.InsertAt(dr, 0);
  typeComboBox.DisplayMember = "TypeName";
  typeComboBox.ValueMember = "InspectionTypeID";
  typeComboBox.DataSource = dt;
  typeComboBox.SelectedIndex = 0;
}
catch(Exception)
{
  MessageBox.Show("Could not load inspection types!", this.Text);
}

通过检查处理程序类实例 (inspectionHandler) 检索具有所有类型的数据表 (dt)。第一行先添加到数据表中,然后它作为数据源添加到组合框中。该检查处理程序中方法 (GetAllTypes) 的实现如下所示。

public DataSet GetAllTypes()
{
  return SqlHelper.ExecuteDataset(cn, CommandType.Text,
    "SELECT * FROM InspectionType", "InspectionType");
}

SqlHelper 类实际上可以算是 Data Access Application Block(包括在 OpenNETCF 的 Application Blocks 1.0 中)的增强版。Application Blocks 1.0 是桌面计算机应用程序块的一个端口。方法 (ExecuteDataSet) 获取以下参数:数据库连接(SqlCeConnection 类型的 connection)、命令类型 (commandType)、语句 (commandText) 以及返回的表的名称 (tableName)。此处使用的重载如下代码示例所示。

public static DataSet ExecuteDataset(SqlCeConnection connection,
  CommandType commandType, string commandText, string tableName)
{
  DataSet ds = ExecuteDataset(connection, commandType, commandText,
   (SqlCeParameter[])null);
  ds.Tables[0].TableName = tableName;
  return ds;
}

调用的另一个重载按以下代码示例的方式实现。

public static DataSet ExecuteDataset(SqlCeConnection connection,
  CommandType commandType, string commandText,
  params SqlCeParameter[] commandParameters)
{
  SqlCeCommand cmd = new SqlCeCommand();
  bool mustCloseConnection = false;
  PrepareCommand(cmd, connection, (SqlCeTransaction)null, commandType,
    commandText, commandParameters, out mustCloseConnection );
          
  SqlCeDataAdapter da = new SqlCeDataAdapter(cmd);
  DataSet ds = new DataSet();
  ds.Locale = CultureInfo.InvariantCulture;
  da.Fill(ds, 0, 100, "Table");
      
  cmd.Parameters.Clear();

  if(mustCloseConnection)
    connection.Close();

  return ds;
}

创建一个 SQL Mobile 命令 (SqlCeCommand) 实例 (cmd) 并准备执行它。然后,创建一个数据适配器 (da) 和一个数据集 (ds),该数据适配器用于使用数据填充数据集。注意如何才能指定只返回前 100 行。这种限制可能是个好点子;很少需要一个大的结果列表,一方面是因为对性能的影响,也因为在移动设备上浏览大数据集的效率并不太高。所有参数都与该命令对象分离,这样它们才可以再次使用。最后,返回创建的数据集。

您按照以下代码示例所示准备该命令。

private static void PrepareCommand(SqlCeCommand command,
  SqlCeConnection connection, SqlCeTransaction transaction,
  CommandType commandType, string commandText, SqlCeParameter[]
  commandParameters, out bool mustCloseConnection )
{
  if(connection.State != ConnectionState.Open)
  {
    mustCloseConnection = true;
    connection.Open();
  }
  else
    mustCloseConnection = false;

  command.Connection = connection;
  command.CommandText = commandText;
  command.CommandType = commandType;

  if(transaction != null)
    command.Transaction = transaction;

  if(commandParameters != null)
    AttachParameters(command, commandParameters);

  return;
}

如果连接尚未打开,则将其打开,根据这些参数配置该命令。有关 SqlHelper 的实现的更多信息,请参阅本文的下载示例代码以及 Data Access Application Block 文档。

对于任何企业开发人员,大大改进对 .NET Compact Framework 2.0 和 Visual Studio .NET 2005 中的数据访问支持不仅仅是受欢迎这么简单的。您可以直接从开发工具中使用数据库这一事实,将大大提高工作效率。典型的开发过程如下所示:在 SQL Server Management Studio 中创建 SQL Server Mobile Edition 数据库文件(sdf 扩展名)。也可以使用该工具添加所有表和数据。然而,您也可以从 SQL Server Management Studio 中的 Server Explorer 窗口连接到 SQL Server Mobile Edition 数据库,可以在其中添加表和数据、测试查询以及类似的项。进行调试时,您可以部署相同的数据库文件以及该应用程序。还有许多其他新增的数据访问功能有待您去探究。

媒体播放器控件

在许多情况下,将标准媒体播放器作为单的进程启动(如前面所示)可能会满足业务需求,但如果需要更多地控制视频播放,则可以使用媒体播放器控件。媒体播放器控件(版本 10)包括在 Windows Mobile 5.0 软件中,它使开发人员能够将媒体播放器用作自己应用程序的一个自定义控件。

宿主媒体播放器控件(本机代码)

媒体播放器控件是一个常规 ActiveX 控件(.ocx 文件),熟悉 COM 的本机开发人员使用它时不会有很多问题。首先,您应该查看 Windows Media Player Mobile 代码示例,这些示例包括用于宿主媒体播放器控件的代码。然而,因为这些示例是针对本机智能设备开发的上一代工具 (Microsoft eMbedded Visual C++) 而编写的,所以本文的下载代码示例包括尝试通过 eMbedded Visual C++ Upgrade Wizard for Visual Studio 2005 Beta 2 方法转换媒体播放器示例 (CEWMPHostML) 的结果。

宿主窗口和该控件的创建如下代码示例所示。

CAxWindow                 m_wndView;
CComPtr<IWMPPlayer>       m_spWMPPlayer;
CComPtr<IConnectionPoint> m_spConnectionPoint;
DWORD                      m_dwAdviseCookie;

RECT rcClient;
GetClientRect(&rcClient);
m_wndView.Create(m_hWnd, rcClient, NULL, 
  WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
if(NULL == m_wndView.m_hWnd)
  goto FAILURE;

CComPtr<IAxWinHostWindow> spHost;
HRESULT hr = m_wndView.QueryHost(&spHost);
if(FAILMSG(hr))
  goto FAILURE;

hr = spHost->CreateControl(CComBSTR(
  _T("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")), m_wndView, 0);
if(FAILMSG(hr))
  goto FAILURE;

hr = m_wndView.QueryControl(&m_spWMPPlayer);
if(FAILMSG(hr))
  goto FAILURE;

CComWMPEventDispatch *pEventListener = NULL;
hr = CComWMPEventDispatch::CreateInstance(&pEventListener);
CComPtr<IWMPEvents> spEventListener = pEventListener;
if(FAILMSG(hr))
  goto FAILURE;

CComPtr<IConnectionPointContainer> spConnectionContainer;
hr = m_spWMPPlayer->QueryInterface(__uuidof(IConnectionPointContainer),
  (void**)&spConnectionContainer);
if(FAILMSG(hr))
  goto FAILURE;

hr = spConnectionContainer->FindConnectionPoint(__uuidof(IWMPEvents),
  &m_spConnectionPoint);
if(FAILMSG(hr))
  goto FAILURE;

m_dwAdviseCookie = 0; 
hr = m_spConnectionPoint->Advise(spEventListener, &m_dwAdviseCookie);
if(FAILMSG(hr))
  goto FAILURE;

全局声明(前四行)之后,控件宿主窗口 (m_wndView) 作为主应用程序窗口 (m_hWnd) 的子窗口(并且具有和客户端区域相同的大小)进行创建。然后,检索宿主窗口的接口引用 (spHost) 并用它来创建媒体播放器控件。GUID(对应于与版本无关的 ProgID WMPlayer.OCX)用于创建该控件,从该宿主窗口检索该控件的实际接口引用 (m_spWMPPlayer)。最后,使用侦听所有类型事件的事件调度程序 (pEventHandler) 建立事件处理。请注意每个调用上的大量错误处理,您在调试和测试时将从中大大受益。

下一个主要操作是用户选择使用菜单打开某个文件,如下代码示例所示。

CFileOpenDlg dlgOpen;
if(dlgOpen.DoModal(m_hWnd) == IDOK)
{
  HRESULT hr = m_spWMPPlayer->put_URL(_T(dlgOpen.m_bstrName);
  if(FAILMSG(hr))
    return 0;
}
return 0;

显示一个对话框 (dlgOpen),用户可从中选择文件名。如果用户点击 OK 关闭该对话框,则媒体播放器的 URL 属性设置为在该对话框中输入的名称。然后媒体播放器控件播放该文件。

该事件处理以如下方式实现。

HRESULT CWMPEventDispatch::Invoke(DISPID dispIdMember, REFIID riid,
  LCID lcid, WORD wFlags, DISPPARAMS FAR* pDispParams,
  VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo,
  unsigned int FAR*  puArgErr)
{
  if (!pDispParams)
    return E_POINTER;

  if (pDispParams->cNamedArgs != 0)
    return DISP_E_NONAMEDARGS;

  HRESULT hr = DISP_E_MEMBERNOTFOUND;

  switch(dispIdMember)
  {
    case DISPID_WMPCOREEVENT_OPENSTATECHANGE:
      OpenStateChange(pDispParams->rgvarg[0].lVal);
      break;

    case DISPID_WMPCOREEVENT_PLAYSTATECHANGE:
      PlayStateChange(pDispParams->rgvarg[0].lVal);
      break;

    case DISPID_WMPCOREEVENT_AUDIOLANGUAGECHANGE:
      AudioLanguageChange(pDispParams->rgvarg[0].lVal);
      break;

    case DISPID_WMPCOREEVENT_STATUSCHANGE:
      StatusChange();
      break;

    // Here comes another 40 events

    case DISPID_WMPOCXEVENT_MOUSEUP:
      MouseUp(pDispParams->rgvarg[3].iVal,
        pDispParams->rgvarg[2].iVal, pDispParams->rgvarg[1].lVal,
        pDispParams->rgvarg[0].lVal);
      break;
  }
  return( hr);
}

对于每个事件调度标识 (dispIdMember),调用一个单独的方法来操作该事件。正如您在上述代码中所看到的,另外 40 个事件在下载代码示例中实现。媒体播放器控件发布的广泛的属性、方法和事件集,使其成为进行媒体播放时的重点考虑对象。

宿主媒体播放器控件(托管代码)

尽管 .NET Compact Framework 2.0 包括对 COM 互操作性的支持,但是没有对 ActiveX 控件的内置支持。然而,多亏我的同事 Alex Feinman,他提供了一种在托管代码中使用 ActiveX 控件的方式,您将在他的文章 (Hosting ActiveX Controls in Compact Framework 2.0 Applications) 中找到在托管代码中使用 ActiveX 控件的方式。通过使用该技术并在前面的示例基础上进行生成,图 17 显示具有集成视频播放的 Exhibit 屏幕在 Smartphone 版本的示例应用程序中可能的外观。


17. 通过媒体播放器控件进行的集成播放。

正如在 Pocket PC 示例(如图 10 所示)中一样,可以编辑展示名称,但此处播放可以从同一屏幕启动。

通过下面的设计器代码开始创建窗体的代码。

private AxWMPLib.AxWindowsMediaPlayer windowsMediaPlayer;
this.windowsMediaPlayer = new AxWMPLib.AxWindowsMediaPlayer();

this.windowsMediaPlayer.Location = new System.Drawing.Point(0, 28);
this.windowsMediaPlayer.Name = "windowsMediaPlayer";
this.windowsMediaPlayer.Size = new System.Drawing.Size(176, 152);
this.windowsMediaPlayer.TabIndex = 0;
this.windowsMediaPlayer.Text = "windowsMediaPlayer";

正如您所看到的,当 ActiveX 控件的包装准备就绪时,可以像处理任何托管控件那样处理该控件。在前面的代码示例基础上生成,该媒体播放器控件可以按以下方式使用展示视频加载。

windowsMediaPlayer.URL = fileName();

URL 属性可以是指向流式源或远程文件的 URL,也可以是本地文件系统中的文件。Menu 命令(PlayPauseStop)的后台代码如下代码示例所示。

private void playMenuItem_Click(object sender, EventArgs e)
{
  windowsMediaPlayer.Ctlcontrols.play();
}

private void pauseMenuItem_Click(object sender, EventArgs e)
{
  windowsMediaPlayer.Ctlcontrols.pause();
}

private void stopMenuItem_Click(object sender, EventArgs e)
{
  windowsMediaPlayer.Ctlcontrols.stop();
}

与该媒体播放器的基本交互不是非常困难,设置事件处理程序的方式也不会更困难。就像任何其他托管控件一样,以如下方式添加事件处理程序。

this.windowsMediaPlayer.StatusChange +=
  new System.EventHandler(windowsMediaPlayer_StatusChange);

然后,该事件处理程序按如下方式实现。

void windowsMediaPlayer_StatusChange(object sender, System.EventArgs e)
{
  string status = windowsMediaPlayer.status;
  // Do something with status string
}

正如在关于从本机代码使用多媒体播放器控件的讨论中提到的一样,该控件有许多可能性。您在独立媒体播放器中可以进行的任何操作在该控件中几乎都可以实现。示例包括使用播放列表、连接、远程媒体、播放器状态以及很多事件(如播放和结束流)。

- 作者: cyber2005 2007年01月11日, 星期四 13:23  回复(0) |  引用(1) 加入博采

Windows Mobile 5中的新特性

作者:马宁

  微软最近推出下一代移动设备操作系统Windows Mobile 5。Windows Mobile 5在用户体验方面做了很多改善,但更多的改进还是在应用程序编程接口方面。在这篇文章中,我们会向您介绍Windows Mobile 5在开发方面的一些新特性,其中包括3D图形编程、新控件、新的API函数等。

开发工具

  Windows Mobile 5的开发工具是Visual Studio 2005。如果要开发Windows Mobile 5的应用程序,还需要装Windows Mobile 5的SDK和ActiveSync 4.0。

  我们要在Windows Mobile 5设备上开发出托管应用程序就需要借助.NET Compact Framework 2.0的强大功能。.NET Compact Framework 2.0在1.0的基础上做了较大的改进,为我们提供了更多的用户控件,比如DateTimePicker、OpenFileDialog、WebBrowser、LinkLabel和Notification等控件。这些控件都是在.NET CF 1.0中所没有提供的,但是因为他们在实际开发过程中会经常用到,到了.NET CF 2.0中,这些功能终于被加了进来。

  在数据访问方面,.NET CF 2.0支持SQL Mobile 2005的访问支持。SQL Mobile 2005的功能增强了很多,支持多用户同时访问数据库,也支持在PC上创建SQL Mobile数据库。Windows Mobile 5的Smartphone版本也支持SQL Mobile数据库了。在XML支持方面,.NET CF 2.0支持XML的Schema、Serialization、XPath等。

  在远程访问方面,.NET CF 2.0支持MSMQ和.NET Remoting,而在对Socket支持方面,IPv6已经得到了很好的支持。

  .NET CF 2.0还有一个重要的特性:支持COM互操作性。我们可以在.NET程序中可以访问COM组件,也可以将Callback函数传递给COM组件。但是我们不能调用ActiveX控件。

  在C++移动设备程序开发方面,Visual Studio 2005支持MFC 8.0、ATL 8.0和标准C++库8.0。我们也可以在Windows Mobile 2003设备上支持.NET CF 2.0,但必须要将.NET CF 2.0的运行库安装到设备上。

用户界面

  Windows Mobile 5的Pocket PC用户界面发生了很大改变。为了和Smartphone界面类似,Pocket PC的程序菜单被改成了左右两个,在实际设备上也添加了两个硬件按键和这两个菜单相对应。这样的变化可以让用户方便地通过硬件按键操作应用程序,而这样的修改也便于应用程序在Pocket PC和Smartphone之间的移植。为了保持兼容性,Pocket PC仍然支持多于两个一级菜单的菜单结构,但是新开发的程序建议还是采用新的菜单结构。

  Windows Mobile 5的应用程序很方便地支持Notification通知机制。当应用程序发生改变的时候,我们可以通过Notification方式来通知用户。

  下面我们就来通过一个示例,来了解一下.NET CF应用中如何使用Notification控件。我们首先来创建一个Windows Mobile 5的应用程序。打开Visual Studio 2005,选择File-New-Project,我们选择Visual C#中的Pocket PC Magneto,来创建一个Windows Mobile 5 Pocket PC应用程序。需要提醒的是在创建项目前,必须安装好Windows Mobile 5的SDK。

  在创建好项目后,我们在界面编辑器中,为窗体添加MainMenu和Notification两个控件。我们在MainMenu的一个子菜单的响应函数中添加下面的代码:

private void menuItem5_Click(object sender, EventArgs e)
{
    StringBuilder HTMLString = new StringBuilder();
    HTMLString.Append("<html><body>");
    HTMLString.Append("Submit data?");
    HTMLString.Append("<form method=\'GET\' action=notify>");
    HTMLString.Append("<input type='submit'>");
    HTMLString.Append("<input type=button name='cmd:2' value='Cancel'>");
    HTMLString.Append("</body></html>");

    //Set the Text property to the HTML string.
    notification1.Text = HTMLString.ToString();
    notification1.Caption = "Notification Demo";
    notification1.Critical = false;

    // Display icon up to 10 seconds.
    notification1.InitialDuration = 10;
    notification1.Visible = true;
}

  Notification控件支持HTML格式的文本,所以我们的示例创建了两个Input控件。然后设置Notification控件的Visible属性为true就可以了。

  编译执行后的效果如上图所示。我们可以看到,Notification已经从Windows Mobile 2003的气泡型窗体变成了从下边出现的形式。输入法图标也从右下角移到了中间。

Microsoft.WindowsMobile.Forms

  Windows Mobile 5为开发者提供了Microsoft.WindowsMobile.Forms类库,该类库为用户提供了调用各种系统功能的对话框。目前该类库为我们提供了三种自定义对话框,分别是提供照相机功能的CameraCaptureDialog、提供选择联系人的ChooseContactDialog和提供选择图片的SelectPictureDialog。

  我们用一个示例来演示Microsoft.WindowsMobile.Forms类库的功能。首先来创建一个Windows Mobile 5的应用程序,平台类型可以是Pocket PC或Smartphone。为了使用Microsoft.WindowsMobile.Forms类库,我们需要首先添加引用。我们在解决方案资源管理器里右击项目名称,在右键菜单中选择添加引用。我们在添加引用对话框中,我们选择“Microsoft.WindowsMobile.Forms”。

  我们在菜单的响应函数中添加ChooseContactDialog的使用。

private void menuItem1_Click(object sender, EventArgs e)
{
    ChooseContactDialog contactPicker = new ChooseContactDialog();

    contactPicker.Title = "Choose a Contact below:";
    contactPicker.ChooseContactOnly = true;
    contactPicker.ShowDialog();
}

  其实我们看到ChooseContactDialog的方法十分简单,只需要设置Title后,调用ShowDialog方法就可以显示出下边的对话框。

  下边我们来添加对SelectPictureDialog的引用。

SelectPictureDialog pickerDialog = new SelectPictureDialog();

pickerDialog.Filter = "Image Files(*.BMP;*.JPG)|*.BMP;*.JPG";
pickerDialog.InitialDirectory = @"\My Device\My Images";
pickerDialog.Title = "Select an image file";

pickerDialog.ShowDialog();

  我们首先来设置SelectPictureDialog的过滤器,允许显示JPG和BMP的图片;然后设置初始文件夹;最后调用ShowDialog方法。

  下边是SelectPictureDialog显示的效果。

电话、短信和电子邮件

  在Windows Mobile 2003中,如果要在.NET程序中拨打电话的话,需要通过P/Invoke来调用API。到了Windows Mobile 5中,Microsoft.WindowsMobile.Telephony类库为我们提供了拨打电话的功能。

  在使用这个功能之前,我们必须添加Microsoft.WindowsMobile.Telephony引用。调用电话功能的代码如下:

Phone phone = new Phone();
phone.Talk("1234567");

  程序运行效果如下:

  Phone类的方法只有一个Talk方法,所以也只能简单的进行电话拨打。我们如果想实现一些复杂的功能,比如监视拨入的电话等,还需要去调用TAPI来实现。

  发送短信息和发送电子邮件都需要Microsoft.WindowsMobile.PocketOutlook类库的支持。PocketOutlook是一个很复杂的命名空间,包括对很多系统功能的支持,而支持发短信的类是SmsMessage。

public void SmsMessageSend()
{
    SmsMessage smsMessage = new SmsMessage();

    //Set the message body and recipient.
    smsMessage.Body = "Would you like to meet for lunch?";
    smsMessage.To.Add(new Recipient("John Doe", "2065550199"));
    smsMessage.RequestDeliveryReport = true;

    //Send the SMS message.
    smsMessage.Send();

    return;
}

  我们可以看到SmsMessage的Body属性是SMS短信的内容,而To属性,则是收件人的姓名和电话号码,因为支持多个收件人,所以在添加收件人的时候需要调用To属性的Add方法。RequestDeliveryReport属性是一个Bool值,设置是否要求得到发送报告。最后调用SmsMessage的Send方法。

  发送Email的代码与发送短信息的代码大致相似,但是需要使用的是EmailMessage类。

public void EmailSend()
{
    EmailMessage message = new EmailMessage();
    message.Subject = "The picture you requested";
    message.BodyText = "Attached is the picture we discussed";

    Recipient client = new Recipient("John","john@test.com");
    message.To.Add(client);

    Attachment image = new Attachment("\test.jpg");
    message.Attachments.Add(image);

    message.Send("ActiveSync");
}

  EmailMessage的Subject属性是电子邮件的标题,BodyText属性是邮件正文。To属性中可以添加收件人的名称和地址。我们还可以在Attachments属性中添加附件。最后我们调用Send方法。

联系人、约会和任务

  Windows Mobile中有三个很重要的程序:联系人、约会和任务。我们可以使用Microsoft.WindowsMobile.PocketOutlook类库,来调用系统中的联系人、约会和任务信息。我们可以通过自己的程序添加信息。

  我们先来看一下Microsoft.WindowsMobile.PocketOutlook命名空间中很重要的一个类OutlookSession。该类的一个对象就表示了一个Pocket Outlook 对象模块,以前我们需要调用POOM实现的功能,现在可以通过PocketOutlook来实现。

属性说明
Appointments得到约会(Calendar)目录的信息。
Contacts得到联系人目录信息。
EmailAccounts得到Email帐号的集合。
SmsAccount得到SMS帐号的信息。
Tasks得到任务目录信息的集合。

  在使用OutlookSession的时候要先创建一个OutlookSession的对象,然后创建相应的对象并添加到OutlookSession相应属性中去。我们来看下边的例子。

OutlookSession session = new OutlookSession();

// 添加约会
Appointment appointment = new Appointment();
appointment.Subject = "test";
appointment.Body = "testtest";
appointment.Start = DateTime.Now;
appointment.End = new DateTime(2005, 7, 17, 16, 25, 0);

session.Appointments.Items.Add(appointment);

// 添加联系人
Contact contact = new Contact();
contact.FirstName = "John";
contact.LastName = "Lee";
contact.CompanyName = "Microsoft";
contact.Email1Address = "John@test.com";
contact.MobileTelephoneNumber = "1234567";
contact.IM1Address = "John@hotmail.com";

session.Contacts.Items.Add(contact);

// 添加任务
Task task = new Task();
task.Subject = "task1";
task.Body = "task1 body";

session.Tasks.Items.Add(task);

  我们创建Appointment、Contact和Task对象,然后设置相应的属性,然后添加到OutlookSession对象的相应的属性中。

其他新特性

  Windows Mobile 5除了支持上面的特性外,还支持一些其他的新特性。比如在图象显示方面,Windows Mobile 5支持DirectX 3D Mobile。.NET应用程序可以通过Microsoft.WindowsMobile.DirectX类库来调用D3D Mobile,而C++应用程序可以通过COM接口的方式来调用。

  在Windows Mobile设备上普遍使用的GPS全球定位系统也得到了更好的支持。Windows Mobile 5提供了GPS Intermediate Driver,使应用程序可以使用统一的API接口来调用GPS系统。

  Windows Mobile 5提供了一个叫做“ExitWindowsEx”的函数,允许软件重启操作系统。Pocket PC使用该函数可以重启系统,而Smartphone支持关机和重启两种功能。

  在数据库方面,SQL Mobile虽然被广泛使用,但是因为SQL Mobile没有被安装到ROM中。所以如果需要SQL Mobile就需要占用一部分RAM内存空间,对于一些轻量级的应用就显得不是很合适了。所以Windows Mobile中还包括一个轻量级的数据库EDB,该数据库是CEDB的升级。

写在最后

  在这篇文章里,我们领略了Windows Mobile 5为开发者提供的新特性。很多常用的特性都被加入到了API中。但是我们还要看到,许多新特性对于复杂的应用来说,还比较简单。如果想实现比较复杂的功能,还需要依靠自定义控件来实现。

  最后也希望这篇文章能够帮助开发者们了解Windows Mobile 5的开发新特性。

- 作者: cyber2005 2007年01月11日, 星期四 12:41  回复(0) |  引用(1) 加入博采

信息采集软件采用的正则表达式
UrlNetwork(h|H)(r|R)(e|E)(f|F) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?提取信息中的网络链接
EmailNetwork\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*提取信息中的邮件地址
Picture AddressNetwork(s|S)(r|R)(c|C) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?提取信息中的图片链接
IP AddressNetwork(\d+)\.(\d+)\.(\d+)\.(\d+)提取信息中的IP地址
Chinese CellBusiness(86)*0*13\d{9}提取信息中的中国手机号码
Chinese TelePhoneBusiness(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}提取信息中的中国固定电话号码
Chinese TelePhone and CellBusiness(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}提取信息中的中国电话号码(包括移动和固定电话)
Chinese PostCodeBusiness[1-9]{1}(\d+){5}提取信息中的中国邮政编码
Chinese ID CardLive\d{18}|\d{15}提取信息中的中国身份证号码
German TelePhoneBusiness((\(0\d\d\) |(\(0\d{3}\) )?\d )?\d\d \d\d \d\d|\(0\d{4}\) \d \d\d-\d\d?)提取信息中的德国电话号码
German PostCodeBusiness(D-)?\d{5}提取信息中的德国邮政编码
France TelePhoneBusiness(0( \d|\d ))?\d\d \d\d(\d \d| \d\d )\d\d提取信息中的法国电话号码
France PostCodeBusiness\d{5}提取信息中的法国邮政编码
USA TelePhoneBusiness((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}提取信息中的美国电话号码
USA ID CardLive\d{3}-\d{2}-\d{4}提取信息中的美国身份证号码
USA PostCodeBusiness\d{5}(-\d{4})?提取信息中的美国邮政编码
Japanese TelePhoneBusiness(0\d{1,4}-|\(0\d{1,4}\) ?)?\d{1,4}-\d{4}提取信息中的日本电话号码
Japanese PostCodeBusiness\d{3}(-(\d{4}|\d{2}))?提取信息中的日本邮政编码
IntegerNumeric\d+提取信息中的整数
FloatNumeric(-?\d*)\.?\d+提取信息中的浮点数(即小数)
NumericNumeric(-?\d*)(\.\d+)?提取信息中的任何数字
Chinese StringString[\u4e00-\u9fa5]*提取信息中的中文字符串
Unicode StringString[^\x00-\xff]*提取信息中的双字节字符串
English StringString\w*提取信息中的英语字符串

- 作者: cyber2005 2006年12月15日, 星期五 20:34  回复(0) |  引用(1) 加入博采

正则表达式工具介绍

1. 什么是 Match Tracer ?

  正则表达式工具 Match Tracer 是用来编写和调试正则表达式的工具。


2. 特点

① 当输入表达式的时候,表达式的树结构和分组会同步更新,表达式文本会采用不同颜色显示不同部分:


② 编辑框中移动光标时,光标所在位置的表达式元素会用黄色底色显示。树结构中的相应元素会被选中:


③ 编辑框中双击鼠标,可以准确选中当前元素的表达式文本。


④ 进行匹配时,可显示各个分组匹配信息:


⑤ 按照相应编程语言表示字符串的格式,可自动生成编程语言代码:

3. 下载

  本工具为绿色软件,没有使用安装程序。压缩文件只包含一个可执行文件,解压后即可运行。

[ 进入下载页]

- 作者: cyber2005 2006年12月15日, 星期五 11:43  回复(0) |  引用(1) 加入博采

Ruby on rails学习笔记

关键词: Ruby rails

谈使用Eclipse 设置Rails在windows下开发环境的配置

原文地址(英文):http://www.napcs.com/howto/railsonwindows.html

首先你要下载并安装Ruby:http://rubyforge.org/projects/rubyinstaller/

One-Click Installer - Windows

我是安装在d:\ruby你可以根据你的要求选择安装路径
打开dos 命令窗口并执行:gem install rails --include-dependencies
第二、安装Eclipse
我用的是Eclipse3.1.1 下载地址http://www.eclipse.org/downloads/index.php 并解压到:d:\eclipse3.1 双击eclipse.exe启动eclipse
第三、好了基本工作已经做好了,现在就开始配置Rails、
1.安装Ruby开发工具包
选择Help→Software Updates→Find and Install
选择Search for new features to install 点击Next
选择 New Remote Site
name: Ruby Developer Tools
URL: http://rubyeclipse.sourceforge.net/nightlyBuild/updateSite/
点击 OK
检查RDT 点击Next,选择feature RDT 点击Next
2.配置RDT plugin
选择 Windows > Prefrences > Ruby
选择Installed Interpreters
选择Add
interpreter name : ruby.exe
path: 例如d:\ruby\bin\ruby.exe
单击 确定 > 确定

ROR学习资料

ror官方网站:
http://www.rubyonrails.org/
可以作为了解这项技术的起点,那里面有一个15分钟搭建一个blog的视频很值得一看

Rolling with Ruby on Rails:
http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html?page=1
Curt Hibbs写的对于ror的学习过程,还没来得及看,但是实在是太多地方reference了...随大流吧

Really Getting Started in Rails
http://www.slash7.com/articles/2005/01/24/really-getting-started-in-rails
另一处比较著名的入门网站

Ruby on Rails中文社区
http://www.railscn.com/
不知为啥,教育网上这个网站还要用代理...而且好像还不能注册?或者是我的代理的问题?

Setting up a Rails Development Environment on Windows Using Eclipse
http://www.napcs.com/howto/railsonwindows.html
这是一个step by step的在windows上利用eclipse搭建ruby on rails开发平台的指南
我自己就是参考的这个东东。

Why's(poignant) guide to ruby
http://poignantguide.net/ruby/
一个很有意思的ruby语言的入门介绍,作者还会自己画小狐狸插图,
还在侧边栏里写自己的价值观,让我们觉得老外还是蛮可爱的
恩,应该可以用强烈推荐来形容,寓学于乐。

RailsOnWindows:
http://wiki.rubyonrails.com/rails/pages/RailsOnWindows
教你怎样在windows下利用Rails进行开发,其中包括Apache服务器的配置等等
服务器的问题可以从这里找到答案。

Ajax on Rails
http://www.onlamp.com/pub/a/onlamp/2005/06/09/rails_ajax.html
Ajax现在绝对是热点,当然不可放过...虽然对Ajax还仅仅是名词和用户体验上的了解...-___-

GemRails:
http://wiki.rubyonrails.com/rails/pages/GemRails
GemRails是rails的管理器,相当于linux系统中的包管理器
可以自动上网安装新的rails包,可以自动解决依赖,非常方便

- 作者: cyber2005 2006年12月14日, 星期四 15:04  回复(0) |  引用(1) 加入博采

站长常用网址推荐
站长常用网址:
网站资讯| 站长资讯 电子商务 站长情报 网站投资 网站运营 网络专家 电子商务指南 网络营销
站长论坛| 落伍者 ChinaZ论坛 傲龙论坛 站长资讯论坛 我要啦 动易论坛 无忧脚本 站长广告论坛
源码下载| 中国源码中心 源码之家 源码天下 冰之源码下载 ChinaZ下载 源码我爱你 蛋壳空间
优化推广| 搜索引擎优化研究网 搜索引擎排名研究中心 中文搜索引擎指南网 搜索引擎优化 SEO
站长学院| ChinaZ站长学院 优秀站长学院 网贝建站学院 buloo站长学院 冰之站长学院
网页制作| 建站学 网易-网页设计教程 新浪网-主页制作学园 eNet网络学院 动态网站制作指南
网页特效| 网页特效观止 网页特效集锦 新浪js网页制作宝 网页特效代码站 JS太平洋学院
模板素材| 中国网站模板网 模板天下 网页模板下载 中国模板基地网 精品模板网
域名查询| 3721实名查询 昨天到期域名 今天到期域名 今天暂停域名 明天拟删除域名
域名交易|网站交易网 域名交易服务平台 易名网 淘米网 域名交易增值平台 sedo域名交易 项目无忧网
主机租用| 主机测评网 中国万网 中资源 中国E动网 中国E动网 商务互联 虎翼网虚拟主机 时代主机
广告联盟| 美通 百度搜索联盟 Google广告 TOM易告联盟 3721网站联盟 263邮件同盟
彩信图铃| 网易无线联盟 21CN短信联盟 A8彩信联盟 天极彩信联盟 彩酷联盟 QQ彩信联盟
流量统计| 一统天下 武林榜 我要拉 太极统计 zhao123 99统计 ITSUN
源码官方| 风讯建站 新云建站 动易建站 动网论坛 Discuz!
流量交换| 奇链 126链 润东链 太极链 五四链 先锋链 无忧链 58链 9号链

- 作者: cyber2005 2006年12月14日, 星期四 13:13  回复(0) |  引用(1) 加入博采

ASP.NET中实现中文简/繁体自动转换的类
在中文网站开发中,为了满足台湾/香港等有中文繁体阅读习惯的用户,很多网站需要实现中文简/繁体转换。

当然在实际的开发中,还要注意网站的图片上如果有中文的,也需要根据当前显示的是简体,还是繁体进行

切换,否则无法达到效果!在本文中,我只帖上汉字转换的代码。如果有不清楚怎么调用的,请在我的Blog下留下Email。我直接把调用代码例子发给你!

注意:如在实际应用中,发现有本例子字库以外的汉字,可以自己添加,繁体简体对应字在_sGB和_tGB中的对应位置要一致!否则转换会出问题!

          代码例子:

/// <summary>
 /// G2B5Filter 的摘要说明。
 /// 将GB2312字符和Big5字符进行对照转换
 /// 作者: 程式猎人 2003-06-24
 /// </summary>

 public class G2B5Filter : Stream
 {
  private Stream _sink;
  private long _position;
  
  private const string _sGB=@"皑蔼碍爱袄奥坝罢摆败颁办绊帮绑镑谤剥饱宝报鲍辈贝钡狈备惫绷笔毕毙币闭边编贬变辩辫标鳖别瘪濒滨宾摈饼并拨钵铂驳卜补财参蚕残惭惨灿苍舱仓沧厕侧册测层诧搀掺蝉馋谗缠铲产阐颤场尝长偿肠厂畅钞车彻尘陈衬撑称惩诚骋痴迟驰耻齿炽冲虫宠畴踌筹绸丑橱厨锄雏础储触处传疮闯创锤纯绰辞词赐聪葱囱从丛凑蹿窜错达带贷担单郸掸胆惮诞弹当挡党荡档捣岛祷导盗灯邓敌涤递缔颠点垫电淀钓调谍叠钉顶锭订丢东动栋冻斗犊独读赌镀锻断缎兑队对吨顿钝夺堕鹅额讹恶饿儿尔饵贰发罚阀珐矾钒烦范贩饭访纺飞诽废费纷坟奋愤粪丰枫锋风疯冯缝讽凤肤辐抚辅赋复负讣妇缚该钙盖干赶秆赣冈刚钢纲岗镐搁鸽阁铬个给龚宫巩贡钩沟构购够蛊顾剐挂关观馆惯贯广规硅归龟闺轨诡柜贵刽辊滚锅国过骇韩汉号阂鹤贺横轰鸿红后壶护沪户哗华画划话怀坏欢环还缓换唤痪焕涣黄谎挥辉毁贿秽会烩汇讳诲绘荤浑伙获货祸击机积饥迹讥鸡绩缉极辑级挤几蓟剂济计记际继纪夹荚颊贾钾价驾歼监坚笺间艰缄茧检碱硷拣捡简俭减荐槛鉴践贱见键舰剑饯渐溅涧将浆蒋桨奖讲酱胶浇骄娇搅铰矫侥脚饺缴绞轿较阶节杰洁结诫届紧锦仅谨进晋烬尽劲荆茎鲸惊经颈静镜径痉竞净纠厩旧驹举据锯惧剧鹃绢觉决诀绝钧军骏开凯颗壳课垦恳抠库裤夸块侩宽矿旷况亏岿窥馈溃扩阔蜡腊莱来赖蓝栏拦篮阑兰澜谰揽览懒缆烂滥捞劳涝乐镭垒类泪篱离里鲤礼丽厉励砾历沥隶俩联莲连镰怜涟帘敛脸链恋炼练粮凉两辆谅疗辽镣猎临邻鳞凛赁龄铃凌灵岭领馏刘龙聋咙笼垄拢陇楼娄搂篓芦卢颅庐炉"
   +"掳卤虏鲁赂禄录陆驴吕铝侣屡缕虑滤绿峦挛孪滦乱抡轮伦仑沦纶论萝罗逻锣箩骡骆络妈玛码蚂马骂吗买麦卖迈脉瞒馒蛮满谩猫锚铆贸么霉没镁门闷们锰梦谜弥觅幂绵缅庙灭悯闽鸣铭谬谋亩钠纳难挠脑恼闹馁内拟腻撵捻酿鸟聂啮镊镍柠狞宁拧泞钮纽脓浓农疟诺欧鸥殴呕沤盘庞抛赔喷鹏骗飘频贫苹凭评泼颇扑铺朴谱栖凄脐齐骑岂启气弃讫牵扦铅迁签谦钱钳潜浅谴堑枪呛墙蔷强抢锹桥乔侨翘窍窃钦亲寝轻氢倾顷请庆琼穷趋区躯驱龋颧权劝却鹊确让饶扰绕热韧认纫荣绒软锐闰润洒萨鳃赛叁伞丧骚扫涩杀纱筛晒删闪陕赡缮伤赏烧绍赊摄慑设绅审婶肾渗声绳胜圣师狮湿诗尸时蚀实识驶势适释饰视试寿兽枢输书赎属术树竖数帅双谁税顺说硕烁丝饲耸怂颂讼诵擞苏诉肃虽随绥岁孙损笋缩琐锁獭挞态摊贪瘫滩坛谭谈叹汤烫涛绦讨腾誊锑题体屉条贴铁厅听烃铜统头秃图涂团颓蜕脱鸵驮驼椭洼袜弯湾顽万网韦违围为潍维苇伟伪纬谓卫温闻纹稳问瓮挝蜗涡窝卧呜钨乌污诬无芜吴坞雾务误锡牺袭习铣戏细虾辖峡侠狭厦吓鲜纤咸贤衔闲显险现献县馅羡宪线厢镶乡详响项萧嚣销晓啸蝎协挟携胁谐写泻谢锌衅兴汹锈绣虚嘘须许叙绪续轩悬选癣绚学勋询寻驯训讯逊压鸦鸭哑亚讶阉烟盐严颜阎艳厌砚彦谚验鸯杨扬疡阳痒养样瑶摇尧遥窑谣药爷页业叶医铱颐遗仪蚁艺亿忆义诣议谊译异绎荫阴银饮隐樱婴鹰应缨莹萤营荧蝇赢颖哟拥佣痈踊咏涌优忧邮铀犹诱舆鱼渔娱与屿语吁御狱誉预驭鸳渊辕园员圆缘远愿约跃钥岳粤悦阅云郧匀陨运蕴酝晕韵杂灾载攒暂赞赃脏凿枣责择则泽贼赠扎"
   +"札轧铡闸栅诈斋债毡盏斩辗崭栈战绽张涨帐账胀赵蛰辙锗这贞针侦诊镇阵挣睁狰争帧郑证织职执纸挚掷帜质滞钟终种肿众诌轴皱昼骤猪诸诛烛瞩嘱贮铸筑驻专砖转赚桩庄装妆壮状锥赘坠缀谆着浊兹资渍踪综总纵邹诅组钻亘芈啬厍厣靥赝匦匮赜刭刿剀伛伥伧伫侪侬俦俨俪俣偾偬偻傥傧傩佥籴黉冁凫兖衮亵脔禀冢讦讧讪讴讵讷诂诃诋诏诒诓诔诖诘诙诜诟诠诤诨诩诮诰诳诶诹诼诿谀谂谄谇谌谏谑谒谔谕谖谙谛谘谝谟谠谡谥谧谪谫谮谯谲谳谵谶卺陉陧邝邬邺郏郐郓郦刍奂劢巯垩圹坜垆垭垲埘埚埙芗苈苋苌苁苎茏茑茔茕荛荜荞荟荠荦荥荩荪荭莳莴莅莸莺萦蒇蒉蒌蓦蓠蓣蔹蔺蕲薮藓奁尴扪抟挢掴掼揿摅撄撷撸撺叽呒呓呖呗咛哒哓哔哕哙哜哝唛唠唢啧啭喽喾嗫嗳辔嘤噜囵帏帱帻帼岖岘岚峄峤峥崂崃嵘嵛嵝巅徕犷狯狲猃猡猕饧饨饩饪饫饬饴饷饽馀馄馊馍馐馑馔庑赓廪忏怃怄忾怅怆怿恸恹恻恺恽悭惬愠愦懔闩闫闱闳闵闶闼闾阃阄阆阈阊阌阍阏阒阕阖阗阙阚沣沩泷泸泺泾浃浈浍浏浒浔涞涠渎渑渖渌溆滟滠滢滗潆潇潋潴濑灏骞迩迳逦屦弪妩妪妫姗娅娆娈娲娴婵媪嫒嫔嫱嬷驵驷驸驺驿驽骀骁骅骈骊骐骒骓骖骘骛骜骝骟骠骢骣骥骧纡纣纥纨纩纭纰纾绀绁绂绉绋绌绗绛绠绡绨绫绮绯绲缍绶绺绻绾缁缂缃缇缈缋缌缏缑缒缗缙缜缛缟缡缢缣缤缥缦缧缪缫缬缭缯缱缲缳缵玑玮珏珑顼玺珲琏瑷璎璇瓒韪韫韬杩枥枨枞枭栉栊栌栀栎柽桠桡桢桤桦桧栾棂椟椠椤椁榄榇榈榉槟槠樯橥橹橼檐檩殁殇殒殓殚殡轫轭轲轳轵轶轸轹轺轼轾辁辂辄辇辋辍辎辏辘辚戋戗戬瓯昙晔晖暧贲贳贶贻贽"
   +"赀赅赆赈赉赇赕赙觇觊觋觌觎觏觐觑毵氇氩氲牍胧胪胫脍脶腌腽膑欤飑飒飓飕飙毂齑斓炀炜炖烨焖焘祢祯禅怼悫愍懑戆沓泶矶砀砗砺砻硖硗碛碜龛睐睑畲罴羁钆钇钋钊钌钍钏钐钔钗钕钛钣钤钫钪钭钬钯钰钲钴钶钸钹钺钼钽钿铄铈铉铊铋铌铍铎铐铑铒铕铖铗铙铛铟铠铢铤铥铧铨铪铩铫铮铯铳铴铵铷铹铼铽铿锂锆锇锉锊锒锓锔锕锖锛锞锟锢锩锬锱锲锴锶锷锸锼锾镂锵镆镉镌镏镒镓镔镖镗镘镙镛镞镟镝镡镤镦镧镨镪镫镬镯镱镳锺穑鸠鸢鸨鸩鸪鸫鸬鸲鸱鸶鸸鸷鸹鸺鸾鹁鹂鹄鹆鹇鹈鹉鹌鹎鹑鹕鹗鹞鹣鹦鹧鹨鹩鹪鹫鹬鹭鹳疖疠痨痫瘅瘗瘿瘾癞癫窦窭裆裢裣裥褛褴襁皲耧聍聩顸颀颃颉颌颏颔颚颛颞颟颡颢颦虬虮虿蚬蚝蛎蛏蛱蛲蛳蛴蝈蝾蝼罂笃笕笾筚筝箦箧箨箪箫篑簖籁舣舻袅羟糁絷麸趱酽酾鹾趸跄跖跞跷跸跹跻踬踯蹑蹒蹰躏躜觞觯靓雳霁霭龀龃龅龆龇龈龉龊龌黾鼋鼍隽雠銮錾鱿鲂鲅鲈稣鲋鲎鲐鲒鲔鲕鲚鲛鲞鲟鲠鲡鲢鲣鲥鲦鲧鲨鲩鲫鲭鲮鲰鲱鲲鲳鲵鲶鲷鲻鲽鳄鳅鳆鳇鳌鳍鳎鳏鳐鳓鳔鳕鳗鳜鳝鳟鳢鞑鞯鹘髅髋髌魇魉飨餍鬓黩黪鼹";
  
  private const string _tGB=@"皚藹礙愛襖奧壩罷擺敗頒辦絆幫綁鎊謗剝飽寶報鮑輩貝鋇狽備憊繃筆畢斃幣閉邊編貶變辯辮標鱉別癟瀕濱賓擯餅並撥缽鉑駁蔔補財參蠶殘慚慘燦蒼艙倉滄廁側冊測層詫攙摻蟬饞讒纏鏟產闡顫場嘗長償腸廠暢鈔車徹塵陳襯撐稱懲誠騁癡遲馳恥齒熾沖蟲寵疇躊籌綢醜櫥廚鋤雛礎儲觸處傳瘡闖創錘純綽辭詞賜聰蔥囪從叢湊躥竄錯達帶貸擔單鄲撣膽憚誕彈當擋黨蕩檔搗島禱導盜燈鄧敵滌遞締顛點墊電澱釣調諜疊釘頂錠訂丟東動棟凍鬥犢獨讀賭鍍鍛斷緞兌隊對噸頓鈍奪墮鵝額訛惡餓兒爾餌貳發罰閥琺礬釩煩範販飯訪紡飛誹廢費紛墳奮憤糞豐楓鋒風瘋馮縫諷鳳膚輻撫輔賦複負訃婦縛該鈣蓋幹趕稈贛岡剛鋼綱崗鎬擱鴿閣鉻個給龔宮鞏貢鉤溝構購夠蠱顧剮掛關觀館慣貫廣規矽歸龜閨軌詭櫃貴劊輥滾鍋國過駭韓漢號閡鶴賀橫轟鴻紅後壺護滬戶嘩華畫劃話懷壞歡環還緩換喚瘓煥渙黃謊揮輝毀賄穢會燴彙諱誨繪葷渾夥獲貨禍擊機積饑跡譏雞績緝極輯級擠幾薊劑濟計記際繼紀夾莢頰賈鉀價駕殲監堅箋間艱緘繭檢堿鹼揀撿簡儉減薦檻鑒踐賤見鍵艦劍餞漸濺澗將漿蔣槳獎講醬膠澆驕嬌攪鉸矯僥腳餃繳絞轎較階節傑潔結誡屆緊錦僅謹進晉燼盡勁荊莖鯨驚經頸靜鏡徑痙競淨糾廄舊駒舉據鋸懼劇鵑絹覺決訣絕鈞軍駿開凱顆殼課墾懇摳庫褲誇塊儈寬礦曠況虧巋窺饋潰擴闊蠟臘萊來賴藍欄攔籃闌蘭瀾讕攬覽懶纜爛濫撈勞澇樂鐳壘類淚籬離裏鯉禮麗厲勵礫曆瀝隸倆聯蓮連鐮憐漣簾斂臉鏈戀煉練糧涼兩輛諒療遼鐐獵臨鄰鱗凜賃齡鈴淩靈嶺領餾劉龍聾嚨籠壟攏隴樓婁摟簍蘆盧顱廬爐"
   +"擄鹵虜魯賂祿錄陸驢呂鋁侶屢縷慮濾綠巒攣孿灤亂掄輪倫侖淪綸論蘿羅邏鑼籮騾駱絡媽瑪碼螞馬罵嗎買麥賣邁脈瞞饅蠻滿謾貓錨鉚貿麼黴沒鎂門悶們錳夢謎彌覓冪綿緬廟滅憫閩鳴銘謬謀畝鈉納難撓腦惱鬧餒內擬膩攆撚釀鳥聶齧鑷鎳檸獰甯擰濘鈕紐膿濃農瘧諾歐鷗毆嘔漚盤龐拋賠噴鵬騙飄頻貧蘋憑評潑頗撲鋪樸譜棲淒臍齊騎豈啟氣棄訖牽扡鉛遷簽謙錢鉗潛淺譴塹槍嗆牆薔強搶鍬橋喬僑翹竅竊欽親寢輕氫傾頃請慶瓊窮趨區軀驅齲顴權勸卻鵲確讓饒擾繞熱韌認紉榮絨軟銳閏潤灑薩鰓賽三傘喪騷掃澀殺紗篩曬刪閃陝贍繕傷賞燒紹賒攝懾設紳審嬸腎滲聲繩勝聖師獅濕詩屍時蝕實識駛勢適釋飾視試壽獸樞輸書贖屬術樹豎數帥雙誰稅順說碩爍絲飼聳慫頌訟誦擻蘇訴肅雖隨綏歲孫損筍縮瑣鎖獺撻態攤貪癱灘壇譚談歎湯燙濤絛討騰謄銻題體屜條貼鐵廳聽烴銅統頭禿圖塗團頹蛻脫鴕馱駝橢窪襪彎灣頑萬網韋違圍為濰維葦偉偽緯謂衛溫聞紋穩問甕撾蝸渦窩臥嗚鎢烏汙誣無蕪吳塢霧務誤錫犧襲習銑戲細蝦轄峽俠狹廈嚇鮮纖鹹賢銜閑顯險現獻縣餡羨憲線廂鑲鄉詳響項蕭囂銷曉嘯蠍協挾攜脅諧寫瀉謝鋅釁興洶鏽繡虛噓須許敘緒續軒懸選癬絢學勳詢尋馴訓訊遜壓鴉鴨啞亞訝閹煙鹽嚴顏閻豔厭硯彥諺驗鴦楊揚瘍陽癢養樣瑤搖堯遙窯謠藥爺頁業葉醫銥頤遺儀蟻藝億憶義詣議誼譯異繹蔭陰銀飲隱櫻嬰鷹應纓瑩螢營熒蠅贏穎喲擁傭癰踴詠湧優憂郵鈾猶誘輿魚漁娛與嶼語籲禦獄譽預馭鴛淵轅園員圓緣遠願約躍鑰嶽粵悅閱雲鄖勻隕運蘊醞暈韻雜災載攢暫贊贓髒鑿棗責擇則澤賊贈紮"
   +"劄軋鍘閘柵詐齋債氈盞斬輾嶄棧戰綻張漲帳賬脹趙蟄轍鍺這貞針偵診鎮陣掙睜猙爭幀鄭證織職執紙摯擲幟質滯鍾終種腫眾謅軸皺晝驟豬諸誅燭矚囑貯鑄築駐專磚轉賺樁莊裝妝壯狀錐贅墜綴諄著濁茲資漬蹤綜總縱鄒詛組鑽亙羋嗇厙厴靨贗匭匱賾剄劌剴傴倀傖佇儕儂儔儼儷俁僨傯僂儻儐儺僉糴黌囅鳧兗袞褻臠稟塚訐訌訕謳詎訥詁訶詆詔詒誆誄詿詰詼詵詬詮諍諢詡誚誥誑誒諏諑諉諛諗諂誶諶諫謁諤諭諼諳諦諮諞謨讜謖諡謐謫譾譖譙譎讞譫讖巹陘隉鄺鄔鄴郟鄶鄆酈芻奐勱巰堊壙壢壚埡塏塒堝塤薌藶莧萇蓯苧蘢蔦塋煢蕘蓽蕎薈薺犖滎藎蓀葒蒔萵蒞蕕鶯縈蕆蕢蔞驀蘺蕷蘞藺蘄藪蘚奩尷捫摶撟摑摜撳攄攖擷擼攛嘰嘸囈嚦唄嚀噠嘵嗶噦噲嚌噥嘜嘮嗩嘖囀嘍嚳囁噯轡嚶嚕圇幃幬幘幗嶇峴嵐嶧嶠崢嶗崍嶸崳嶁巔徠獷獪猻獫玀獼餳飩餼飪飫飭飴餉餑餘餛餿饃饈饉饌廡賡廩懺憮慪愾悵愴懌慟懨惻愷惲慳愜慍憒懍閂閆闈閎閔閌闥閭閫鬮閬閾閶閿閽閼闃闋闔闐闕闞灃溈瀧瀘濼涇浹湞澮瀏滸潯淶潿瀆澠瀋淥漵灩灄瀅潷瀠瀟瀲瀦瀨灝騫邇逕邐屨弳嫵嫗媯姍婭嬈孌媧嫻嬋媼嬡嬪嬙嬤駔駟駙騶驛駑駘驍驊駢驪騏騍騅驂騭騖驁騮騸驃驄驏驥驤紆紂紇紈纊紜紕紓紺絏紱縐紼絀絎絳綆綃綈綾綺緋緄綞綬綹綣綰緇緙緗緹緲繢緦緶緱縋緡縉縝縟縞縭縊縑繽縹縵縲繆繅纈繚繒繾繰繯纘璣瑋玨瓏頊璽琿璉璦瓔璿瓚韙韞韜榪櫪棖樅梟櫛櫳櫨梔櫟檉椏橈楨榿樺檜欒欞櫝槧欏槨欖櫬櫚櫸檳櫧檣櫫櫓櫞簷檁歿殤殞殮殫殯軔軛軻轤軹軼軫轢軺軾輊輇輅輒輦輞輟輜輳轆轔戔戧戩甌曇曄暉曖賁貰貺貽贄"
   +"貲賅贐賑賚賕賧賻覘覬覡覿覦覯覲覷毿氌氬氳牘朧臚脛膾腡醃膃臏歟颮颯颶颼飆轂齏斕煬煒燉燁燜燾禰禎禪懟愨湣懣戇遝澩磯碭硨礪礱硤磽磧磣龕睞瞼佘羆羈釓釔釙釗釕釷釧釤鍆釵釹鈦鈑鈐鈁鈧鈄鈥鈀鈺鉦鈷鈳鈽鈸鉞鉬鉭鈿鑠鈰鉉鉈鉍鈮鈹鐸銬銠鉺銪鋮鋏鐃鐺銦鎧銖鋌銩鏵銓鉿鎩銚錚銫銃鐋銨銣鐒錸鋱鏗鋰鋯鋨銼鋝鋃鋟鋦錒錆錛錁錕錮錈錟錙鍥鍇鍶鍔鍤鎪鍰鏤鏘鏌鎘鐫鎦鎰鎵鑌鏢鏜鏝鏍鏞鏃鏇鏑鐔鏷鐓鑭鐠鏹鐙鑊鐲鐿鑣鍾穡鳩鳶鴇鴆鴣鶇鸕鴝鴟鷥鴯鷙鴰鵂鸞鵓鸝鵠鵒鷳鵜鵡鵪鵯鶉鶘鶚鷂鶼鸚鷓鷚鷯鷦鷲鷸鷺鸛癤癘癆癇癉瘞癭癮癩癲竇窶襠褳襝襇褸襤繈皸耬聹聵頇頎頏頡頜頦頷顎顓顳顢顙顥顰虯蟣蠆蜆蠔蠣蟶蛺蟯螄蠐蟈蠑螻罌篤筧籩篳箏簀篋籜簞簫簣籪籟艤艫嫋羥糝縶麩趲釅釃鹺躉蹌蹠躒蹺蹕躚躋躓躑躡蹣躕躪躦觴觶靚靂霽靄齔齟齙齠齜齦齬齪齷黽黿鼉雋讎鑾鏨魷魴鮁鱸穌鮒鱟鮐鮚鮪鮞鱭鮫鯗鱘鯁鱺鰱鰹鰣鰷鯀鯊鯇鯽鯖鯪鯫鯡鯤鯧鯢鯰鯛鯔鰈鱷鰍鰒鰉鼇鰭鰨鰥鰩鰳鰾鱈鰻鱖鱔鱒鱧韃韉鶻髏髖髕魘魎饗饜鬢黷黲鼴";

  public G2B5Filter(Stream sink)
  {
   //System.Web.HttpContext.Current.Response.ContentEncoding=Encoding.GetEncoding(950);
   _sink = sink;

  }

  // The following members of Stream must be overriden.
  public override bool CanRead
  {
   get { return true; }
  }

  public override bool CanSeek
  {
   get { return true; }
  }

  public override bool CanWrite
  {
   get { return true; }
  }

  public override long Length
  {
   get { return 0; }
  }

  public override long Position
  {
   get { return _position; }
   set { _position = value; }
  }

  public override long Seek(long offset, System.IO.SeekOrigin direction)
  {
   return _sink.Seek(offset, direction);
  }

  public override void SetLength(long length)
  {
   _sink.SetLength(length);
  }

  public override void Close()
  {
   _sink.Close();
  }

  public override void Flush()
  {
   _sink.Flush();
  }

  public override int Read(byte[] buffer, int offset, int count)
  {
   return _sink.Read(buffer, offset, count);
  }
  
  /// <summary>
  /// 实际处理字符替换的作业,将简体字和繁体字进行替换。
  /// </summary>
  /// <param name="buffer"> </param>
  /// <param name="offset"></param>
  /// <param name="count"></param>
  public override void Write(byte[] buffer, int offset, int count)
  {
   Encoding e=Encoding.GetEncoding(936);  //936是GB2312编码,950是Big5编码

   string str=e.GetString(buffer,offset,count);
  
   for(int i=0;i<str.Length;i++)
   {
    int j=_sGB.IndexOf(str[i]);
    if(j!=-1)str=str.Replace(_sGB[j],_tGB[j]);
   }
   e=Encoding.GetEncoding(System.Web.HttpContext.Current.Response.Charset);
   _sink.Write(e.GetBytes(str), 0, e.GetByteCount(str));
      
  }    

 }

 public class EncodingFilter
 {
  Page thisPage;

  public EncodingFilter(Page mPage)
  {
      thisPage=mPage;
  }

  /// <summary>
  /// 对输入的流对象进行编码,然后Write
  /// </summary>
  /// <param name="EncodingStyle"></param>
  public void G2BEncoding(string EncodingStyle)
  {  
   //======================== 公共函数 Start =============================  
   thisPage.Response.ContentEncoding=Encoding.GetEncoding("GB2312");

   if(EncodingStyle=="BIG5")
   {     
    thisPage.Response.Filter = new G2B5Filter(thisPage.Response.Filter);
    thisPage.Response.Charset="BIG5"; 
   }

   if(EncodingStyle=="GB2312")
   {
    thisPage.Response.Charset="GB2312"; 
   }
   
   //======================== 公共函数 End =============================  
  }
 
 }
   

转自:http://blog.csdn.net/hnwanghb/archive/2005/03/15/319854.aspx



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=320652


- 作者: cyber2005 2006年12月12日, 星期二 15:03  回复(0) |  引用(0) 加入博采