在ActiveX控件中如何动态调用DLL函数

刚到公司不久,接到领导的下达的一个任务,就是把对POS机操作功能封装在ActiveX控件中,在IE中调用。这样就能实现在IE上直接对POS机进行操作。而我要封装的这个动态库,厂家只提供了一个单的动态库和一百多字的说明,也就是说明一下动态库中有机个函数和其对应的参数。也就是厂家就连动态库对应的头文件也没有提供。:-(这样也行?!

接到这个任务后,我第一想到的是用VCATL来实现它。你问我为什么要用ATL也不用别的,如CBDelphi之类的。我只能说我觉得写ActiveX还是用VC好;况且还要对硬件进行操作,这样一来当然是用VC了。别说我没提醒你,用CBDelphi之类的有可能会出现预想不到的惊奇......

现在让我带着进入正题吧!先用ATLCOMAppWizard生成一个名叫PosActiveX的工程,生成时系统会问你是生成DLL还是EXE。当然是DLL的了。生成好后加入一个接口叫IPosCtrl,当然了要在Web上用,所以生成的接口一定是要小所以选择LiteControl的。你可别问我怎么加入,如果这都不会,那我写的这文章是不适合你看的。所以等你学会加入接口后再看。接口加好后,我就要实现方法了。首先用接口一般都要对其进行初始化。所以加入一个叫Init(shortnCom)的接口方法,该方法完成加载DLLDLL中的功能函数,还有就是打开对POS机进行操作的COM口;还有一个是修改POS机的时间的方法叫ModifyPosDT(BSTRbstrDT);还有个是清空POS机中数据的方法--EmptyPos()。最后,当你不想用时就要关闭所打开的COM--Quit()。在生成接口IPosCtrl时同时会生成CPosCtrl类。我有个习惯,就是我一般是把实现方法都写在类中,而接口只时输出该类中你想输出的方法。所以在类中我就写了以下几个方法:

InitDll()----加载DLL库和其中的功能函数;
ExitDll()----
卸载DLL库,用完后不卸载是在占用内存。所以它是少不了的。
SetPosDateTime(char*pchDT)---
设置POS机的时间。
ClearPos()----
清空POS机中的记录。

在类中我就写了这几个方法。

在说一下我要输出的接口方法有:

Init(shortnCom)----初化接口,为调用做准备。
Quit()----
退出程序时,调用它退出接口调用。
ModifyPosDT(BSTRbstrDT)----
设置POS机时间。
EmptyPos()----
清空POS机数据。

完了就这么多。
现在来看看我的源程序吧!

//PosCtrl.cpp:ImplementationofCPosCtrl

#include"stdafx.h"
#include"PosActiveX.h"
#include"PosCtrl.h"
 
//--------------------------------------------------------
//Police.dll所用到的常量定义
//--------------------------------------------------------
#defineCom_UpRecord1
#defineCom_UpPoliceLen2
#defineCom_UpSimpleDataLen3
#defineCom_UpSimplePunishLen4
#defineCom_UpGeneralDataLen5
#defineCom_UpGeneralPunishLen6
 
#defineCom_EmptyPolice7
#defineCom_EmptySimpleData8
#defineCom_EmptySimplePunish9
#defineCom_EmptyGeneralData10
#defineCom_EmptyGeneralPunish11
 
#defineCom_DownRecord0x80
#defineCom_DownStreetCodeLen0x81
#defineCom_DownBlackListLen0x82
#defineCom_DownPeccancySimpleLen0x83
#defineCom_DownPeccancyGeneralLen0x84
#defineCom_DownDateTime0x85
#defineCom_Exit0x86
#defineCom_Init0x87
 
#defineErr_UpSimpleDataLen0
#defineErr_UpSimplePunishLen1
#defineErr_UpGeneralDataLen2
#defineErr_UpGeneralPunishLen3
#defineErr_UpPoliceLen4
#defineErr_UpRecord5
#defineErr_DownStreetCodeLen6
#defineErr_DownSimplePeccancyCodeLen7
#defineErr_DownGeneralPeccancyCodeLen8
#defineErr_DownBlackList9
#defineErr_DownDateTime10
#defineErr_EmptyData11
#defineErr_GetCode12;
 
#defineConst_Terminator0x20
 
#pragmadata_seg("mydata")
 
staticHINSTANCEDLLInst=NULL;//动态库句柄
 
#pragmadata_seg()//
 
HANDLEhCom;//COM串口句柄
 
//------------------------------------------------------
//POLICE.DLL动态库函数功能定义
//------------------------------------------------------

HANDLE(__stdcall*Init_comm)(LPSTRstr);//初始化通信口
BYTE(__stdcall*Exit)(HANDLEhCom);//关闭通信口
BYTE(__stdcall*Protocol)(HANDLEhCom,BYTEcmd,BYTElen,BYTE*_dt,BYTE*prlen,BYTE*prdt);//通信协议
BYTE(__stdcall*Pipe_control)(HANDLEhCom,BYTEmode);//多路控制typedef
BYTE(__stdcall*Dev_escape)(HANDLEhCom);//断开多路控制
 

//----------------------------------------------------------------------------//
//
功能:加载Police.dll动态库和其中的一些功能函数

//
输入/输出参数:无
//
版本:1.0
//
修改:

//----------------------------------------------------------------------------//

voidCPosCtrl::InitDll()
{
DLLInst=LoadLibrary("police.dll");
if(DLLInst!=NULL)
{
Init_comm=(HANDLE(__stdcall*)(LPSTR))GetProcAddress(DLLInst,"Init_comm");
Exit=(BYTE(__stdcall*)(HANDLE))(GetProcAddress(DLLInst,"Exit"));
Protocol=(BYTE(__stdcall*)(HANDLE,BYTE,BYTE,BYTE*_dt,BYTE*prlen,BYTE*prdt))(GetProcAddress(DLLInst,"Protocol"));
Pipe_control=(BYTE(__stdcall*)(HANDLE,BYTE))(GetProcAddress(DLLInst,"Pipe_control"));
Dev_escape=(BYTE(__stdcall*)(HANDLE))(GetProcAddress(DLLInst,"Dev_escape"));
}
else
{
::MessageBox(NULL,"加载动态库失败!","提示信息",MB_OK|MB_ICONINFORMATION);
exit(0);
}
}
 

//----------------------------------------------------------------------------//
//
功能:释放动态库

//
输入/输出参数:无
//
版本:1.0
//
修改:

//----------------------------------------------------------------------------//

voidCPosCtrl::ExitDll()
{
if(DLLInst!=NULL)
FreeLibrary(DLLInst);
}
 

//----------------------------------------------------------------------------//
//
功能:控件接口方法,对外提供关闭串口,释放动态库。

//
输入/输出参数:无//版本:1.0
//
修改:

//----------------------------------------------------------------------------//

STDMETHODIMPCPosCtrl::Quit()
{
//TODO:Addyourimplementationcodehere
 
(*Exit)(hCom);
ExitDll();
::MessageBox(NULL,"关闭COM口成功","提示信息",MB_OK|MB_ICONINFORMATION);
returnS_OK;
}
 
STDMETHODIMPCPosCtrl::get_ComNo(short*pVal)
{
//TODO:Addyourimplementationcodehere
*pVal=m_ComNo;
returnS_OK;
}
 
STDMETHODIMPCPosCtrl::put_ComNo(shortnewVal)
{
//TODO:Addyourimplementationcodehere
m_ComNo=newVal;
returnS_OK;
}

//----------------------------------------------------------------------------//
//
功能:提供初化动态库的对外接口,并实现打开口串口的功能。

//
输入/输出参数:11--要打开的串口号。
//
版本:1.0
//
修改:

//----------------------------------------------------------------------------//

STDMETHODIMPCPosCtrl::Init(shortnComNo)
{
//TODO:Addyourimplementationcodehere
 
InitDll();
charstr[20]="";
sprintf(str,"COM%d",nComNo);
hCom=(*Init_comm)((LPSTR)str);
sprintf(str,"%d",hCom);
chartemp[255]="";
strcpy(temp,"打开的端口为COM1,句柄为:");
strcat(temp,str);
::MessageBox(NULL,temp,"提示信息",MB_OK|MB_ICONINFORMATION);
//TCHARstr[255];
//sprintf(str,"%d",hCom);
//MessageBox(str,"Caption",MB_OK);
returnS_OK;
}

//----------------------------------------------------------------------------//
//
功能:实现ASCII码到BCD码的转换功能函数

//
输入/输出参数:11-想转换的ASCII码,22-返回的BCD码,13-ASCII码的长度,14-返回的BCD码长度
//
版本:1.0
//
修改:

//----------------------------------------------------------------------------//

voidCPosCtrl::ASCII_TO_BCD(char*cSource,char*cResult,intiSourceLen,intiResultLen)
{
intiBegin,i;
iBegin=0;
if(iSourceLen%2)
{
iBegin=1;
cResult[0]=cSource[0]-''0'';
}
for(i=iBegin;i<iResultLen;i++)
{
cResult[i]=(cSource[2*i-iBegin]-''0'')*16+cSource[2*i-iBegin+1]-''0'';
}
//depriveoffpreData
cResult[iResultLen]=''/0'';
}
 
//----------------------------------------------------------------------------//
//
功能:设置POS机时间函数。

//
输入/输出参数:11-想要设置的时间
//
版本:1.0
//
修改:

//----------------------------------------------------------------------------//
BOOLCPosCtrl::SetPosDateTime(char*pchDateTime)
{
 
intn=1;
unsignedcharcInput[257],cOutput[256];
BYTEbyOutput,retVal;
for(inti=0;i<8;i++)
{
 
(*Pipe_control)(hCom,n);//多路控制
//修改POS机时间
{
if(::MessageBox(NULL,"是否确定修改POS机时间?","提示信息",MB_YESNO)==IDNO)
{
returnFALSE;
}
 
ASCII_TO_BCD(pchDateTime,(char*)cInput,10,5);
retVal=(*Protocol)(hCom,Com_DownDateTime,5,cInput,&byOutput,cOutput);
if(retVal)
{
::MessageBox(NULL,"修改成功!","提示信息",MB_OK|MB_ICONINFORMATION);
}
else
{
::MessageBox(NULL,"修改不成功!","提示信息",MB_OK|MB_ICONINFORMATION);
}
}
n=n<<1;
}
(*Protocol)(hCom,0x86,5,cInput,&byOutput,cOutput);//下载成功
(*Dev_escape)(hCom);//关闭多路控制
(*Pipe_control)(hCom,0);//多路控制复位
returnTRUE;
}
//----------------------------------------------------------------------------//
//
功能:对外提供的修改时间的接口方法
//
输入/输出参数:11-想要设置的时间
//
版本:1.0
//
修改:
//----------------------------------------------------------------------------//
STDMETHODIMPCPosCtrl::ModifyPosDT(BSTRbstrDT)
{
//TODO:Addyourimplementationcodehere
if(SetPosDateTime((char*)bstrDT))
{
returnS_OK;
}
{
returnS_FALSE;
}
}
//----------------------------------------------------------------------------//
//
功能:实现清空POS机内数据的函数。
//
输入/输出参数:无
//
版本:1.0
//
修改:
//----------------------------------------------------------------------------//
voidCPosCtrl::ClearPos()
{
intn=1;
unsignedcharcInput[257],cOutput[256];
BYTEbyOutput,retVal;
for(inti=0;i<8;i++)
{
 
(*Pipe_control)(hCom,n);//多路控制
//清空POS机内的数据
 
if(::MessageBox(NULL,"是否要清空POS机内数据?","提示信息",MB_YESNO|MB_ICONQUESTION)==IDNO)
{
return;
}
retVal=Protocol(hCom,7,1,cInput,&byOutput,cOutput);//通信协议
if(!retVal)
{
retVal=Protocol(hCom,8,1,cInput,&byOutput,cOutput);
if(!retVal)
{
retVal=Protocol(hCom,9,1,cInput,&byOutput,cOutput);
if(!retVal)
{
retVal=Protocol(hCom,10,1,cInput,&byOutput,cOutput);
if(!retVal)
{
retVal=Protocol(hCom,11,1,cInput,&byOutput,cOutput);
}
}
}
::MessageBox(NULL,"POS机内数据已被清空!","提示信息",MB_OK|MB_ICONINFORMATION);
}
n=n<<1;
}
 
(*Protocol)(hCom,0x86,5,cInput,&byOutput,cOutput);//下载成功
(*Dev_escape)(hCom);//关闭多路控制
(*Pipe_control)(hCom,0);//多路控制复位
return;
}
//----------------------------------------------------------------------------//
//
功能:对外提供的清空POS机内数据的接口方法
//
输入/输出参数:无
//
版本:1.0
//
修改:
//----------------------------------------------------------------------------//
 
STDMETHODIMPCPosCtrl::EmptyPos()
{
//TODO:Addyourimplementationcodehere
ClearPos();
returnS_OK;
}
 
下面是调用PosActiveX.Dll的效果,调用时,要先对其进行注册,否则调用是不会成功的.注册是在
"Windows的开始菜单中调用"运行","运行"对话框中输入:regsvr32C:/PosActiveX/PosActiveX.dll
注册成功后就可对COM口进行操作了。还有一点是要特别注意的,必须把你要在ActiveX控件调用的Dll
文件拷贝到Windows/System目录(对于Win9x系统),对于NT,2000系统就要拷贝到WI

目录下才能正确的运行。

开发环境:Windows2000VC6

测试环境:Windows200
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值