阜阳网站建设价格低,利辛做网站,中国十大it公司,北京十大活动策划公司HTML的界面有以下特点#xff1a;图文混排#xff0c;格式灵活#xff0c;可以包含Flash、声音和视频等#xff0c;实现图文声像的多媒体界面#xff0c;而且易于建立和维护。另外#xff0c;HTML的显示环境一般机器上都具备#xff0c;通常不需要安装额外的软件。当然图文混排格式灵活可以包含Flash、声音和视频等实现图文声像的多媒体界面而且易于建立和维护。另外HTML的显示环境一般机器上都具备通常不需要安装额外的软件。当然HTML界面也有它欠缺的方面即界面控制能力有限代码调试不便----虽然DHTML提供了比较强的编程特性但是比起Delphi的传统的开发语言和工具来对界面的控制能力尤其是和数据交互时的控制能力还是稍逊一筹。了解了这些特点我们就可以在实际应用开发中适时地选择HTML技术。下面举个例子一种仪器的管理程序需要显示该仪器的操作方法文档包含文字和图片并要求可以隐藏或显示文档并能安要求打印。这个应用中图文显示、隐藏/显示部分文档、图文打印等需求都是HTML界面所擅长的用传统的表单控件实现几乎无法想像。用Delphi实现HTML界面的应用主要有两种选择WebBrowser Control或MSHTML。为了弄清两者如何选择我们先来看看Internet Exporer 4.0及其后续版本的体系结构IE浏览器是建立在SHDOCVW.DLL组件之上的而SHDOCVW.DLL则建立在MSHTML.DLL组件之上底层则包括脚本引擎等。SHDOCVW.DLL提供了对活动文档(Active Document)的支持----例如Word等文档可以在IE中显示并提供导航、in-place*连接、收藏夹、浏览历史和分级内容选择(PICS: Platform for Internet Content Selection)等功能。SHDOCVW.DLL组件虽然也提供了很多接口可以单独使用但是通常所指的SHDOCVW.DLL就是WebBrowser Control。MSHTML.DLL是实行HTML解析和表现的组件。它通过DHTML对象模型提供对HTML文档的访问。它实现了活动文档服务器接口可以通过COM接口调用。不难看出WebBrowser在比较高的层次上提供了更为丰富的功能因此一般通常编程都采用WebBrower控件。MSHTML只有在需要解析HTML这样的特殊应用中才推荐使用。微软的MSDN网站上提供了一个使用MSHTML的例子WalkAll Sample Source Page。(*注In-place链接是指点击HTML连接时在相同的WebBrowser实例中显示连接的HTML文档。如果仅使用MSHTML.DLL点击链接将导致在新的浏览器实例中打开链接的文档。)首先在Delphi 7.0组件面板的Internet页上把TWebBrowser组件放到表单上。通过执行以下语句装载HTML文档到WebBrowser中进行显示WebBrowser1.Navigate(GetCurrentDir ‘\index.htm‘);隐藏/显示HTML元件代码示例varDoc : IHTMLDocument2;element: IHTMLElement;beginDoc : IHTMLDocument2(WebBrowser1.Document);if nil Doc thenbeginelement : Doc.all.item(‘T1‘, 0) as IHTMLElement;if nil element then beginif ‘‘ element.style.display thenelement.style.display : ‘none‘elseelement.style.display : ‘‘;end;end;end;设置/取值代码示例varDoc : IHTMLDocument2;inputText : IHTMLInputTextElement;beginDoc : IHTMLDocument2(WebBrowser1.Document);if nil Doc thenbegin//如果T1不是IHTMLInputTextElement类型将出错inputText : Doc.all.item(‘T1‘, 0) as IHTMLInputTextElement;inputText.value : Edit1.Text;Edit2.Text : inputText.value;end;end;提示关于哪些HTML元件(标记)应该采用什么MSHTML接口进行访问请参考MSDN Library中的Web Development Programming and Reusing the Browser MSHTML Reference Interfaces and Scripting Objects。知道了访问HTML内容的方法就可以通过间接方式调用HTML页面上包含的JavaScript代码。具体实现方式是在HTML中插入等不可见元件利用它的click事件调用响应的JavaScript函数然后再Delphi中调用该元件的click过程。下面我们就用Delphi调用JavaScript的alert函数来实现消息提示框。首先在HTML中加入Delphi中的调用代码如下procedure TForm1.Alert(const Msg : string);varDoc : IHTMLDocument2;Element : IHTMLElement;beginDoc : IHTMLDocument2(WebBrowser1.Document);Assert(nil Doc);//一定要先加载HTMLElement : Doc.all.item(‘ShowMessage‘, 0) as IHTMLElement;if nil Element thenbeginElement.innerText : Msg;Element.click;end;end;我发现在Delphi中用Browser显示HTML如果你的表单是作为EXE运行然后嵌入到了别的表单的组件上显示的例如Form1.Parent : Form2.Panel1即Form1显示在Form2中Panel1所占据的位置当你用ShowMessage显示提示信息时HTML的内容依然可以被操作这显然不太好。使用JavaScript中的alert函数则可避免这种现象。默认情况下在显示HTML的WebBrowser上点击鼠标右键会显示一个弹出菜单和IE中看到的一样。通过这个菜单用户可以查看HTML的源代码。因此有时候我们需要屏蔽该菜单。和该菜单相关的接口是IEDocHostUIHandler。已经用人对它进行了封装详见ieConst.pas 和 IEDocHostUIHandler.pas。使用方法如下varForm1: TForm1;FDocHostUIHandler: TDocHostUIHandler;...implementation...procedure TForm1.FormCreate(Sender: TObject);beginFDocHostUIHandler : TDocHostUIHandler.Create;end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);beginFDocHostUIHandler.Free;end;procedure TForm1.WebBrowser1NavigateComplete2(Sender: TObject;pDisp: IDispatch; var URL: OleVariant);varhr: HResult;CustDoc: ICustomDoc;beginhr : WebBrowser1.Document.QueryInterface(ICustomDoc, CustDoc);if hr S_OK thenCustDoc.SetUIHandler(FDocHostUIHandler);end;有时你可能还需要定制自己的右键菜单这是还是要借助于IEDocHostUIHandler具体实现方法可以看看MSDN Library。HTML事件的响应方式有两种一种是JavaScript一种是在Delphi中响应。一些简单的功能可以在JavaScript中实现这样易于修改。但是从功能、安全性等方面考虑通常还是要在Delphi中实现。例如当用户点击HTML上的一个按钮时需要访问数据库这是就得用Delphi了。在Delphi中响应HTML事件实际上就是响应ActiveX事件的问题这通过事件槽(Event Sink)来实现有些繁琐。还好前人已经为我们作了很多工作。利用Experts Exchange网站的Cynna封装的TDHTMLEvent类(该源码请看本文的附件)实现就简单多了。实现代码如下varForm1: TForm1;EventSink: TDHTMLEvent;...implementation...procedure TForm1.FormCreate(Sender: TObject);beginEventSink: TDHTMLEvent.Create;end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);beginEventSink.Free;end;procedure TForm1.DemoEventSink(Sender: TObject);beginShowMessage(‘成功从HTML中调用Delphi的过程。‘);end;procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;const pDisp: IDispatch; var URL: OleVariant);varDoc : IHTMLDocument2;Element : IHTMLElement;beginDoc : IHTMLDocument2(WebBrowser1.Document);if nil Doc thenbegin //找到HTML元件 Element : Doc.all.item(‘B3‘, 0) as IHTMLElement;//使HTML元件的click事件和DemoEventSink过程关连Element.onclick : EventSink.HookEventHandler(DemoEventSink);end;end;点击HTML页面中ID为‘B3‘的按钮就会调用DemoEventSink过程。含有多行文本输入框(textarea )或提交(submit)按钮的HTML表单在TWebBrowser中显示时对回车键不响应。另外Delphi表单上按钮的快捷字母键也无法在HTML表单上输入因为一输入就触发相应按钮的单击事件。解决代码如下unitUnit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, OleCtrls, SHDocVw_TLB, ActiveX, StdCtrls;typeTForm1 class(TForm)WebBrowser1: TWebBrowser;Button1: TButton;Button2: TButton;procedureFormDestroy(Sender: TObject);procedureFormCreate(Sender: TObject);procedureButton1Click(Sender: TObject);procedureButton2Click(Sender: TObject);private{ Private declarations }FOleInPlaceActiveObject: IOleInPlaceActiveObject;procedureMsgHandler(varMsg: TMsg; varHandled: Boolean);public{ Public declarations }end;varForm1: TForm1;implementation{$R *.dfm}procedureTForm1.FormDestroy(Sender: TObject);beginFOleInPlaceActiveObject : nil;end;procedureTForm1.FormCreate(Sender: TObject);beginApplication.OnMessage : MsgHandler;end;procedureTForm1.MsgHandler(varMsg: TMsg; varHandled: Boolean);constDialogKeys: set ofByte [VK_LEFT, VK_RIGHT, VK_BACK, VK_UP, VK_DOWN,$30..$39, $41..42, $44..$55, $57, $59..$5A];variOIPAO: IOleInPlaceActiveObject;Dispatch: IDispatch;begin{ exit if we don‘t get back a webbrowser object }if(WebBrowser1 nil) thenbeginHandled : System.False;Exit;end;Handled : (IsDialogMessage(WebBrowser1.Handle, Msg) System.True);if(Handled) and(notWebBrowser1.Busy) thenbeginifFOleInPlaceActiveObject nil thenbeginDispatch : WebBrowser1.Application;ifDispatch nil thenbeginDispatch.QueryInterface(IOleInPlaceActiveObject, iOIPAO);ifiOIPAO nil thenFOleInPlaceActiveObject : iOIPAO;end;end;ifFOleInPlaceActiveObject nil thenif((Msg.message WM_KEYDOWN) or(Msg.message WM_KEYUP)) and(Msg.wParam inDialogKeys) then// nothing - do not pass on the DialogKeyselseFOleInPlaceActiveObject.TranslateAccelerator(Msg);end;end;initializationOleInitialize(nil);finalizationOleUninitialize;本段代码出自SwissDelphiCenter.ch作者未知。主要要引用ActiveX。Delphi 7中SHDocVw_TLB改为SHDocVw。HTML的打印和预览向来是个难题但自从IE5.5推出后情况大有改观。你可以利用其“打印模板”功能实现自己的预览窗口和控制打印。“打印模板”的使用方法请参考MSDN Library中的Web Development Programming and Reusing the Browser Print Templates目录下的文章。从微软的网站上还可以下载到一个不错的例子示例如何一步步由浅入深地使用Print Template (下载打印模板示例)。你会发现要自己实现一个功能完善的打印模板也并非易事。IE浏览器本身带的打印模板做得还不错能否在它的基础上加上自己的定制功能呢答案是肯定的至少从技术上看是这样(不考虑版权问题)。下面就介绍这偷懒的招。用Visual Studio打开x:\Program Files\Internet Explorer\MUI\0804\SHDOCLC.DLL会看到其资源目录。其中HTML/PREVIEW.DLG就是IE所带的打印模板了。把它export(导出)出来把文件扩展名改成HTM打开看看是不是特刺激PREVIEW.DLG用到了几个图片文件在2110目录下别忘了导出。(注我的环境是Windows XP Professional英文版SP1aIE是6.0sp1。)IE默认的模版中页眉页脚均只支持纯文字。下面以定制HTML页眉为例看看如何定制自己的打印模板。思路是用自己的页眉内容换掉原有的内容并修改其页眉高度和页边距使之和新的页眉相对应。第一步定义页眉。在要使用此模版预览打印的HTML文件中加入一个id为Header的div标记括起HTML页眉内容并制定以英寸为单位的页眉的高度和宽度其中宽度应该和模版相符。例...(HTML页眉内容)第二步声明变量。在模版前面变量声明部分加上两个变量声明var g_htmlHeader ;//用于保存页眉内容var g_nHeaerHeight 0;//页眉的高度第三步取得页眉。在函数OnLoadBody()中的“Printer.footer dialogArguments.__IE_FooterString”语句之后加入这段代码oPageHeader dialogArguments.__IE_BrowseDocument.all.item(Header, 0);if (null ! oPageHeader){g_htmlHeader oPageHeader.innerHTML;g_nHeaerHeight oPageHeader.style.posHeight;}第四步指定页边距和页眉高度。在上面的代码下面紧接着加入//指定页边距。其中40可以自己改单位是百分之一英寸。Printer.marginTop 40 (g_nHeaerHeight * 100);Printer.marginBottom 40;Printer.marginLeft 40;Printer.marginRight 40;在函数EnsureDocuments()中/*注释掉以下代码if (header){tmp upTop (27 / 100);if (tmp top)top tmp;}if (footer){tmp upBottom (27 / 100);if (tmp bottom)bottom tmp;}*///紧接着加上tmp upTop g_nHeaerHeight;if (tmp top)top tmp;//下面隔几行注释掉oRule.style.top upTop in;第五步指定页眉内容。在函数CPrintDoc_AddPage()中在“HeadFoot.page HeadFoot.pageTotal;”语句之后加入//这两行用于设置页码你在页眉可以通过加入“[P]”和“[p]”分别代表总页数和当前页数。g_htmlHeader g_htmlHeader.replace([P], );var pageHeader g_htmlHeader.replace([p], HeadFoot.pageTotal);//下面隔3行注释掉//~oPage.children(header).innerHTML HeadFoot.HtmlHead;//~oPage.children(footer).innerHTML HeadFoot.HtmlFoot;//下面隔几行把“newHTM HeadFoot.HtmlHead;”改为newHTM pageHeader ;//然后注释掉(不要页脚)newHTM HeadFoot.HtmlFoot;至此一个支持自定义HTML页眉的新模版就定制完成了。是不是觉得特爽如果觉得它给你省下了两周的时间就赶紧到“希望之光”网站上花你2天的工资资助一个小孩上学吧。定制好的打印模板怎么用呢请看以下代码varvaIn, vaOut: OleVariant;CmdTarget : IOleCommandTarget;MyHandle : THandle;beginvaIn : ‘c:\\Preview.htm‘;//预览方法1WebBrowser1.ControlInterface.ExecWB(OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_PROMPTUSER, vaIn, vaOut);//下面是方法2 if WebBrowser1.Document nil thenbeginWebBrowser1.Document.QueryInterface(IOleCommandTarget, CmdTarget);if CmdTarget nil thenbegintryCmdTarget.Exec( PGuid(nil), OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_PROMPTUSER, vaIn, vaOut);finallyCmdTarget._Release;end;endelsebeginShowMessage(‘IE不支持该功能请升级至IE5.5以上。‘);end;end;end;方法1简洁但是如果WebBroswer不支持打印预览的话就会出错。第二种方法可能更好一些。在打印预览时预览窗口的尺寸大小总是和WebBrowser所在的Form的一样而且没法最大化。更麻烦的是如果你的表单是嵌入到了别的表单的组件上显示的例如Form1.Parent : Form2.Panel1即Form1显示在Form2中Panel1所占据的位置那么预览窗口就变得很小了不拉大根本没法看。解决办法如下在预览的代码后面加上以下代码使预览窗口最大化Handle:FindWindow(‘Internet Explorer_TridentDlgFrame‘, ‘打印预览‘);if 0 MyHandle thenbeginShowWindow(MyHandle , SW_MAXIMIZE);end;如果不预览而是直接打印则把OLECMDID_PRINTPREVIEW换成OLECMDID_PRINT就可以了。如果要在Web应用中使用打印模板可以通过ActiveX来实现调用。注打印模板需要安装Internet Explorer 5.5以上版本本文其它功能需要安装Internet Explorer4.0以上版本。应用做好了总不能把HTML文件和相关的图片文件等直接发布吧。这样既不安全前面禁止用户查看源代码的努力也白费了。因此至少应该将这些文件打个包。一般来说作为资源编译到exe或dll里就行了。我觉得编译到DLL中最为方便。在Visual Studio中新建一个Win32工程应用类型选择DLL。然后把HTML文件和相关的图片文件等资源加到工程中然后编译即可。再添加HTML等资源时我强烈推荐用手工加入的方法。原因有二一GIF等图片文件加入到工程中时Studio可能会把文件内容自动改了使得该文件不能正确显示二加入资源后会自动生成资源ID需要把它改成你需要的名称(通常改成和文件名相同)当文件很多时这项工作就很浪费时间也很烦人。手工加入即用文本编辑器把资源脚本文件(工程名.rc)打开手工加入内容。我就不赘述了格式例子如下About.htm HTML HTML\\About.htmimage016.gif IMAGES HTML\\images\\image016.gif当加入很多文件时如何节省时间呢没有实践经验的人是不可能想到这些问题的。别着急按我说的做。首先进入命令行(DOS)界面(Windows NT/2000/XP/2003下运行cmd.exe进入)进入你的HTML等资源文件所在的目录执行“dir temp.txt”,把文件列表输出到temp.txt。接着用文本编辑器把该文件打开去掉头尾内容仅留文件列表部分例如2004-03-17 11:20 20,397 About.htm2004-03-17 11:20 27,397 index.htm然后用Excel把修改后的文件打开。打开时“原始数据类型”请选择“固定宽度 - 每列字段加空格对齐”。这样日期、时间、文件大小、文件名就被分别放在了不同的列中。删除前三列仅留文件名一列并把该列复制一份。在两个文件名列之间插入两个空列分别填写“HTML”和“HTML\\”然后就可以另存成以制表符分隔的文本文件了。最后用文本编辑器把上一步处理好的文件打开不用我多说只要几个替换就得到所需要的资源脚本了。对于不同目录下的文件均需要这么弄以下。资源脚本弄好了把资源文件也加入(不是作为资源加入)工程编译就得到打包好的DLL文件了。接下来的问题是这个DLL怎么用啊别急WebBrowser支持一种叫res的协议可以访问文件里的资源。例如假设上面About.htm打包到了myresource.dll文件中则可以通过res://myresource.dll/About.htm访问image016.gif则可通过res://myresource.dll/images/image016.gif访问(注意到了吧HTML在根目录下而IMAGES等其它资源则在同名目录下)。如果About.htm中通过“images/image016.gif”引用了image016.gif文件则该图片在WebBrowser中正常显示。换句话说你在打包之前程序可以通过file://...访问HTML打包之后只需要换成res://...就可以了----打包对程序和HTML几乎没什么影响。但是切记切记千万不要仅以数字来做文件名(如1.htm、2.gif等)因为数字是被用来标识某种资源或某个资源的如果用仅用数字作文件名(可以用字母数字)打包后会导致访问找不到文件。