SC:我正在尝试一个图形化的计数器,在HTML里是这样写的:come here now have <img src="http://127.0.0.1/cgi-bin/num.pl?mydata.txt">PERL的程序如下: (略)我觉得十分清晰,可就是不能成功,能不能告诉我这是为什么?
李海:你把问题想得太简单了。按照你的思路,你把10个数字分别放在10个GIF文件中,然后在调用时按下面的方式返回图象:
for ($i=0;$i<$size;$i++) {
$x=substr($num,$i,$i+1);
$which=$imagedir.$image[$x];
print "Content-type:image/gif\n\n";
open(IMG,"$which");
print<IMG>;
close(IMG);
}
一个Perl程序一次只能返回一个GIF图象,而不能象你那样将几幅图象首尾相节地返回,所以你应该将多位数字组合成一幅GIF图象,然后返回。由于GIF格式比较复杂,Perl处理起来有困难,所以一般图象组合的工作是另外调用C语言程序(通常称作FLY)完成的。如果使用100%的Perl代码来实现,一般只能处理X-Bitmap格式,这种格式是黑白的,不好看。此外,也有借助服务器端嵌入(SSI)来实现的彩色图形计数器。在http://cgi.resourceindex.com/Programs_and_Scripts/Perl/Access_Counters/你可以找到各种用Perl实现的计数器。这个站点也包括使用其他语言实现的计数器和CGI资源。
回到开始SowenChueng:你好,我是贵刊的忠实读者之一,近来正在研究网络上的编程,遇到了一些疑难,希望得到贵刊的帮助。朋友说现在中国的服务器基本都只支持PERL写的CGI,是这样的吗?如果真的,那用Dephi、C语言来写CGI又还有什么意义?又听说很多服务器也不支持SSI,是吗?我现在用的是Sambar4.2服务器软件,为什么以下一段代码无法被解释呢?
<p>
<h1>Welcome to my server at<! --#echo var="SERVER_NAME"-->
<p><h1>
<hr><h1>The file you are looking is <! --#echo var="DOCUMENT_NAME"-->
<hr>
<h1>
The current time is :<! --#echo var="DATA_GMT"-->
我不知道这到底有什么错,贵刊能否刊登一些关于这方面的文章呢?内嵌了SSI的HTML的后缀名是否就用HTML就可以了?
李海:几乎所有的WWW服务器都支持非Perl的CGI,而并不是只有Perl才能编写CGI。但现在国内使用Perl编写CGI比较多,主要是三方面:1、Perl比Delphi、C更容易学;2、所有平台对Perl的支持都差不多,兼容性好,而如果你使用Windows 95系统开发,而你的服务器是Unix的,那么你很难在本机编译生成Unix的可执行文件;3、提供CGI权限的主页服务商出于安全考虑,有时限制用户只能使用Perl,因为这样管理员在必要地时候可以随时检查Perl源程序,避免恶意攻击服务器的行为。
绝大多数的WWW服务器都支持服务器端嵌入(Server-Side Include,SSI),即使象Sambar4.2服务器这样的免费服务器也支持SSI。但是有的服务器管理员出于安全考虑,禁止用户使用CGI权限,当然也就不能使用SSI。为了使用SSI,Sambar和大多数服务器一样规定要将文件扩展名改为.shtml(个别服务器还允许使用.shtm),只有这样的文件中才能使用SSI,否则服务器将会忽略普通的HTML文件中的SSI指令。SSI指令就是一些服务器段定义的特殊的HTML标记,服务器会在送出HTML文档前对这些标记进行处理,然后将转换后的HTML文本送出,最终用户得到是普通的HTML文本,这样做对浏览器并没有特别的要求,但不同的服务器支持的SSI指令有所不同。.shtml文本中的每个SSI指令都是包含在<!-- -->中的,看起来象是注释。除了必须使用.shtml扩展名,你的“<! --”中在“!”和“-”之间多了一个空格,应该删掉这个空格。这样处理之后,你的前两个SSI就都正确了,但第三个仍然不正确,将得到如下错误信息:
SSI - unknown echo value data_gmt SSI processing failure.
如果你想显示服务器的时间,应该使用DATE_GMT,而不是DATA_GMT。
此外,如果你在本地使用Sambar服务器,请注意只有你使用http://localhost/… 这样的URL时,Sambar才会处理.shtml文件,而如果使用file://…这样的URL,Sambar不会处理SSI。如果你想得到更多的有关SSI的信息,可以在Sambar启动后输入:http://localhost/help/ssi.htm。
回到开始lihanrong:请问:在用ASP编程的时候怎样实现将以二进制方式存在ORACLE中的的JPEG图像直接输出到页面上,我用VB写了个DLL可以把数据写成文件再显示,但很不方便,我想知道能不能用BINARYWRITE方法直接实现,而且要求是能图像和文本同页面显示的,有无好办法。最好提供源代码。
李海:显然每次把图象数据写入文件再显示是比较麻烦的,你可以编写一个.asp(比如show.asp),由这个show.asp返回JPEG图形,而在需要显示图形的地方写上:
<img src="show.asp">
关键是show.asp怎么编写。如果你的Oracle的RAW/LONG RAW字段中只包含JPEG图形数据,你可以直接采用下面的代码:
<%@ LANGUAGE="VBSCRIPT" %>
<%
'清除已有的HTTP头信息
Response.Expires = 0
Response.Buffer = TRUE
Response.Clear
'设置HTTP头为图象类型
Response.ContentType = "image/jpeg"
Dim strTemp
Set oConn = Server.CreateObject("ADODB.Connection")
'建立连接
oConn.Open "DSN=Ovteam;UID=userid;PWD=password;"
sSQL = "Select ID, IMG from IMAGE where ID = 1"
Set oRS = Server.CreateObject("ADODB.Recordset")
oRS.Source = sSQL
oRS.ActiveConnection = oConn
oRS.Open
strtemp = oRS("IMG")
Response.BinaryWrite(strTemp)
Response.End
oRS.Close
Set oRS = nothing
oConn.Close
Set oConn = nothing
%>
但是,如果你的JPEG图象是使用Access或类似的工具插入到Oracle数据库中的,那么在数据中会包括一个Ole数据头,这样你就不能直接使用BinaryWrite了,需要先行预处理一番。具体做法可以参考微软的Knowledge Base的文章“Q175261 HOWTO: Retrieving Bitmap from Access and Displaying In Web Page”(http://support.microsoft.com/default.aspx?scid=kb;EN-US;q175261)。如果你了解如何使加入的图象不包括Ole数据头,可以参考“Q185958 HOWTO: Use ADO GetChunk/AppendChunk with Oracle for BLOB Data”( http://support.microsoft.com/support/kb/articles/Q185/9/58.asp)。
回到开始
小东瓜:想请请教一个问题:我在Word97中有一个表格,其数据都存在Access 数据库中,如何引用这些数据批量打印?整天用Ctrl+C,Ctrl+V太烦了, 是否要用宏来写?望赐教,不胜感激!
李海:Word 97具有直接插入数据库的能力。首先在工具条上击右键,选择“数据库”工具条。然后在图1所示的工具条上选择“插入数据库”按钮。这时会出现一个文件对话框供你选择数据库。然后,你选择要插入的表或查询,你也可以设置查询选项,这样只插入满足要求的数据。如果希望源数据改变时可更新 Word 表格中的数据,请选中“将数据作为域插入”复选框(图2)。Word 将这些 Word 表格中的这些数据作为 DATABASE 域插入,它们与源数据链接。如果要更新这些域,请按住 F9 键单击表格,或在表格的快捷菜单上选择“更新域”。你可以在Word中对这个表格进行字体、颜色等设置。
图1 在Word 97中插入数据库
图2 插入数据时,可以指定数据作为域插入
回到开始ChangJun :我想问一个VC编程的问题。VC5, Win95下, 用MFC做SDI程序。想直接在程序中更改显示模式如何实现。目前我只能访问系统注册表HKEY_CURRENT_CONFIG\DISPLAY\SETINGS来获知当前的显示分辨率和颜色数。
李海:我们的很多回答都会涉及到一些未公开的Windows API,所以我常觉得我们好象是在发布一些游戏秘技。不过这次我们所介绍的API都是可以在Win32 API手册上可以找到的。关键的API函数是EnumDisplaySettings和ChangeDisplaySettings。前者用来获得当前显示驱动所支持的所有显示模式,而后者用来改变显示模式。如果有个程序改变了显示模式,Windows会向所有正在运行的程序发送WM_DISPLAYCHANGE消息。获得当前显示模式可以使用下面的函数,它比访问注册表可靠。
BOOL CVideoModes::GetCurrentVideoSettings(DEVMODE *devmode){
HWND hwndDesktop = GetDesktopWindow();
HDC hdc = GetDC(hwndDesktop);
devmode->dmSize = sizeof(DEVMODE);
devmode->dmBitsPerPel = GetDeviceCaps(hdc,BITSPIXEL);
devmode->dmPelsWidth = GetSystemMetrics(SM_CXSCREEN);
devmode->dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
devmode->dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
return TRUE;
}
下面的代码展示了如何使用EnumDisplaySettings获得当前支持的所有显示模式:
int modenum, done;
DEVMODE devmode;
done = 0;
modenum = 0;
do
{
done = !EnumDisplaySettings(NULL, modenum, &devmode);
AddToList(&devmode);
modenum++;
} while (!done);
设置显示模式的方法如下:
rc = ChangeDisplaySettings(&devmode, CDS_FULLSCREEN));
这里的devmode就是前面使用EnumDisplaySettings获得的。如果设置正常,返回值为DISP_CHANGE_SUCCESSFUL
如果您有任何建议,请给我发电子邮件:
。
版权所有 李海,热情软件屋 1997-2006