Wednesday, August 13, 2008

How to resolve error: "CoInitialize has not been called" that found in Delphi Application

In a project that needed to display HTML documents, I decided to use the TWebBrowser control. I had used this handy ActiveX control successfully in other projects before.

This application was an MDI application, written in Delphi 5. As a 'specialty' I had installed a beta version of Internet Explorer on my system. I am not sure which of this is responsible for it, but when I would call the function in my application to display the HTML document, the TWebBrowser element could not be instantiated.
Instead I would receive an error message:

'CoInitialize has not been called'

The surprising thing is that the webbrowser control shows fine in design mode! I checked and TWebBrowser was properly installed. The underlieing DLL was also registered properly. A call of

regsvr32 shdocvw.dll

did not help. Finally I manually called the CoInitialize() function. I had to add OLE2 to the list of used units. A good place to do this is the initialization part as the sample snippet below shows.
Thanks to Martin Vreeken for pointing out the necessary CoUninitialize() call.

In a multithreaded application, you have to put a call to CoInitialize() at the beginning of your thread's Execute method and a matching CoUnInitialize() at its end.

ActiveX, // <-- make sure to include this unit
// older Delphi versions use: OLE2 instead
Windows; // and others

CoInitialize(nil); // <-- manually call CoInitialize()

CoUnInitialize; // <-- free memory