专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »PHP教程 » 重温delphi的如何快速开发原生ActiveXControl控件 »正文

重温delphi的如何快速开发原生ActiveXControl控件

来源: 发布时间:星期四, 2009年12月17日 浏览:0次 评论:0
  ActiveX技术虽然是项古老技术但是却有着广泛应用支付宝密码输入Control控件各大银行密码输入Control控件网页聊天室中截屏功能网页播放器中p2p播放...甚至Flash,Silverlight等等在IE中都表现为ActiveX虽然c#也能开发"用于网页com应用"能达到类似ActiveX效果但是有个要命问题是必须得安装几百M.net framework框架如果仅仅为了安全输入个密码而要用户下载几百M安装这是很多人不能接受delphi做为win32下原生开发工具能很好支持微软各种"古老"经典技术(再做点小广告:delphikyrix版本还能编译跨平台应用哦!) 

  ok开工吧:

  开发工具:推荐用delphi 2010(d7也可以不过添加属性思路方法等过程要手动稍微麻烦点) 

  1.启用delphi2010-->File->New->Other-->Active Library



  查看原图(大图)

  2.项目命名为MyActiveX



  查看原图(大图)

  3.File-->Save All 全部保存

  实际上这样就能编译了不过只是空dll

  4.File-->New-->Other-->Active Form



  查看原图(大图)

  改名为MyForm



  将对应单元文件保存为UMyForm.pas

  5.打开MyAcitveX.ridl文件切换到design视图选中IMyForm接口右击New-->Property 添加个属性Msg



  查看原图(大图)

  将Msg属性Type改为BSTR 即WideString类型



  查看原图(大图)

  完了的后点击工具栏中Refresh Implementation(即上图中工具栏中圈起来部分)--这步很重要点击的后它将自动生成属性Msg对应声明和实现代码模板

  6.打开UMyForm.pas--即ActiveForm对应单元找到Set_Msg以及Get_Msg实现部分补充代码如下:

function TMyForm.Get_Msg: WideString;
begin
    result:=_msg;
end;
procedure TMyForm.Set_Msg(const Value: WideString);
begin
  _msg := value;
end;


  当然TMyFormprivate部分得先加个私有成员 

type
  TMyForm = (TActiveForm, IMyForm)
  private
    { Private declarations }
    _msg:WideString;
...


  这样我们就为即将生成ActiveXControl控件添加了串类型属性Msg下面来测试下:

  7.编译项目会生成个MyActiveX.ocx在运行栏里输入

  regsvr32 C:\Users\jimmy.yang\Desktop\delphi_activex\MyActiveX\MyActiveX.ocx

  注:这里ocx路径请各位根据自己实际路径修改

  这样就完成了ocx注册

  8.放到html里测试下:

<OBJECT ID='x' name='x' CLASSID='CLSID:52D17094-0687-4A2F-B2DB-30F3189AC659' align=center hspace=0 vspace=0 ></OBJECT>
<script type='text/javascript'>
var x = document.getElementById("x");
alert(x.Msg);
</script>


  有关CLSID在哪里查看打开:MyActiveX_TLB.pas文件定位到下面这里:

const
  // TypeLibrary Major and minor versions
  MyActiveXMajorVersion = 1;
  MyActiveXMinorVersion = 0;
  LIBID_MyActiveX: TGUID = '{49138437-8265-4B1A-9EAE-D0F615D68464}';
  IID_IMyForm: TGUID = '{54A20855-29A3-4C92-85DE-A419DA457C7A}';
  DIID_IMyFormEvents: TGUID = '{60BBC967-E1E6-4E98-BAE5-776BFD06E9CC}';
  CLASS_MyForm: TGUID = '{52D17094-0687-4A2F-B2DB-30F3189AC659}';


  其中 CLASS_MyForm: TGUID对应就是ClassID

  运行后除了弹出个空白警告框暂时看不到其它:)(可不就是这样么?Msg属性没给任何当然是空所以弹出个空警告框是正常)

  9.我们再来添加些Control控件和思路方法以验证刚才设置属性确实有效

  在MyForm上添加个文件框个按钮

 

  按钮事件如下:

procedure TMyForm.Button1Click(Sender: TObject);
begin
  _msg:= self.Edit1.Text;
end;


  即把文本框值赋给属性Msg

  再继续定位到Set_Msg,略做修改

procedure TMyForm.Set_Msg(const Value: WideString);
begin
  _msg := value;
  self.Edit1.Text := _msg;
end;


  即设置Msg属性时同时也把值显示在文本框里以便等会儿我们好测试在js中给activeX属性赋值效果

  ok了再来测试编译如果通不过请先运行

  regsvr32 C:\Users\jimmy.yang\Desktop\delphi_activex\MyActiveX\MyActiveX.ocx /u

  将刚才注册ocx反注册同时关掉浏览器不然该ocx文件直被占用无法更新.

  修改下html代码:

<OBJECT ID='x' name='x' CLASSID='CLSID:52D17094-0687-4A2F-B2DB-30F3189AC659' align=center hspace=0 vspace=0 ></OBJECT>
<hr />
<input type='button' value='显示Msg属性值' onclick='ShowMsg'/>
<input type='button' value='设置Msg属性值' onclick='SetMsg'/>
<script type='text/javascript'>
var x = document.getElementById("x");
var ShowMsg = function{
    alert(x.Msg);
}
var SetMsg = function{
    x.Msg = 'js传过来值';
}
</script>


  运行效果:



  10.添加Method

  我们已经知道了如何给ActiveX添加对外公开属性但是光有属性显然不够我们再添加个Method参考第5步中截图选择-->Method,添加

  个思路方法,命名为ShowMsgReturn参数项用默认值HRESULT然后Parameters添加个参数如下图:



  查看原图(大图)

  同样不要忘记了点击工具栏中更新按钮,再打开UMyForm.pas会发现自动添加了个过程定义:

  procedure ShowMsg(const p: WideString); safecall;

  转到它实现部分写几行测试代码:

procedure TMyForm.ShowMsg(const p: WideString);
begin
  showmessage('Msg属性值为:' + _msg + #13 + '传入参数为:' + p);
end;


  再编译html代码中添加些代码:

<OBJECT ID='x' name='x' CLASSID='CLSID:52D17094-0687-4A2F-B2DB-30F3189AC659' align=center hspace=0 vspace=0 ></OBJECT>
<hr />
<input type='button' value='显示Msg属性值' onclick='ShowMsg'/>
<input type='button' value='设置Msg属性值' onclick='SetMsg'/>
<input type='button' value='ShowMsg思路方法' onclick='CallShowMsg'/>
<script type='text/javascript'>
var x = document.getElementById("x");
var ShowMsg = function{
    alert(x.Msg);
}
var SetMsg = function{
    x.Msg = 'js传过来值';
}
var CallShowMsg = function{
    x.ShowMsg('这是js传过来参数');
}
</script>


  运行看下:



  类似我们还可以为ActiveX添加带返回值function,而非过程procedure但是比较郁闷我试了半天delphi中编译正常后但是在javascript中就是无法取得返回值估计是delphi变量类型和javascript变量类型不匹配引起哪位 delphi高人如果知道原因还请指点 2在此先谢过.

  11.深入看下ActiveX中到底有哪些玩意儿?

  既然ActiveX能加载到网页中肯定也是dom树份子了想知道ActiveX到底提供了哪些其它属性或思路方法吗?以下js代码可以测试出来:

<div id="info"></div>
<script type="text/javascript">
var _info="";
for(var p in x){
    _info  p + ":" + x[p] + "<br/>";
}
document.getElementById("info").innerHTML = _info;
</script>


  当然如果你用IE8js调试功能也能看到刚才定义那些思路方法和属性:



  查看原图(大图)

  注意下这里还有其它很多属性比如Caption所以你在js中用alert(x.Caption)也能弹出ActiveForm标题这是我们通过IE/JS从外部来看ActiveX其实也能换个角度从delphi内部看下activex结构com技术号称就是组通用接口规范标准所以我们在delphi内部确实也能发现不少接口:

  MyActiveX.ridl中可以看到

library MyActiveX
{
  ...
  erface IMyForm;
  ...
...


  表明IMyForm就是个接口,再定位到MyActiveX_TLB.pas可以发现:

type
...
  IMyForm = erface;
  ...
  MyForm = IMyForm;
IMyForm = erface(IDispatch)
   ...


  介绍说明MyForm就是从IDispatch继承下来个接口

  最后再到UMyForm.pas中可以看到

type
  TMyForm = (TActiveForm, IMyForm)
    Edit1: TEdit;
...


  介绍说明最终运行窗口就是继承自TActiveForm并实现了IMyForm个类

  12.事件支持

  打开MyActiveX.ridl查看IMyFormEvents部分可以看到delphi生成ActiveXControl控件中已经预置了很多事件

disperface IMyFormEvents
  {
    properties:
    methods:
    [id(0x000000C9)]
    void OnActivate(void);
    [id(0x000000CA)]
    void OnClick(void);
    [id(0x000000CB)]
    void OnCreate(void);
    [id(0x000000CC)]
    void OnDblClick(void);
    [id(0x000000CD)]
    void OnDestroy(void);
    [id(0x000000CE)]
    void OnDeactivate(void);
    [id(0x000000CF)]
    void OnKeyPress([in, out] * Key);
    [id(0x000000D0)]
    void OnMouseEnter(void);
    [id(0x000000D1)]
    void OnMouseLeave(void);
    [id(0x000000D2)]
    void OnPa(void);
  };




  我们可以用javascript来响应这些事件比如就拿我们最熟悉OnClick事件js中要这么处理:

<OBJECT ID='x' name='a' CLASSID='CLSID:52D17094-0687-4A2F-B2DB-30F3189AC659' align=center hspace=0 vspace=0 ></OBJECT>
<script type="text/javascript" event="OnClick" for="a">
 alert('你点击了ActiveXControl控件');
</script>


  运行后鼠标在ActiveX空白处点击会弹出个警告框:"你点击了ActiveXControl控件"

  13.其它问题

  前面提到了带返回值function不好弄其实这个不是什么大问题完全可以迂回用procedure和属性解决

  比如我们可以定义个带参数procedurejs时传入参数然后在procedure内部对参数进行处理后将其赋值为 ActiveX任何个类型匹配属性比如前面提到Caption属性然后js获取Caption属性相当于就是ActiveX处理后返回值了

  文章来源:http://www.cnblogs.com/yjmyzz/archive/2009/12/16/1625559.html 



  本文举例源代码或素材下载

标签:
0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: