Menu in ActiveX

转载 2005年05月06日 20:17:00

Environment: VC6, Windows 2000

It took me some time to figure out how to enable menu in an ATL/MFC ActiveX control and I think the result is simple but instructive. You simply have to change the style of the window of the AX control. ActiveX is the 3rd generation of COM (Basic COM and Automation are the 1st and 2nd) and it added support to the following weeknesses of its predeccessors: lack of user interface, standardized storage, custom events, optimization for the Internet. Basic COM and Automation servers could display and use dialog-boxes but not through the COM system. Being an elementary thing in a user interface, menu is very important.

ATL

Let's create a simple ATL AX Control:

Start Visual C++ and select File/New/ATL COM AppWizard, specify a location and let the project name be ATLMenu. Click OK then click Finish then OK. Now you will insert a Full Control through the menu items Insert/New ATL Object. Select Controls and Full Control, click Next. In the 'Short Name' box enter MyMenu then click on the Miscellaneous tab and click 'Windowed only' then click OK. Now select Insert/Resource/Menu from the VC's menu and click New. Type 'File' then 'MsgBox' in the menu items and ID_MSGBOX as the identifier for the 'MsgBox' menuitem. Choose the ClassView tab of th Workspace window and right click on CMyMenu and select 'Add Windows Message Handler'. Expand the tree if necessary. Select WM_CREATE then click on Add Handler, and OK. Now select the FileView tab of the Workspace window and expand the tree until MyMenu.h. Double click on it and locate the OnCreate function and type:

LRESULT OnCreate( UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled)
{
long lStyle;
HMENU hMenu;

lStyle = ::GetWindowLong(m_hWnd, GWL_STYLE);

lStyle &= WS_DISABLED;
lStyle |= WS_CAPTION;
//lStyle |= WS_OVERLAPPEDWINDOW;

::SetWindowLong(m_hWnd, GWL_STYLE, lStyle);

hMenu = ::LoadMenu( _Module.GetModuleInstance(),
MAKEINTRESOURCE(IDR_MENU1));
::SetMenu(m_hWnd, hMenu);

return 0;
}

Now you will add the code to handle the message sent by the menu item. Locate the BEGIN_MSG_MAP macro and alter it like this (COMMAND_ID_HANDLER):

BEGIN_MSG_MAP(CMyMenu)
CHAIN_MSG_MAP(CComControl<CMyMenu>)
DEFAULT_REFLECTION_HANDLER()
MESSAGE_HANDLER(WM_CREATE, OnCreate)
COMMAND_ID_HANDLER(ID_MSGBOX, OnMsgBox)
END_MSG_MAP()

Now add the handler function too and you are ready to compile:

LRESULT OnMsgBox( WORD wNotifyCode,
WORD wID,
HWND hWndCtl,
BOOL& bHandled)
{
::MessageBox( m_hWnd,
"Hello World!",
"From Menu",
MB_OK);
return 0;
}
Select Build/Set Active Configuration and set it to Release MinDependency and click OK. Now Build your AX Control by selecting Build/Build ATLMenu.dll. The Wizard automatically generated a MyMenu.html file in your project's folder, double click on it and test your work.

It's interesting that you can drag your AX Control by its caption and move it. You can prevent dragging by overriding WM_NCLBUTTONDOWN:

LRESULT OnNcLButtonDown( UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled)
{
// TODO : Add Code for message handler.
// Call DefWindowProc if necessary.
if (HTCAPTION == (INT)wParam)
{
::SetActiveWindow(m_hWnd);
return 1;
}
::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
return 0;
}

You can manipulate your Control by using the interfaces derived from IOleWindow. Add IOleInPlaceObject::SetObjectRects to your Control's class because this will be called by the Container as a response to call to IOleInPlaceSite::OnPosRectChange by your Control or when the user makes changes to the Container's window. When neccessary call OnPosRectChange which is implemented by the Container from your Control(m_spInPlaceSite->OnPosRectChange(&rc) where m_spInPlaceSite is a pointer to the Container's IOleInplaceSite interface).

STDMETHODIMP SetObjectRects( LPCRECT prcPos,
LPCRECT prcClip)
{
//Call ::SetWindowPos Win32 API function
return NOERROR;
}

MFC

It's almost the same as in ATL but it's much easier because of the powerful ClassWizard:

Select File/New/MFC ActiveX Control Wizard and just click next and OK everywhere. Insert menu resource and add menu items. Use ClassWizard to add WM_CREATE, and the menu item handler code to the project. Add the code needed to OnCreate function: see the ATL way above but change from HMENU to CMenu etc or use the Win32 API functions just like in the case of ATL above. Finally add AfxMessageBox("Hello World!") to your menuitem handler code. Build and Register your AX Control(Tools/Register Control menu). The Wizard won't generate .html file this time, so you have to write it or create an MFC AppWizard(exe) container project and test it there.

It's interesting that if you test your MFC control in IE then the window acts like a child of the Control(You can drag it only in the Control's client area), but it has a menu. It's strange because as far as I know a child window can't have a menu. But if you test it in a dialog-based MFC container it works fine.

You should override the WM_NCLBUTTONDOWN message like this in case of MFC:

void CMFCMenuCtrl::OnNcLButtonDown( UINT nHitTest,
CPoint point)
{
if (HTCAPTION == nHitTest)
return;
COleControl::OnNcLButtonDown(nHitTest, point);
}

The pointer to an IOleInPlaceSite interface is m_pInPlaceSite in case of MFC.

项目实战:Java Applet与ActiveX控件应用

控件技术是B/S项目的高级开发手段,在项目实战中非常重要! 作为一个高级程序员和架构师,掌握控件的开发和集成技术,是必须的技能; 浏览器中显示的内容主要是标签,当需要复杂操作时,控件技术是超越标签、给B/S项目扩展功能的重要方法! 学习本套视频,主要是掌握java applet的开发技术,同时需要掌握在大项目开发中, 如何有效的集成第三方控件;
  • 2017年04月08日 20:59

ActiveX控件学习笔记(一)

本文是入门学习ActiveX的学习笔记,属于系统学习整个框架部分,具体细节自己写代码时再深入。学习参考书籍是《MFC Windows程序设计(第二版)》,使用开发环境是VS2010,VS2010和6....
  • babyKangaroo
  • babyKangaroo
  • 2015-05-17 20:24:37
  • 1449

my Activex ocx (menu)

  • 2017年01月18日 20:43
  • 82KB
  • 下载

activex与前台JS交互

以下Demo演示如何在activex中与前台的js进行交互: activex中: private mshtml.HTMLWindow2Class window = null...
  • guchuanlong
  • guchuanlong
  • 2014-06-15 00:31:18
  • 1286

Activex打包于发布完整版---ActiveX打包

前面介绍了数字证书的原理与制作:http://blog.csdn.net/jiangtongcn/article/details/13508365,下面来看一下ActiveX组件的打包。 我现在有一...
  • jiangtongcn
  • jiangtongcn
  • 2013-10-29 17:47:16
  • 2958

ActiveX组件开发和使用

ActiveX控件的概念  (COM组件的应用)     1 什么是ActiveX控件        基于COM组件技术的,使用与一般控件一样方便。与一般控件的区别是,它可以被任何支持COM标准的计算...
  • eldn__
  • eldn__
  • 2014-08-06 21:18:45
  • 7435

ActiveX回调js函数 之 变量调用

ActiveX回调js函数 之 变量调用 1、在VC6.0下创建一个MFC ActiveX工程,此处滤过具体步骤。 2、添加外部调用的变量OnDataIn,步骤如下:              ...
  • youyongyoumou
  • youyongyoumou
  • 2016-09-18 17:12:03
  • 1192

Activex和javaScript结合使用

http://download1.csdn.net/down3/20070613/13093058219.rar由于项目的需要,将一组事务封装成Activex控件(使用传统的delphi),总结来前人...
  • liuzuofei
  • liuzuofei
  • 2007-06-13 09:31:00
  • 1072

Activex 控件编程入门实例

直接上图,使用vs2008IDE 1.新建 Activex项目 2.自动生成项目文件  3. 现在添加自己的方法供外部调用     4.实现添加的方法 5....
  • mfc5158
  • mfc5158
  • 2016-06-29 11:04:54
  • 464

ActiveX开发流程

ActiveX是微软九十年代中期开发的一种技术,它允许你创建一个类似applet的应用程序,并允许你在微软的浏览器中下载和运行。这篇教程的阅读对象是那些希望使用Visuall C++开发第一个Acti...
  • rankun1
  • rankun1
  • 2016-04-09 13:56:56
  • 1023
收藏助手
不良信息举报
您举报文章:Menu in ActiveX
举报原因:
原因补充:

(最多只允许输入30个字)