网站首页 | J1212大学论坛 | 公务员考试 | CEAC网络工程师 | 软件水平考试 | 专升本考试 | 大学英语4-6级 |计算机等级考试| C/C++编程 | 学习法语 | TOEFL考试资料 | 大学怎么过 | 中英文歌词下载 | 免费资料下载 | 大学知识面 | Linux网络课程 | Java/JSP教程 | 古诗词选录|
公告消息
大学生考试网站

  本站为大学生考试提供全面,及时,准确的服务!还为当代大学生提供学习生活的指点。来源于大学生,服务到大学生中去,是本站的理念!免费是本站的筹码!
栏目分类
 南昌大学计算机系92班级论坛

 ■考试中心
 ◆软件水平考试
 ◆专升本考试
 ◆公务员考试
 ◆CEAC网络工程师
 ◆大学英语四六级
 ◆计算机等级考试
 ◆Toefl考试资料

 大学生频道
 ◆Java/JSP教程
 ◆Linux网络课程
 ◆C/C++编程
 ◆大学怎么过
 ◆大学知识面
 ◆经典英文演讲录音
 ◆招聘信息就业指导
 ◆学习法语
 ◆古诗词选
 下载频道
 ◆电脑软件
 ◆中英文歌词下载
 ◆学习资料
 图库频道
 ◆大学时代相册
 ◆经典图片
 影视频道
 ◆FLASH专区
 ◆站长之家
 ◆站长留言簿
 
 
网站首页

李继名的文章

1.Java中正确使用字体编码全攻略 点击查看更大文章扫描图(李继名 吴军丽于2005年11月14日发表) 《计算机世界》链接

2.如何自动截获输出到打印机的文本数据 (吴军丽 李继名于2003年1月22日发表)《计算机世界》链接

3. Delphi 中自做动态显示的控件 (李继名于1999年5月发表)《计算机世界》链接

 

 

深圳赞

美在深南道,乐于欢乐谷;

五湖四海人,一天一层楼.

 

异地情

阔地蓝天走北美,叹古落雁见巴黎.

南洋地少腾龙起,香港人多八达通.

Java中正确使用字体编码全攻略

李继名 吴军丽

Java是目前最流行的真正面向对象的编程语言之一,其简单易学曾经使得中国留学生在硅谷名噪一时..不过要想成为真正的Java高手,还有很多要学.Java支持UTF-8,ISO-8859-1,GBK等各种字体编码.笔者两年前就被这个中文字体编码所困住.经过网上大量查询,发现Java中字体编码的问题难倒了不少程序员,网上也有不少关于Java中如何正确显示中文的文章,但都不够全面.笔者特意总结如下,如有不同意见,还望指教.
影响Java中字体编码正确显示的有几个因素: 1) 数据库的连接方式 2) 网页使用的字体编码 3) 数据库里存放数据的字体编码 4) Java的缺省字体编码. 如果在编程中遇到不能正确显示中文,先要弄清楚以上几项所使用的字体编码,再分析并找出原因,即可解决问题.
众所周知,JSP其实就是Java的一种,由于和网页有关,网页有自己的中文编码系统,所以JSP处理中文要比纯Java的类文件更为麻烦.本文测试的数据库是MySQL3.2,数据库连接驱动是用org.gjt.mm.mysql.Driver这里主要讨论UTF-8和GBK的显示,(实际上GB2312是GBK的一个子集,Java中可以使用GBK来代替GB系列). 我们先来研究JSP中字体编码问题,下面第一到第六点是针对JSP的(因为从数据库里读出中文数据与写入中文有所区别,咱们分别说明,前三点是从读取数据库到显示在网页,后三点是从网页输入到存入数据库),第七到第九点针对纯Java的类文件. 以下rs表示ResultSet的一个实例,执行Select语句之后数据集.

一. 数据库连接方式使用UTF-8(在连接数据库的驱动后面加上这句参数useUnicode=true&characterEncoding=UTF-8), 例如jdbc:mysql://localhost/DBVF?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8.
从数据库里读出中文,显示在使用GBK的JSP的网页里. 如果数据库里存放的字体编码是UTF-8,在JSP中使用 str=new String(rs.getBytes(1),”UTF-8”)或者str=rs.getString(1),可以正确显示中文.如果数据库里存放的是GBK数据,那么JSP中也要使用str=new String(rs.getBytes(1),”GBK”),,即可显示正确的中文.值得注意的是如果页面使用UTF-8,数据库里存放的是UTF-8,也可以用str=new String(rs.getBytes(1),”GBK”)能正确显示中文. 如果网页是UTF-8,而数据库里存放的是GBK,无法直接显示中文,需要2步转换, str=new String(rs.getBytes(1),"GBK");再str=new String(str.getBytes("UTF-8"),"GBK");才可以正确显示中文

二. 数据库连接方式使用GBK(在连接数据库的驱动后面加上这句参数useUnicode=true&characterEncoding=GBK)例如jdbc:mysql://localhost/DBVF?autoReconnect=true&seUnicode=true&characterEncoding=GBK
从数据库里读出中文,显示在使用GBK的JSP的网页里. 如果数据库里存放的字体编码是UTF-8,在JSP中一定要使用 str=new String(rs.getBytes(1),”UTF-8”),可以正确显示中文.如果数据库里存放的是GBK数据,那么JSP中也要使用str=new String(rs.getBytes(1),”GBK”),或者直接使用str=rs.getString(1),即可显示正确的中文. 如果网页是UTF-8,而数据库里存放的是GBK,只能用str=new String(rs.getString(1).getBytes("UTF-8"),"GBK");方法来显示中文; 如果网页是UTF-8,而数据库里存放的是UTF-8,可用str=new String(rs.getBytes(1),”GBK”);或者rs.getString(1)方法来显示中文

三. 使用缺省数据库连接方式 (即连接数据库的驱动后面没有这句参数useUnicode=&characterEncoding=)例如jdbc:mysql://localhost/DBVF?autoReconnect=true. 没有参数useUnicode=true&characterEncoding,表示使用默认的ISO-8895-1编码.
1. 从数据库里读出中文,显示在GBK的网页里. 如果数据库里存放的字体编码是UTF-8,在JSP网页中一定要使用语句 str=new String(rs.getBytes(1),”UTF-8”) 或者str= new String(rs.getString(1).getBytes("ISO-8859-1"),"UTF-8");,可以正确显示中文.如果数据库里存放的是GBK数据,那么JSP中也要使用str=new String(rs.getBytes(1),”GBK”)或str=new String(rs.getString(1).getBytes("ISO-8859-1"),"GBK");,即可显示正确的中文.
2. 如果网页是UTF-8,不能直接正确显示GBK, 需要2步转换, str=new String(rs.getBytes(1),"GBK");再str=new String(str.getBytes("UTF-8"),"GBK");才可以正确显示中文.如果数据库里存的是UTF-8,直接用str=new String(rs.getBytes(1),"GBK");或者str=new String(rs.getString(1).getBytes("ISO-8859-1"),"GBK")可以显示中文

以上是读取数据库里中文正确显示在网页上,下面三点是如何正确存入数据库.

四. 数据库连接方式使用UTF-8编码
JSP中要把网页输入的中文存入数据库,通常有一个提交(Submit)的过程,是用str=request.getParameter("username");然后执行update或者insert语句来存入数据库.如何赋值给str很重要.而且这里中文输入与网页所使用的字体编码有关
1. 网页使用UTF-8,使用str= new String(request.getParameter("username").getBytes("ISO-8859-1"),"UTF-8"), 或者str= new String(request.getParameter("username").getBytes(),"UTF-8"),都可以使得存到数据库里的数据是UTF-8码.
2. 网页使用GBK,使用str= new String(request.getParameter("username").getBytes(),"GBK"),那么存入数据库的是UTF-8
3. 值得注意的是使用UTF-8的数据库连接方式,不能存得GBK

五. 数据库连接方式使用GBK编码
1. 输入使用GBK网页,存到数据库里是GBK的方法:str= new String(request.getParameter("username").getBytes("ISO-8859-1"),"GBK"),.或者str= new String(request.getParameter("username").getBytes(),"GBK"),
2. 网页使用GBK,想存入UTF-8到数据库里,要分2步: 先str=new String(request.getParameter("username").getBytes(),"GBK"); 再 str=new String(str.getBytes("UTF-8"),"GBK");即可.
3. 网页使用UTF-8,而且使用str= new String(request.getParameter("username").getBytes("ISO-8859-1"),"GBK"), 或者str= new String(request.getParameter("username").getBytes(),"UTF-8"),那么存到数据库里的数据是UTF-8编码.
4. 网页使用UTF-8,而且使用str= new String(request.getParameter("username").getBytes("ISO-8859-1"),"UTF-8"), 那么存到数据库里的数据是GBK编码.

六. 数据库连接方式使用缺省,即不使用参数useUnicode和characterEncoding
1. 网页使用GBK,如果使用str= request.getParameter("username"),或者str= new String(request.getParameter("username").getBytes()),那么在数据库里的数据是GBK码.. 网页使用UTF-8 和使用str= request.getParameter("username"),则存入数据库是UTF-8.
2. 如果使用str= new Stering(request.getParameter("username").getBytes("ISO-8859-1")),那么根据网页提供的字体编码而存到数据库里,比如是UTF-8的网页,那么存到数据库中就是UTF-8,如果使用GBK网页,那么存到数据库里的字就是GBK.,
3. 如果使用str= new String(request.getParameter("username").getBytes("UTF-8”),”UTF-8”)这一种组合能存到正确的数据以外存,其他存到数据库里的数据都是乱码或者错误码.在这个UTF-8组合的特例中.网页使用的是GBK,则存放到数据库里就是GBK,网页使用UTF-8,那么存到数据库里的就是UTF-8.
4. 网页是GBK要存得UTF-8,一定需要2步: company=new String(request.getParameter("company").getBytes(),"GBK"); company=new String(company.getBytes("UTF-8"));
5. 网页是UTF-8的,不能存得GBK在数据库里.一句话,改种数据库连接方式不能存得GBK码.
以上所有的都是基于JSP网页和数据库交换数据,下面讨论一下纯JAVA编程下的字体编码转换.

七. 数据库连接方式使用UTF-8编码
1. 数据库里的中文是UTF-8,可以转换为GBK,但不能把GBK存入数据库!
2. 数据库是GBK,如何转换为UTF-8: 使用content=new String(rs.getBytes(2),"GBK"); 直接将content存入数据库就为UTF-8
八. 数据库连接方式使用GBK编码
1. 数据库里的中文是UTF-8,如何转换为GBK: 使用content= new String(rs.getString(2).getBytes(),"UTF-8"); 再直接使用update或者insert语句插入到数据库,即存得GBK.如果使用content= new String(rs.getString(2).getBytes(),"GBK");或者content= new String(rs.getString(2).getBytes());再存入数据库,即存得还是UTF-8编码
2. 数据库里的中文是GBK,如何转换为UTF-8: 使用content= new String(rs.getString(2).getBytes("UTF-8"))或者content= new String(rs.getString(2).getBytes("UTF-8"),”GBK”); 再直接使用update或者insert语句插入到数据库,即存得UTF-8.
3. 如果某个String是GBK,要转换为UTF-8,也是用这种办使用content= new String(GBKstr.getBytes("UTF-8"))或者content= new String(GBKstr.getBytes("UTF-8"),”GBK”); 如果某个String是UTF-8,要转换为GBK,应该使用new String(UTFstr.getBytes("GBK"),"UTF-8");
九. 数据库连接方式使用缺省,即不跟参数
1. str2=new String(GBKstr.getBytes("UTF-8"),"ISO-8859-1");可以将数据库里的GBK编码转换为UTF-8.
2. 读取UTF-8然后存入UTF-8,则用str1=new String(UTFstr.getBytes(),"ISO-8859-1");或者str1=new String(UTFstr.getBytes("GBK"),"ISO-8859-1");
3. 不能实现数据库里的UTF-8转换为GBK:
总结: 如果采用UTF-8的数据库连接方式或者缺省数据库连接方式,那么无法将UTF-8转换为GBK:而GBK的数据库连接方式可以实现UTF-8和GBK的相互转换.建议大家采用GBK的数据库连接方式

关键词: 字体编码, JAVA, UTF-8, GBK, ISO-8859-1,JSP
参考: <<谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词>>
作者简介: 李继名 广州爱奇通讯技术有限公司(Atchik China) 软件开发项目经理 从事JAVA开发和J2EE设计多年.
联系地址: 广州 邮编:510655
Email: ljm1810@sohu.com ; ljm1810@hotmail.com
吴军丽: 新加坡国立大学在读EE博士. 从事JAVA研究和开发多年.
Email: junli_wu@hotmail.com

如何自动截获输出到打印机的文本数据

吴军丽 李继名
2003-1-22 10:47:43


所有的应用软件当中,几乎都会提供打印结果的功能,但大部分的软件并不提供输出结果到文本文件功能(如速达,用友和金碟应用软件等能够打印,但不能将结果直接输出到文本文件;再比如一些与硬件配套的应用软件类似PeakNet等软件,也只能打印,不能输出到文本文件)。有时候客户需要对这些结果进行再次处理分析和统计。传统的方法,只能把打印到纸上的数据手工输入电脑,再利用自己的统计分析软件来处理这些数据。如果这些数据量大,仅靠人工输入是不可能的。笔者经过探讨和测试,找到了一个方法,实现了他们的无缝连接。为方便起见,以下称本文最早提到提供打印结果功能的软件为软件A,对这些结果再次进行处理分析和统计的软件为软件B。

问题(一)描述:
由于软件A不提供打印文本数据到文本文件中,但可以通过打印机打印出来。比如有些监控机器的软件一直要监控并且不时产生数据,而这些数据又需要重新处理和统计。我们需要的是文本文件。如何解决这个问题,请详见解决思路1),2),3)。
解决思路:
1) 虽然有些软件(比如Excel, Word等)在打印功能中提供“打印到文件”,但实际上打印出来的文件并不是我们所想要的纯数据的文本文件,而是有一堆的打印控制信息在里面。所以我们必须创建一个文本文件打印机,然后选该文本文件打印机为软件A默认的打印机。这样我们才能得到纯数据的文本文件。
2) 创建一个文本文件打印机:在Windows中创建一个新的本地打印机,选“FILE(打印到文件)”端口(注意不是打印机端口也不是串行口);然后需要选一个打印驱动程序(当然,你是牛人的话,自己可以写一个打印驱动程序,但写打印驱动程序对大多数程序员来说是一件很困难的事情)。
3) 尽管Windows提供了数十个厂家的打印驱动程序,但唯独只有Generic提供了文本文件打印程序,所以只能选Generic的“Generic/Text only” 作为该文本文件打印机的驱动程序。建好了文本文件打印机后,再将软件A默认的打印机重新指向到该文本打印机。这样我们再打印后就可以得到文本文件了。
问题(二)描述
我们的确可以得到文本文件,但新的问题又来了。当软件A用默认的文本文件打印机打印数据到文件时,会弹出一个输入文件名的对话框,此时如果没有操作员使用计算机,软件A会停留住。不为了不要人工输入文件名,请详见解决思路4),5)。
解决思路:
4) 每次打印到文本文件时候,系统会弹出一个对话框,需要输入文件名。对某些一天24小时不停运作的软件来说,靠人工输入文件名是不可能的。
5) 因此,我们可以设计一个程序,或者在软件B中增加一个功能,它的任务就是先找到该对话框,然后自动模拟键盘输入文件名到这个弹出的对话框,并且模拟鼠标点击“确定”按扭来关闭这个对话框,这样无须人工操作就能生成文本文件。
笔者设计的这个软件就是为了解决问题(二)。该软件不光是针对打印弹出的对话框,也可以针对其他一切类似需要人工输入的对话框。该程序代码还有助于解决如何自动关闭弹出的消息框的问题。软件B的数据来源可以是指定文件名的文本文件即我们刚刚得到的文本文件。它应该会定时地去读取这个文本文件,然后进行分析处理和统计。
笔者主要是采用了Windows API 函数,下面先对几个API函数简单的介绍一下:
FindWindow( LPCTSTR lpszClassName, LPCTSTR lpszWindowName ):
查找指定类名和窗口名的窗口,返回一个窗口句柄。GetWindowText( HWND hWndLPTSTR lpString, int nMaxCount ):
获得窗口的文本,如果该窗口是对话框,则lpString返回它的标题。
FindWindowEx( HWND hwndParent, HWND hwndChildAfter, LPCTSTR lpszClass,
LPCTSTR lpszWindow ):
在指定的父窗口内查找第一个指定类名的子窗口,返回一个窗口句柄。
SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ):
发一个消息给指定窗口,直到消息被处理完才返回。
SendNotifyMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam):
发一个消息给指定窗口。
有了设计思想后,再来选定一种程序语言。由于大部分语言都支持Windows API函数,所以选什么语言并不太重要,比如DELPHI,VC++,C++BUILDER,VB等都可以,笔者采用的是VC++6.0。
HWND a_window,b_window,f_window;
CFileException e;
char* pFileName ;
char pbuf[100];
memset(pbuf,0,100);
LPTSTR lpString;
CString filename=theApp.GetProfileString("Parameter","FileName","result.txt");//从配置文件中读取要填入对话框的文件名,也就是打印到文件的文件名
CString title=theApp.GetProfileString("Parameter","DialogName","打印到文件");//从配置文件中读取要输入文件名的对话框的标题,如果是英文软件就应该是”Print to file”
f_window=::FindWindow((LPCSTR)(DWORD)WC_DIALOG,title);//找到要输入文件名的对话框的窗口,获得它的句柄。
memset(pbuf,0,100);
::GetWindowText(f_window,pbuf,15);
lpString=title.GetBuffer(15);
if(*lpString==*pbuf) {
pFileName=filename.GetBuffer(20);
CFile::Remove( pFileName );//如果已经有同名文件存在,则先删除。
filename.ReleaseBuffer();
//注意: CEdit和CButton 都是CWnd 的子类,所以都是窗口,也可以用::FindWindowEx查找得到。
a_window=::FindWindowEx(f_window,NULL,"Edit",NULL);//找到要输入文件名的编辑框。
lpString=filename.GetBuffer(15);
::SendMessage(a_window, WM_SETTEXT,NULL,(LPARAM)lpString);//模拟键盘输入文件名
b_window=::FindWindowEx(f_window,NULL,"Button",NULL);// 找到”确定”按扭
::SendNotifyMessage(b_window, WM_LBUTTONDOWN,MK_LBUTTON,NULL);//给”确定”按扭发送一个按下鼠标左键的消息
::SendNotifyMessage(b_window, WM_LBUTTONUP, NULL,NULL);// 再给”确定”按扭发送一个弹起鼠标左键的消息,第三个参数一定要是NULL,否则不成功。
}
title.ReleaseBuffer();
本程序在VC++6.0下编译,并在Window98,window2000,window XP运行通过。如果有谁需要该程序,我们可以免费Email给有需要的人。

Delphi 中自做动态显示的控件

李继名


---- Delphi以其优秀的界面和简单的用法深受广大程序员的喜爱.笔者经过摸索,自做了一个具有动态显示特性的控件。只需在主程序中调用该控件的一个方法即可实现动态显示。在动态显示的同时,为了不影响主程序做其他的事情,笔者采用了比较流行的线程技术。
---- 一. 方案
---- 自做一个父类为TEdit的控件,应该有一个Text属性,能自由地输入要动态显示的内容; 并且有一个MoveShow方法,使的Text的内容能动态的显示。在主程序中创建一个线程,启动线程时,调用该控件的MoveShow方法。
---- 二. 制作控件
---- 启动New Component,选Tedit为父类,建立L_Tedit1类,并创建L_edit.pas. 再编写L_edit.pas 如下:
unit L_Edit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type
L_TEdit1 = class(TEdit)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner:TComponent); override;
procedure MoveShow;
published
{ Published declarations }
property Text;
end;

procedure Register;

implementation
constructor L_TEdit1.Create(AOwner:TComponent);
begin
inherited create(aowner);
color:=clblue;
font.Color:=clyellow;
font.Size:=12;
font.Name:= '@仿宋_GB2312';
tabstop:=false;
update;
end;

procedure L_TEdit1.MoveShow;
var
edit_length,i:integer;
edit_char:char;
chars: string;
begin
chars:='';
if (length(text)=0) then
text:=’Welcom you to use the software!’;
edit_length:=length(text);
for i:=1 to edit_length do
begin
edit_char:=text[1];
if (Ord(edit_char) >127) then
if length(chars) >1 then
begin
text:=copy(text,2,edit_length-2)+chars;
chars:='';
end
else
begin
chars:=copy(text,1,2);
text:=copy(text,2,edit_length-1);
end
else
begin
text:=copy(text,2,edit_length-1)+edit_char;
end;
update;
sleep(100);
end;
end;


procedure Register;
begin
RegisterComponents('Samples', [L_TEdit1]);
end;

end.
再保存该文件。
---- 启动Image Editor 创建L_Edit.dcr , 选New- >Bitmap,自己做一个图标,保存名为L_TEDIT1(与新建的类同名)。注意L_Edit.dcr 与L_Edit.pas 要在同一个目录中(缺省为\delphi\lib目录中。再单击Install Component. 选Into new package属性页,填上L_Edit.pas 的路径和文件名,并在该路径下新建L_Edit1.dpk 文件。之后一直单击OK即可。此时我们可以在Delphi 的工具栏Sample 一项中看到自己创建的图标。
---- 三. 编写主程序
---- 在主窗体Form1中放一自己创建的控件,在Text的属性中填上要显示的文字(中英文都可)。与该窗体对应的L_unit1.pas内容如下:
unit L_Unit1;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls, L_Edit;

type
Tmythread=class(TThread)
protected
procedure Execute; override;
end;
TForm1 = class(TForm)
L_TEdit11: L_TEdit1;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
MyThread1:TMyThread;
implementation

{$R *.DFM}
Procedure TMyThread.Execute;
begin
while true do form1.L_TEdit11.MoveShow;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
MyThread1:=TMyThread.Create(false);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage('Welcome You!');
end;

end.
---- 该程序在Delphi4.0 for win95 下编译运行通过。

 

   友好链接:

 
首 页 网站介绍 支持论坛 南昌大学计算机系92级班级论坛 联系我们
@j1212.com版权所有,本站所有资料内容和图片文章未经j1212.com或作者本人同意,其他媒体一律不得转载@
Copyright@http://www.j1212.com all rights reserved
Powered by www.j1212.com