文档章节

ActiveX控件

小青_1989
 小青_1989
发布于 2014/05/14 14:48
字数 2003
阅读 490
收藏 2

创建一个MFC ActiveX控件项目,会得到整个程序的基本架构,下面以msdn下载的button为例,介绍下ActiveX的制作:

ActiveX控件

工程自动为我们生成了框架,有3个类和两个接口。CButtonApp做了注册等工作,我们一般不需要改动;CButtonCtrl是实现ActiveX控件的主体;CButtonPropPage是一个对话框,实现自定义的属性页;DButton接口是控件属性的接口;DButtonEvents是事件的接口。在函数OnDraw中绘制控件的外观,如果我们想使用一个公共Windows控件的外观,在创建工程时,可以指定基于哪个现有控件,生成的代码如下:

BOOL CButtonCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
 cs.lpszClass = _T("BUTTON");
 return COleControl::PreCreateWindow(cs);
}

void CButtonCtrl::OnDraw(
   CDC* pdc, const CRect& rcBounds, const CRect& )
{
 DoSuperclassPaint(pdc, rcBounds);
}

一个ActiveX控件就像MFC工具栏上的那些控件一样,通过它的属性来自定义控件的样式,通过写事件处理函数来响应该控件发出的事件。下面描述属性和事件的添加以及它们的原理。

一.属性的添加

右击DButton->添加->属性,库存属性可以用常规或get\set的方式实现,自定义属性以成员变量或get\set的方式实现。当创建的ActiveX控件继承自公共Windows控件时,我们创建控件就具备了该公共Windows控件的外观:

void CButtonCtrl::OnDraw(
   CDC* pdc, const CRect& rcBounds, const CRect& )
{
 DoSuperclassPaint(pdc, rcBounds);
}

此时,库存属性使用常规的方式,属性的值会直接反映到该公共Windows控件上。成员变量的方式创建属性会自动创建OnXXXXChanged方法,当该属性变动时,此方法便会调用,注意方法结束时要调用SetModifiedFlag()通知控件属性的改变。get\set方式创建的属性会构造get、set方法。

二.事件的添加

ActiveX控件的事件处理是这样的(摘自msdn):"Windows controls typically send certain window messages to their parent window. Some of these messages, such as WM_COMMAND, provide notification of an action by the user. Others, such as WM_CTLCOLOR, are used to obtain information from the parent window. An ActiveX control usually communicates with the parent window by other means. Notifications are communicated by firing events (sending event notifications), and information about the control container is obtained by accessing the container's ambient properties. Because these communication techniques exist, ActiveX control containers are not expected to process any window messages sent by the control.

To prevent the container from receiving the window messages sent by a subclassed Windows control,COleControl creates an extra window to serve as the control's parent. This extra window, called a "reflector," is created only for an ActiveX control that subclasses a Windows control and has the same size and position as the control window. The reflector window intercepts certain window messages and sends them back to the control. The control, in its window procedure, can then process these reflected messages by taking actions appropriate for an ActiveX control (for example, firing an event). See Reflected Window Message IDs for a list of intercepted windows messages and their corresponding reflected messages.”

大意是这样的:控件收到windows message会传递给它的父类,当ActiveX继承自一个公共Windows控件时,为了防止这个ActiveX控件的容器(理解为父类)接收到windows message,COleControl创建了一个"reflector" 来拦截Windows message,翻译后再传给ActiveX控件。所以我们在ActiveX控件中处理的都是OCM_XXX message,而不是WM_XXX message。

BOOL CButtonCtrl::PreTranslateMessage(MSG* pMsg)
{
 // give container a shot at processing accelerators
 if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
  if (::OleTranslateAccelerator(m_pInPlaceFrame,&m_frameInfo,pMsg)==S_OK)
   return TRUE;

 return COleControl::PreTranslateMessage(pMsg);
}

这便是ActiveX处理Windows message的原理,那么ActiveX控件暴露给容器处理的事件是什么呢?

右击CButtonCtrl->添加->事件,用以在DButtonEvents接口添加暴露给容器的事件,我们会看到源程序中多了两行:

EVENT_CUSTOM_ID("Click", DISPID_CLICK, FireClick, VTS_NONE)

void FireClick()
  {FireEvent(DISPID_CLICK,EVENT_PARAM(VTS_NONE));}

EVENT_CUSTOM_ID宏定义了事件名和事件标号的对应关系,FireClick中只调用FireEvent用以触发DISPID_CLICK事件。事件是这样调用的,ActiveX控件捕获OCM_XXX message(BN_CLICKED)再调用FireClick函数触发DISPID_CLICK事件,而DISPID_CLICK的触发会调用容器中的响应方法,这是一个回调的过程。为了建立这样的关系链,我们还需添加代码:

ON_MESSAGE(OCM_COMMAND, OnOcmCommand)

LRESULT CButtonCtrl::OnOcmCommand(WPARAM wParam, LPARAM lParam)
{
 #ifdef _WIN32
  WORD wNotifyCode = HIWORD(wParam);
  lParam;
 #else
  WORD wNotifyCode = HIWORD(lParam);
  wParam;
 #endif
   switch (wNotifyCode)
   {
   case BN_CLICKED:
    // Fire click event when button is clicked
    //FireClick();
    break;
   }
 return 0;
}

至此,事件就从控件传到了容器,中间经过了2次转换:WM message->OCM message,OCM message->自定义事件。

 

以下关于ActiveX的介绍摘自msdn:

An ActiveX control is a reusable software component based on the Component Object Model (COM) that supports a wide variety of OLE functionality and can be customized to fit many software needs. ActiveX controls are designed for use both in ordinary ActiveX control containers and on the Internet, in World Wide Web pages. You can create ActiveX controls either with MFC, described here, or with the Active Template Library (ATL).

An ActiveX control can draw itself in its own window, respond to events (such as mouse clicks), and be managed through an interface that includes properties and methods similar to those in Automation objects.

These controls can be developed for many uses, such as database access, data monitoring, or graphing. Besides their portability, ActiveX controls support features previously not available to ActiveX controls, such as compatibility with existing OLE containers and the ability to integrate their menus with the OLE container menus. In addition, an ActiveX control fully supports Automation, which allows the control to expose read\write properties and a set of methods that can be called by the control user.

You can create windowless ActiveX controls and controls that only create a window when they become active. Windowless controls speed up the display of your application and make it possible to have transparent and nonrectangular controls. You can also load ActiveX control properties asynchronously.

An ActiveX control is implemented as an in-process server (typically a small object) that can be used in any OLE container. Note that the full functionality of an ActiveX control is available only when used within an OLE container designed to be aware of ActiveX controls. See Port ActiveX Controls to Other Applications for a list of containers that support ActiveX controls. This container type, hereafter called a "control container," can operate an ActiveX control by using the control's properties and methods, and receives notifications from the ActiveX control in the form of events. The following figure demonstrates this interaction.

Interaction Between an ActiveX Control Container and a Windowed ActiveX Control:



ActiveX控件

Basic Components of an ActiveX Control

An ActiveX control uses several programmatic elements to interact efficiently with a control container and with the user. These are class COleControl, a set of event-firing functions, and a dispatch map.

Every ActiveX control object you develop inherits a powerful set of features from its MFC base class, COleControl. These features include in-place activation, and Automation logic.COleControl can provide the control object with the same functionality as an MFC window object, plus the ability to fire events. COleControl can also provide windowless controls, which rely on their container for help with some of the functionality a window provides (mouse capture, keyboard focus, scrolling), but offer much faster display.

Because the control class derives from COleControl, it inherits the capability to send, or "fire," messages, called events, to the control container when certain conditions are met. These events are used to notify the control container when something important happens in the control. You can send additional information about an event to the control container by attaching parameters to the event. For more information about ActiveX control events, see the article MFC ActiveX Controls: Events.

The final element is a dispatch map, which is used to expose a set of functions (called methods) and attributes (called properties) to the control user. Properties allow the control container or the control user to manipulate the control in various ways. The user can change the appearance of the control, change certain values of the control, or make requests of the control, such as accessing a specific piece of data that the control maintains. This interface is determined by the control developer and is defined using Class View. For more information on ActiveX control methods and properties, see the articles MFC ActiveX Controls: Methods and Properties.


Interaction Between Controls with Windows and ActiveX Control Containers

When a control is used within a control container, it uses two mechanisms to communicate: it exposes properties and methods, and it fires events. The following figure demonstrates how these two mechanisms are implemented.

Communication Between an ActiveX Control Container and an ActiveX Control:



ActiveX控件

 

The previous figure also illustrates how other OLE interfaces (besides automation and events) are handled by controls.

All of a control's communication with the container is performed by COleControl. To handle some of the container's requests, COleControl will call member functions that are implemented in the control class. All methods and some properties are handled in this way. Your control's class can also initiate communication with the container by calling member functions of COleControl. Events are fired in this manner.

Active and Inactive States of an ActiveX Control

A control has two basic states: active and inactive. Traditionally, these states were distinguished by whether the control had a window. An active control had a window; an inactive control did not. With the introduction of windowless activation, this distinction is no longer universal, but still applies to many controls.

When a windowless control goes active, it invokes mouse capture, keyboard focus, scrolling, and other window services from its container. You can also provide mouse interaction to inactive controls, as well as create controls that wait until activated to create a window.

When a control with a window becomes active, it is able to interact fully with the control container, the user, and Windows. The figure below demonstrates the paths of communication between the ActiveX control, the control container, and the operating system.

 

Windows Message Processing in a Windowed ActiveX Control (When Active):

 



ActiveX控件 


本文转载自:http://blog.sina.com.cn/s/blog_5d9101fd0100idfz.html

小青_1989
粉丝 3
博文 75
码字总数 12913
作品 0
大连
程序员
私信 提问
【转】ActiveX控件注册的几种方法

from:http://hi.baidu.com/estellejiang/blog/item/af16e862bbd1d3d7e6113aa7.html ActiveX控件是一个动态链接库,是作为基于COM服务器进行操作的,并且可以嵌入在包容器宿主应用程序中, Ac...

夏春涛
2009/10/12
0
0
c++ ActiveX基础1:使用VS2010创建MFC ActiveX工程项目

1.ActiveX的基本概念 ActiveX控件可以看作是一个极小的服务器应用程序,它不能独立运行,必须嵌入到某个容器程序中,与该容器一起运行。这个容器包括WEB网页,应用程序窗体等。。。 ActiveX控...

moki_oschina
2015/01/08
384
0
登录VPN时,提示ActiveX无法安装,需进行的配置。

1、打开IE-->工具-->安全-->可信任站点,将VPN的地址添加到信任列表。 2、对可信任站点进行以下配置 可信任站点-->自定义类别: 修改 ActiveX控件自动提示-->启用, 修改 对标记为可安全执行脚...

瓜子葫芦侠
2013/09/18
221
1
VC6开发视频监控ActiveX控件总结

总结前段时间在VC6下使用MFC开发视频监控控件过程中遇到的一些问题. 1.获取控件当前所在路径,用于读取该目录下的INI配置文件 获取配置文件路径 2.获取当前运行控件的电脑上的固定盘符列表,用...

长征2号
2017/09/06
0
0
Win32编程点滴3 - 简单ActiveX控件的使用

虽然这里一片的.net气氛,到处充斥着像MVC、WPF、WorkFlow、LINQ等各种niubility的术语。但我们使用的Windows还是由COM技术主宰着;我们在选择日常使用的软件时,也会避免使用.net开发的软件...

xumaojun
2018/04/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

作为一个(IT)程序员!聊天没有话题?试试这十二种技巧

首先呢?我是一名程序员,经常性和同事没话题。 因为每天都会有自己的任务要做,程序员对于其他行业来说;是相对来说比较忙的。你会经常看到程序员在发呆、调试密密麻麻代码、红色报错发呆;...

小英子wep
今天
12
0
【SpringBoot】产生背景及简介

一、SpringBoot介绍 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程,该框架使用了特定的方式来进行配置,从而使开发人员不再需要...

zw965
今天
4
0
简述并发编程分为三个核心问题:分工、同步、互斥。

总的来说,并发编程可以总结为三个核心问题:分工、同步、互斥。 所谓分工指的是如何高效地拆解任务并分配给线程,而同步指的是线程之间如何协作,互斥则是保证同一时刻只允许一个线程访问共...

dust8080
今天
6
0
OSChina 周四乱弹 —— 当你简历注水但还是找到了工作

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @花间小酌 :#今日歌曲推荐# 分享成龙的单曲《男儿当自强》。 《男儿当自强》- 成龙 手机党少年们想听歌,请使劲儿戳(这里) @hxg2016 :刚在...

小小编辑
今天
3.2K
22
靠写代码赚钱的一些门路

作者 @mezod 译者 @josephchang10 如今,通过自己的代码去赚钱变得越来越简单,不过对很多人来说依然还是很难,因为他们不知道有哪些门路。 今天给大家分享一个精彩的 GitHub 库,这个库整理...

高级农民工
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部