前一阵子写一个控件,感觉接口有些地方使用返回值控制不大方便使用,所以打算给控件增加上几个事件,结果在网上搜了很久,也看不到合适的方法,网上说的一些东西,在我的VC环境中看的时候,根本就没有办法那么操作(包括VC6和VC2010)。于是找了一个示例程序,反反复复试验了好多次,终于自己的控件能够通过事件回调了,现在把我的试验方法记录下来。(网上说的更多是在建立控件工程时增加事件,如果对于一个建立工程时没有时间支持的控件,根本没有提到的)。
我的试验中提到的内容,不知道是否都是必要的,我也没有在这方面再去尝试。
(1)修改控件类的继承列表,如果需要有事件支持,需要继承以下的类:
IDispatchImpl IProvideClassInfo2Impl IConnectionPointContainerImpl |
继承这些类,有可能还需要在 BEGIN_COM_MAP 和END_COM_MAP加入相应的宏。
加入连接点支持,需要使用 BEGIN_CONNECTION_POINT_MAP、CONNECTION_POINT_ENTRY和END_CONNECTION_POINT_MAP加入连接点的宏
(2)IDL中声明事件支持,在Library一节中,CoClass上面,如下方式说明:
importlib("stdole32.tlb"); { properties: methods: [id(1), helpstring("method OnOK")] HRESULT OnOK(); [id(2), helpstring("method OnError")] HRESULT OnError(LONG err,BSTR msg); }; |
(3)实现代理类,在其中实现触发事件的代码,例如:
template <class T> class CProxy_IMyCtrlEvents : public IConnectionPointImpl<T, &DIID__IMyCtrlEvents, CComDynamicUnkArray> { //Warning this class may be recreated by the wizard. public: HRESULT __stdcall Fire_OnOK() { CComVariant varResult; T* pT = static_cast<T*>(this); int nConnectionIndex; int nConnections = m_vec.GetSize(); for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++) { pT->Lock(); CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex); pT->Unlock(); IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p); if (pDispatch != NULL) { VariantClear(&varResult); DISPPARAMS disp = { NULL, NULL, 0, 0 }; pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL); } } return varResult.scode; } HRESULT __stdcall Fire_OnError(LONG err,BSTR msg) { CComVariant varResult; T* pT = static_cast<T*>(this); int nConnectionIndex; int nConnections = m_vec.GetSize(); for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++) { pT->Lock(); CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex); pT->Unlock(); IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p); if (pDispatch != NULL) { VariantClear(&varResult); //DISPPARAMS disp = { NULL, NULL, 0, 0 }; DISPPARAMS dispparams; memset(&dispparams, 0, sizeof(dispparams)); dispparams.cArgs=2; // 设置参数个数 dispparams.rgvarg=new VARIANTARG[1]; // 初始化参数数组 dispparams.rgvarg[0].vt=VT_UI4; // 第一个参数的类型 dispparams.rgvarg[0].uintVal=(UINT)err; dispparams.rgvarg[1].vt=VT_BSTR; // 第一个参数的类型 dispparams.rgvarg[1].bstrVal=(BSTR)msg; pDispatch->Invoke(0x2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &varResult, NULL, NULL); } } return varResult.scode; } }; |
我们可以看到,触发事件的FireEvent实现中,特殊之处在于,要把参数进行赋值,再调用定义的事件,0x1、0x2就是定义的事件。
实现之后,还需要在控件类定义处加入代理类,如(1)中需继承的其他类。
(4)有了这些之后,就可以在需要的地方触发事件,例如,在出现某种错误或情况时触发onError事件
(5)请注意,不要在控件所起的线程中触发事件,如果需要的话,请在线程中需要触发事件的地方给控件窗口(仅限控件有窗口的情况)发送自定义的消息,由控件窗口接收到消息后触发事件。要使用线程消息,需要在控件类定义时,在BEGIN_MSG_MAP和END_MSG_MAP中定义消息处理函数。
(6)一个题外话,控件类还应该继承 IObjectSafetyImpl,并在COM_MAP中声明宏,这样在浏览器中使用时,就不会弹出“在此页上的ActiveX控件和本页上的其它部分交互可能不安全”这样的提示。当然,要更好的解决安全问题,还需要考虑对控件数字签名等等方式。
相关推荐
6. **自定义事件**:增加了更多的回调函数,允许开发者根据需要添加自己的逻辑,比如在切换标签时触发特定的事件。 7. **多语言支持**:可能集成了多语言支持,方便国际化应用的开发。 8. **性能优化**:可能对...
这个“VC树控件多选”实现就是针对这种情况,提供了一个扩展的树控件类,支持节点的多选操作。 这个实现可能包括以下关键知识点: 1. **多选模式**:默认的TreeView控件不支持多选,需要通过自定义控件或扩展已有...
"vc写的多功能表格控件增加数据源"这个主题聚焦于一个特定的表格控件,它是由VC++(Visual C++)编写的,并且具有增强的功能,特别是支持绑定到数据源,能够展示数据库中的内容。这一特性使得开发人员能更方便地创建...
本资源提供了一个从`CWnd`派生的图片显示控件,它专为在Visual C++ 6(VC6)环境中使用而设计,并且利用了GDI+库来实现图像的显示功能。GDI+是Microsoft Windows API的一个扩展,它提供了更高级的图形绘制功能,包括...
"VC开发实时曲线控件"是指利用Microsoft的MFC(Microsoft Foundation Classes)库或者ATL(Active Template Library)库来设计一个能够实时更新并显示动态数据变化的图形控件。这种控件类似于LabVIEW中的Graph控件,...
扩展可能涉及增加输入验证、自动完成功能、多行文本编辑、右键菜单支持等。通过继承CEdit类并覆盖其成员函数,可以定制编辑框的行为,例如实现自定义的文本格式化、颜色高亮或者输入限制。 Progress控件通常用于...
6. **控件的国际化和本地化**:如何使控件支持多语言环境,包括字符串资源的管理。 7. **控件的扩展**:利用MFC的派生机制,你可以创建自己的控件类,增加新的功能或优化已有功能。 在"VC通用控件使用实例"部分,...
在Windows编程领域,Visual C++ 6.0...总结来说,VC6.0中改变控件颜色和形状主要依赖于MFC库、代码绘制以及可能的第三方库支持。熟练掌握这些技术,能够帮助你创建出独特且吸引人的用户界面,提高应用程序的用户体验。
本文将详细讲解如何在VC中为列表控件ListCtrl增加列和行的内容。 首先,我们需要了解CListCtrl的基本用法。在创建CListCtrl对象后,通常需要设置其风格,例如LVS_REPORT,这使得列表控件以报告视图显示,支持多列和...
总的来说,“VC树形控件制作的鄱阳湖看图程序”涵盖了Windows桌面应用开发的基础知识,包括UI设计、事件处理、资源管理、文件操作等多个方面,是一个学习和实践VC++编程的好案例。通过深入研究这个程序,开发者可以...
在VC6中,我们需要引入第三方库来支持皮肤功能,因为原生的MFC(Microsoft Foundation Classes)框架并不直接支持皮肤化。 常见的皮肤库有如AlloySkin、eXtreme Skin Engine、Snowy Night等,这些库提供API接口,...
6. **SuperGrid** 和 **QuickList**: 这些是第三方库提供的高级网格控件,提供了更多的自定义选项和功能,如单元格合并、颜色定制、行/列拖动等,能够更好地满足复杂界面的需求。 7. **ReportCtrl**: 报表控件通常...
### 制作VC表格控件 在开发基于数据库的应用程序时,经常需要...例如,可以通过增加滚动条支持更大的数据集,或者添加排序功能提高用户体验等。希望本文能够帮助你在VC开发过程中更加得心应手地处理表格数据展示问题。
6. **响应机制**:除了消息处理外,还可以通过重载OnMouseMove成员函数来检测鼠标的位置,当鼠标在控件范围内时显示提示,否则隐藏。 7. **布局与定位**:为了使泡泡提示在屏幕上的位置合理,可能需要计算提示框相...
6. **定制与扩展**:由于提供了源码,开发者可以根据实际需求对控件进行修改和扩展,例如增加新的功能,优化性能,或者调整用户界面以适应特定应用场景。 7. **嵌入与集成**:控件的使用方式是“拉一拉”即可,这...
一个支持事件响应 保存 读取的VC 动态控件应用示例,可以在窗体上动态添加文本框、标签及按钮控件,可以循环的添加下去,每点击一次添加按钮,就会动态添加一个控件对象,如演示截图所示的运行窗口,动态控件可被...
以上是关于"VC 自定义时间轴控件"的一些核心知识点,实际开发中可能还会涉及到更多的细节和技术,例如性能优化、多线程更新、国际化支持等。通过对这些技术的掌握和应用,可以创建出功能强大且用户友好的时间轴控件...
在这个“VC增强版TreeList树形列表控件”中,开发者可能已经对其进行了优化,增加了更多的功能和更好的性能,使其更适合复杂的项目需求。 在描述中提到的“好用的treelistctl”,这表明这个控件在易用性和功能上都...
随着跨平台开发的需求增加,选择支持Windows、Linux甚至移动端的曲线控件会提高应用的可移植性。 总之,"VC上用的曲线控件(多个)"集合提供了多样化的曲线绘制解决方案,涵盖了从基本的2D图表到复杂的工业级图表...