vs2015制作供js调用的ATL组件dll库详解

ATL组件和mfc ActiveX组件都可以供网页去调用,在我其它的博客中详细讲述了ocx组件的开发方式以及在网页中如何调用,在这篇博客中将详细讲解ATL组件的开发以及在网页中的调用。

1 创建ATL组件项目

打开vs2015,选择新建ATL项目
在这里插入图片描述
后面的页面都按照默认设置,最后一步点击完成。
项目创建完成后可以看到在解决方案资源管理器中有两个项目,一个项目名称为atl_test,一个项目为atl_testPS
在这里插入图片描述

2 添加ATL简单对象类

右键atl_test项目名称,选择添加–类
在这里插入图片描述
在打开的添加类对话框中选择添加ATL简单对象
在这里插入图片描述
在简称里输入类名,这里输入Test
在这里插入图片描述
点击完成,至此ATL简单对象类创建好了。

3 添加函数方法

在类视图中,右键ITest
在这里插入图片描述
右键ITest–添加–方法
在这里插入图片描述
输入方法名func
在参数特性里勾选in,这样先添加入参
输入入参以及入参类型
在这里插入图片描述
然后添加返回类型BSTR*
注意返回类型必须是指针类型
输入返回类型名称,然后勾选retval
在这里插入图片描述
点击添加,这样就添加了返回值了。
在这里插入图片描述
点击完成。
在Test.cpp中可以看到生成了该函数方法。
在这里插入图片描述
添加如下的代码:

#include "stdafx.h"
#include"Test.h"
#include<iostream>
#include<Windows.h>
#include<comutil.h>
using namespace std;
/* 项目属性--C/C++ -- 语言--将Wchar_t设置为内置类型选择是 然后添加comsuppw.lib这个lib库 如果选择否,就添加comsupp.lib这个lib库 */
#pragma comment(lib,"comsuppw.lib")
// CTest



STDMETHODIMP CTest::func(BSTR name, BSTR* ret)
{
   
	// TODO: 在此添加实现代码
	//name为入参
	string s1 = _com_util::ConvertBSTRToString(name);
	s1 = "from C++" + s1;
	//ret为返回值
	BSTR bstr_ret = _com_util::ConvertStringToBSTR(s1.c_str());
	*ret =bstr_ret;
	SysFreeString(bstr_ret);//释放BSTR变量内存
	return S_OK;
}

然后右键atl_test这个项目,选择生成
这样就成功生成了ATL组件的dll库了。
在这里插入图片描述

4 注册ATL组件库

以管理员权限打开cmd
以cd命令进入到组件库的那个目录
在这里插入图片描述
然后输入注册命令:

regsvr32 atl_test.dll

可以看到注册成功
在这里插入图片描述

5 在html中使用js进行调用

在项目的idl文件atl_test.idl中可以查看该组件的classid,就是importlib这行代码下面的那个id
在这里插入图片描述
然后在网页中object元素中引入这个id就可以调用这个控件
网页中调用代码如下:

<html>
<head>
    <title>test</title>
    <meta charset="utf-8" />
</head>
<script type="text/javascript"> function test1() {
     var ret=atl.func("hello"); alert(ret); } </script>

<body>
<object id=atl border=0 classid=CLSID:0F9024DF-450A-4B8B-B5B8-2B49ABA2E49D width="100" height="100";>
</object>
<div align="center">
  <input class="submit_01" type="button" value="ATL控件测试" onclick="test1()" />
</div>
</body>
</html>

使用IE浏览器打开这个网页,点击按钮
在这里插入图片描述
提示ActiveX控件的提示,点击是
在这里插入图片描述
可以看到成功调用了该函数。

6 标记控件为安全控件

当在步骤5中调用该函数时,可以看到有个警告提示框,那么如何避免该弹出框了?当然就是标记ATL组件为安全组件
ATL控件的接口类为CTest,我们打开接口类的头文件Test.h
在这里插入图片描述
在继承类的后面添加一个逗号, 然后在后面添加一行

public   IObjectSafetyImpl<CTest, INTERFACESAFE_FOR_UNTRUSTED_CALLER>

在这里插入图片描述
那个类名改成自己工程的ATL简单类的对象类名
在com映射map里添加这么一行

COM_INTERFACE_ENTRY(IObjectSafety)//添加一个com映射

在这里插入图片描述
如果在添加的过程中出现IObjectSafetyImpl未定义 ,那么就包含添加头文件Atlctl.h
整个头文件改完后的代码如下:

// Test.h : CTest 的声明

#pragma once
#include "resource.h" // 主符号



#include "atl_test_i.h"



#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。"
#endif

using namespace ATL;


// CTest

class ATL_NO_VTABLE CTest :
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CTest, &CLSID_Test>,
	public IDispatchImpl<ITest, &IID_ITest, &LIBID_atl_testLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
	public   IObjectSafetyImpl<CTest, INTERFACESAFE_FOR_UNTRUSTED_CALLER>
{
   
public:
	CTest()
	{
   
	}

DECLARE_REGISTRY_RESOURCEID(IDR_TEST)


BEGIN_COM_MAP(CTest)
	COM_INTERFACE_ENTRY(ITest)
	COM_INTERFACE_ENTRY(IDispatch)
	COM_INTERFACE_ENTRY(IObjectSafety)//添加一个com映射
END_COM_MAP()



	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
   
		return S_OK;
	}

	void FinalRelease()
	{
   
	}

public:



	STDMETHOD(func)(BSTR name, BSTR* ret);
};

OBJECT_ENTRY_AUTO(__uuidof(Test), CTest)

然后重新生成该工程
重新再次注册该组件,这样在网页中调用就没有出现安全提示了。

张贴在2