在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
#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
接到这个任务后,我第一想到的是用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
//功能:加载Police.dll动态库和其中的一些功能函数
//输入/输出参数:无
//版本:1.0
//修改:
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
//功能:释放动态库
//输入/输出参数:无
//版本:1.0
//修改:
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
//功能:控件接口方法,对外提供关闭串口,释放动态库。
//输入/输出参数:无//版本:1.0
//修改:
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
//功能:提供初化动态库的对外接口,并实现打开口串口的功能。
//输入/输出参数:11--要打开的串口号。
//版本:1.0
//修改:
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
//功能:实现ASCII码到BCD码的转换功能函数
//输入/输出参数:11-想转换的ASCII码,22-返回的BCD码,13-ASCII码的长度,14-返回的BCD码长度
//版本:1.0
//修改:
//----------------------------------------------------------------------------//
//功能:设置POS机时间函数。
//输入/输出参数:11-想要设置的时间
//版本:1.0
//修改:
//----------------------------------------------------------------------------//
//功能:对外提供的修改时间的接口方法
//输入/输出参数:11-想要设置的时间
//版本:1.0
//修改:
//----------------------------------------------------------------------------//
//功能:实现清空POS机内数据的函数。
//输入/输出参数:无
//版本:1.0
//修改:
//----------------------------------------------------------------------------//
//功能:对外提供的清空POS机内数据的接口方法
//输入/输出参数:无
//版本:1.0
//修改:
//----------------------------------------------------------------------------//
[/code]
$(document).ready(function(){dp.SyntaxHighlighter.HighlightAll('code');});
原文链接:
相关文章推荐
- 在ActiveX控件中如何动态调用DLL函数
- 在ActiveX控件中如何动态调用DLL函数
- 在ActiveX控件中如何动态调用DLL函数之"准"一体化方法
- 在ActiveX控件中如何动态调用DLL函数之"准"一体化方法
- 在ActiveX控件中如何动态调用在资源中的DLL函数之"准"一体化方法
- 如何动态调用WebService?
- 关于C#如何动态加载程序并调用其中某个类的方法
- 如何动态调用WebService
- java动态代理中的invoke方法是如何被自动调用的
- 如何在托管程序中动态加载dll并且调用其中的函数
- 动态添加的ActiveX控件如何响应事件
- C#如何动态调用DLL中类的方法以及属性
- 动态添加的ActiveX控件如何响应事件
- 在C#中调用一个dll函数,其中有个参数为 hdc,如何在C#中得到这个值并传给这个参数呢?
- java动态代理中的invoke方法是如何被自动调用的
- 如何用AU3调用自己用VC++写的dll函数
- 如何动态调用WebServices
- C# 中如何动态调用非托管DLL(一)转载
- 在C#里如何调用标准DLL函数
- 如何动态调用DLL中类的方法以及属性