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:
-
int
/long
: In COM, the equivalent type islong
. -
float
: In COM, the equivalent type isfloat
. -
double
: In COM, the equivalent type isdouble
. -
char
/unsigned char
: In COM, the equivalent type isBSTR
(wide character string). -
const char*
/char*
: In COM, the equivalent type isBSTR
(wide character string ), or you can use theVT_BSTR
type of theVARIANT
structure. -
bool
: In COM, the equivalent type isVARIANT_BOOL
, whereVARIANT_TRUE
meanstrue
code>,VARIANT_FALSE
meansfalse
. -
wchar_t
/LPCWSTR
: In COM, the equivalent type isBSTR
(wide character string). -
const wchar_t* / wchar_t*
: In COM, the equivalent type isBSTR
(wide character string). -
char[]
: In COM, the equivalent type isBSTR
(wide character string). -
std::string
: In COM, the equivalent type isBSTR
(wide character string), orVARIANT can be used The
structure.VT_BSTR
type of -
std::wstring
: In COM, the equivalent type isBSTR
(wide character string). -
Pointer type: The pointer type in COM may correspond to interface pointers such as
IDispatch*
(for interfaces),IUnknown*
(for interfaces) etc. . -
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.