CoInitialize

CoInitializeで、COMの初期化を行う。

CoInitialize function (objbase.h) - Win32 apps | Microsoft Docs

まずは、

// ヘッダファイルのインクルード
#include <windows.h>	// 標準WindowsAPI
#include <tchar.h>		// TCHAR対応
#include <stdio.h>		// C標準入出力

// _tmain関数の定義
int _tmain(int argc, TCHAR *argv[]){	// main関数のTCHAR版.

	// COMの初期化.
	HRESULT hr = CoInitialize(NULL);	// CoInitializeでCOMを初期化し, 戻り値をhrに格納.
	if (hr == S_OK){	// S_OKなら初期化成功.
		_tprintf(_T("CoInitialize success!\n"));	// "CoInitialize success!"と出力.
	}

	// COMの終了処理.
	CoUninitialize();	// CoUninitializeで終了処理.

	// プログラムの終了.
	return 0;	// 0を返して終了.

}

こう書いて、実行すると、

CoInitialize success!
続行するには何かキーを押してください . . .

こうなる。
CoInitializeによる初期化が成功すると、S_OKが返ってくる。
次に、

// ヘッダファイルのインクルード
#include <windows.h>	// 標準WindowsAPI
#include <tchar.h>		// TCHAR対応

// _tmain関数の定義
int _tmain(int argc, TCHAR *argv[]){	// main関数のTCHAR版.

	// COMの初期化.
	HRESULT hr = CoInitialize(NULL);	// CoInitializeでCOMを初期化し, 戻り値をhrに格納.
	if (hr == S_OK){	// S_OKなら初期化成功.
		_tprintf(_T("CoInitialize success!\n"));	// "CoInitialize success!"と出力.
	}

	// 2回目のCOMの初期化.
	HRESULT hr2 = CoInitialize(NULL);	// CoInitializeでCOMを初期化し, 戻り値をhr2に格納.
	if (hr2 == S_FALSE){	// S_FALSEならすでに初期化されている.
		_tprintf(_T("Already initialized!\n"));	// "Already initialized!"と出力.
	}

	// COMの終了処理.
	CoUninitialize();	// CoUninitializeで終了処理.

	// プログラムの終了.
	return 0;	// 0を返して終了.

}

2回呼び出すと、

CoInitialize success!
Already initialized!
続行するには何かキーを押してください . . .

S_FALSEが返ってくる。
これは失敗というより、すでに初期化されてるという意味。
最後に、

メインスレッドでCoInitialize初期化した後で、ワーカースレッドでCoInitialize初期化。

CoInitialize success!
Already initialized!
Thread Begin
ThreadProc: CoInitialize success!
Thread End
dwExitCode = 0
続行するには何かキーを押してください . . .

プログラムの最初で初期化というより、スレッドごとに初期化できるということ。

Sample/com/CoInitialize/CoInitialize/src/CoInitialize at master · bg1bgst333/Sample · GitHub