2007-01-20

挑战极限!制作220分钟vcd光盘

一张700mb容量的普通光盘能刻录多长时间的vcd视频?80分钟还是更短?如果我说最多能刻录360分钟,而且画面质量并不比普通vcd差,可能你会说那是用rmvb格式吧?如果我说这张光盘还能在vcd、dvd影碟机上播放,而且用的就是普通vcd使用的mpeg编码,你相信吗?



一、kvcd。



首先可以肯定地告所你,这种技术是存在的,它的名字就叫做kvcd。它并不是一种新



的压缩编码技术,而是基于mpeg1压缩算法的一种非标准vcd编码方式。



二、kvcd模板。



Kvcd的作者设计了专用的编码模板文件,这些模板使用在mpeg压缩品质最好的软件“TMPGEnc plus”上,通过优化的动态码率和修正的量化矩阵来压缩编码,保证了生成的视频质量。



Kvcd编码模板文件在http://kvcd.net/dvd-models.html页面上获得,在页面中有许多不同压缩质量的模板,右击带下划线的模板名称,选择“另存为”就可以将这些扩展名为“MCF”的模板文件保存到硬盘中,我们国家使用的是pal制式,要下载对应的模板。



这里的模板文件按照不同的类型分别以红、绿、蓝背景显示,其中红色背景中的模板是最常用的,判断模板生成视频质量的标准是700mb容量光盘可以刻录的视频时间长度,其中“352×288 ULBR”就是最多可以在一张700mb容量光盘上刻录360分钟视频模板,不过这是理论值,一般情况可以做到150分钟~220分钟,常用来作为制作电视剧模板;“352×288 LBR”是180分钟模板,这个非常适合编码普通长度的电影;“352×288”是120分钟模板,其编码这里比前两个要好一些;“352×576”是120分钟高分辨率视频编码模板;“704×576”模板编码生成的视频接近dvd分辨率,即使这样也可以在普通cdr光盘上刻录将近90分钟的高品质视频。



三、kvcd实战:rmvb刻录kvcd



第一步,使用“TMPGEnc plus”转换rmvb格式视频,必须使用2.54或2.53版本,http://www.ayxz.com/down.asp?id=4849 下载2.54版。这是绿色板,内有序列号,找到序列号注册。



第二步,打开运行后出现“项目向导”对话框,直接关闭该对话框,然后在主界面中单击“输入影像”栏的“浏览”按钮,在弹出的“打开”对话框中先设置“文件类型”为“所有文件(*.*)”,就可以选择要转换的rmvb文件了,这时在“输入声音”栏中会自动添加好同样rmvb文件路径,注意,如提示错误,请安装能够播放rmvb格式视频的播放器。



第三步,点“读取”按钮,选择kvcd编码模板文件,这时默认的“码流类型”设置是“video only”也就是只转换视频,所以这里一定要选择“system(video+audio)选项,这样才能转换出既有画面又有声音的电影



第四步,单击“设定“按钮”,然后单击“音频”标签,默认的“声道模式”是“dual channel”,一定要修改为“stereo”立体声模式。最后单击“确定”按钮保存设置。



第五步,文件输出路径根据个人情况设定,最后点“开始”按钮开始转换视频。



第六步,用nero进行刻录光盘,不过由kvcd编码的mpeg文件是非标准vcd格式,所以在nero中添加文件时,它会提示“不是建立标准vcd的有效文件”这时要注意,必须选择“关闭标准一致性并继续”,否则活就白干了。后面就可以按照正常流程刻录vcd光盘了。

二级域名转发程序实现原理

二级域名程序的实现其实很简单,很多人不明白其中原理,觉得很深奥或者很迷茫。下面我来讲将二级域名的实现原理。

功能服务:首先来分析一下二级域名程序所有提供的服务。就是我们来通过国际域名moocky.net,提供诸如abc.moocky.net的域名转发到目的的网站(网址)。这就是二级域名程序所要实现的功能。

虚拟主机:
随着Web服务器的发展,也有原来的一台服务器上只能建立一个Web站点,发展到现在可以建立虚拟主机更加成熟的WebServer。当然这个也和浏览器的发展是分不开的。大家在访问一个站点的时候比如http://www.moocky.net,浏览器首先连接http://www.moocky.net这 个网站所对应的服务器,然后再把主机头(也就是域名,http://后面到第一个[/]反斜杠之间之间的部分)给服务器,服务器接收到主机头之后,然后再 返回所对应的站点的内容。这也就是基于名称的虚拟主机的原理,当然基于IP的虚拟主机的原理就是通过IP地址来判断相应的Web站点。个默认站点,就是当 基于IP的虚拟主机找不到所对应的IP、基于名称的虚拟主机找不到对应的名称是所有访问的站点,就是默认站点了。当然这个也为我们实现域名转发提供可能。

范解析和范绑定:
什么是范解析?比如:我有一个moocky.net的国际顶级域名,那么我需要将“任意字符.moocky.net(*.moocky.net)”,解析 到一个固定的ip,如果我们要一个一个的去做那当然是不可能实现的了,那范解析就是用来做这个的。现在的大多数域名注册商都有提供泛解析(也就是大家通常 说的范域名解析)。
什么是范绑定?上面刚刚讲了虚拟主机的实现原理,那么范绑定也就是一个范域名到对应站点的一个实现过程。比如刚刚我已经做了*.moocky.net的范 解析,接下来要做的就是让*.moocky.net指向到我的站点(注意同一个IP上也可能有很多个主机);对于基于IP的虚拟主机,那我可以告诉你“恭 喜你,你不用再作范绑定了。”(为什么呢,自己多想想),但是对于基于名字的虚拟主机要做范绑定,恐怕就是不是人人都知道了。不同的Web服务器范绑定是 不同的,我就简单得说一下我所知道的:


据我目前所知IIS、TomCat不能绑定范域名(如果你知道怎么绑定请你告诉我一下),但这并不是说IIS、Tomcat就不能实现二级域名程序,别忘 了我们还有基于IP的虚拟主机和一个默认站点呢。虽然不能想范绑定那样可以为所有站点都做到,但至少可以勉强实现。

到此,有关二级域名程序实现原理的服务器部分就算是讲完了,不知道你能否明白。


二级域名转发的程序实现部分相对来说就很简单了。
测试:首先来看一个测试,我们首先在web站点下面建立一个文件test.php(test.asp、test.jsp;php可以使用phpinfo ()函数,ASP和JSP可以遍历ServerVariable),用该程序来打印服务器的相关信息,这里不再赘述程序的具体写法,主要对比的是 HTTP_HOST这个参数的变化,然后用http://test1.moocky.net/test.phphttp://test2.moocky.net/test.phphttp://test3.moocky.net/test.php, 我么可以看到,三次访问HTTP_HOST分别对应的是tes1.moocky.net、tes2.moocky.net、 tes3.moocky.net,这也就是我前面讲到的浏览器发送给WebServer的主机头,到这里我想你应该差不多明白怎么用程序来实现二级域名转 发了。

程序编写:明白来实现的原来,下面我来看看为用户提供二级域名的程序流程。用户通过注册,申请一个域名abc.moocky.net,提供自己的网址:http://www.moocky.net/blog.xml,注册完成,用户在浏览器打开http://abc.moocky.net,程序自动跳转的http://www.moocky.net/blog.xml

第一步,我们就是建立数据库,来保存用户注册信息;

user_info表结构:
PRIMARY KEY (user_id);
UNIQUE KEY `domain` (`domain);
user_id int auto_increment;
domain varchar(20);
password varchar(20);
homepage varchar(100);
第二步,编写用户注册程序(略);

第三步,编写转发程序;

ASP程序:
<%
dim host = request.servervariables('http_host')
dim sql = "select * from user_info domain='" & host & "'"
.....查询数据库操作,将网址付值给homepage(省略)....
%>

Aspupload 属性

UploadManager 属性
=============================================
CodePage As Long (Read/Write)
可以把表单的文本项目名和文件名的字符从指定的CodePage转换为Unicode,比如表单是按UTF-8提交的,那么这个属性应该设置为65001。其他的如1251 (Cyrillic), 1255 (Hebrew), 1256 (Arabic)等等。

用法:
程序代码: [ 复制代码到剪贴板 ]
Upload.CodePage = 65001
-------------------------------------------
DetectMacBinary As Boolean (Read/Write)
默认为True。 这个属性用来控制是否检测上传的文件是MacBinary格式的,如果是则从中提取“data fork”。AspUpload 3.0 Beta 1. 不支持。

用法:
Upload.DetectMacBinary = False
--------------------------------------------
Directory (Path As String, Optional SortBy, Optional Ascending) As Object (Read-Only)
返回一个集合,这个集合包括指定目录的所有子目录和文件的引用。
在这个集合里,子目录总是优先于文件.Path 可以包括通配符 * 和 ?。

SortBy 可以是: SORTBY_NAME (1, default). SORTBY_TYPE (2), SORTBY_SIZE (3), SORTBY_CREATIONTIME (4), SORTBY_LASTWRITETIME (5), and SORTBY_LASTACCESSTIME (6).

Ascending 默认为True。

用法:


Set Dir = Upload.Directory("c:\path\*.*", SORTBY_SIZE)
For Each Item in Dir
...
Next
-------------------------------------------
Expires As Date (Read-Only)
如果已经注册,返回9/9/9999,否则返回失效期。

用法:
Response.Write Upload.Expires
-------------------------------------------
Files As Object (Read-Only)
返回一个集合,这个集合包含有上传文件的引用。

使用这个集合之前,必须调用Save或 SaveVirtual方法。

要引用一个单个文件,可以使用从1开始的整数下标,或者相应的文件框的名称。

要列举集合里的项目,可以使用For/Each 语句。

用法:

Set File = Upload.Files(1)

Set File = Upload.Files("FILE1")

For Each File in Upload.Files
...
Next
-------------------------------------------
Form As Object (Read-Only)
返回一个集合,这个集合包括所有不是文件框的表单项目的引用。

使用这个集合之前,必须调用Save或 SaveVirtual方法。

要引用一个单个表单项目,可以使用从1开始的整数下标,或者相应的项目的名称。

要列举集合里的项目,可以使用For/Each 语句。

用法:

Name = Upload.Form(1)

Name = Upload.Form("Name")

For Each Item in Upload.Form
Response.Write Item.Value
Next
-------------------------------------------
IgnoreNoPost As Boolean (Read/Write)
当Upload.Save方法被脚本直接调用,而不是通过表单提交时,可以避免 "Wrong Content-Type"这个错误。当表单和相应的上传脚本在同一个文件时,这个属性很有用。

用法:

Upload.IgnoreNoPost = True
-------------------------------------------
OverwriteFiles As Boolean (Read/Write)
默认为True。如果设置为False,那么当文件名已经存在时,AspUpload会在原文件名后附加“(12)”这种形式的字符。这个属性影响Save, SaveVirtual 和 File.SaveAs方法。
用法:

Upload.OverwriteFiles = False
-------------------------------------------
PreserveFileTime As Boolean (Read/Write)
默认为Flase。如果设置为True,会试图保护上传文件的上次修改时间。
这个属性只是客户端使用XUpload或者JUpload 的时候有用。
当使用常规Form提交的时候,它没有任何作用。
用法:

Upload.PreserveFileTime = False
-------------------------------------------
ProgressID As String (Read/Write)
上传进度条所用的,用来区分上传进程。

用法:

Upload.ProgressID = Request.QueryString("PID")
-------------------------------------------
RegKey As String (Read/Write)
指定注册码,如果没有指定,AspUpload会从系统注册表读取。
用法:

Upload.RegKey = "12345-67890-12345"
-------------------------------------------
TotalBytes As Long (Read-Only)
返回上传的总字节数。
只能在成功调用Save(SaveVirtual)方法后调用这个属性。

用法:
Response.Write Upload.TotalBytes
-------------------------------------------
TotalSeconds As Long (Read-Only)
返回上传持续的总时间。
只能在成功调用Save(SaveVirtual)方法后调用这个属性。

用法:
Response.Write Upload.TotalSeconds
-------------------------------------------
Version As String (Read-Only)
返回组件的版数,如:"3.0.0.0".
用法:

Response.Write Upload.Version
-------------------------------------------
UploadManager Methods
======================================================
Sub CopyFile (FromPath As String, ToPath As String, Optional Overwrite)
复制文件。
Overwrite 默认为True。如果设置为False,当目标路径存在时,这个方法会失败。

用法:
Upload.CopyFile "c:\path1\file.ext", "c:\path2\file.ext"
-------------------------------------------
Sub CreateDirectory (Path As String, Optional IgnoreAlreadyExists)
建立目录。
IgnoreAlreadyExists 默认为False。如果设置为True,当目标路径存在时,这个方法不会报错。

用法:
Upload.CreateDirectory "c:\dir1\dir2", True
-------------------------------------------
Sub CreateFile (Path As String)
建立一个空文件。

用法:
Upload.CreateFile "c:\path\file.txt"

-------------------------------------------
Sub DecryptAndSendBinary (Path As String, IncludeContentType As Boolean, ContentType As String, Key As CryptoKey, RemoveExt As Boolean, Optional Attachment, Optional FileName)

和SendBinary相同,但是发送之前会使用Key对文件进行编码,这个Key可以由AspEncrypt组件生成。

RemoveExt参数指定下载框中是否显示文件的扩展名。

如果Attachment参数设置为True,输出的Header中Content-Disposition 将包括关键字"attachment;",以强迫IE下载这个文件。

FileName参数, 指定下载框中显示的文件名。

用法:
Upload.DecryptAndSendBinary "c:\dir\file.txt.xxx", True, "application/octet-stream", Key, True, True

-------------------------------------------
Sub DeleteFile (Path As String)
删除文件。

用法:
Upload.DeleteFile "c:\path\file.txt"
-------------------------------------------
Function FileExists (Path As String) As Boolean
检测文件是否存在。

用法:
if Upload.FileExists("c:\path\file.txt") Then ...
-------------------------------------------
Sub FromDatabase (Connect As String, SQL As String, Path As String)
使用ODBC,从数据库的表中输出BLOB字段到硬盘。
Connect 指定ODBC连接字符串。
SQL 该SQL语句应该返回一条记录,这个记录应该包括Blob字段。
Path 完整的文件路径,包括文件名。

用法:
Upload.FromDatabase "DSN=mydb;UID=sa;PWD=xxx;", "select image_blob from myimages where id = 3", "c:\path\file.txt"
-------------------------------------------
Sub FromRecordset (RecorsetValue As Variant, Path As String) 使用ADO Recordset 对象从数据库的表中输出BLOB字段。

RecordsetValue 是一个recordset字段,比如rs("image_blob").Value。

Path 完整的路径,包括文件名。

用法:
Set rs = Server.CreateObject("adodb.recordset")
rs.Open "MYIMAGES", Connect, 2, 3
Upload.FromRecordset rs("image_blob").Value, "c:\path\file.txt"
-------------------------------------------
Sub LogonUser (Domain As String, Username As String, Password As String, Optional Flags) 扮演指定的用户帐号。

如果Domain 是空的,那么本机将会验证这个密码。

如果您当前的安全设置不允许你执行上传到远程机器或者其他操作,可以使用这个方法。

Flags 可以是以下值: LOGON_INTERACTIVE (2, default), LOGON_NETWORK (3), LOGON_BATCH (4), and LOGON_SERVICE (5)。不推荐使用这个可选参数。


用法:
Upload.LogonUser "domain", "jsmith", "xxxxxx"
-------------------------------------------
Sub MoveFile (FromPath As String, ToPath As String) 移动文件。如果目标路径存在,这个方法将会报错。

用法:
Upload.MoveFile "c:\path1\file.ext", "c:\path2\file.ext"
-------------------------------------------
Function OpenFile (Path As String) As Object 建立一个UploadedFile 实例,它指向指定的文件。
如果你想使用UploadedFile.Binary属性的优势,保存任意文件到数据库,这个方法很有用。

用法:
Set File = Upload.OpenFile("c:\path1\file.ext")
-------------------------------------------
Sub RegisterServer (Path As String, Optional Register) 模仿 REGSVR32 (/u)的动作。 注册或者卸载指定的ActiveX DLL.

如果Register参数为True或忽略,为注册DLL, 否则为卸载。

用法:
Upload.RegisterServer "c:\path1\file.dll"

Upload.RegisterServer "c:\path1\file.ocx", False
-------------------------------------------
Sub RemoveDirectory (Path As String)
删除目录,如果目录包含文件或子目录,会报错。

用法:
Upload.RemoveDirectory "c:\path"
-------------------------------------------
Sub RevertToSelf
结束由 LogonUser方法开始的扮演。
通常不需要调用这个方法,角色扮演会自动结束。

用法:
Upload.RevertToSelf
-------------------------------------------
Function Save (Optional Path, Optional Key, Optional Ext) As Long
最主要的方法。捕获文件,保存到硬盘或内存,组装Files和Form集合。

Path参数, 如果指定,则是文件保存到的路径。

如果Path参数被忽略,文件保存到内存,可以通过File.Binary存取,或者通过File.SaveAs保存到硬盘。

参数Key和Ext,用来加密上传的文件。

Key是一个CryptoKey对象,它由AspEncrypt组件生成。如果指定这个参数,文件保存之前将会被加密。

Ext是可选扩展名。

方法返回值:成功保存的文件数。

用法:

Count = Upload.Save ' save to memory

Count = Upload.Save("c:\upload") ' save to hard drive

Upload.Save "c:\upload" ' save to hard drive, ignore return value

Upload.Save , Key, "xxx" ' Save to memory, encrypt with Key

Upload.Save "c:\upload", Key, "xxx" ' Save to hard drive, encrypt with Key
-------------------------------------------
Function SaveEncrypted (Path As String, Key As Object, Ext As String) As Long
此方法废止。 只用来向后兼容。用Save方法替代。

Upload.SaveEncrypted(Path, Key, Ext)
等价于
Upload.Save(Path, Key, Ext)
-------------------------------------------
Function SaveToMemory As Long
此方法废止。 只用来向后兼容。用Save方法替代。

Upload.SaveToMemory
等价于
Upload.Save
-------------------------------------------
Function SaveVirtual (Optional VirtualPath, Optional Key, Optional Ext) As Long

和Save方法相同,但是参数为虚拟路径,而不是物理路径。

方法内部调用Server.MapPath方法转换虚拟路径为物理路径。

因此, Upload.SaveVirtual(path) 等价于Upload.Save(Server.MapPath(path))。

在Web主机环境里,系统管理员可以禁止Save方法,强迫AspUpload用户使用SaveVirtual方法,以便限制他在自己的目录中进行操作。

用法:
Upload.SaveVirtual "/images"
Upload.SaveVirtual "/images", Key, "xxx"
-------------------------------------------
Function SaveVirtualEncrypted (Optional VirtualPath, Optional Key, Optional Ext) As Long
此方法废止。 只用来向后兼容。用SaveVirtual方法替代。
-------------------------------------------
Sub SendBinary (Path As String, Optional IncludeContentType, Optional ContentType, Optional Attachment, Optional FileName)

用作文件下载。
取得指定的文件,发送给客户端浏览器。
参数IncludeContentType默认为True。
它控制着是否建立Content-Type, Content-Disposition 和Content-Length 这些Header信息. 如果设置为False,这些Header信息不会建立。

ContentType 指定Content-Type header。

Attachment 默认为False。如果设置为True,“Content-Disposition” header 将包括“attachment”关键字,强迫浏览器弹出下载框,而不是在浏览器中打开。

FileName 指定下载框中的文件名。
用法:

Upload.SendBinary "c:\path\file.ext", True, "application/octet-stream", True
-------------------------------------------
Sub SetMaxSize (MaxSize As Long, Optional Reject)
指定单个文件的限定大小。
参数Reject 指定过大的文件是否会拒绝(True的时候)或截取(False或省略的时候。)。

用法:
Upload.SetMaxSize 150000, True
-------------------------------------------
Sub ToDatabaseEx (Path As String, Connect As String, SQL As String, Optional MSAccessHeaders)
保存任意的文件到数据库。
查看UploadedFile.ToDatabase 方法。

用法:
Upload.ToDatabaseEx "c:\path\file.txt", "DSN=mydb;", "insert into myimages(image_blob) values(?)"
-------------------------------------------
UploadedFile 属性
================================================
Attributes As Long (Read/Write)
设置和取得文件的系统属性。
可以是以下值的结合。
FILE_ATTR_READONLY = &H1
FILE_ATTR_HIDDEN = &H2
FILE_ATTR_SYSTEM = &H4
FILE_ATTR_DIRECTORY = &H10
FILE_ATTR_ARCHIVE = &H20
FILE_ATTR_NORMAL = &H80
FILE_ATTR_TEMPORARY = &H100
FILE_ATTR_COMPRESSED = &H800

用法:

Response.Write File.Attributes

File.Attributes = File.Attributes + FILE_ATTR_READONLY
-------------------------------------------------------------
Binary As Variant (Read-Only)
返回文件的binary image 。It is a Variant-packed safe array of bytes.
保存文件到数据库的时候有用。

用法:
rs.AddNew
rs("image_blob).Value = File.Binary
rs.Update
-------------------------------------------------------------
ContentType As String (Read-Only)
返回文件的Content-Type。
如:"text/plain" 或 "application/octet-binary".

用法:
Response.Write File.ContentType
-------------------------------------------------------------
CreationTime As Date (Read-Only)
返回文件的创立时间戳。如果是内存文件,这个属性没有定义。

用法:
Response.Write File.CreationTime
-------------------------------------------------------------
Ext As String (Read-Only)
返回文件扩展名。

用法:
Response.Write File.Ext
-------------------------------------------------------------
FileName As String (Read-Only)
返回文件被保存的名称。
如果Upload.OverwriteFiles为False,它可能和原始文件名不同。

用法:
Response.Write File.FileName
-------------------------------------------------------------
Folder As String (Read-Only)
返回文件被保存的文件夹名。
如果是内存文件,和原始文件夹名相同。

用法:
Response.Write File.Folder
-------------------------------------------------------------
ImageHeight As Long (Read-Only)
返回图片的像素高。如果不是图片,返回0。
格式支持BMP, JPG, GIF, 和 PNG。

用法:
Response.Write File.ImageHeight
-------------------------------------------------------------
ImageType As String (Read-Only)
返回图片类型。 可能的返回值有"BMP", "GIF", "JPG", "PNG", 和"TIF" for BMP, GIF, JPEG, PNG 和TIFF images, 分别的, 和"UNKNOWN" (如果文件不是图片,或是已知图片类型以外的。)

用法:
Response.Write File.ImageType
-------------------------------------------------------------
ImageWidth As Long (Read-Only)
返回图片的像素宽。如果不是图片,返回0。
格式支持BMP, JPG, GIF, 和 PNG。

用法:
Response.Write File.ImageWidth
-------------------------------------------------------------
LastAccessTime As Date (Read-Only)
返回文件的上次存取时间戳。如果是内存文件,这个属性没有定义。

用法:
Response.Write File.LastAccessTime
-------------------------------------------------------------
LastWriteTime As Date (Read-Only)
返回文件的上次写入时间戳。如果是内存文件,这个属性没有定义。
除非这个文件是由XUpload或JUpload上传的,并且PreserveFileTime特性是打开的。

用法:
Response.Write File.LastWriteTime
-------------------------------------------------------------
MD5Hash As String (Read-Only)
以十六进制返回文件的MD5 one-way Hash值。

用法:
Response.Write File.MD5Hash
-------------------------------------------------------------
Name As String (Read-Only)
返回文件在表单中对应项目的名称。
这个属性不能取得文件名,应该使用FielName。

用法:
Response.Write File.Name
-------------------------------------------------------------
OriginalFileName As String (Read-Only)
返回文件的原始文件名。

用法:
Response.Write File.OriginalFileName
-------------------------------------------------------------
OriginalFolder As String (Read-Only)
返回文件的原始文件夹。

用法:
Response.Write File.OriginalFolder
-------------------------------------------------------------
OriginalPath As String (Read-Only)
返回文件的原始的完整路径。

用法:
Response.Write File.OriginalPath
-------------------------------------------------------------
OriginalSize As Long (Read-Only)
返回文件的原始大小。
这个值可能和当前大小不同,如果文件通过SetMaxSize方法被截断的时候。

用法:
Response.Write File.OriginalSize
-------------------------------------------------------------
Path As Long (Read-Only)
返回文件在服务器上的完整路径。

用法:
Response.Write File.Path
-------------------------------------------------------------
Size As Long (Read-Only)
返回文件在服务器上的大小。
如果SetMaxSize 特性是有效的,这个值可能和原始大小不同。

用法:
Response.Write File.Size
-------------------------------------------------------------
UploadedFile Methods
======================================================
Sub AllowAccess (Account As String, Flags As Long)
给指定的NT用户增加“允许访问控制(ACE)”到文件的“访问控制列表(ACL)”。

参数Flags 必须是有效的访问类型的组合,这些值在AspUpload.inc中进行了定义,如: GENERIC_ALL。

其他有效的Flag组合包括:

Read (RX):GENERIC_READ + FILE_GENERIC_EXECUTE
Change(RWXD): GENERIC_READ + GENERIC_WRITE + FILE_GENERIC_EXECUTE + DELETE
Full Control (All): GENERIC_ALL

用法:
File.AllowAccess "jsmith", GENERIC_ALL
----------------------------------------------------------
Sub Copy (Path As String, Optional Overwrite)
复制文件到指定的路径,此路径必须是有权限的。
如果参数Overwrite设置为True或者忽略,覆盖存在的文件。如果设置为False,并且指定路径下文件已经存在,那么报错。

用法:
File.Copy "c:\newpath\" & File.FileName
----------------------------------------------------------
Sub CopyVirtual (VirtualPath As String, Optional Overwrite)
和Copy方法相同。 但是参数为虚拟路径,而不是物理路径。
如果系统管理员禁止了Copy方法,用户被迫使用CopyVirtual方法,这将限制他们在自己的目录下进行操作。

用法:
File.CopyVirtual "/uploads/" & File.FileName
----------------------------------------------------------
Sub Delete
删除文件。

用法:
File.Delete
----------------------------------------------------------
Sub DenyAccess (Account As String, Flags As Long)
给指定的NT用户增加“拒绝访问控制(ACE)”到文件的“访问控制列表(ACL)”。

参数Flags必须设置为GENERIC_READ。

用法:
File.DenyAccess "jsmith", GENERIC_ALL
----------------------------------------------------------
Sub ExtractFileName
此方法废止,仅用来保持向后兼容。请使用FileName。

用法:
Response.Write File.ExtractFileName
----------------------------------------------------------
Sub ExtractFolderName
此方法废止,仅用来保持向后兼容。请使用Folder。
用法:

Response.Write File.ExtractFolderName
----------------------------------------------------------
Sub Move (Path As String)
复制文件到指定的路径,该路径必须有权限。

如果文件已经存在,将报错。

副作用:如果此方法成功执行,File.Path 属性将更新为新路径。

用法:
File.Move "c:\newpath\" & File.FileName
----------------------------------------------------------
Sub MoveVirtual (VirtualPath As String)
和Move方法相同,但参数是虚拟路径,而不是物理路径。

用法:
File.MoveVirtual "/uploads/" & File.FileName
----------------------------------------------------------
Sub RevokeAllowance (Account As String)
从文件的ACL移除相应的允许ACE 。

用法:
File.RevokeAllowance "jsmith"
----------------------------------------------------------
Sub RevokeDenial (Account As String)
从文件的ACL移除相应的拒绝ACE 。

用法:
File.RevokeDenial "jsmith"
----------------------------------------------------------
Sub SaveAs (Path As String)
保存文件到指定的路径。
如果UploadManager.OverwriteFiles 设置为False,并且指定的路径下文件已经存在, 次方法将在原文件名后追加(1)(2)等形式的字符,以生成唯一文件名。

此方法是保存内存文件到硬盘的唯一方法。

副作用:如果此方法成功执行, UploadedFile.Path 将更新为新路径(或者源于他的新的唯一文件名。)。

用法:
File.SaveAs "c:\path\" & File.FileName
----------------------------------------------------------
Sub SaveAsVirtual (VirtualPath As String)
和Save方法相同。 但是参数为虚拟路径,而不是物理路径。
如果系统管理员禁止了Save方法,用户被迫使用SaveVirtual方法,这将限制他们在自己的目录下进行操作。
用法:

File.SaveAsVirtual "/path/" & File.FileName
----------------------------------------------------------
Sub SetOwner (Account As String, Flags As Long)
将指定的NT用户指定为文件的NTFS所有者。

用法:
File.SetOwner "jsmith"
----------------------------------------------------------
Sub ToDatabase (Connect As String, SQL As String, Optional MSAccessHeaders)
使用ODBC,将文件作为BLOB保存到数据库。

参数Connect 是一个ODBC连接字符创,可以用系统DSN,或非DSN,如:

"DSN=mydb;UID=sa;PWD=xxxxx"

或者

"Driver={Microsoft Access Driver (*.mdb)};DBQ=c:\path\db.mdb"

但是, Connect 不能使 ADO-style 连接串,也就是说,它不能涉及一个旧的DB provider, 因为这个方法是基于ODBC的。

SQL 是一个INSERT或UPDATE的SQL语句, 用问号作为保存到数据库的文件的占位符,

如:

"INSERT INTO mytable(image_blob, path) values(?, 'c:\path\file.ext')"

或者

"UPDATE mytable SET imageblob = ? WHERE id = 15"

MSAccessHeaders 参数只能用在 MS Access 数据库。

如果设置为True, AspUpload 将试图把文件作为OLE对象保存,而不是作为BLOB。
以便文件可以在MS Access中通过双击字段直接调用。

只有当文件类型存在于OLE document servers 的文件类型(如MS Word documents (*.doc), Excel workbooks (*.xls), bitmaps (*.bmp)等等)中时,此特性才有效。

对于其他类型的文件,(如 *.gif) ,参数 MSAccessHeaders 将被忽略,并且假定为False。

注意:你不能直接下载一个以OLE对象保存的文件。

用法:
File.ToDatabase "DSN=mydb;UID=sa;PWD=xxxx;", "insert into myimages(image_blob) values(?)"

2007-01-14

绝妙的创意

1、洗碗机

2、护苗盒

3、创意灯

4、听力保护耳罩

5、距离提醒器

6、马桶清新盒

7、简易照片夹

8、打盹头部保护器

9、方便筷

10、物品夹

11、效果灯

12、美甲

13、门护

14、雪糕护板

15、护脚蹬

16、衣帽钩

十大最神秘的史前古物

1、南非金属凹槽球

十几年前,南非的矿工挖出一些神秘的金属球。其起源 无从得知,这些球直径大小约为1英寸,其中的一些球的“赤道”附近刻着三条平行凹槽。这种球分为两种:一种是实心的蓝色金属夹带白色斑点;另一种是空心 的,内部填充柔软的白色物质。据说这些金属球是在前寒武层中被发现的,距今已有28亿年之久!

金属凹槽球

金属球来自南非德兰士瓦省Ottosdal附近的叶 蜡石矿中。它们是天然形成的,共有两种:埋藏较浅的球暴露在叶蜡石中,是针铁矿结核;埋藏较深的球没有碰到叶蜡石,是黄铁矿结核。地质学家认为叶蜡石的来 源是史前沉积的黏土或火山灰,那些沉积物在埋藏的过程中遇到了一定的压力和温度,慢慢变成了叶蜡石,地质上叫“变质作用”;黄铁矿结核是黄铁矿的一种常见 的存在形式,也是由变质作用形成的;针铁矿结核(FeO(OH))则是黄铁矿结核(FeS2)遇到叶蜡石(Al2Si4O10(OH)2)后产生化学反应 形成的。在以上这些物质中,只有黏土或火山灰是28亿年前的,叶蜡石和黄铁矿结核的年代都要晚一些,针铁矿结核比黄铁矿结核的年代更晚。

金属凹槽球

据说其中一些金属球上有环行的凹槽,但天然形成的结 核上没有凹槽,因此有人认为它们代表了一个史前文明。当然我们还可以假设,有人事先在一些铁结核上雕刻好凹槽再埋入地下,但是经过亿万年的变质作用,那些 凹槽都会被抹平。实际上,在强大变质所用下,没什么东西能保持原样。所以当现代的你看到了这些凹槽,便可以说:它们确实是人造的,但时间在铁结核被挖出来 以后。谁,为了什么,做了这些球,现在还不能得知。

2、中国朱洛巴石盘

1938年,中国考古学家纪蒲泰等人到青海南部 的巴颜喀拉山地区考察时,在一个不太显眼的山洞里共挖出716块花岗石圆形体,中间稍四无孔,每块厚度约2厘米,从中间向四周辐射出许多十分规则的水波纹 线条,极似现代的镭射唱片,上面还刻有许多现代人无法解读的各种符号。经过测定,这些石盘大约是1万多年以前的东西。后来,石盘几经辗转到达苏联,在莫斯 科所作的各项科学分析表明,这些石盘含有大量的钻金属和其他金属元素,而且石盘的振荡频率特别高,这说明它长期用于高电压之中,仿佛石盘曾经带电,或者是 某种电路的组成部分。


朱洛巴石盘

1962年,一位中国学者徐鸿儒教授根据当地的古老 传说,经过长时间的研究,最终破译了石盘上的表意符号,译文是:特罗巴人来自云端,他们乘坐的是古老的飞船,后来飞船在着陆时损坏,这些特罗巴人只好藏身 山洞。在巴颜喀拉山地区一直流传着有关特罗巴人的各种传说。实际上在西藏地区确实曾经生活过两个十分特殊的部落, 一个叫朱洛巴,一个叫康巴,这两个部落的人种与世界其他地区的人种都不一样,他们就生活在巴颜喀拉山一带,平均身高1.2米,瘦小柔弱,骨骼纤细,眼眶奇 大,脑颅容量比一般人平均大100毫升,而且血型独一无二。这两个部落1935年被首次发现,1950年曾有一支考察队前往考察,但结果不得而知。有报道 说,最近考古学家在这一带地区曾出上过身材矮小的人种化石,与传说中的特罗巴人和发现的朱洛巴、康巴人十分相似。这些特罗巴人是地球人吗?人类在1万多年 以前能造出宇宙飞船吗?

3、秘鲁伊卡石刻

在秘鲁纳斯卡平原北部有一座名为伊卡(ICA)的小村庄有一座石头博 物馆。馆中陈列着一万多块刻有图案的神秘石头,上面雕刻着许多令人难以置信的图画,记录的是一个业已消失的极其先进人类远古文明,这些石头画被称为ICA 石刻。博物馆里这批雕刻着图案的石头是在伊卡河决堤时开始大量被人发现。刻石依照图案的类别,被划分为太空星系,远古动物,史前大陆,远古大灾难等几类。 这种分类与现代科学完全脱节,似乎在谈论一个完全崭新的课题。

伊卡石刻

这些珍藏的石头根据推测可能有上千年的历史。专家将刻石进行了化验,结果表明,这些石头是产于当地河流之中的一种安第斯山石,表面覆有一层氧化物。经德国科学家的鉴定,石头上的刻痕历史极为久远,而发现刻石的山洞附近,遍布着几百万年前的生物化石。

伊卡石刻的收藏者

最不可思议的是,那些刻石头的远古人类被科学家称为“格里托里西克人”,从刻石的图案上看,他们具有极为先进的文明。刻石上描绘着器官移植手术,输血,望远镜,医疗器械,追逐恐龙的人……


伊卡石刻上雕刻着一个人骑在一头恐龙(三角龙)背上

在这些石头图画里,人们可以清楚看到人与恐龙生活在一起的情况,以图上的比例来看,所画的人类与恐龙身材比例并不悬殊,约略是现代人类与家畜的身材比例,恐龙像是一种家畜,或是当时人们驯养的动物,几乎比较著名的恐龙类型都在这些石头雕刻里有出现。

4、希腊Antikythera装置

Antikythera Mechanism是已知最早的包含有复杂的齿轮系统的装置,它是于1901年在一艘失事的船上被发现的,但直到现在,它的用途也还是个迷。尽管被发现的 Antikythera Mechanism已经只剩下了82个黄铜碎片,但来自英国、希腊、美国的科学家利用高清晰的X 线断层扫描技术复制了它的一个模型。他们相信,这个研究将使得人们重新考虑古希腊的科技水平。

Antikythera计算器

卡地夫大学的天体物理学教授爱德蒙兹表示,它可以被 称作是已知的第一台计算器。我们近来的研究使用了非常现代化的技术,我们相信已经揭示了它的真实用途。Antikythera Mechanism能够进行加、减、乘、除运算,能够制定日历,显示太阳和月亮的位置。爱德蒙兹和他的同事发现,Antikythera Mechanism有一个刻度盘,能够预测何时可能会发生日食或月食。

Antikythera Mechanism还考虑了月亮的椭圆形轨道。它的特别之处在于,古希腊人已经能够制造如此精巧的技术装置,而且是用金属制造的。模型显示, Antikythera Mechanism在一个木制容器中安装有37个齿轮,外部刻有与天体运动相关的文字。德国Ludwig-Maximilians大学的佛朗哥斯在《自 然》杂志上发表的一篇论文中说,这一模型为未来的研究提供了大量的资料。

他表示,新破译的与天体运动相关的文字似乎表明,Antikythera Mechanism能够预测行星的运动。爱德蒙兹将Antikythera Mechanism称作是独一无二的,在天文学历史是没有其它技术可以与它媲美。直到中世纪教堂用的大钟出现前,我们没有发现类似的复杂的机械装置。

5、伊拉克巴格达电池

1936年6月的一天,一群筑路工人正在伊拉克首都巴格达城外修筑铁路,忽然发现了一块巨大的石板,上面刻有许多古代波斯文字。工人们感到非常惊奇。他们继续深挖,结果发现是一个巨大的百板砌成的古代坟墓。古墓惊动了伊位克博物馆的考古工作人员。他们立即赶到现场进行发掘。

巴格达电池
巴格达电池

经过两个多月的艰苦工作,考古学家们找到了许多文物。尤其是打开石棺以后,发现了大量从公元前248年到公元前226年波斯王朝时代的器物。在这些古物中,发现了一些奇特的陶制器皿、锈蚀的铜管和铁棒。

当时担任伊拉克博物馆馆长的德国考古学家威廉·卡维 尼格这样描述:“陶制器皿类似花瓶,高15厘米,白色中夹杂一点淡黄色,边沿已经破碎。上端为口状,瓶里装满了沥青。沥青之中有一个铜管,直径2.6厘 米,高9厘米,铜管顶端有一层沥青绝缘体。在铜管中又有一层沥青,并有一根锈迹斑斑的铁棒。铁棒高出沥青绝缘体一厘米,由一层灰色偏黄的物质覆盖着,看上 去好象是一层铅。铁库的下端长出铜管的底座3厘米,使铁棒与铜管隔开。看上去好像是一组化学仪器。”经过鉴定,卡维尼格宣布了一个惊人的消息:“在巴格达 出土的陶制器皿,是一个古代化学电池。只要加上酸溶液或碱溶液,就可以发出电来。”

电池工作原理图

电池工作原理图

卡维尼洛的论断震惊了考古学界。如果承认这是一个古代电池, 那就意味着,早在公元前3世纪居住在这一地区的波斯人就已经开始使用电池了。这比公元1800年由世界著名物理学家伏特发明的第一个电池早了2000多 年。于是,许多考古学家纷纷从世界各地赶来,希望对这个古代电地进行仔细研究。但就在这时,卡维尼格和古代电池都不见了。人们四处寻觅,毫无结果。

原来卡维尼治带着巴格达电 池悄悄地返回到了德国。他用带来的陶制器皿、铁棒、沥青绝缘体和铜管组合成了10个电池。几个月后,卡维尼格在柏林公布了更为惊人的消息。他说:“古代人 很可能是把这些电池串联起来,用以加强电力,制造这种电池的目的在于用电解法给塑像和饰物镀金。”有人指责卡维尼格是骗子、神经病。考古学界争论更是激 烈。时至今日,此事仍是个悬案。

6、美国科索人造物品

在美国加利福尼亚州的奥兰察(Olancha),华 莱士·莱恩(Wallace Lane)、迈克·麦克塞尔(Mike Mikesell)和弗吉尼亚·马克塞(Virginia Maxey)3人共同经营着一家出售纪念品与宝石的商店。1961年2月13日,3人前往科索(Coso)山采集晶石。晶石是一种球形、中空且有水晶条纹 的石头。在接近科索山顶峰的地方,麦克塞尔第一个发现了一块极其坚硬的奇特晶石,此处海拔约1300米,高出干涸的欧文斯(Owens)河床110米。

x光下可以看到其复杂的结构

在费尽九牛二虎之力,几乎弄断了一把新的金刚石锯条 后,麦克塞尔并没有看到大多数晶石都有的特征,切口处的情形似乎更像是某种机械装置的残骸:最外层是黏土、卵石和化石的混合物,接下来是质地非常接近于被 腐蚀的铜的六面体,包着一层类似瓷质的白色物质,最中心部分是一个2毫米的亮铜色磁性金属轴。这个结构让人觉得它是一种非常复杂的人造物品,可这是不可能 的,因为科索的晶石可以追溯到距今50万年前。

专家的解释

现在,石头中包含的这种神秘物质已经广为人知:它是 一种内燃机上用的老式火花塞。它也被美国人正式定名为“科索的人造物品”(Coso Artifact)。不过仍有许多人认为,科索晶石是一种“欧帕兹”(OOPARTS,Out of Place Artifacts的缩写),意即在不该出现的地方出土的加工物。这个词是美国博物学家伊万·桑德森(Ivan Sanderson)创造的,主要针对近些年来从古老地层中掘出的、已如动植物化石般的人造物品。桑德森盲目地认为这些物体非同寻常,并指责科学家们对事 实的隐瞒,即地球上生命的出现要远远早于人们的想象,更异于书中的描绘。因此,也不排除有外星人的造访。

这种石头可谓第一个“正式的”欧帕兹。不过,随着研究的开展,它的神秘面纱日渐褪色。一位地质学家在分析了 它的化石状外壳之后,断定它已经有50万年的历史。这位科学家的身份始终不为人知,而且他的评论也从未见诸于正式的出版物中。但可以肯定,这块石头不是真 正的晶石。石头里另藏两件坚硬的物品,像是一只钉子和一个垫圈,这些无疑是比较现代的东西。石头的发现者们将其送到了专业协会,拍摄了很多照片并作了X光 测定。测定的结果证实它的确是机械装置的一部分,但奇怪的是X光片显示出中心金属轴的一端已被腐蚀,另一端却有类似弹簧或者螺旋纹似的结构。欧帕兹假设的 支持者认为它不可能是一个火花塞:因为现代的火花塞根本不会有像弹簧或螺旋终端的结构。

西北太平洋怀疑论派(Pacific Northwest Skeptics)的皮埃尔·斯特龙伯格(Pierre Stromberg)和保罗·海因里希(Paul Heinrich)的努力终于使这件事有了柳暗花明的转机:他们把这些照片和X光片寄给了美国火花塞收藏者协会(Spark Plug Collectors of America)。协会的主席查德·温德姆(Chad Windham)为此进行了长时间的研究,在经过认真的分析和比对之后,于1999年11月得出结论:毫无疑问这是一个火花塞。他还找出了它的模型:1920年的一件样品。他的解释同时澄清了类似弹簧或螺旋终端的那一部分的功用:这些螺旋起一种“平衡套”的作用,被用来均衡陶瓷和金属轴之间的热膨胀系数之差。

温德姆的解释还与另外一个细节相吻合,那就是据文件记载,发现神秘晶石的地区在20世纪初是采矿区,可能就是当时使用了配备有老式内燃机的机械,火花塞落入较深的地方,与矿石共同融合而形成了这块令人费解的石头。

7、埃及的远古模型飞机

尽人皆知,直到1903年地球人才制造了第一架飞机。可奇怪的是,考古学家却发现了4000年前的飞机模型。

1879 年,英籍考古学家韦斯在埃及东北部荒芜沙漠中的Abydos古庙(Abydos temple)遗址内的浮雕壁画中,发现一个奇怪现象,就是看见与现今飞机形状极之相同的浮雕,以及一系列类似飞行物体。有一图案状似今日直升机,有图案 状似潜艇或飞船,甚至还有“UFO” 却出现于三千年前的古埃及。还有至少三至四个飞行物与今日的飞机形状极为相同,飞机在十九世纪才开发,但竟然在三千年前的古埃及的壁画中出现。
壁画上显示的古代飞行器

在世界历史中,不少远古民族在发展语言和文字之初, 均以壁画记载历史。出现在庙宇中的浮雕,也应该是古埃及人用以记载某一件事或表达某一种意思,但三千年前的人可以预言到今日的文明产物吗?在三千年前,即 使是外星文明曾经降临过古埃及,当时的人亦未必有直升机和潜艇这些概念。并且,如果壁画内的“UFO”是外星人的,又为何要与现代文明的飞机画于同处?

1898年,有人在埃及一座4千多年前的古墓里发现 了一个与现代飞机极为相似的模型。这个模型是用当时古埃及盛产的小无花果树木制成的,有31.5克重。因当时人们还没有飞机这个概念,便把它念为"木鸟模 型"。这个模型现在放在开罗古物博物馆,编号为"物种登记"第6347号,放在第22室。 直到1969年,考古学家卡里尔·米沙博士获得特许进入这个博物馆的古代遗物仓库,发现了许多飞鸟一样的模型。这些飞鸟模型有个共同特点,即都有鸟足,形 状半人半鸟的,而这个模型除了头有些像鸟外,其他部分都跟现在的单翼飞机差不多;有一对平展展的翅膀,一个平卧的机体,尾部还有垂直的尾翼,下面还有脱落 的水平尾翼的痕迹。


为了弄清这架飞机模型的本来面目,米沙博士便建议埃 及文化部组成特别委员会进行专门调查研究。1971年12月,由考古学家、航空史学家、空气动力学家和飞行员组成的委员会开始了对这架飞机模型的确认研 究。经鉴定,许多专家认为,它具有现代飞机的基本特点和性能:机身长5.6英寸,两翼是直的,跨度7.2英寸,嘴尖长1.3英寸,机尾像鱼翅一样垂直,尾 翼上有像现代飞机尾部平衡器的装置。尾翼除外形符合空气动力要求外,还有反上反角的特点,使机身有巨大的上升力。机内各部件的比例也很精确。只要稍加推 动,还能飞行相当一段距离。所以,一些专家们断定,这绝不是古埃及工匠给国王制造的玩具,而是经过反复计算和实验的最后成品。后来在埃及其他一些地方,又 陆续找到了14架这类飞机模型。

更令人奇怪的是,在南美洲的一些地方,也发现了一些 与古埃及飞机模型极为相似的飞机模型。在南美的一个国家的地下约780英尺深的地方,挖出了一个用黄金铸造的古代飞机模型,跟现代的B52型轰炸机十分相 像。据科学家们分析,这架飞机的模型不但设计精巧,而且具有飞行性能。美国纽约研究所的专家们在为这架古代飞机模型作过风洞试验后,绘制了一张技术图纸, 这些图纸把古代飞机模型的概貌描绘了出来。1954年,哥伦比亚共和国在美国的博物馆展出过古代金质飞机的模型。后来在南美其他国家也陆续发现过这类飞机 模型。

埃及与南美之间的飞机模型之间有什么内在联系吗?是 埃及人架机曾经飞到过南美洲吗?既然4千年前的人已经发明了飞机,可为什么直到1903年才有了世界上的第一架飞机叱?古代人是凭借什么手段制造了飞机的 呢?如果这些谜都解不开,人们就只好把这件事归结为外星人了。西方有些人就认为:几千年前的人根本不可能制造出飞机,这些飞机模型,都是外星人在地球上留 下的制品。

8、哥斯达黎加巨型石球

中美洲南部的哥斯达黎加,在古代,曾有3万多名印第 安人生活在这里。20世纪30年代末,美国人乔治·奇坦在该国人迹罕至的三角洲热带丛林以及山谷和山坡上,发现了约200个好似人工雕饰的石球。这些石球 大小不等,大的直径有几十米,最小的直径也在两米以上,制作技艺精湛,堪称一绝。加拉卡有一处石球群多达45枚,另两处分别有15枚和17枚,有的排列成 直线,有的略成弧线,无一定规则。据怪异现象专家米切尔·舒马克研究,有些石球显然是从山上滚落下来,碰巧排成直线的。

这些石球引起了人们极大的兴趣。科学家对它们进行了认真的测量,发现这些石球表面各点的曲率几乎完全一样,简直是一些非常理想的圆球。这些石球有什么用?有人推测,摆放在墓地东西两侧的石球可能代表太阳和月亮,或图腾标志,有人把它们戏称为“巨人玩的石球”。

哥斯达黎加巨型石球

对大石球做过周密调查的考古学家们都确认,这些石球 的直径误差小于1/100,准确度接近于球体的真圆度。从大石球精确的曲率可以知道,制作这些石球的人员必须具备相当丰富的几何学知识和高超的雕凿加工技 术,还要有坚硬无比的加工工具及精密的测量装置。否则,便无法想象他们能够完成这些杰作。诚然,远古时期,生活在这里的印第安人不乏雕凿石头的能工巧匠。 然而,打磨如此硕大的石球必须付出艰巨的劳动,从采石、切割到打磨,每一道工序都要求不断地转动石块,要知道这些石球重达几十吨,这无论如何不是一件容易 的事。仅凭一些简陋的原始工具能完成吗?

据考查,这些谜一样的石球,差不多都是用坚固美观的 花岗岩制成。令科学家和考古工作者迷惑不解的是,这些石球所在地的附近并没有花岗岩石料,在其他地方也找不到任何原始制作者留下的痕迹。面对这样奇特的现 象,人们提出了一连串问题:是什么人制作了这些了不起的巨大石球?所必需的巨大石料如何运到这里?究竟用什么工具加以制作?

有人根据当地印第安人中流传的传说:宇宙人曾经乘坐 球形太空船降临这里,认为这些大石球是宇宙人制作的,并按照一定的位置和距离进行了排列,布置成模拟某种空间天象的“星球模型”。但是,今天有谁能理解这 个“星球模型”的真正涵义呢?又有谁能知晓在这些大石球中,哪一个代表这些天外来客生活的故乡呢?

9、不可能的足迹化石

1817年,考古学家 HenryR.Schoolcraft和ThomasH.Benton在美国密西西比河西岸附近的一块石灰岩石板上,发现了两个人类的脚印,长约10.5 英寸,脚趾较分散,脚掌平展,与长期习惯于不穿鞋走路的脚印相近。脚步强健有力,脚印自然,各种迹象均表明:其压痕是在岩石很软时踩上去的。据鉴定,这块 石灰岩石板有2亿7000万年的历史。


1938年美国肯塔基州柏里学院地质系主任柏洛兹博 士宣布,他在石炭纪砂岩中发现10个与人类完全相同的脚印。显微照片和红外线照片证明,这些脚印是人足压力自然造成,而非人工雕刻。据估计,有人足痕迹的 这些岩石约有二点五亿年历史。更早一些时候,有人在美国圣路易市密西西比河西岸一块岩石上,曾发现过一对人类脚印。据地质学家判断,这块岩石约有二点七亿 年历史。三叶虫是5.4至2.5亿年前的生物,早已绝迹。最为奇特的是业余化石爱好者麦斯特(William J.Meister,)于1968年6月在犹他州羚羊泉(AntelopeSprings)的寒武纪沉积岩中发现了几块三叶虫化石。

就在一只三叶虫的化石上面竟然发现一只成人的穿着便鞋踩上去的的脚印和一个小孩的脚印,长约10.25英寸,宽约0.5英寸,嵌在岩层中。经犹他(Utah)大学著 名的化学家MelvinA.Cook鉴定这的确是人的脚印。他叙述说,“当我用地质锤轻轻敲开一块石片时,石片“像书本一样打开,我吃惊地发现,一片上面 有一个人的脚印,中央处踩着三叶虫,另一片上也显出几乎完整无缺的脚印形状。更令人奇怪的是,那几个人穿着便鞋!”之后,1968年7月,地质学名家伯狄 克博士亲往羚羊泉考察,又发现了一个小孩的脚印。1968年8月,盐湖城公立学校的一位教育工作者华特,又在含有三叶虫化石的同一块岩石中发现了两个穿鞋 子的人类足迹。所有这些发现,经有关学者鉴定,均认为令人无法怀疑,是对传统地质学的严重挑战。

犹他州大学地球科学博物馆馆长马迪生,在记者招待会上说,那时候“地球上没有人类,也没有可以造成近似人类脚印的猴子、熊或大懒兽,那么,在连脊椎动物也未演化出来之前,有什么似人的动物会在这个星球上行走呢?”三叶虫是细小的海洋无脊椎动物,与虾蟹同类。在地球上存在时间从6亿年前开始,至2.8亿年前灭绝。而人类出现的历史与之相比,很短,至于穿上象样的鞋子不过三千多年。这一切,又该作何解释?

10、不可能出现的金属制品

1885年,有人在法国一个拥有6500万年 历史的白垩纪地层挖出了一个半卵形的金属管,它显然是“手工制造”的。1912年,一家电厂雇员砸碎了一大块煤时,竟然在里面发现了一只铁罐。在苏格兰京 古迪采石场的石块中,矿工们发现了一枚铁钉。据鉴定,这些岩石形成的年代比人类诞生的年代还久远得多。究竟是谁制造了这些金属制品,没人能够解答?

2007-01-10

WebBrowser知识

Q: What is WebBrowser?
A: The WebBrowser is Microsoft's Internet Explorer in the form of an ActiveX control. It can be imported into the Delphi IDE and dropped on a form like any other component. Therefore, you can harness the power of Internet Explorer to turn your Delphi application into a customized browser.

Q: Where can I get documentation on the WebBrowser?
A: For more information, visit the WebBrowser overview section of the Microsoft site and the WebBrowser object page.

Q: How can I use the WebBrowser component in my Delphi application?
A: You must have Internet Explorer installed on your system. From the menu in the Delphi IDE, select "Component - Import ActiveX Control". Select "Microsoft Internet Controls" and add it to a new or existing package. Delphi will generate a ShDocVw_TLB.pas file and add the WebBrowser component to the component palette's ActiveX tab.

Q: I see 2 components on my component palette's ActiveX tab, WebBrowser and WebBrowser_V1. Which one do I use?
A: If you have 2 components then you are using IE 4.x or greater and WebBrowser is IE 4.x and WebBrowser_V1 is IE 3.x. If you only have one component, then WebBrowser is IE 3.x.

Q: How can I determine which version of IE is installed on a target machine?
A: Information is available on the Microsoft site.

Q: How do I Print?
A: There are a couple of ways to print. The first example works in IE 4.x and up, but you'll have to use the second example in IE 3.x:
var
vaIn, vaOut: OleVariant;
...
WebBrowser.ControlInterface.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, vaIn, vaOut);
or
procedure TForm1.PrintIE;
var
CmdTarget : IOleCommandTarget;
vaIn, vaOut: OleVariant;
begin
if WebBrowser1.Document nil then
try
WebBrowser1.Document.QueryInterface(IOleCommandTarget, CmdTarget);
if CmdTarget nil then
try
CmdTarget.Exec( PGuid(nil), OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, vaIn, vaOut);
finally
CmdTarget._Release;
end;
except
// Nothing
end;
end;
Note: If you're not using Delphi 3.02 or higher, you'll have to change
PGuid(nil)
to
PGuid(nil)^
. And you really should upgrade to 3.02, if you're using 3.0 or 3.01.

Q: How do I invoke the Find, Option or View Source options?
A: Here's a code sample for invoking the Find dialog:
const
HTMLID_FIND = 1;
HTMLID_VIEWSOURCE = 2;
HTMLID_OPTIONS = 3;
...
procedure TForm1.FindIE;
const
CGID_WebBrowser: TGUID = '{ED016940-BD5B-11cf-BA4E-00C04FD70816}';
var
CmdTarget : IOleCommandTarget;
vaIn, vaOut: OleVariant;
PtrGUID: PGUID;
begin
New(PtrGUID);
PtrGUID^ := CGID_WebBrowser;
if WebBrowser1.Document nil then
try
WebBrowser1.Document.QueryInterface(IOleCommandTarget, CmdTarget);
if CmdTarget nil then
try
CmdTarget.Exec( PtrGUID, HTMLID_FIND, 0, vaIn, vaOut);
finally
CmdTarget._Release;
end;
except
// Nothing
end;
Dispose(PtrGUID);
end;

Q: How do I disable the right-click popup menu?
A: You have to implement the IDocHostUIHandler interface. You'll need these two files: ieConst.pas and IEDocHostUIHandler.pas. In the ShowContextMenu method of the IDocHostUIHandler interface, you have to change the return value from E_NOTIMPL to S_OK and the menu will not appear on a right-click. Add the two units mentioned above to your Uses clause and implement the following code:
...
var
Form1: TForm1;
FDocHostUIHandler: TDocHostUIHandler;
...
implementation
...
procedure TForm1.FormCreate(Sender: TObject);
begin
FDocHostUIHandler := TDocHostUIHandler.Create;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FDocHostUIHandler.Free;
end;
procedure TForm1.WebBrowser1NavigateComplete2(Sender: TObject;
pDisp: IDispatch; var URL: OleVariant);
var
hr: HResult;
CustDoc: ICustomDoc;
begin
hr := WebBrowser1.Document.QueryInterface(ICustomDoc, CustDoc);
if hr = S_OK then
CustDoc.SetUIHandler(FDocHostUIHandler);
end;

Q: How do I load a string into the WebBrowser without Navigating to a file?
A: Load the string into a Variant array and then write to the Document:
...
var
v: Variant;
HTMLDocument: IHTMLDocument2;
begin
HTMLDocument := WebBrowser1.Document as IHTMLDocument2;
v := VarArrayCreate([0, 0], varVariant);
v[0] := HTMLString; // Here's your HTML string
HTMLDocument.Write(PSafeArray(TVarData(v).VArray));
HTMLDocument.Close;
...
end;
...
This tip provided by Ron Loewy

Q: How do I load a stream into the WebBrowser without Navigating to a file?
A: Here's some sample code:
function TForm1.LoadFromStream(const AStream: TStream): HRESULT;
begin
AStream.seek(0, 0);
Result := (WebBrowser1.Document as IPersistStreamInit).Load(TStreamAdapter.Create(AStream));
end;
This tip provided by Per Larsen

Q: How do I use the "about:" protocol?
A: The "about:" protocol will let you Navigate to an HTML string:
procedure TForm1.LoadHTMLString(sHTML: String);
var
Flags, TargetFrameName, PostData, Headers: OleVariant;
begin
WebBrowser1.Navigate('about:' + sHTML, Flags, TargetFrameName, PostData, Headers)
end;

Q: How do I use the "res:" protocol?
A: The "res:" protocol will let you Navigate to an HTML file stored as a resource. More informations is available from the Microsoft site:
procedure TForm1.LoadHTMLResource;
var
Flags, TargetFrameName, PostData, Headers: OleVariant;
begin
WebBrowser1.Navigate('res://' + Application.ExeName + '/myhtml', Flags, TargetFrameName, PostData, Headers)
end;
Create a resource file (*.rc) with the following code and compile it with brcc32.exe:
MYHTML 23 ".\html\myhtml.htm"
MOREHTML 23 ".\html\morehtml.htm"
Edit your project file so that it looks like this:
{$R *.RES}
{$R HTML.RES} //where html.rc was compiled into html.res

Q: How can I get the full HTML source?
A: With IE5, you can get the source by using the HTML tags outerHTML property. With IE4 or IE3, you have to save the document to a file and then load the file into a TMemo, TStrings, etc.
var
HTMLDocument: IHTMLDocument2;
PersistFile: IPersistFile;
begin
...
HTMLDocument := WebBrowser1.Document as IHTMLDocument2;
PersistFile := HTMLDocument as IPersistFile;
PersistFile.Save(StringToOleStr('test.htm'), True);
while HTMLDocument.readyState 'complete' do
Application.ProcessMessages;
...
end;
This tip provided by Ron Loewy
Note: You have to import the MSHTML type library and include the resulting MSHTML_TLB, as well as ActiveX, in your Uses clause.

Q: How can I pass PostData when I Navigate to a URL?
A: I call the below method with a URL destination, PostData in the format of 'animal=cat etc. and the TWebBrowser object that I want to load the URL inside of...
procedure TDBModule.Navigate(stURL, stPostData: String; var wbWebBrowser: TWebBrowser);
var
vWebAddr, vPostData, vFlags, vFrame, vHeaders: OleVariant;
iLoop: Integer;
begin
{Are we posting data to this Url?}
if Length(stPostData) 0 then
begin
{Require this header information if there is stPostData.}
vHeaders:= 'Content-Type: application/x-www-form-urlencoded'+ #10#13#0;
{Set the variant type for the vPostData.}
vPostData:= VarArrayCreate([0, Length(stPostData)], varByte);
for iLoop := 0 to Length(stPostData)- 1 do // Iterate
begin
vPostData[iLoop]:= Ord(stPostData[iLoop+ 1]);
end; // for
{Final terminating Character.}
vPostData[Length(stPostData)]:= 0;
{Set the type of Variant, cast}
TVarData(vPostData).vType:= varArray;
end;
{And the other stuff.}
vWebAddr:= stURL;
{Make the call Rex.}
wbWebBrowser.Navigate2(vWebAddr, vFlags, vFrame, vPostData, vHeaders);
end; {End of Navigate procedure.}
This tip provided by Craig Foley based on techniques from Nathan Wilhelmi's Usenet posting to borland.public.delphi.internet on the 31/1/99
A: Here's another option:
procedure TForm1.SubmitPostForm;
var
strPostData: string;
Data: Pointer;
URL, Flags, TargetFrameName, PostData, Headers: OleVariant;
begin
{
submit this html form: -- method="post" action="http://127.0.0.1/cgi-bin/register.pl" type="text" name="FIRSTNAME" value="Hans" type="text" name="LASTNAME" value="Gulo" type="text" name="NOTE" value="thats it" type="submit" }
strPostData := 'FIRSTNAME=Hans PostData := VarArrayCreate([0, Length(strPostData) - 1], varByte);
Data := VarArrayLock(PostData);
try
Move(strPostData[1], Data^, Length(strPostData));
finally
VarArrayUnlock(PostData);
end;
URL := 'http://127.0.0.1/cgi-bin/register.pl';
Flags := EmptyParam;
TargetFrameName := EmptyParam;
Headers := EmptyParam; // TWebBrowser will see that we are providing
// post data and then should automatically fill
// this Headers with appropriate value
WebBrowser1.Navigate2(URL, Flags, TargetFrameName, PostData, Headers);
end;
This tip provided by Hans Gulo.

Q: How can I make WebBrowser flat instead of 3D?
A: Here's a code sample to set the Body's borderStyle:
procedure TForm1.WBDocumentComplete(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant);
var
Doc : IHTMLDocument2;
Element : IHTMLElement;
begin
Doc := IHTMLDocument2(TWebBrowser(Sender).Document);
if Doc = nil then
Exit;
Element := Doc.body;
if Element = nil then
Exit;
case Make_Flat of
TRUE : Element.style.borderStyle := 'none';
FALSE : Element.style.borderStyle := '';
end;
end;
This tip provided by Donovan J. Edye

Q: How can I save a web page to a bitmap?
A: Here's a code sample:
procedure TForm1.Button1Click(Sender: TObject);
var
ViewObject: IViewObject;
sourceDrawRect: TRect;
begin
if EmbeddedWB1.Document nil then
try
EmbeddedWB1.Document.QueryInterface(IViewObject, ViewObject);
if ViewObject nil then
try
sourceDrawRect := Rect(0, 0, Image1.Width, Image1.Height);
ViewObject.Draw(DVASPECT_CONTENT, 1, nil, nil, Self.Handle,
image1.Canvas.Handle, @sourceDrawRect, nil, nil, 0);
finally
ViewObject._Release;
end;
except
end;
end;
This tip provided by John

Q: How can I save a web page to a bitmap?
A: Here's a code sample:
procedure generateJPEGfromBrowser(browser: iWebBrowser2; jpegFQFilename: String;
srcHeight: Integer; srcWidth: Integer; tarHeight: Integer; tarWidth: Integer);
var
sourceDrawRect : TRect;
targetDrawRect: TRect;
sourceBitmap: TBitmap;
targetBitmap: TBitmap;
jpeg: TJPEGImage;
viewObject: IViewObject;
begin
sourceBitmap := TBitmap.Create ;
targetBitmap := TBitmap.Create ;
jpeg := TJPEGImage.Create ;
try
try
sourceDrawRect := Rect(0,0, srcWidth , srcHeight );
sourceBitmap.Width := srcWidth ;
sourceBitmap.Height := srcHeight ;
viewObject := browser as IViewObject;
if viewObject = nil then
Exit;
OleCheck(viewObject.Draw(DVASPECT_CONTENT, 1, nil, nil, self.Handle,
sourceBitmap.Canvas.Handle, @sourceDrawRect, nil, nil, 0));
// Resize the src bitmap to the target bitmap
targetDrawRect := Rect(0,0, tarWidth, tarHeight);
targetBitmap.Height := tarHeight;
targetBitmap.Width := tarWidth;
targetBitmap.Canvas.StretchDraw(targetDrawRect, sourceBitmap);
// Create a JPEG from the Bitmap and save it
jpeg.Assign(targetBitmap) ;
makeFileWriteable(jpegFQFilename);
jpeg.SaveToFile (jpegFQFilename);
finally
jpeg.free;
sourceBitmap.free ;
targetBitmap.free;
end;
except
// Error Code
end;
end;
This tip provided by Donall Burns

Q: What is DOM?
A: The Document Object Model is a platform- and language-neutral interface that will allow programs and scripts to dynamically access and update the content, structure and style of documents. The document can be further processed and the results of that processing can be incorporated back into the presented page.

Q: Where can I get documentation on the DOM?
A: There's an overview of DOM-related materials at the W3C site and an FAQ. Check the Document object on the Microsoft site for the DOM implementation in IE 4 5.

Q: How can I iterate through all frames currently shown in the WebBrowser?
A: This sample code shows how to interate through all frames in order to test whether the 'copy' command is enabled:
procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
begin
for i := 0 to (WebBrowser1.OleObject.Document.frames.Length - 1) do
if WebBrowser1.OleObject.Document.frames.item(i).document.queryCommandEnabled('Copy') then
ShowMessage('copy command is enabled for frame no.' + IntToStr(i));
end;
This tip provided by Peter Friese

Q: How can I iterate through all the cells of a
A: This sample code shows how to interate through all the cells of a table, adding the contents of each cell to a TMemo:
procedure TForm1.Button1Click(Sender: TObject);
var
i, j: integer;
ovTable: OleVariant;
begin
ovTable := WebBrowser1.OleObject.Document.all.tags('TABLE').item(0); // I'm using the first TABLE on the page as an example only
for i := 0 to (ovTable.Rows.Length - 1) do
begin
for j := 0 to (ovTable.Rows.Item(i).Cells.Length - 1) do
begin
Memo1.Lines.Add(ovTable.Rows.Item(i).Cells.Item(j).InnerText;
end;
end;
end;

Q: Paste works fine, but Cut and Copy won't work. What's the problem?
A: You have to add the following line to the bottom of your unit:
initialization
OleInitialize(nil);
finalization
OleUninitialize;

Q: ShortCut (Ctrl-C, Ctrl-O, etc.) and Delete keys have no effect. What's the problem?
A: It's not a bug, it's a feature. There's information about this in a Microsoft KnowledgeBase article Q168777. The code below should fix the problem:
...
var
Form1: TForm1;
FOleInPlaceActiveObject: IOleInPlaceActiveObject;
SaveMessageHandler: TMessageEvent;
...
implementation
...
procedure TForm1.FormActivate(Sender: TObject);
begin
SaveMessageHandler := Application.OnMessage;
Application.OnMessage := MyMessageHandler;
end;
procedure TForm1.FormDeactivate(Sender: TObject);
begin
Application.OnMessage := SaveMessageHandler;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Application.OnMessage := SaveMessageHandler;
FOleInPlaceActiveObject := nil;
end;
procedure TForm1.MyMessageHandler(var Msg: TMsg; var Handled: Boolean);
var
iOIPAO: IOleInPlaceActiveObject;
Dispatch: IDispatch;
begin
{ exit if we don't get back a webbrowser object }
if WebBrowser = nil then
begin
Handled := False;
Exit;
end;
Handled:=(IsDialogMessage(WebBrowser.Handle, Msg) = True);
if (Handled) and (not WebBrowser.Busy) then
begin
if FOleInPlaceActiveObject = nil then
begin
Dispatch := WebBrowser.Application;
if Dispatch nil then
begin
Dispatch.QueryInterface(IOleInPlaceActiveObject, iOIPAO);
if iOIPAO nil then
FOleInPlaceActiveObject := iOIPAO;
end;
end;
if FOleInPlaceActiveObject nil then
if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and
((Msg.wParam = VK_BACK) or (Msg.wParam = VK_LEFT) or (Msg.wParam = VK_RIGHT)) then
//nothing - do not pass on Backspace, Left or Right arrows
else
FOleInPlaceActiveObject.TranslateAccelerator(Msg);
end;
end;

TWebBrowser编程简述

1、初始化和终止化(Initialization inalization)
  大家在执行TWebBrowser的某个方法以进行期望的操作,如ExecWB等的时候可能都碰到过“试图激活未注册的丢失目标”或“OLE对象未注册”等错误,或者并没有出错但是得不到希望的结果,比如不能将选中的网页内容复制到剪贴板等。以前用它编程的时候,我发现ExecWB有时侯起作用但有时侯又不行,在Delphi生成的缺省工程主窗口上加入TWebBrowser,运行时并不会出现“OLE对象未注册”的错误。同样是一个偶然的机会,我才知道OLE对象需要初始化和终止化(懂得的东东实在太少了)。
  我用我的前一篇文章《Delphi程序窗口动画 />
  initialization
   OleInitialize(nil);
  finalization
   try
    OleUninitialize;
   except
   end;
  这几句话放在主窗口所有语句之后,“end.”之前。
-----------------------------------------------------------------------
2、EmptyParam
  在Delphi 5中TWebBrowser的Navigate方法被多次重载:
  procedure Navigate(const URL: WideString); overload;
  procedure Navigate(const URL: WideString; var Flags: OleVariant); overload;
  procedure Navigate(const URL: WideString; var Flags: OleVariant; var TargetFrameName:     OleVariant); overload;
  procedure Navigate(const URL: WideString; var Flags: OleVariant; var TargetFrameName:     OleVariant; var PostData: OleVariant); overload;
  procedure Navigate(const URL: WideString; var Flags: OleVariant; var TargetFrameName:     OleVariant; var PostData: OleVariant; var Headers: OleVariant); overload;
  而在实际应用中,使用后几种方法调用时,由于我们很少用到后面几个参数,但函数声明又要求是变量参数,一般的做法如下:
  var
   t:OleVariant;
  begin
   webbrowser1.Navigate(edit1.text,t,t,t,t);
  end;
  需要定义变量t(还有很多地方要用到它),很麻烦。其实我们可以用EmptyParam来代替(EmptyParam是一个公用的Variant空变量,不要对它赋值),只需一句话就可以了:
  webbrowser1.Navigate(edit1.text,EmptyParam,EmptyParam,EmptyParam,EmptyParam);
  虽然长一点,但比每次都定义变量方便得多。当然,也可以使用第一种方式。
  webbrowser1.Navigate(edit1.text)
-----------------------------------------------------------------------
3、命令操作
  常用的命令操作用ExecWB方法即可完成,ExecWB同样多次被重载:
  procedure ExecWB(cmdID: OLECMDID; cmdexecopt: OLECMDEXECOPT); overload;
  procedure ExecWB(cmdID: OLECMDID; cmdexecopt: OLECMDEXECOPT; var pvaIn:
    OleVariant); overload;
  procedure ExecWB(cmdID: rOLECMDID; cmdexecopt: OLECMDEXECOPT; var pvaIn:
    OleVariant; var pvaOut: OleVariant); overload;
  打开: 弹出“打开Internet地址”对话框,CommandID为OLECMDID_OPEN(若浏览器版本为IE5.0,
      则此命令不可用)。
  另存为:调用“另存为”对话框。
      ExecWB(OLECMDID_SAVEAS,OLECMDEXECOPT_DODEFAULT, EmptyParam,
           EmptyParam);

  打印、打印预览和页面设置: 调用“打印”、“打印预览”和“页面设置”对话框(IE5.5及以上版本才支持打
                印预览,故实现应该检查此命令是否可用)。
      ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, EmptyParam,
           EmptyParam);
      if QueryStatusWB(OLECMDID_PRINTPREVIEW)=3 then
       ExecWB(OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DODEFAULT,
           EmptyParam,EmptyParam);
      ExecWB(OLECMDID_PAGESETUP, OLECMDEXECOPT_DODEFAULT, EmptyParam,
           EmptyParam);

  剪切、复制、粘贴、全选: 功能无须多说,需要注意的是:剪切和粘贴不仅对编辑框文字,而且对网页上的非编
               辑框文字同样有效,用得好的话,也许可以做出功能特殊的东东。获得其命令使能状
               态和执行命令的方法有两种(以复制为例,剪切、粘贴和全选分别将各自的关键字替
               换即可,分别为CUT,PASTE和SELECTALL):
   A、用TWebBrowser的QueryStatusWB方法。
     if(QueryStatusWB(OLECMDID_COPY)=OLECMDF_ENABLED) or
      OLECMDF_SUPPORTED) then
      ExecWB(OLECMDID_COPY, OLECMDEXECOPT_DODEFAULT, EmptyParam,
           EmptyParam);
   B、用IHTMLDocument2的QueryCommandEnabled方法。
     var
      Doc: IHTMLDocument2;
     begin
      Doc :=WebBrowser1.Document as IHTMLDocument2;
      if Doc.QueryCommandEnabled('Copy') then
       Doc.ExecCommand('Copy',false,EmptyParam);
     end;
  查找: 参考第九条“查找”功能。
-----------------------------------------------------------------------
4、字体大小
  类似“字体”菜单上的从“最大”到“最小”五项(对应整数0~4,Largest等假设为五个菜单项的名字,Tag 属性分别设为0~4)。
   A、读取当前页面字体大小。
     var
      t: OleVariant;
     Begin
      WebBrowser1.ExecWB(OLECMDID_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER,
       EmptyParam,t);
      case t of
      4: Largest.Checked :=true;
      3: Larger.Checked :=true;
      2: Middle.Checked :=true;
      1: Small.Checked :=true;
      0: Smallest.Checked :=true;
      end;
     end;
   B、设置页面字体大小。
     Largest.Checked :=false;
     Larger.Checked :=false;
     Middle.Checked :=false;
     Small.Checked :=false;
     Smallest.Checked :=false;
     TMenuItem(Sender).Checked :=true;
     t :=TMenuItem(Sender).Tag;
     WebBrowser1.ExecWB(OLECMDID_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER,
      t,t);
-----------------------------------------------------------------------
5、添加到收藏夹和整理收藏夹
    const
     CLSID_ShellUIHelper: TGUID = '{64AB4BB7-111E-11D1-8F79-00C04FC2FBE1}';
    var
     p:procedure(Handle: THandle; Path: PChar); stdcall;
    procedure TForm1.OrganizeFavorite(Sender: Tobject);
    var
     H: HWnd;
    begin
     H := LoadLibrary(PChar('shdocvw.dll'));
     if H 0 then
     begin
    p := GetProcAddress(H, PChar('DoOrganizeFavDlg'));
      if Assigned(p) then p(Application.Handle, PChar(FavFolder));
     end;
     FreeLibrary(h);
    end;
    
    procedure TForm1.AddFavorite(Sender: TObject);
    var
     ShellUIHelper: ISHellUIHelper;
     url, title: Olevariant;
    begin
     Title := Webbrowser1.LocationName;
     Url := Webbrowser1.LocationUrl;
     if Url '' then
     begin
      ShellUIHelper := CreateComObject(CLSID_SHELLUIHELPER) as IShellUIHelper;
      ShellUIHelper.AddFavorite(url, title);
     end;
    end;
-----------------------------------------------------------------------
6、使WebBrowser获得焦点
  TWebBrowser非常特殊,它从TWinControl继承来的SetFocus方法并不能使得它所包含的文档获得焦点,从而不能立即使用Internet Explorer本身具有得快捷键,解决方法如下: />
  procedure TForm1.SetFocusToDoc;
  begin
   if WebBrowser1.Document nil then
    with WebBrowser1.Application as IOleobject do
     DoVerb(OLEIVERB_UIACTIVATE, nil, WebBrowser1, 0, Handle, GetClientRect);
  end;
  除此之外,我还找到一种更简单的方法,这里一并列出:
  if WebBrowser1.Document nil then
   IHTMLWindow2(IHTMLDocument2(WebBrowser1.Document).ParentWindow).focus
  刚找到了更简单的方法,也许是最简单的:
  if WebBrowser1.Document nil then
   IHTMLWindow4(WebBrowser1.Document).focus
  还有,需要判断文档是否获得焦点这样来做:
  if IHTMLWindow4(WebBrowser1.Document).hasfocus then
-----------------------------------------------------------------------
7、点击“提交”按钮
  如同程序里每个窗体上有一个“缺省”按钮一样,Web页面上的每个Form也有一个“缺省”按钮——即属性为“Submit”的按钮,当用户按下回车键时就相当于鼠标单击了“Submit”。但是TWebBrowser似乎并不响应回车键,并且,即使把包含TWebBrowser的窗体的 KeyPreview设为True,在窗体的KeyPress事件里还是不能截获用户向TWebBrowser发出的按键。
  我的解决办法是用 ApplicatinEvents构件或者自己编写TApplication对象的OnMessage事件,在其中判断消息类型,对键盘消息做出响应。至于点击“提交”按钮,可以通过分析网页源代码的方法来实现,不过我找到了更为简单快捷的方法,有两种,第一种是我自己想出来的,另一种是别人写的代码,这里都提供给大家,以做参考。
  A、用SendKeys函数向WebBrowser发送回车键
   在Delphi 5光盘上的Info\Extras\SendKeys目录下有一个SndKey32.pas文件,其中包含了两个函数SendKeys和 AppActivate,我们可以用SendKeys函数来向WebBrowser发送回车键,我现在用的就是这个方法,使用很简单,在 WebBrowser获得焦点的情况下(不要求WebBrowser所包含的文档获得焦点),用一条语句即可:
   Sendkeys('~',true);// press RETURN key
   SendKeys函数的详细参数说明等,均包含在SndKey32.pas文件中。
  B、在OnMessage事件中将接受到的键盘消息传递给WebBrowser。
   procedure TForm1.ApplicationEvents1Message(var Msg: TMsg; var Handled: Boolean);
   {fixes the malfunction of some keys within webbrowser control}
   const
    StdKeys = [VK_TAB, VK_RETURN]; { standard keys }
    ExtKeys = [VK_DELETE, VK_BACK, VK_LEFT, VK_RIGHT]; { extended keys }
    fExtended = $01000000; { extended key flag }
   begin
    Handled := False;
    with Msg do
    if ((Message WM_KEYFIRST) and (Message WM_KEYLAST)) and
     ((wParam in StdKeys) or
     {$IFDEF VER120}(GetKeyState(VK_CONTROL) 0) or {$ENDIF}
     (wParam in ExtKeys) and
     ((lParam and fExtended) = fExtended)) then
    try
     if IsChild(Handle, hWnd) then { handles all browser related messages }
     begin
      with {$IFDEF VER120}Application_{$ELSE}Application{$ENDIF} as
        IOleInPlaceActiveObject do
       Handled := TranslateAccelerator(Msg) = S_OK;
       if not Handled then
       begin
        Handled := True;
        TranslateMessage(Msg);
        DispatchMessage(Msg);
       end;
       end;
    except
    end;
   end; // MessageHandler
  (此方法来自EmbeddedWB.pas)
-----------------------------------------------------------------------
8、直接从TWebBrowser得到网页源码及Html
  下面先介绍一种极其简单的得到TWebBrowser正在访问的网页源码的方法。一般方法是利用TWebBrowser控件中的 Document对象提供的IPersistStreamInit接口来实现,具体就是:先检查WebBrowser.Document对象是否有效,无效则退出;然后取得IPersistStreamInit接口,接着取得HTML源码的大小,分配全局堆内存块,建立流,再将HTML文本写到流中。程序虽然不算复杂,但是有更简单的方法,所以实现代码不再给出。其实基本上所有IE的功能TWebBrowser都应该有较为简单的方法来实现,获取网页源码也是一样。下面的代码将网页源码显示在Memo1中。
   Memo1.Lines.Add(IHtmlDocument2(WebBrowser1.Document).Body.OuterHtml);
  同时,在用TWebBrowser浏览HTML文件的时候要将其保存为文本文件就很简单了,不需要任何的语法解析工具,因为TWebBrowser也完成了,如下:
   Memo1.Lines.Add(IHtmlDocument2(WebBrowser1.Document).Body.OuterText);
-----------------------------------------------------------------------
9、“查找”功能
  查找对话框可以在文档获得焦点的时候通过按键Ctrl-F来调出,程序中则调用IOleCommandTarget对象的成员函数Exec执行OLECMDID_FIND操作来调用,下面给出的方法是如何在程序中用代码来做出文字选择,即你可以自己设计查找对话框。
   var
    Doc: IHtmlDocument2;
    TxtRange: IHtmlTxtRange;
   begin
    Doc :=WebBrowser1.Document as IHtmlDocument2;
    Doc.SelectAll;    //此处为简写,选择全部文档的方法请参见第三条命令操作
                //这句话尤为重要,因为IHtmlTxtRange对象的方法能够操作的前提是
                //Document已经有一个文字选择区域。由于接着执行下面的语句,所以不会
                //看到文档全选的过程。
    TxtRange :=Doc.Selection.CreateRange as IHtmlTxtRange;
    TxtRange.FindText('Text to be searched',0.0);
    TxtRange.Select;
   end;
  还有,从Txt.Get_text可以得到当前选中的文字内容,某些时候是有用的。
-----------------------------------------------------------------------
10、提取网页中所有链接
  这个方法来自大富翁论坛hopfield朋友的对一个问题的回答,我本想自己试验,但总是没成功。
  var
   doc:IHTMLDocument2;
   all:IHTMLElementCollection;
   len,i:integer;
   item:OleVariant;
  begin
   doc:=WebBrowser1 .Document as IHTMLDocument2;
   all:=doc.Get_links;             //doc.Links亦可
   len:=all.length;
   for i:=0 to len-1 do begin
    item:=all.item(i,varempty);        //EmpryParam亦可
    memo1.lines.add(item.href);
   end;
  end;
-----------------------------------------------------------------------
11、设置TWebBrowser的编码
  为什么我总是错过很多机会?其实早就该想到的,但是一念之差,便即天壤之别。当时我要是肯再多考虑一下,多试验一下,这就不会排到第11条了。下面给出一个函数,搞定,难以想象的简单。
  procedure SetCharSet(AWebBrowser: TWebBrowser; ACharSet: String);
  var
   RefreshLevel: OleVariant;
  Begin
   IHTMLDocument2(AWebBrowser.Document).Set_CharSet(ACharSet);
   RefreshLevel :=7;              //这个7应该从注册表来,帮助有Bug。
   AWebBrowser.Refresh2(RefreshLevel);
  End;

世界为之倾倒:iPhone震撼发布

经过无数次的反复,对iPhone无数次的想象,占据了全球所有IT媒体版面却始终看不到真机的iPhone终于由苹果和Cingular共同发布,我们惊叹,苹果又一次让我们佩服,又一次完美的现身:


如果图片缩小请点击以放大查看


才11.6
毫米的厚度(这身材太完美了),拥有极致的3.5英寸宽屏,当然,带触摸控制技术,200万像素摄像头,8GB的容量大小,同时支持3G技术的收音,运行
OS
X(天,所有的手机都无法做到,果然是Apple厉害),在你把手机贴近脸部的时候通过探测器自动关闭触摸功能(防止误操作),这下所有的尘埃落定,赶紧
看我们的现场图,另外,别忘了把你的惊讶,惊奇,意见,观点留下!


如果图片缩小请点击以放大查看


如果图片缩小请点击以放大查看


如果图片缩小请点击以放大查看


如果图片缩小请点击以放大查看


如果图片缩小请点击以放大查看


如果图片缩小请点击以放大查看


如果图片缩小请点击以放大查看


如果图片缩小请点击以放大查看


如果图片缩小请点击以放大查看


如果图片缩小请点击以放大查看


现在Apple主页上关于其最新iPhone的宣传已是铺天盖地。各位可以通过文末的链接官方链接查看到更多的介绍和细节参数。这款超酷的iPhone将于今年7月上市,售价$499。

精选文章

旧手机变废为宝|五分钟安装Ollama跑开源大模型 - 开发调优 - LINUX DO

旧手机变废为宝|五分钟安装Ollama跑开源大模型 - 开发调优 - LINUX DO 在开始之前,请你先准备好一台旧Android手机以及特殊的网络环境。 1.安装Termux 2.更新软件包及依赖 pkg update && pkg upgrade 3.安...