ATL——com学习笔记
1 、如何替换默认的类厂? 2 、如何让 COM 组件支持 Web 事件? 3 、如何动态创建要求 License 的 ActiveX 控件? 4 、如何在 Web 页面上生成基于 XML 的树形菜单? 5 、如何在 Web 页面上创建动态表格? 6 、如何为 Win32 服务程序提供事件源消息文件? 7 、如何创建单实例(静态) COM 组件? 8 、如何在 Delphi 6 及以上版本中使用可变常量(类型常量)? 9 、几个有用的 ANSI C 和 VC++ 预定义宏 10 、如何在自己的程序中使用脚本语言? 11 、如何在基于 CHtmlView 的程序中使用 HTML 事件映射? 12 、如何得到 Web 页面中的 COM 组件的原始接口? 13 、如何生成全球唯一标识( UID )? 14 、如何重写 MFC 的缺省控件容器( IOleContainer )? 15 、如何重写 WebBroswer 控件的缺省安全处理功能? 16 、如何重写 WebBroswer 控件的缺省下载管理器? 17 、如何定制 IE 或 WebBroswer 控件的缺省打印和打印预览框? 18 、如何扩展 IE 或 WebBroswer 控件提供的文档对象模型( DOM )? 19 、如何给 WebBroswer 控件的扩展文档对象(文档 .external )提供事件能力 ? 20 、如何打开流中的 HTML 文档? 21 、如何使 Web 页面中的对象可以拖动? 22 、如何把 Web 页面中用到的图像等外部文件嵌入 DLL 或 Exe ? 23 、如何使用 #import 指令从文件定位特定类型库资源 ID ? 24 、如何让你的 MFC 类实现 IDispatch 接口? 25 、如何自行管理 IE 缓存目录里的内容? 26 、 Windows Mobile 里如何使用 WebBrowser 控件? 27 、为什么在 Windows Mobile 里无法使用宿主在 exe 里的 COM 组件? 28 、如何扩展 IE 的协议,使其支持自定义的协议? ### 1、如何替换默认的类厂? 在COM编程中,类工厂负责创建对象实例。在ATL中,默认情况下,每个类都会有一个自动创建的类工厂。然而,在某些情况下,我们可能希望替换这个默认的类厂,以实现更加灵活或者自定义的功能。 #### 实现步骤 1. **定义自己的类工厂**:首先需要继承自`CComClassFactory`并实现必要的接口方法,例如`CreateInstance`、`LockServer`等。 ```cpp template<class T> class CDictionaryClassFactory : public CComClassFactory { // 成员变量与方法... }; ``` 2. **重写`CreateInstance`方法**:此方法负责创建类的对象实例。你可以在这里添加额外的逻辑来控制对象的创建过程。 ```cpp HRESULT STDMETHODCALLTYPE CreateInstance( IUnknown *pUnkOuter, REFIID riid, void **ppvObject) { // 创建自定义对象实例 CComObject<T> *p = new CComObject<T>; return p->QueryInterface(riid, ppvObject); } ``` 3. **重写`LockServer`方法**:该方法用于控制服务器的锁定状态,通常可以保持默认实现。 ```cpp HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock) { return _AtlModule.Lock(); } ``` 4. **实现`QueryInterface`方法**:此方法返回指向请求的接口指针。你需要确保返回正确的接口指针。 ```cpp HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) { // 实现细节... } ``` 5. **实现`AddRef`和`Release`方法**:这两个方法用于管理类工厂的引用计数。 ```cpp ULONG STDMETHODCALLTYPE AddRef(void) { return InterlockedIncrement(&m_lRef); } ULONG STDMETHODCALLTYPE Release(void) { if (InterlockedDecrement(&m_lRef) == 0) { delete this; return 0; } return m_lRef; } ``` 6. **注册自定义类工厂**:最后一步是在ATL项目中注册自定义类工厂。这可以通过在项目的`.cpp`文件中添加相应代码来完成。 ### 2、如何让COM组件支持Web事件? COM组件可以支持Web事件,从而实现与Web页面之间的交互。支持Web事件通常涉及到实现特定的接口,并将这些接口暴露给客户端。 #### 实现步骤 1. **定义事件接口**:使用IDL文件定义事件接口,如`IEvents`。 ```idl [object, uuid(....), pointer_default(unique)] interface IEvents : IDispatch { [id(1)] HRESULT OnEvent([in] BSTR eventName); }; ``` 2. **实现事件接口**:在COM组件内部实现`IEvents`接口。 ```cpp STDMETHODIMP CMyComponent::OnEvent(BSTR eventName) { // 处理事件 } ``` 3. **暴露事件接口**:通过`DISPID`和`VARIANT`等机制,将事件接口暴露给客户端。 ```cpp STDMETHODIMP CMyComponent::GetIDsOfNames( /* [in] */ REFIID riid, /* [size_is][in] */ LPOLESTR *rgszNames, /* [range][in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ DISPID *rgDispId) { // 暴露事件接口 } ``` 4. **客户端订阅事件**:客户端通过调用`Advise`方法订阅事件。 ```cpp STDMETHODIMP CMyComponent::QueryInterface( /* [in] */ REFIID riid, /* [iid_is][out] */ void **ppvObject) { if (riid == IID_IEvents) { *ppvObject = static_cast<IEvents*>(this); AddRef(); return S_OK; } // 其他接口... } ``` 5. **触发事件**:当需要触发事件时,调用`OnEvent`方法。 ```cpp void TriggerEvent() { BSTR eventName = SysAllocString(L"CustomEvent"); OnEvent(eventName); SysFreeString(eventName); } ``` ### 3、如何动态创建要求License的ActiveX控件? 有些ActiveX控件需要许可证才能正常工作。在创建这类控件时,需要正确处理许可证验证。 #### 实现步骤 1. **获取许可证信息**:通常需要先获取许可证信息,这可以通过读取注册表或其他存储位置来实现。 ```cpp BSTR GetLicenseKey() { // 读取许可证信息 } ``` 2. **设置许可证信息**:在创建控件之前,需要将许可证信息设置到控件上。 ```cpp void SetLicense(IUnknown *pUnk, BSTR licenseKey) { // 设置许可证信息 } ``` 3. **创建控件**:在设置了许可证信息之后,可以安全地创建控件实例。 ```cpp HRESULT CreateAndInitControl( IUnknown **ppUnkOut, REFIID riid, BSTR licenseKey) { // 创建控件 CComObject<YourControl>* p = new CComObject<YourControl>; HRESULT hr = p->QueryInterface(riid, ppUnkOut); if (SUCCEEDED(hr)) { SetLicense(*ppUnkOut, licenseKey); } return hr; } ``` ### 4、如何在Web页面上生成基于XML的树形菜单? 生成基于XML的树形菜单可以让Web页面具有更好的组织结构和导航性。 #### 实现步骤 1. **定义XML结构**:首先定义一个描述树形菜单结构的XML文件。 ```xml <?xml version="1.0"?> <Menu> <Item Text="Home" /> <Item Text="About"> <Item Text="Company" /> <Item Text="Contact" /> </Item> </Menu> ``` 2. **解析XML数据**:使用DOM或XML解析库解析XML文件。 ```cpp IXMLDOMDocument *pDoc = NULL; HRESULT hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_ALL, IID_IXMLDOMDocument, (void**)&pDoc); if (SUCCEEDED(hr)) { hr = pDoc->load(L"menu.xml"); } ``` 3. **构建树形菜单**:遍历XML节点,根据节点内容构建HTML菜单。 ```cpp void BuildMenu(IXMLDOMNode *pNode, std::wstring &html) { // 遍历节点,构建HTML } ``` 4. **生成HTML**:最终生成包含树形菜单的HTML代码。 ```cpp std::wstring html; BuildMenu(pDoc->documentElement, html); ``` 通过上述步骤,可以实现一个功能完备的基于XML的树形菜单,提高Web页面的用户友好性和导航效率。
剩余81页未读,继续阅读
- 东东06152012-11-28不错的东西,浏览了下。
- 粉丝: 5
- 资源: 6
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助