OCX adds methods and events, HTML calls ocx functions and callbacks, and ocx calls dll VS2017

ocx adding method

Right-click on XXXXXlib at the end of the class view and click Add to add a method.

Other default

Add event

Right-click the XXXXX at the end of the class view and click Add to add an event.


In this way, ocx can be compiled.

#include <iostream>
#include <string>
#include <comutil.h>

CMFCActiveXControlSmartPosCtrl* pWnd;



BSTR ConvertUnicodeCharToBSTR(const char* input) {<!-- -->
// Calculate the length of the string (not including the terminating null character)
int inputLength = strlen(input);

// Calculate the number of wide characters required
int wideCharCount = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0);

// Use SysAllocStringLen to allocate a BSTR
BSTR bstr = SysAllocStringLen(NULL, wideCharCount);

//Copy the Unicode content of char* to BSTR
MultiByteToWideChar(CP_UTF8, 0, input, -1, bstr, wideCharCount);

return bstr;
}
// CMFCActiveXControlSmartPosCtrl message handler

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) {<!-- -->
// Process the logic of the callback function
//You can add specific callback processing code here
//do something
PrintLog("Callback code: %d, info: %s", code, info);
pWnd->OCX_Callback(code, ConvertUnicodeCharToBSTR(info));//Callback html
}
HRESULT CMFCActiveXControlSmartPosCtrl::OCX_Purchase(long amount, BSTR orderNo) {<!-- -->
AFX_MANAGE_STATE(AfxGetStaticModuleState());
PrintLog("OCX_Purchase");
//Convert BSTR to char*
_bstr_t bstr(orderNo);
const char* orderNoStr = static_cast<const char*>(bstr);
// Call DLL interface
Purchase(amount, orderNoStr, Callback);//Callback
PrintLog("OCX_Purchase OK");
return S_OK;
}


LONG CMFCActiveXControlSmartPosCtrl::OCX_DisConnectDevice()
{<!-- -->
AFX_MANAGE_STATE(AfxGetStaticModuleState());

// TODO: add dispatch handler code here
PrintLog("OCX_DisConnectDevice");
return DisConnectDevice();
}


LONG CMFCActiveXControlSmartPosCtrl::OCX_ListDevice(BSTR deviceNameList, VARIANT & amp; deviceNameLen)
{<!-- -->
AFX_MANAGE_STATE(AfxGetStaticModuleState());

//Convert BSTR to char*
_bstr_t bstr(deviceNameList);
char* deviceNameListStr = static_cast<char*>(bstr);


// Call DLL interface
ListDevice(deviceNameListStr, & amp;deviceNameLen.intVal);
PrintLog("OCX_ListDevice OK");
return 0;
}


HRESULT CMFCActiveXControlSmartPosCtrl::OCX_ConnectDevice(BSTR deviceName)
{<!-- -->
AFX_MANAGE_STATE(AfxGetStaticModuleState());

// TODO: add dispatch handler code here
//Convert BSTR to char*
_bstr_t bstr(deviceName);
char* deviceNameStr = static_cast<char*>(bstr);
// Call DLL interface
ConnectDevice(deviceNameStr, Callback);
PrintLog("OCX_ConnectDevice OK");
return S_OK;
}

HTML writing and debugging

<!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" /> <!-- gb2312 -->
<title>Test</title>
<body>
<!--clsid: If the control is successfully registered to the local machine, this value can be found in the local registry. This is how js obtains the control object.
<script type="text/javascript">
var _app = navigator.appName;
if (_app == 'Netscape') {
document.write('<OBJECT name="ocxobject" ID="ocxobject" WIDTH="0" HEIGHT="0"',
'TYPE="application/x-itst-activex"',
'clsid="{D90F26D2-1FBC-4BC6-9722-393D338E6A68}"',
'> </OBJECT>');
\t\t\t
} else if (_app == 'Microsoft Internet Explorer') {
document.write('<OBJECT name="ocxobject" ID="ocxobject" WIDTH="0" HEIGHT="0"',
'CLASSID="CLSID:D90F26D2-1FBC-4BC6-9722-393D338E6A68"',
'> </OBJECT>');
} else {
document.write('<p>Sorry, unsupported browser.</p>');
}
</script>-->
<p>
<input type="button" value="Clear" onclick="clearBtn()" />
<input type="button" value="BankTrans" onclick="BankTrans()" />
\t\t</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); //Callback response
document.getElementById("S3").value="Code: " + code + " Info: " + info;
</script>
<script type="text/javascript" language="javascript">
function BankTrans() {<!-- -->
//Test ocx
var ocx = document.getElementById("myOCX");
try {<!-- -->
var result = ocx.CommPosProcess("123");
document.getElementById("S1").value = result;
} catch (error) {<!-- -->
document.getElementById("S1").value = error;
}
//Test ocx calling dll
try {<!-- -->
var result = ocx.OCX_GetDllVersion();
document.getElementById("S2").value = result;
} catch (error) {<!-- -->
document.getElementById("S2").value = error;
}
//test callback
try {<!-- -->
var result = ocx.OCX_Purchase(1,"123456");
//document.getElementById("S3").value = result;
} catch (error) {<!-- -->
document.getElementById("S3").value = error;
}
}
</script>
\t
</body>
</html>


All have been successful. Method (html calls ocx method), event (ocx triggers callback html method).

Some issues to pay attention to in the middle.

ocx only supports IE. If you want Windows 11 Edge, you need to switch to IE mode.

If the dll cannot be found, it was discovered during debugging. Please check the ocx log for details. For example, the Loadlibrary report of 126 means that the dll was not found, and the report of 193 means that the dll is inconsistent with the platform, such as win32. It is best to write the path of win11 dll as an absolute path.

When registering a dll, it is reported that the dll module is missing: This may be because the dll is loaded using lib, not dynamic Loadlibrary. Place the relevant dll in the current directory and copy it to system32. It is best to use a windows demo to try it first, and then use ocx to call it after it is ok.

Reported that Internet Explorer has closed this page to help protect your computer and the dll was not found.

Register Output Select No. Just register manually.

::Register 32-bit ocx. Please run it as administrator.
cd /d "%~dp0"


regsvr32 MFCActiveXControl1.ocx

::pause



::::To register 64-bit OCX, please run it as an administrator. To register a 64-bit OCX file (ActiveX control), you need to use the 64-bit version of regsvr32, regsvr32.exe, to register.
::cd C:\Windows\System32
::
::SET ocxPath=%~dp0MFCActiveXControl1.ocx
::regsvr32.exe /u %ocxPath%

All ocx types corresponding to c++ types

OCX (ActiveX Control) usually uses COM (Component Object Model) on the Windows platform to define interfaces and types. Here are some common C++ types and their equivalents in COM/OCX:

  1. int / long: In COM, the equivalent type is long.

  2. float: In COM, the equivalent type is float.

  3. double: In COM, the equivalent type is double.

  4. char / unsigned char: In COM, the equivalent type is BSTR (wide character string).

  5. const char* / char*: In COM, the equivalent type is BSTR (wide character string ), or you can use the VT_BSTR type of the VARIANT structure.

  6. bool: In COM, the equivalent type is VARIANT_BOOL, where VARIANT_TRUE means true code>, VARIANT_FALSE means false.

  7. wchar_t / LPCWSTR: In COM, the equivalent type is BSTR (wide character string).

  8. const wchar_t* / wchar_t*: In COM, the equivalent type is BSTR (wide character string).

  9. char[]: In COM, the equivalent type is BSTR (wide character string).

  10. std::string: In COM, the equivalent type is BSTR (wide character string), or VARIANT can be used The VT_BSTR type of structure.

  11. std::wstring: In COM, the equivalent type is BSTR (wide character string).

  12. Pointer type: The pointer type in COM may correspond to interface pointers such as IDispatch* (for interfaces), IUnknown* (for interfaces) etc. .

  13. Custom structures and classes: In COM, you usually need to create a COM interface for a custom data structure and use the properties and methods in the interface to pass data.

It is important to note that COM is a technology based on binary standards, so when it comes to interoperability of data types, data often needs to be serialized and deserialized. The types of mapping described above are generally general rules for parameter passing and interaction, and the specific rules may vary depending on the COM interface definition and programming language.