是否有一些已知的单元在使用时自动初始化 COM 库?

Is there some known unit who automatically initialize the COM Library when it's used?

我制作了一个需要使用API DoDragDrop函数的自定义控件,他们说我必须先调用OleInitialize才能调用这个函数。

我在 MyControl.Create 方法中这样做,但我得到 S_FALSE 结果,所以这意味着 COM 库已经初始化。但是谁初始化它呢?

我之前没有在我的应用程序中初始化它。我在想,也许有一些 delphi 单位在他的 initialization 部分初始化它......第二个问题是我应该怎么做,我应该继续在 [=12= 中初始化 COM 库吗? ] 方法还是我根本不应该初始化(因为它已经初始化)?

正如我在 answer 中对类似问题所述:

In the RTL/VCL source, COM is initialized in the following ways:

  1. By a call to OleInitialize made from Forms.TApplication.Create. So this call will be made for all VCL forms applications, but not, for example, for service applications.
  2. By a call to CoInitialize or CoInitializeEx in ComObj.InitComObj. This is registered as an InitProc in the initialization section of the ComObj unit. In turn, the call to Application.Initialize in your project .dpr file's code will invoke ComObj.InitComObj.
  3. In many and various other locations around the RTL/VCL. Including, but not limited to, Datasnap, ComServ, Soap, System.Win.Sensors, Winapi.DirectShow9. Some of these areas of code are more recent than Delphi 7.

Now, of these various COM initializations, the ones that count are 1 and 2. In any standard VCL forms application, both of these will run at startup in the main thread. Item 1 runs first and so gets to initialize COM first. That's the initialization that counts. Item 2 runs after and returns S_FALSE meaning that COM was already initialized.

所有 VCL 应用程序都包含 Forms 单元,因此您可以确定 COM 在主 VCL 线程中初始化。对于其他线程,您需要在必要时初始化 COM。


您绝不能初始化控制中的 COM,或者更一般地说,不能初始化您无法控制的线程。如果这样做,那么您的初始化可能会与线程所有者指定的单元类型发生冲突。