#pragma once #include "CommWrapperBase.h" #include "Utils.h" #include #include #include #include #include #include #include #include // ActiveX控件的CLSID和接口IID定义 static const CLSID CLSID_CommModifyKit = {0x97531C46, 0x4E70, 0x414F, {0x9A, 0x8F, 0x75, 0x8D, 0x38, 0xD5, 0x74, 0xC4}}; static const IID IID_ICommModifyKit = {0xAE3785CB, 0x0862, 0x4FD0, {0xB6, 0x24, 0x1E, 0x10, 0x38, 0x2D, 0x21, 0x7A}}; static const IID IID_ICommModifyKitEvents = {0x18A98A73, 0xE96C, 0x4268, {0x88, 0x1E, 0x1E, 0x82, 0xDE, 0x50, 0xB2, 0x10}}; static const IID IID_TypeLib_CommModifyKit = {0x41159543, 0xEA6B, 0x4C44, {0x84, 0xF2, 0xD5, 0xF9, 0xFC, 0xEE, 0x35, 0x41}}; // 使用基类定义的事件类型、数据结构和回调函数类型 // enum class ActiveXEventType -> CommEventType // struct ActiveXEventData -> CommEventData // using ActiveXEventCallback -> CommEventCallback // COM事件接收器类 class ActiveXEventSink : public IDispatch { private: LONG ref_count_; CommEventCallback callback_; public: ActiveXEventSink(CommEventCallback callback); virtual ~ActiveXEventSink(); // IUnknown methods STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject); STDMETHOD_(ULONG, AddRef)(); STDMETHOD_(ULONG, Release)(); // IDispatch methods STDMETHOD(GetTypeInfoCount)(UINT *pctinfo); STDMETHOD(GetTypeInfo)(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo); STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId); STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr); }; class ActiveXWrapper : public CommWrapperBase { private: IDispatch *activex_control_; IConnectionPoint *connection_point_; DWORD connection_cookie_; ActiveXEventSink *event_sink_; bool event_connected_; // COM接口方法ID DISPID init_monitor_id_; DISPID monitor_port_id_; DISPID stop_port_id_; DISPID read_data_id_; DISPID write_data_id_; DISPID free_monitor_id_; DISPID get_last_error_id_; // 初始化方法ID bool InitializeMethodIds(); // 连接事件 bool ConnectEvents(); // 断开事件 void DisconnectEvents(); // 调用COM方法的辅助函数 HRESULT InvokeMethod(DISPID dispid, VARIANT *params, int param_count, VARIANT *result = nullptr); // 创建SAFEARRAY的辅助函数 SAFEARRAY* CreateSafeArrayFromBytes(const std::vector& bytes); public: ActiveXWrapper(); ~ActiveXWrapper(); // 初始化ActiveX控件 bool Initialize(); // 释放资源 void Cleanup(); // 初始化监控 bool InitMonitor(const std::string &key = "C09976511B62F0ADB759D87E6906D865"); // 监控端口 bool MonitorPort(int port); // 停止监控端口 bool StopPort(int port); // 读数据 bool ReadData(int port, const std::string &hex_data); // 写数据 bool WriteData(int port, const std::string &hex_data); // 释放监控 bool FreeMonitor(); // 获取最后错误 int GetLastError(); // 设置事件回调 void SetEventCallback(CommEventCallback callback) override; // 获取错误信息 std::string GetErrorMessage(int error_code) override; // 检查端口是否正在监控 bool IsPortMonitored(int port) override; // 友元类,允许事件接收器访问私有方法 friend class ActiveXEventSink; };