2

I am new to IntraWeb. I want to make a simple application which connects and displays an access database using ADO controls. When I execute the server it gives me

"CoInitialize has not been called"

error. I searched the internet and found many text telling that

Change ComInitialization property of IWServerController to ciMultiThreaded.

I tried to do this in IWAppFormCreate event. Then I got compilation error:

"Undeclared Identifier ciMultiThreaded"

I put the line IWServerController.ComInitialization:=ciMultiThreaded; then the runtime error comes up:

"Access violation at address . . ."

Since I don't know what I am doing I cant find the problem. Please help me.

Azad Salahli
  • 876
  • 3
  • 14
  • 30
  • possible duplicate of [Coinitialize error on IntraWeb using ADO](http://stackoverflow.com/questions/1134845/coinitialize-error-on-intraweb-using-ado) – jachguate Mar 19 '11 at 19:10
  • I checked that question but the solution didn't worked for me. I have mentioned in the question that I cannot use CoInitialize(). So it is not a dublicate – Azad Salahli Mar 19 '11 at 19:37

3 Answers3

3

The CoInitialize error on IntraWeb using ADO gives you the correct answer.

As I catch from comments on @David answer to this question, there are two things left:

  1. Where is declared the TComInitialization type, which in turns defines the ciMultiThreaded identifier. Answer to this is: IWServerControllerBase unit, part of Intraweb.
  2. Where to change the ComInitialization property of the IWServerController object to get this working.
    • The first thing you have to know is the actual class used to construct the IWServerController object is part of your IntraWeb project.
    • Next, trying to set this property on a page OnCreate event looks too late (it must be created in the thread you want to initialize COM), my guess is that altering this property at this time is forbidden and will raise an exception, or will be ignored completely.
    • Using the Delphi XE VCL for the Web Application wizard I got a unit named ServerController, with the class TIWServerController. After failing to override the constructor, I override the AfterConstruction method to initialize such property, like this

Example:

  TIWServerController = class(TIWServerControllerBase)
    procedure IWServerControllerBaseNewSession(ASession: TIWApplication;
      var VMainForm: TIWBaseForm);

  private

  protected
    //constructor Create; override;  //failed!!
  public
    procedure AfterConstruction; override;
  end;

  //..

procedure TIWServerController.AfterConstruction;
begin
  inherited;
  ComInitialization := ciMultiThreaded;  //succeded
end;

I then added a button, a label and properly configured ADOConnection (against SQL Server if that matters) and:

procedure TIWForm2.IWButton1Click(Sender: TObject);
begin
  try
    ADOConnection1.Connected := True;
    IWLabel1.Caption := 'Connected';
  except
    on E:Exception do
      IWLabel1.Caption := E.ClassName + ' ' + E.Message;
  end;
end;

Hitting the button, produces this:

TADOConnection Succesfully connected

Hope this is enough to you.

Community
  • 1
  • 1
jachguate
  • 16,976
  • 3
  • 57
  • 98
0

If you used the IntraWeb Application Wizard in XE2, it would of created a ServerController.pas unit for you.

If you open that unit in the visual designer, and click on the "form", you'll see a slew of properties for the TIWServerController. One of those is ComInitialization, which is a dropdown containing ciMultiThreaded, ciNone, ciNormal. It defaults to ciNone.

Here is the DFM after I changed the ComInitialization property:

object IWServerController: TIWServerController
  OldCreateOrder = False
  AuthBeforeNewSession = False
  AppName = 'MyApp'
  CharSet = 'UTF-8'
  CacheExpiry = 120
  ComInitialization = ciMultiThreaded
  Compression.Enabled = False
  Compression.Level = 6
  Description = 'My IntraWeb Application'
  DebugHTML = False
  DisplayName = 'IntraWeb Application'
  Log = loNone
  EnableImageToolbar = False
  ExceptionDisplayMode = smAlert
  HistoryEnabled = False
  InternalFilesURL = '/'
  JavascriptDebug = False
  PageTransitions = False
  Port = 8888
  RedirectMsgDelay = 0
  ServerResizeTimeout = 0
  ShowLoadingAnimation = True
  SessionTimeout = 10
  SSLOptions.NonSSLRequest = nsAccept
  SSLOptions.Port = 0
  SSLOptions.SSLVersion = sslv3
  Version = '12.0.8'
  OnNewSession = IWServerControllerBaseNewSession
  Height = 310
  Width = 342
end

Hope this helps some.

SiBrit
  • 1,460
  • 12
  • 39
0

It sounds like you haven't initialized COM, which you are required to do by calling CoInitializeEx(). From the documentation:

CoInitializeEx must be called at least once, and is usually called only once, for each thread that uses the COM library. Multiple calls to CoInitializeEx by the same thread are allowed as long as they pass the same concurrency flag, but subsequent valid calls return S_FALSE. To close the COM library gracefully on a thread, each successful call to CoInitialize or CoInitializeEx, including any call that returns S_FALSE, must be balanced by a corresponding call to CoUninitialize.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • in which unit it is declared. Still error Undeclared identifier CoInitializeEx() – Azad Salahli Mar 19 '11 at 18:27
  • Ok. From what I understood, I added the line `CoInitializeEx(nil,COINIT_MULTITHREADED);` to the initialization section of Unit1(the unit containing main form). I still get the same error `CoInitialization has not been called` – Azad Salahli Mar 19 '11 at 18:40
  • @Azad You need to do it in all threads. Read [this](http://msdn.microsoft.com/en-us/library/ms809971.aspx). – David Heffernan Mar 19 '11 at 18:42
  • Sorry, I have no knowledge about threads. I was using Intraweb without knowing anything about threads. So, exactly where I have to call CoInitializeEx() and am I calling it with the right parametrs? – Azad Salahli Mar 19 '11 at 18:50
  • I don't know if you've got the right parameters. I don't know what you are doing. Do you want all your threads in a single multi-threaded apartment? – David Heffernan Mar 19 '11 at 19:12
  • @Azad, @David, this is a duplicate question with a good answer: http://stackoverflow.com/questions/1134845/coinitialize-error-on-intraweb-using-ado – jachguate Mar 19 '11 at 19:13
  • @jachguate It looks like a good answer to that question, but OP states in his question that he has done exactly what that answer proposes. – David Heffernan Mar 19 '11 at 19:15
  • @jachguate It's clearly a case of missing COM initialization, what the right solution is for OP's case I'm not sure. – David Heffernan Mar 19 '11 at 19:17
  • @David, @Azad So, the question shall be in which unit is declared the TComInitialization type, which answer is: IWServerControllerBase – I just found by googling it in a Chinese looking page. As for the moment to set this property, I think is better at application startup and not on a FormCreate event: the thread will be already initialized at that time, and maybe the property change will be rejected or ignored at all, at least for this first client thread – jachguate Mar 19 '11 at 19:41