加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

OCX开发手记

发布时间:2020-12-17 02:07:34 所属栏目:安全 来源:网络整理
导读:在这里发图片比较费事,本文的PDF版本可点此下载. ? ? ? ? ? OCX 开发手记 ? ? 系 统: 图形平台 子 模 块: 二次开发应用 时 间: 2009-11-23 ? ? ? ? ? ? ? ? 目 录 0. ??? 项目来源 ....................................................................

在这里发图片比较费事,本文的PDF版本可点此下载.

?

?

?

?

?

OCX开发手记

?

?


系 统:

图形平台

子 模 块:

二次开发应用

时 间:

2009-11-23

?

?

?

?

?

?

?

?


0.??? 项目来源................................................................................................................................ 1

1.??? OCX........................................................................................................................................ 2

1.1????? 准备工作.......................................................................................................................... 2

1.2????? 工程设置.......................................................................................................................... 3

1.3????? 发布相关.......................................................................................................................... 4

1.4????? 提高效率.......................................................................................................................... 9

2.??? 拷屏与显示........................................................................................................................... 12

2.1????? 拷屏................................................................................................................................ 12

2.2????? 检验................................................................................................................................ 12

2.3????? OCX大小调整................................................................................................................. 14

3.??? 网络传输............................................................................................................................... 16

3.1????? 基本元件......................................................................................................................... 16

3.2????? 通信................................................................................................................................ 16

4.??? 添加OCX属性..................................................................................................................... 19

5.??? 部署OCX.............................................................................................................................. 22

5.1????? 服务端与客户端网页....................................................................................................... 22

6.??? 测试...................................................................................................................................... 24


0.?? 项目来源

公元20091120日星期五,晚上,20:05

我刚上线不久,一位朋友给我发了个消息,说需要帮忙做个小东西。

具体的需求还是用在电力上,需要将员工计算机屏幕上的内容发送给客户计算机,确实是个小东西。

当然,需求需要更细化一些,大概讨论了10分钟,得到结论:

1)????? 编程实现一个OCX

2)????? OCX嵌入到员工计算机网页内时,将向指定客户计算机网页内的OCX实时发送桌面

3)????? OCX嵌入到客户计算机网页内时,将接收员工计算机网页内的OCX发送桌面数据并显示,以拉伸方式进行缩放

4)????? 客户机OCX的显示与否由合作方进行控制,因此,对于我这边的任务是,只要OCX活着,就一直工作就OK

呵呵,不需要控制,是不是有点太简单了。我信心满满,说,一天时间就足够了。明天开始干活。

据我的经验,这个项目根本不值得一做,为什么要做呢?

原因有二:

1)????? 一是这个项目(美其名曰是项目,KAO,这个曰字还是用拼音敲出来的)OCX开发,好久不做OCX了,练练手

2)????? 二是,毕竟还有点效益,前两天,媳妇说,我们家半年时间用了800吨水(我怀疑是不是水表坏了),又要交物业费、车位费,还正准备进行车检,一查,发现5个违章,罚1000元,扣14分,TNND,又得找个驾照去了,不然得学习了。哦,车检顺便还要交保险,这一算,几大千出去了,做个这个小玩意还有点盈余,嘿嘿

从技术角度来分析一下,需要解决以下几个技术难题(不好意思,实在没什么词好说了,总要好过说技术创新点吧)

1)????? 拷屏,也就是把屏幕内容抓下来,结果为BMPMemoryStream形式。这点,网上应该是一大堆的代码,好象用不着写

2)????? 网络传输。把MemoryStream中的数据通过网络传送到目标计算机上,这点,好象用Socket之类的技术就OK了,哦,好久没用INDY了,这次就用它吧

3)????? 显示,也就是把接收到的MemoryStream中的内容以图形形式显示出来,呃,好象不难哈

4)????? OCX新属性设置,在这个项目里,需要设计通信端口、目标IP、启动停止等一些属性,通过TLB就可以了哈

5)????? OCX部署,好象这一点比较难,要注意的东东多一些

说时迟,那时快,当时这些想法在我的头脑里也就电光火石般地过了一下,我就应承了这件事。

结果如何呢?懒得去想。只是想起以前一些朋友问我如何开发OCX,干脆把这个过程记录下来,不敢说是教材,但应该有所作用。

?

?

1.?? OCX

开始干活。首先得做出一个可以在网页中看得到的OCX

1.1????? 准备工作

打开BCB6,看着那熟悉的LOGO,轻轻抚摸它一下,乖,今天争点气哈。

?

以下的步骤,轻车熟路,驾轻就熟,嘿嘿,没什么好说的。

第一步,当然是新建一个ActiveForm

?

再下来,改ActiveX名字为CbwScreen,选中Make Control LicensedInclude Version Information选项,About Box没啥用,也就不选Include About Box选项了。

?

?

OK之后,全部保存,改一堆文件名以及工程名,改成下面这个效果就好了。

?

1.2????? 工程设置

下一步,设置工程的属性,为打个包准备。也就是在Packages标签页面下不选中Build with runtime packages,在Linker标签下不选中Use dynamic RTL选项,这样编译出来的EXEDLL才可以单独运行,而不需要这个那个DLL

?

为使编译结果与源代码文件不混杂在一起,设置一下各个输出目录。

?

现在,编译,运行,对前者,BCB当然无条件支持的了,但一运行,它不干了

?

需要设置一下才能直接运行。

1.3????? 发布相关

当然,这还需要做一点铺垫,因为OCX要嵌入到网页中,所以得先有个网页。

这个网页需要自己设计吗?先还是免了吧,BCB能为我们做这件事。

选择菜单项ProjectàWeb Deployment Options,按如下设置

?

其中,10.210.9.2是我本机的IP地址。注意URL地址设置为http://10.210.9.2/DoubleScreen/,其中有个虚拟目录DoubleScreen,稍后设置。

然后Web Deploy进行发布,到目标目录下一看,嘿,一堆文件

?

为了刚才的URLhttp://10.210.9.2/DoubleScreen/起作用,需要设置一下虚拟目录DoubleScreen,在目录DoubleScreen上右键点击,选择“共享和安全”,在Web共享页面中共添加共享。

?

当然,这点需要有IIS的支持,在此不对其多加说明。

现在进行IIS信息服务窗口中,可以看到DoubleScreen虚拟目录

?

右键选择其属性,设置其身份验证方法为匿名访问。

?

?

?

?

?

现在到资源管理器中,双击打开CbwScreen.htm,网页出来了哈

?

一切顺利,点击提示项,选择“允许阻止的内容”,IE没办法了,只好再提示一下

?

还有什么说的,确定Y,这下该出来了吧。

?

这是有点傻眼了。哪里做得不对呢。网上有一大堆的建议。花了大约15分钟,才想起来可以参考一下我原来做的OCX,一看,哦,需要屏蔽一下LICENSE,在CbwScreenImpl1.h中,屏蔽以下代码

/*

//$$---- activex control license support (stActiveXControlLicensing)

? // Licensing support

? //

? typedef TLicenseString<TCbwScreenImpl> TLicenseClassImpl;

? DECLARE_CLASSFACTORY2(TLicenseClassImpl)

?

? // Add logic to determine whether this Control is properly licensed on this machine

? // in the following method..

? //

? static const WCHAR* GetLicenseString()

? {

??? return L"{9DEB874C-56CF-4A4E-B247-CEB9152488DC}";

? }

?

? static const TCHAR* GetLicenseFileName()

? {

??? return _T("DoubleScreen.lic");

? }

?

? static BOOL IsLicenseValid()

? {

??? // By default we validate the license by verifying that the

??? // license string GUID is in the .LIC file generated by the Wizard.

??? //

??? // You may replace the logic of this routine to implement another

??? // method to verify that your control is properly licensed.

??? //

??? return TValidateLicense::IsGUIDInFile(GetLicenseString(),GetLicenseFileName());

? }

*/

再次发布,打开CbwScreen.htmOK

?

1.4????? 提高效率

哦,每次都要发布再打开文件看,多麻烦,设置一下吧,提高效率。

RunàParameters调出对话框中,设置如下

?

现在在窗口中加一个按钮,直接按F9,嘿嘿,又出来了。

?

这下,工作应该完成1/3了,OCX已经能显示了。哦,等等,还需要有个什么安全性的处理,呃,参考以前OCX的代码,哦,IObjectSafety接口,加入几句代码就OK了。也就是CbwScreenImpl1.h中要修改成以下模样,怎么修改呢,自己琢磨哈。

class ATL_NO_VTABLE TCbwScreenImpl:

? VCLCONTROL_IMPL(TCbwScreenImpl,CbwScreen,TCbwScreen,ICbwScreen,DIID_ICbwScreenEvents)

? ,public IObjectSafetyImpl<TCbwScreenImpl,INTERFACESAFE_FOR_UNTRUSTED_CALLER>

。。。。。。。。。

BEGIN_CATEGORY_MAP(TCbwScreenImpl)

?? IMPLEMENTED_CATEGORY(CATID_SafeForScripting)

?? IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)

END_CATEGORY_MAP()??

BEGIN_COM_MAP(TCbwScreenImpl)

? VCL_CONTROL_COM_INTERFACE_ENTRIES(ICbwScreen)??

? COM_INTERFACE_ENTRY(IObjectSafety)

END_COM_MAP()

时间嘀嗒嘀嗒不停转,一抬头,已经8:30了。过去了半个小时,唉,要是不上网转那10多分钟就好了。起来转会吧。

2.?? 拷屏与显示

2.1????? 拷屏

拷屏,也就是将屏幕内容拷贝到一个MemoryStream中,这个,呃,还是上网搜一下吧,确实一大堆代码。

整理一下,核心代码如下:

if(HDC hdcScreen = GetWindowDC(GetDesktopWindow()))

{

????? int w = Screen->Monitors[0]->Width;

????? int h = Screen->Monitors[0]->Height;

????? BitBlt(MoniterBitmap->Canvas->Handle,w,h,hdcScreen,SRCCOPY);

????? ReleaseDC(GetDesktopWindow(),hdcScreen);

????? BmpStream->Clear();

????? MoniterBitmap->SaveToStream(BmpStream);

}

呵呵,上面代码要运行,需要声明一些辅助变量,主要是MoniterBitmapBmpStream,这点工作应该能搞定吧。

2.2????? 检验

效果如何呢?需要检验一下,用什么来检验呢?图形化效果那是最好了,干脆,自己先显示一下,看看对不对,放置一个Image1alClient,拉伸效果,然后代码为

if(HDC hdcScreen = GetWindowDC(GetDesktopWindow()))

{

????? int w = Screen->Monitors[0]->Width;

????? int h = Screen->Monitors[0]->Height;

????? BitBlt(MoniterBitmap->Canvas->Handle,hdcScreen);

????? BmpStream->Clear();

????? MoniterBitmap->SaveToStream(BmpStream);

?????? ? Image1->Picture->Bitmap->LoadFromStream(BmpStream);??

}

运行后,居然没变化!!什么问题,调试看看BmpStreamSize,啊?居然每次的值不一样!!

想来想去,不得其解。

难道拷屏方法有误?翻来覆去,辗转反侧,没发现什么问题。

查看一下TMemoryStream的帮助,随手点开其属性,简单至极

Derived from TCustomMemoryStream

Memory

Derived from TStream

Position

Size

猛然想起,其Position是位置,LoadFromStream是从当前位置开始读的,是不是需要手动从头开始呢。先不管了,强制置其位置为0试试:

MoniterBitmap->SaveToStream(BmpStream);

BmpStream->Position = 0;

Image1->Picture->Bitmap->LoadFromStream(BmpStream);?????

F9运行一下,啊哈,期望结果出来了

?

?

?

?

?

?

?

?

2.3????? OCX大小调整

好象有点美中不足哈,窗口太小了,这点可在网页中修改,现在的网页源文本内容为:

<HTML>

<H1> C++Builder 6 ActiveX Test Page </H1><p>

You should see your C++Builder 6 forms or controls embedded in the form below.

<HR><center><P>

<OBJECT

?????? ? classid="clsid:0680890D-4D0A-45FB-BF44-3AF41DC04165"

?????? ? codebase="http://10.210.9.2/DoubleScreen/CbwScreen.inf"

?????? ? width=350

?????? ? height=250

?????? ? align=center

?????? ? hspace=0

?????? ? vspace=0

>?

</OBJECT>

</HTML>

widthheight改成100%OK了,即

<HTML>

<H1> C++Builder 6 ActiveX Test Page </H1><p>

You should see your C++Builder 6 forms or controls embedded in the form below.

<HR><center><P>

<OBJECT

?????? ? classid="clsid:0680890D-4D0A-45FB-BF44-3AF41DC04165"

?????? ? codebase="http://10.210.9.2/DoubleScreen/CbwScreen.inf"

?????? ? width=100%

?????? ? height=100%

?????? ? align=center

?????? ? hspace=0

?????? ? vspace=0

>?

</OBJECT>

</HTML>

再次运行,这下满意了

?

3.?? 网络传输

对于网络传输的需求是早就想好了的,直接用INDY

3.1????? 基本元件

在员工机端,放置一个TIdTCPClient

object IdTCPClient: TIdTCPClient

? Host = '10.210.9.1'

? Port = 6001

? Left = 424

? Top = 232

end

再用一个TIdAntiFreeze增加其健壮性

object IdAntiFreeze1: TIdAntiFreeze

? Left = 464

? Top = 232

end

而在客户端,也就是目标计算机上,放置一个TIdTCPServer

object IdTCPServer: TIdTCPServer

? Active = True

? Bindings = <10.210.9.2:6001>

? DefaultPort = 6001

? OnExecute = IdTCPServerExecute

? Left = 40

? Top = 152

end

为了在同一个OCX中支持发送与接收端,因此可加入两个基本FORM,分别为处理员工端与客户端。

先固定端口为6001吧,其修改留待后续开放属性时再处理

同样,目标计算机的IP地址即Host也先固定为10.210.9.1,开放属性后由网页的JS进行修改为宜。

3.2????? 通信

在实现通信之前,我想是否需要先实现一个文本方式通信呢?这时,头脑里出现正反双方两个声音:

“需要吗?”

“不需要吗?”

“需要吗?”

“不需要吗?”

“需要吗?”

“不需要吗?”

“呃,研究研究嘛,何必那么认真呢?需要吗?”

嗨,哪跟哪呀。就俺目前这水平,还需要这点小玩意来验证吗?不做也该知道做出来的结果是什么样子的了。直接上图片,不然不足以显示出水平,上!

自己YY得热血沸腾,顺手就写了个发送端:

????? AnsiString errorPrompt = "";

????? try

????? {? // 各种容错处理

???????? IdTCPClient->Connect();

???????? try

???????? {

??????????? int length = BmpStream->Size;

?

??????????? AnsiString protocol = bmpProtocol;???? // 为避免错误,再加一层握手协议

??????????? IdTCPClient->WriteLn(protocol);?????? // 以流的方式进行发送,将减小出错的概率

??????????? IdTCPClient->WriteInteger(length);

??????????? IdTCPClient->WriteStream(BmpStream,true,false);

??????????? IdTCPClient->Disconnect();

???????? }

???????? catch(Exception& ex)

???????? {

??????????? IdTCPClient->Disconnect();

??????????? if(!SameText(ex.Message,"Connection Closed Gracefully."))

???? ???????{

????? ?????????errorPrompt.printf("通信出错 ==> 向目的服务器 '%s' 发送数据失败!/n/n网络信息:/n",cPromptHost.c_str());

?????????????? errorPrompt += ex.Message;

?????????????? throw Exception(errorPrompt);

??????????? }

???????? }

????? }

????? catch(Exception& ex)

????? {

??????? ?errorPrompt.printf("网络连接出错,无法发送数据,请检查!/

??????????? /r/n/r/n%s/

??????????? /r/n/r/n可能出现的情况:/

??????????? /r/n/r/n/t1. %s的地址或端口设置出错;/

??????????? /r/n/r/n/t2. %s程序没有运行;/

??????????? /r/n/r/n/t3. 网络不通 /

??????????? /n/n网络信息:/n",

??????????? (cPromptHost.Length() ?

?????????????? (AnsiString("目的服务器名: ") + cPromptHost).c_str() :

?????????????? (AnsiString("目的主机地址: ") + IdTCPClient->Host).c_str()),

??????????? (cPromptHost.Length() ?

?????????????? cPromptHost.c_str() : "目的主机"),

??????????? (cPromptHost.Length() ?

?????????????? cPromptHost.c_str() : "服务器端")

??????????? );

???????? errorPrompt += ex.Message;

???????? throw Exception(errorPrompt);

????? }

手随心动,看着手指头在键盘上飞舞,编程和打字一样惬意,心里那个爽啊。一边敲一边想,幸亏咱经验多,还知道try…catch来捕捉异常哈。又想,这个小项目,收人家的费用是不是有点多了呢。猛地,一首歌调浮现了出来:您看这道菜,群英荟萃,收您老八十一点都不多。呵呵,摇头兼晃脑,正想着间,代码写完了,按个Ctrl+F9编译一下,看看有没有手误敲错的。糊了。

这不,打铁要趁热,俺手一抖,服务端代码就跃然于屏幕之上了。

void __fastcall TCbwScreen::IdTCPServerExecute(

????? TIdPeerThread *AThread)

{

?? AnsiString protocol = AThread->Connection->ReadLn(EOL);

?? bool bmpFlag = SameText(protocol,bmpProtocol);

?? if(!bmpFlag)?? return;

????? // 以流的方式读取

?? int number = AThread->Connection->ReadInteger();

?? AThread->Connection->ReadStream(MemoryStream,number,false);

?? if(MemoryStream->Size == 0)

????? return;

?

????? // 获取通信内容

?? try

?? {

????? EnterCriticalSection(&g_CriticalSection); // 串行处理

????? MemoryStream->Position = 0;

????? Image1->Picture->Bitmap->LoadFromStream(MemoryStream);???

?? }

?? __finally

?? {

????? LeaveCriticalSection(&g_CriticalSection); // 可以处理下一个请求了

?? }

我的思绪飞呀飞,歌曲调调已经是笑脸中的有情人千里共婵娟了。顺便把CriticalSection处理完毕。

运行,OK,啊啊,太不把人当腕了。

4.?? 添加OCX属性

剩下的事情是不是该扫尾了,发布一下OCX属性,供网页中的JS调用以方便设置,要不然,部署到不同的计算机上还要改一下源代码,可羞死人了。

?

BCB中,添加OCX属性是如此的简单,当然首先需要知道要添加什么属性,想干什么?这个很简单,一个属性Client,表示是否为客户机,一个属性为Host,表示客户机的IP地址,一个属性为Monitor,表示启动/停止发送桌面。

呃,你说,上面各属性的类型都是些什么呢,用脚趾头想,使劲想。

添加的结果如上图所示。

其实现代码没啥好说的,直接看吧。

STDMETHODIMP TCbwScreenImpl::set_Monitor(VARIANT_BOOL Value)

{

? try

? {

?? bool v = Value;

?? GlobalCbwScreen->Timer1->Enabled = v;

? }

? catch(Exception &e)

? {

??? return Error(e.Message.c_str(),IID_ICbwScreen);

? }

? return S_OK;

};

?

STDMETHODIMP TCbwScreenImpl::set_Host(BSTR Value)

{

? try

? {

???? GlobalCbwScreen->IdTCPClient->Host = Value;

???? GlobalCbwScreen->Label1->Caption = Format("机型:%s/r/n发送目标IP: %s,端口:%d/r/n本机监听端口:%d,激活态:%s",

????? ARRAYOFCONST(((ClientFlag ? "客户机" : "员工机"),

????? GlobalCbwScreen->IdTCPClient->Host.c_str(),

????? GlobalCbwScreen->IdTCPClient->Port,

????? GlobalCbwScreen->IdTCPServer->DefaultPort,

????? GlobalCbwScreen->IdTCPServer->Active ? "true" : "false")));

? }

? catch(Exception &e)

? {

??? return Error(e.Message.c_str(),IID_ICbwScreen);

? }

? return S_OK;

};

?

STDMETHODIMP TCbwScreenImpl::set_Client(VARIANT_BOOL Value)

{

? try

? {

????? ClientFlag = Value;

????? int sendPort = 6001;

????? int recievePort = 6010;

????? if(ClientFlag)

????? {? // 客户机

???????? int temp = sendPort;

???????? sendPort = recievePort;

???????? recievePort = temp;

????? }

????? GlobalCbwScreen->IdTCPClient->Port = sendPort;

????? GlobalCbwScreen->IdTCPServer->DefaultPort = recievePort;

? }

? catch(Exception &e)

? {

??? return Error(e.Message.c_str(),IID_ICbwScreen);

? }

? return S_OK;

};

5.?? 部署OCX

5.1????? 服务端与客户端网页

为了完成项目需求,还需要设计一个服务端网页(部署在员工机上)和一个客户端网页(部署在客户机上)。服务端负责向客户端发送桌面。

OCX嵌入网页嘛,具体可参照BCB替我们生成的标准网页。

下面是员工机的网页ServerScreen.htm

<HTML>

<OBJECT

?????? ? classid="clsid:0680890D-4D0A-45FB-BF44-3AF41DC04165"

?????? ? codebase="DoubleScreen/CbwScreen.inf"

?????? ? id="doublescreen"

?????? ? width=0

?????? ? height=0

?????? ? align=center

?????? ? hspace=0

?????? ? vspace=0

>?

</OBJECT>

<Body onload=Init()????? >

</Body>

<script language="javascript">

function Init()

{// 设置图形控件访问的WebService地址,其最重要的是要对图形控件设置其访问的WebService地址

?????? doublescreen.Client=0;????????????????????????????????????? // 1为客户机,0为员工机

?????? doublescreen.Host="10.210.9.2";??????????????? // 客户机IP地址

}

</script>

<form name="form1">

?????? <input type="button" onclick='doublescreen.Monitor=true' value="发送">

</form>

</HTML>

其中,OCX的宽度高度设置为0,表示该OCX不可见。嗯,笨就一个字,我只说一次。

直接在网页onload事件中调用Init()初始化函数,主要是设置OCX工作在员工机模式(Client=0),目标客户机IP地址为10.210.9.2(本机,呵呵,测试一下)。发送按钮将触发发送事件。

客户机网页ClientScreen.htm如下:

<HTML>

<OBJECT

?????? ? classid="clsid:0680890D-4D0A-45FB-BF44-3AF41DC04165"

?????? ? codebase=" DoubleScreen/CbwScreen.inf"

?????? ? id="doublescreen"

?????? ? width=100%

?????? ? height=100%

?????? ? align=center

?????? ? hspace=0

?????? ? vspace=0

>?

</OBJECT>

<Body onload=SetClient()????? >

</Body>

<script language="javascript">

function SetClient()

{???? // 设置图形控件访问的WebService地址,其最重要的是要对图形控件设置其访问的WebService地址

?????? doublescreen.Client=1;????????? // 1为客户机,0为员工机

}

</script>

</HTML>

6.?? 测试

万事俱备了,想直接拷贝给朋友,作一了断,转念一想,还是简单测试一下吧。

换台计算机,环境配置完毕,测试。

没想到啊没想到,真傻眼了,那个小小的红叉叉它硬是要出来。

嗨,这不是还没有配置新计算机的IE吗。立马设置一下。

首先,IE的菜单 工具àInternet选项,设置Internet的安全级别,简单点,直接设置为低安全级吧。啊?人倒霉了,喝凉水都塞牙,那个该死的Windows不让我设置更低的级别,气得我连图都懒得贴出来了。

内事不决问百度,外事不决找GOOGLE,这是微软的事,那就G吧。

找了一大圈,找到了解决方法:修改注册表,额的神啊。

不过改注册表这种行为,俺也不是一次两次的了,进入HKEY_CURRENT_USERSOFTWAREMICROSOFTWINDOWSCURRENTVERSIONINTERNET SETTINGSZONES3(迷糊了吗?没迷糊我再讲一遍哈),修改CurrentLevel值为10000,确定。

嘿嘿,可以设置为低安全级了。脸上都笑开了花。

刷新一下,笑容就僵在脸上了,可要了亲命了,还是不行。

重来

这次老子也不信安全级别了,直接进入自定义级别,呃,要是你不清楚怎么整出个自定义级别的话,说明你是新来的,还是直接从这段才开始看的。

?

瞪圆了双眼,愣是把Active控件和插件下的所有选项一个一个地、挨个地、逐个地设置为启用了。再次打开网页,OMG,外甥打灯笼了。

GOOGLE,你这次再不好好表现一下,以后你就给我爬一边去。

GOOGLE还是好啊,它也不生气,告诉了我另外一个方式:Internet选项中还有个高级标签呢,在安全下面的复选框中,有一项,它名叫,哦,专业一点,应该是标题是“允许运行或安装软件,即使签名无效”。我一看,哟,果真呢,我这项没有选,选上,赶紧的。

?

办法都想尽了,这下该好了吧。想咱没有功劳也有苦劳,没有苦劳也有疲劳。唉,又是一个杨白劳。

GOOGLE又说,可以设置一下本地Intranet的安全级别,呜呜呜呜,结果呢,地球人都知道了。

?

GOOGLE还说,应该加入受信任的站点,我也加了的呀。

没办法了,再G一下吧,GOOGLE也没啥新意了,东说西说,都是上面的这些解决方法,唉,中文的博客、文章之类的,抄来抄去的,再看个开头就知道结尾,不看也罢。

突然,眼前一亮,发现一个新方法,说是系统属性中有个硬件,通过“驱动程序签名”按钮进行签名选项设置,应选择为“忽略 安装软件,不用征求我的同意”。哦,我什么时候说过需要我的同意了,你赶紧出来吧。

?

我想,我当时的眼睛可能都亮得发出绿光了,但过了5秒钟,正常了。

我都有点想撞墙了,换换脑子吧。前两天听一个小朋友成天给我吹风说现在蜗居很热很真实,呃,要不看上一集?先上网看看评论,嗬,那是人山人海,锣鼓喧天,相当的热闹。有两个标题党,一个说是史上最淫荡台词的电视剧,附了一大堆的截图,另一个说是让80后有当二奶的冲动。啊?这哪跟哪呀?看一集吧。

结果看了三集,中间吃了中午饭。我看时间不早了,肠子都悔青了。今天咋给朋友交待呢。

一不做,二不休,再上网溜溜,一会儿就跑题了,看到了北大两名学生关机山事件的各种版本,笑死俺了。在此借用一下易中天版本哈。

上一讲我们说到了OCX控件在IE中无法显示的问题。为什么无法显示呢?史书上没有记载,但我们可以从一些野史上找到一些蛛丝马迹。根据我们的分析,这其中的原因可能有三个,一是IE安全级别设置得不对,导致OCX无法下载;二是OCX的包没打全;三是OCX行了一些苟且之事,编得有问题。对于第一个原因,基本可以排除,因为我们已经系统地试验过了。第二个原因倒是有可能,因为在开发的计算机上可以运行,换台机子就不行了。让我们参考一下《三国志》OCX传裴松注中的说法,“橘生南国为橘,北国为桔”,换台机子后它水土不服,这只是表象,究其根本原因在于自己的毛还没有长全,打包的时候少打了些东东。但仔细一想,不对呀,已经全部设置清楚了呀,该干的事都做了,偷鸡摸狗的事一件没做呀,因此,这第二个原因也可以排除。那现在只剩下第三个原因,也就是说,OCX行了一些苟且之事,编得有问题。

哦,易中天教授,您太伟大了,按照您的思路,我一下子就找到了问题的根源。我知道该怎么做了。

首先,我就只做一个空白的OCX,经过接口处理,发布,部署,拷贝到新的计算机上,一看,哟嗬,你猜怎么着,小红叉叉不见了,OCX控件出来了。呃,有戏。

然后,我就逐个模块往上添加,添加一个,发布一版,只见那文件版本,从1.0.1.0噌噌上升到了1.0.52.0,这中间,我就象个机器人,修改、编译、发布、插U盘、拷贝文件、拔U盘、拷贝文件、修改版本号、拔U盘,一系列工作,我把它流程化了,幸亏我的椅子带有滚轮,不然,我能跑个5公里

你又猜怎么着,嘿,我找到问题所在了,是IdTCPServer出错了,我反复试了下,把原来的IdTCPServer复制粘贴到新的OCX中就不行,小红叉叉如约守候在网页中,不要它就OK

呃,不要可就不行了,网络传输还要靠它呢,怎么办呢?

仔细看了看IdTCPServer

object IdTCPServer: TIdTCPServer

? Active = True

? Bindings = <10.210.9.2:6001>

? DefaultPort = 6001

? OnExecute = IdTCPServerExecute

? Left = 40

? Top = 152

end

哦,把它的Active改为false,并将Bindings清空试试。

天可怜见,一切正常了。

原来,在本机上,Bindings绑定了本机IP与端口,所以初始化时,置其Activetrue,它能正确处理。但换到另一台计算机上,它不在本局域网内,10.210.9.2这个IP地址它找不到,所以IdTCPServertrue时将会失败,可能抛出异常,导致OCX不能正常初始化,结果失败。将其Active属性改为false并将Bindings清空后,它的初始化过程不会出错,一切正常,OCXOK了。

我恍然大悟。

我想我快是什么教徒了:“主啊,原谅我的无知吧,我再也不妄自菲薄了。”

再一看时间,都下午5点了,赶紧的,把一切弄得看起来专业一点,把版本定为1.1.1.0,打了个包,发给了朋友。呃,不好意思,顺便再把账号也发了一遍。

朋友在下班前测试了一下,一切正常,说,明天就去给客户演示。我说,好,你去吧。

本来想总结一下的,结果一想,值得总结吗?至少在一段时间内,我需要谦虚了,谨慎了,低调了,这是今天的最大收获。你呢?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读