王朝网络
分享
 
 
 

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

王朝vc·作者佚名  2006-01-17
宽屏版  字体: |||超大  

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

作者:马云冬(xacn)

下载本文配套源代码

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

这样也行?!

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

现在让我带着进入正题吧!先用ATL COM AppWizard生成一个名叫PosActiveX的工程,生成时系统会问你是生成DLL还是EXE。当然是DLL的了。生成好后加入一个接口叫IPosCtrl,当然了要在Web上用,所以生成的接口一定是要小所以选择Lite

Control的。你可别问我怎么加入,如果这都不会,那我写的这文章是不适合你看的。所以等你学会加入接口后再看。接口加好后,我就要实现方法了。首先用接口一般都要对其进行初始化。所以加入一个叫Init(short

nCom)的接口方法,该方法完成加载DLL和DLL中的功能函数,还有就是打开对POS机进行操作的COM口;还有一个是修改POS机的时间的方法叫ModifyPosDT(BSTR

bstrDT);还有个是清空POS机中数据的方法--EmptyPos()。最后,当你不想用时就要关闭所打开的COM口--Quit()。在生成接口IPosCtrl时同时会生成CPosCtrl类。我有个习惯,就是我一般是把实现方法都写在类中,而接口只时输出该类中你想输出的方法。所以在类中我就写了以下几个方法:

InitDll()----加载DLL库和其中的功能函数;

ExitDll()----卸载DLL库,用完后不卸载是在占用内存。所以它是少不了的。

SetPosDateTime(char * pchDT)---设置POS机的时间。

ClearPos()----清空POS机中的记录。

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

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

Init(short nCom)----初化接口,为调用做准备。

Quit()----退出程序时,调用它退出接口调用。

ModifyPosDT(BSTR bstrDT)----设置POS机时间。

EmptyPos()----清空POS机数据。

完了就这么多。

现在来看看我的源程序吧!

// PosCtrl.cpp : Implementation of CPosCtrl

#include "stdafx.h"

#include "PosActiveX.h"

#include "PosCtrl.h"

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

// Police.dll所用到的常量定义

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

#define Com_UpRecord 1

#define Com_UpPoliceLen 2

#define Com_UpSimpleDataLen 3

#define Com_UpSimplePunishLen 4

#define Com_UpGeneralDataLen 5

#define Com_UpGeneralPunishLen 6

#define Com_EmptyPolice 7

#define Com_EmptySimpleData 8

#define Com_EmptySimplePunish 9

#define Com_EmptyGeneralData 10

#define Com_EmptyGeneralPunish 11

#define Com_DownRecord 0x80

#define Com_DownStreetCodeLen 0x81

#define Com_DownBlackListLen 0x82

#define Com_DownPeccancySimpleLen 0x83

#define Com_DownPeccancyGeneralLen 0x84

#define Com_DownDateTime 0x85

#define Com_Exit 0x86

#define Com_Init 0x87

#define Err_UpSimpleDataLen 0

#define Err_UpSimplePunishLen 1

#define Err_UpGeneralDataLen 2

#define Err_UpGeneralPunishLen 3

#define Err_UpPoliceLen 4

#define Err_UpRecord 5

#define Err_DownStreetCodeLen 6

#define Err_DownSimplePeccancyCodeLen 7

#define Err_DownGeneralPeccancyCodeLen 8

#define Err_DownBlackList 9

#define Err_DownDateTime 10

#define Err_EmptyData 11

#define Err_GetCode 12;

#define Const_Terminator 0x20

#pragma data_seg("mydata")

static HINSTANCE DLLInst = NULL; //动态库句柄

#pragma data_seg() //

HANDLE hCom; //COM串口句柄

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

//POLICE.DLL动态库函数功能定义

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

HANDLE (__stdcall *Init_comm)(LPSTR str);//初始化通信口

BYTE (__stdcall *Exit)(HANDLE hCom);//关闭通信口

BYTE (__stdcall *Protocol)(HANDLE hCom,BYTE cmd,BYTE len,BYTE *_dt,BYTE *prlen,BYTE *prdt);//通信协议

BYTE (__stdcall *Pipe_control)(HANDLE hCom,BYTE mode);//多路控制typedef

BYTE (__stdcall *Dev_escape)(HANDLE hCom);//断开多路控制

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

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

// 输入/输出参数:无

// 版本:1.0

// 修改:

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

void CPosCtrl::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

// 修改:

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

void CPosCtrl::ExitDll()

{

if(DLLInst!=NULL)

FreeLibrary(DLLInst);

}

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

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

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

// 修改:

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

STDMETHODIMP CPosCtrl::Quit()

{

// TODO: Add your implementation code here

(*Exit)(hCom);

ExitDll();

::MessageBox(NULL,"关闭COM口成功","提示信息",MB_OK | MB_ICONINFORMATION);

return S_OK;

}

STDMETHODIMP CPosCtrl::get_ComNo(short *pVal)

{

// TODO: Add your implementation code here

*pVal = m_ComNo;

return S_OK;

}

STDMETHODIMP CPosCtrl::put_ComNo(short newVal)

{

// TODO: Add your implementation code here

m_ComNo = newVal;

return S_OK;

}

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

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

// 输入/输出参数:11--要打开的串口号。

// 版本:1.0

// 修改:

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

STDMETHODIMP CPosCtrl::Init(short nComNo)

{

// TODO: Add your implementation code here

InitDll();

char str[20] = "";

sprintf(str,"COM%d",nComNo);

hCom = (*Init_comm)((LPSTR)str);

sprintf(str,"%d",hCom);

char temp[255] = "";

strcpy(temp,"打开的端口为COM1,句柄为:");

strcat(temp,str);

::MessageBox(NULL,temp,"提示信息",MB_OK | MB_ICONINFORMATION);

//TCHAR str[255];

//sprintf(str,"%d",hCom);

//MessageBox(str,"Caption",MB_OK);

return S_OK;

}

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

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

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

// 版本:1.0

// 修改:

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

void CPosCtrl::ASCII_TO_BCD(char *cSource, char *cResult, int iSourceLen, int iResultLen)

{

int iBegin,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'';

}

//deprive off preData

cResult[iResultLen]=''\0'';

}

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

// 功能:设置POS机时间函数。

// 输入/输出参数:11-想要设置的时间

// 版本:1.0

// 修改:

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

BOOL CPosCtrl::SetPosDateTime(char * pchDateTime)

{

int n=1;

unsigned char cInput[257],cOutput[256];

BYTE byOutput,retVal;

for(int i=0;i<8;i++)

{

(*Pipe_control)(hCom,n); //多路控制

//修改POS机时间

{

if(::MessageBox(NULL,"是否确定修改POS机时间?","提示信息",MB_YESNO)==IDNO)

{

return FALSE;

}

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); //多路控制复位

return TRUE;

}

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

// 功能:对外提供的修改时间的接口方法

// 输入/输出参数:11-想要设置的时间

// 版本:1.0

// 修改:

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

STDMETHODIMP CPosCtrl::ModifyPosDT(BSTR bstrDT)

{

// TODO: Add your implementation code here

if(SetPosDateTime((char *)bstrDT))

{

return S_OK;

}

{

return S_FALSE;

}

}

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

// 功能:实现清空POS机内数据的函数。

// 输入/输出参数:无

// 版本:1.0

// 修改:

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

void CPosCtrl::ClearPos()

{

int n=1;

unsigned char cInput[257],cOutput[256];

BYTE byOutput,retVal;

for(int i=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

// 修改:

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

STDMETHODIMP CPosCtrl::EmptyPos()

{

// TODO: Add your implementation code here

ClearPos();

return S_OK;

}

下面是调用PosActiveX.Dll的效果,调用时,要先对其进行注册,否则调用是不会成功的.注册是在"Windows的开始菜单中调用"运行",在"运行"对话框中输入:regsvr32

C:\PosActiveX\PosActiveX.dll 注册成功后就可对COM口进行操作了。还有一点是要特别注意的,必须把你要在ActiveX控件调用的Dll文件拷贝到Windows\System目录(对于Win9x系统),对于NT,2000系统就要拷贝到WINNT\System32目录下才能正确的运行。

开发环境:Windows2000和VC6

测试环境:Windows200

代码使用许可:可用

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有