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
- Create a new ATL Project (e.g., “HelloAx”).
- In Project Wizard choose “Dynamic-Link Library (DLL)”, uncheck “Support MFC”, leave defaults.
- 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” #includeclass 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
- Build the project in Release or Debug.
- Register the DLL (post-build step or run regsvr32 HelloAx.dll as admin).
- 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.
Leave a Reply