Hello World as ActiveX — Complete Source Included

Building a Hello World ActiveX Control (Full Source Code)

This article walks through creating a minimal Hello World ActiveX control in C++ using Microsoft Visual C++ and ATL. It includes complete source for a simple control that exposes a string property and a ShowMessage method which displays “Hello World”. Assumptions: you have Visual Studio with ATL support and basic C++/COM knowledge.

Project setup

  1. Create a new ATL Project (e.g., “HelloAx”).
  2. In Project Wizard choose “Dynamic-Link Library (DLL)”, uncheck “Support MFC”, leave defaults.
  3. Add an ATL Simple Object named “HelloCtrl”. Select “Control” as the threading model (or apartment), enable “IViewObject” if prompted.

Key files overview

  • HelloAx.idl — COM interface and coclass declarations.
  • CHelloCtrl.h / CHelloCtrl.cpp — control implementation.
  • resource files and project settings for registration and typelib.

IDL excerpt

Add a simple interface with a string property and a method:

idl

import “oaidl.idl”; import “ocidl.idl”;[ uuid(12345678-1234-1234-1234-1234567890AB), version(1.0) ] library HelloAxLib {

importlib("stdole32.tlb"); importlib("stdole2.tlb"); [   object,   uuid(87654321-4321-4321-4321-BA0987654321),   dual,   nonextensible,   oleautomation ] interface IHelloCtrl : IDispatch {     [propget, id(1)] HRESULT Message([out, retval] BSTR* pVal);     [propput, id(1)] HRESULT Message([in] BSTR newVal);     [id(2)] HRESULT ShowMessage(); }; [   uuid(0FEDCBA9-8765-4321-ABCD-1234567890AB),   helpstring("HelloCtrl Class") ] coclass HelloCtrl {     [default] interface IHelloCtrl;     interface IViewObjectEx;     interface IPersistStreamInit;     interface IOleControl;     interface IOleObject; }; 

};

Control header (CHelloCtrl.h)

cpp

#pragma once #include “resource.h” #include class ATL_NO_VTABLE CHelloCtrl : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CHelloCtrl, &CLSID_HelloCtrl>, public CComControl<CHelloCtrl>, public IDispatchImpl<IHelloCtrl, &IID_IHelloCtrl, &LIBID_HelloAxLib, /wMajor =/1, /wMinor =/0> { public: CHelloCtrl() : m_bstrMessage(SysAllocString(L“Hello World”)) {} DECLARE_REGISTRY_RESOURCEID(IDR_HELLOCTRL) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CHelloCtrl) COM_INTERFACE_ENTRY(IHelloCtrl) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IOleControl) COM_INTERFACE_ENTRY(IOleObject) COM_INTERFACE_ENTRY(IViewObjectEx) COM_INTERFACE_ENTRY(IPersistStreamInit) END_COM_MAP() BEGIN_PROP_MAP(CHelloCtrl) PROP_ENTRY(“Message”, 1, VT_BSTR) END_PROP_MAP() // IHelloCtrl STDMETHOD(get_Message)(BSTR pVal); STDMETHOD(put_Message)(BSTR newVal); STDMETHOD(ShowMessage)(); private: CComBSTR mbstrMessage; };

Control implementation (CHelloCtrl.cpp)

cpp

#include “pch.h” #include “HelloAx.h” #include “CHelloCtrl.h” #include #include STDMETHODIMP CHelloCtrl::get_Message(BSTR pVal) { if (!pVal) return E_POINTER; *pVal = m_bstrMessage.Copy(); return S_OK; } STDMETHODIMP CHelloCtrl::put_Message(BSTR newVal) { m_bstrMessage = newVal; // Fire property change if necessary: FireOnChanged(1); return S_OK; } STDMETHODIMP CHelloCtrl::ShowMessage() { MessageBox(NULL, m_bstrMessage, L“HelloCtrl”, MB_OK); return S_OK; }

Registration and GUIDs

  • Use guidgen or Visual Studio to set the UUIDs in the IDL and class definitions.
  • Ensure the project has proper registry script (DECLARE_REGISTRYRESOURCEID) and build to register the DLL (regsvr32 will be called by the ATL project post-build if enabled).

Building and testing

  1. Build the project in Release or Debug.
  2. Register the DLL (post-build step or run regsvr32 HelloAx.dll as admin).
  3. Create an HTML test page embedding the control:

html

<html> <body> <object id=hello classid=clsid:0FEDCBA9-8765-4321-ABCD-1234567890AB width=200 height=50></object> <script> try { hello.Message = “Hello from JS!”; hello.ShowMessage(); } catch(e) { alert(“Error: “ + e); } </script> </body> </html>

Open in Internet Explorer (ActiveX is supported there) to test.

Notes and security

  • ActiveX runs only in Internet Explorer; modern browsers don’t support it.
  • Running ActiveX controls requires trust — sign the control and ensure safe initialization to avoid security prompts.
  • For more features (drawing, property pages), implement additional ATL interfaces (IViewObjectEx, IPersistPropertyBag, etc.).

Full-source packaging

Include these files in your project:

  • HelloAx.idl (with the IDL excerpt above)
  • HelloAx.h / HelloAx.cpp (ATL module and resource includes)
  • CHelloCtrl.h / CHelloCtrl.cpp (above)
  • Resource.rc, resource.h, and registry script entry for IDR_HELLOCTRL

This minimal example gives a working Hello World ActiveX control exposing a property and method. Expand with proper error handling, apartment threading, and security hardening for production use.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *