Creating OCX Controls using U++
1. |
Use the U++ version later than 2005-11-24. There was a very nasty bug in the OCX registration routine, capable of deleting half of CLSID registry keys and consequently nuking Windows installation. (Actually, this was not a bug in the routine as such, it was a bug in one of the overloads of the AsString routine). |
2. |
Add DLL to the main configuration flags. This is more or less all that's needed to build into aDLL (OCX is technically a DLL). |
3. |
You have to build the OCX interface using MIDL. You can use a custom step to do this: |
Custom step (extension = idl), output files: $(DIR)/$(TITLE)_idl.h,
$(DIR)/$(TITLE)_idl.cpp, $(DIR)/$(TITLE).tlb
midl /newtlb $(!/I) /h "$(DIR)/$(TITLE)_idl.h" /iid
"$(DIR)/$(TITLE)_idl.cpp" /tlb "$(DIR)/$(TITLE).tlb" "$(PATH)"
4. |
You have to define a def-file to declare public exports, like this: |
LIBRARY "mycontrol.ocx"
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
5. |
You need to put the type library (the TLB file created by MIDL from the IDL file) into your resources. Put this line on the beginning of your resource file: |
1 TYPELIB "mycontrol.tlb"
Do not forget to manually add "mycontrol.tlb" to the list of the resource file's dependencies. Otherwise next time you change the IDL file and the MIDL recompiles your TLB, TheIDE builder won't find out it needs to rebuild the resource script.
6. |
In the application, #include <Ole/Ctrl/OleCtrl.h> and use OCX_APP_MAIN to declare the "main" initialization routine. To be honest, the initialization routine is not really called during the very startup (DllMain -> DLL_PROCESS_ATTACH), its invocation is postponed until 1st object from the library is requested from the type factory. The reason for this is that too heavy initializations tend to deadlock or crash the Windows DLL loader. |
7. |
To make an object an OCX control, derive it from OcxControl. You should also use multiple inheritance to derive it from your custom interfaces, perhaps like this: |
class MyViewOcx
: public OcxControl // handles OCX control client functionality
, public DispatchInterface<IMyView> // custom control's interface
, public OcxConnectionPointContainer // needed only for callback (aka event) interface
8. |
The whole project should be demonstrated in a simple project called Ole/Ctrl/Calc. |
|