您的位置:首页 > 其它

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

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

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

现在让我带着进入正题吧!先用ATLCOMAppWizard生成一个名叫PosActiveX的工程,生成时系统会问你是生成DLL还是EXE。当然是DLL的了。生成好后加入一个接口叫IPosCtrl,当然了要在Web上用,所以生成的接口一定是要小所以选择LiteControl的。你可别问我怎么加入,如果这都不会,那我写的这文章是不适合你看的。所以等你学会加入接口后再看。接口加好后,我就要实现方法了。首先用接口一般都要对其进行初始化。所以加入一个叫Init(shortnCom)的接口方法,该方法完成加载DLL和DLL中的功能函数,还有就是打开对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);//多路控制typedefBYTE(__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'';}//depriveoffpreDatacResult[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:Addyourimplementationcodehereif(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:AddyourimplementationcodehereClearPos();returnS_OK;}下面是调用PosActiveX.Dll的效果,调用时,要先对其进行注册,否则调用是不会成功的.注册是在"Windows的开始菜单中调用"运行",在"运行"对话框中输入:regsvr32C:/PosActiveX/PosActiveX.dll注册成功后就可对COM口进行操作了。还有一点是要特别注意的,必须把你要在ActiveX控件调用的Dll文件拷贝到Windows/System目录(对于Win9x系统),对于NT,2000系统就要拷贝到WI目录下才能正确的运行。开发环境:Windows2000和VC6 测试环境:Windows200
[/code]

$(document).ready(function(){dp.SyntaxHighlighter.HighlightAll('code');});

原文链接:
http://blog.csdn.net/augusdi/article/details/4642376
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: