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

1 创建ATL组件项目

打开vs2015,选择新建ATL项目

javascript怎么调用dll js如何调用dll_ATL组件


后面的页面都按照默认设置,最后一步点击完成。

项目创建完成后可以看到在解决方案资源管理器中有两个项目,一个项目名称为atl_test,一个项目为atl_testPS

javascript怎么调用dll js如何调用dll_js调用_02

2 添加ATL简单对象类

右键atl_test项目名称,选择添加–类

javascript怎么调用dll js如何调用dll_javascript怎么调用dll_03


在打开的添加类对话框中选择添加ATL简单对象

javascript怎么调用dll js如何调用dll_ATL组件_04


在简称里输入类名,这里输入Test

javascript怎么调用dll js如何调用dll_dll库_05


点击完成,至此ATL简单对象类创建好了。

3 添加函数方法

在类视图中,右键ITest

javascript怎么调用dll js如何调用dll_javascript怎么调用dll_06


右键ITest–添加–方法

javascript怎么调用dll js如何调用dll_javascript怎么调用dll_07


输入方法名func

在参数特性里勾选in,这样先添加入参

输入入参以及入参类型

javascript怎么调用dll js如何调用dll_js调用_08


然后添加返回类型BSTR*

注意返回类型必须是指针类型

输入返回类型名称,然后勾选retval

javascript怎么调用dll js如何调用dll_javascript怎么调用dll_09


点击添加,这样就添加了返回值了。

javascript怎么调用dll js如何调用dll_ATL组件_10


点击完成。

在Test.cpp中可以看到生成了该函数方法。

javascript怎么调用dll js如何调用dll_js调用_11


添加如下的代码:

#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库了。

javascript怎么调用dll js如何调用dll_dll库_12

4 注册ATL组件库

以管理员权限打开cmd

以cd命令进入到组件库的那个目录

javascript怎么调用dll js如何调用dll_js调用_13


然后输入注册命令:

regsvr32 atl_test.dll

可以看到注册成功

javascript怎么调用dll js如何调用dll_Test_14

5 在html中使用js进行调用

在项目的idl文件atl_test.idl中可以查看该组件的classid,就是importlib这行代码下面的那个id

javascript怎么调用dll js如何调用dll_javascript怎么调用dll_15


然后在网页中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浏览器打开这个网页,点击按钮

javascript怎么调用dll js如何调用dll_ATL组件_16


提示ActiveX控件的提示,点击是

javascript怎么调用dll js如何调用dll_js调用_17


可以看到成功调用了该函数。

6 标记控件为安全控件

当在步骤5中调用该函数时,可以看到有个警告提示框,那么如何避免该弹出框了?当然就是标记ATL组件为安全组件

ATL控件的接口类为CTest,我们打开接口类的头文件Test.h

javascript怎么调用dll js如何调用dll_javascript怎么调用dll_18


在继承类的后面添加一个逗号, 然后在后面添加一行

public   IObjectSafetyImpl<CTest, INTERFACESAFE_FOR_UNTRUSTED_CALLER>

javascript怎么调用dll js如何调用dll_dll库_19


那个类名改成自己工程的ATL简单类的对象类名

在com映射map里添加这么一行

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

javascript怎么调用dll js如何调用dll_ATL组件_20


如果在添加的过程中出现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)

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