• OCX 添加方法和事件 HTML调用ocx函数及回调 ocx又调用dll VS2017


    ocx添加方法

    类视图 最后面的XXXXXlib 右键 添加 添加方法。
    在这里插入图片描述
    其它默认
    在这里插入图片描述

    添加事件

    类视图 最后面的XXXXX 右键 添加 添加事件。
    在这里插入图片描述
    在这里插入图片描述
    这样编译就ocx可以了。
    在这里插入图片描述

    #include 
    #include 
    #include 
    
    CMFCActiveXControlSmartPosCtrl* pWnd;
    
    
    
    BSTR ConvertUnicodeCharToBSTR(const char* input) {
    	// 计算字符串的长度(不包括终止空字符)
    	int inputLength = strlen(input);
    
    	// 计算需要的宽字符数目
    	int wideCharCount = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0);
    
    	// 使用SysAllocStringLen分配一个BSTR
    	BSTR bstr = SysAllocStringLen(NULL, wideCharCount);
    
    	// 将char*的Unicode内容复制到BSTR中
    	MultiByteToWideChar(CP_UTF8, 0, input, -1, bstr, wideCharCount);
    
    	return bstr;
    }
    // CMFCActiveXControlSmartPosCtrl 消息处理程序
    
    BSTR CMFCActiveXControlSmartPosCtrl::OCX_GetDllVersion()
    {
    	//AFX_MANAGE_STATE(AfxGetStaticModuleState());
    	PrintLog("OCX_GetDllVersion");
    	char version[10] = { 0 };
    	GetDllVersion(version);
    	PrintLog("GetDllVersion = %s", version);
    	return ConvertUnicodeCharToBSTR(version);
    }
    BSTR CMFCActiveXControlSmartPosCtrl::CommPosProcess(BSTR b)
    {
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());
    	CString result = _T("Hello! OCX OK");
    	return result.AllocSysString();
    }
    void Callback(int code, const char* info) {
    	// 处理回调函数的逻辑
    	// 这里可以添加具体的回调处理代码
    	//do something	
    	PrintLog("Callback code: %d, info: %s", code, info);
    	pWnd->OCX_Callback(code, ConvertUnicodeCharToBSTR(info));//回调html
    }
    HRESULT CMFCActiveXControlSmartPosCtrl::OCX_Purchase(long amount, BSTR orderNo) {
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());
    	PrintLog("OCX_Purchase");
    	// 将BSTR转换为char*
    	_bstr_t bstr(orderNo);
    	const char* orderNoStr = static_cast<const char*>(bstr);
    	// 调用DLL接口
    	Purchase(amount, orderNoStr, Callback);//回调
    	PrintLog("OCX_Purchase OK");
    	return S_OK;
    }
    
    
    LONG CMFCActiveXControlSmartPosCtrl::OCX_DisConnectDevice()
    {
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
    	// TODO: 在此处添加分派处理程序代码
    	PrintLog("OCX_DisConnectDevice");
    	return DisConnectDevice();
    }
    
    
    LONG CMFCActiveXControlSmartPosCtrl::OCX_ListDevice(BSTR deviceNameList, VARIANT & deviceNameLen)
    {
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
    	// 将BSTR转换为char*
    	_bstr_t bstr(deviceNameList);
    	char* deviceNameListStr = static_cast<char*>(bstr);
    
    
    	// 调用DLL接口
    	ListDevice(deviceNameListStr, &deviceNameLen.intVal);
    	PrintLog("OCX_ListDevice OK");
    	return 0;
    }
    
    
    HRESULT CMFCActiveXControlSmartPosCtrl::OCX_ConnectDevice(BSTR deviceName)
    {
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
    	// TODO: 在此处添加分派处理程序代码
    		// 将BSTR转换为char*
    	_bstr_t bstr(deviceName);
    	char* deviceNameStr = static_cast<char*>(bstr);
    	// 调用DLL接口
    	ConnectDevice(deviceNameStr, Callback);
    	PrintLog("OCX_ConnectDevice OK");
    	return S_OK;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99

    HTML编写与调试

    DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
    <html xmlns="http://www.w3.org/1999/xhtml">  
    <head>  
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <title>Testtitle>
    <body>
      
    		<p>
    			<input type="button" value="清空" onclick="clearBtn()" /> 			
    			<input type="button" value="BankTrans" onclick="BankTrans()" /> 
    		p>
    		 <p><textarea id="S1"  rows="3"   cols="120"  >textarea>p>
    		 <p><textarea id="S2"  rows="3"   cols="120"  >textarea>p>
    		 <p><textarea id="S3"  rows="3"   cols="120"  >textarea>p>
    		 <object id="myOCX" classid="clsid:D90F26D2-1FBC-4BC6-9722-393D338E6A68"> object>
    <script LANGUAGE=javascript  FOR=myOCX EVENT=OCX_Callback(code,info)>
    	//alert(code+info); //回调响应
    	document.getElementById("S3").value="Code: " + code+" Info: " + info;
    script> 
    <script type="text/javascript" language="javascript"> 	
    	function BankTrans() {
    		//测试ocx
    		var ocx = document.getElementById("myOCX");
    		try {
    			var result = ocx.CommPosProcess("123");
    			document.getElementById("S1").value = result;
    		} catch (error) {
    		   document.getElementById("S1").value = error;
    		}
    		//测试ocx调用dll
    		try {
    			var result = ocx.OCX_GetDllVersion();
    			document.getElementById("S2").value = result;
    		} catch (error) {
    		   document.getElementById("S2").value = error;
    		}
    		//测试回调		
    		try {
    			var result = ocx.OCX_Purchase(1,"123456");
    			//document.getElementById("S3").value = result;
    		} catch (error) {
    		   document.getElementById("S3").value = error;
    		}		
    	}
    script>
    	
    body>  
    html>  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    在这里插入图片描述
    已经都成功了。方法(html调用ocx方法),事件(ocx触发回调html方法) 。
    在这里插入图片描述

    中间要注意的一些问题。

    ocx只支持IE。windows11要edge要切换到ie模式。

    如果dll找不到,调试的时候发现的,具体看ocx的日志,比如Loadlibrary时报126就是没找到dll,报193是dll是平台不一致 比如win32。win11 dll的路径最好写能绝对路径。

    注册dll时就报缺少dll模块时:这可能是dll用lib加载的,不是动态Loadlibrary加载的。把相关的dll放在当前目录并复制到system32下。最好用个windows demo先试下,ok后再用ocx来调用。

    报 Internet Explorer 已经为了帮助保护你的计算机而关闭此网页 也是没找到dll.

    在这里插入图片描述

    注册输出 选否。用手工注册即可。

    在这里插入图片描述

    ::注册32位ocx 请用管理员运行
    cd /d "%~dp0"
    
    
    regsvr32 MFCActiveXControl1.ocx
    
    ::pause
    
    
    
    ::::注册64位ocx 请用管理员运行  注册一个 64 位的 OCX 文件(ActiveX 控件)需要使用 regsvr32 的 64 位版本 regsvr32.exe 来进行注册。
    ::cd C:\Windows\System32
    ::
    ::SET ocxPath=%~dp0MFCActiveXControl1.ocx
    ::regsvr32.exe /u %ocxPath%
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    所有与c++类型相对应的ocx类型

    OCX(ActiveX 控件)通常在 Windows 平台上使用 COM(Component Object Model)来定义接口和类型。以下是一些常见的 C++ 类型与它们在 COM/OCX 中的等效类型:

    1. int / long: 在 COM 中,等效的类型是 long.

    2. float: 在 COM 中,等效的类型是 float.

    3. double: 在 COM 中,等效的类型是 double.

    4. char / unsigned char: 在 COM 中,等效的类型是 BSTR(宽字符字符串)。

    5. const char* / char*: 在 COM 中,等效的类型是 BSTR(宽字符字符串),或者可以使用 VARIANT 结构的 VT_BSTR 类型。

    6. bool: 在 COM 中,等效的类型是 VARIANT_BOOL,其中 VARIANT_TRUE 表示 trueVARIANT_FALSE 表示 false

    7. wchar_t / LPCWSTR: 在 COM 中,等效的类型是 BSTR(宽字符字符串)。

    8. const wchar_t* / wchar_t*: 在 COM 中,等效的类型是 BSTR(宽字符字符串)。

    9. char[]: 在 COM 中,等效的类型是 BSTR(宽字符字符串)。

    10. std::string: 在 COM 中,等效的类型是 BSTR(宽字符字符串),或者可以使用 VARIANT 结构的 VT_BSTR 类型。

    11. std::wstring: 在 COM 中,等效的类型是 BSTR(宽字符字符串)。

    12. 指针类型: 指针类型在 COM 中可能对应到 IDispatch*(用于接口)、IUnknown*(用于接口)等接口指针。

    13. 自定义结构体和类: 在 COM 中,通常需要为自定义数据结构创建 COM 接口,并使用接口中的属性和方法来传递数据。

    需要注意的是,COM 是一种基于二进制标准的技术,因此涉及数据类型的互操作性时,数据通常需要进行序列化和反序列化。上述类型的映射通常是针对参数传递和交互的一般规则,具体规则可能因 COM 接口定义和编程语言而异。

  • 相关阅读:
    FFmpeg AAC文件和H264文件合成MP4/FLV文件
    有效沟通是情绪管理
    数据结构与算法5-栈
    电脑重装系统后Win11底部任务栏大小调整方法
    力扣每日一题53:最大子数组和
    【DELM回归预测】基于matlab多元宇宙优化算法改进深度学习极限学习机数据回归预测【含Matlab源码 2230期】
    解决RabbitMQ报错Stats in management UI are disabled on this node
    [附源码]SSM计算机毕业设计学习资源共享与在线学习系统JAVA
    阿里云ACP认证考试易错题集
    kubeadm安装k8s高可用集群
  • 原文地址:https://blog.csdn.net/chenhao0568/article/details/133277917