Commit d67b99ae authored by Alexandre Julliard's avatar Alexandre Julliard

ole32: Delay registering the apartment class until needed.

parent 7eebd74c
...@@ -1478,18 +1478,44 @@ static HRESULT apartment_hostobject_in_hostapt( ...@@ -1478,18 +1478,44 @@ static HRESULT apartment_hostobject_in_hostapt(
return hr; return hr;
} }
static BOOL WINAPI register_class( INIT_ONCE *once, void *param, void **context )
{
WNDCLASSW wclass;
/* Dispatching to the correct thread in an apartment is done through
* window messages rather than RPC transports. When an interface is
* marshalled into another apartment in the same process, a window of the
* following class is created. The *caller* of CoMarshalInterface (i.e., the
* application) is responsible for pumping the message loop in that thread.
* The WM_USER messages which point to the RPCs are then dispatched to
* apartment_wndproc by the user's code from the apartment in which the
* interface was unmarshalled.
*/
memset(&wclass, 0, sizeof(wclass));
wclass.lpfnWndProc = apartment_wndproc;
wclass.hInstance = hProxyDll;
wclass.lpszClassName = wszAptWinClass;
RegisterClassW(&wclass);
return TRUE;
}
/* create a window for the apartment or return the current one if one has /* create a window for the apartment or return the current one if one has
* already been created */ * already been created */
HRESULT apartment_createwindowifneeded(struct apartment *apt) HRESULT apartment_createwindowifneeded(struct apartment *apt)
{ {
static INIT_ONCE class_init_once = INIT_ONCE_STATIC_INIT;
if (apt->multi_threaded) if (apt->multi_threaded)
return S_OK; return S_OK;
if (!apt->win) if (!apt->win)
{ {
HWND hwnd = CreateWindowW(wszAptWinClass, NULL, 0, HWND hwnd;
0, 0, 0, 0,
HWND_MESSAGE, 0, hProxyDll, NULL); InitOnceExecuteOnce( &class_init_once, register_class, NULL, NULL );
hwnd = CreateWindowW(wszAptWinClass, NULL, 0, 0, 0, 0, 0,
HWND_MESSAGE, 0, hProxyDll, NULL);
if (!hwnd) if (!hwnd)
{ {
ERR("CreateWindow failed with error %d\n", GetLastError()); ERR("CreateWindow failed with error %d\n", GetLastError());
...@@ -1516,31 +1542,6 @@ void apartment_joinmta(void) ...@@ -1516,31 +1542,6 @@ void apartment_joinmta(void)
COM_CurrentInfo()->apt = MTA; COM_CurrentInfo()->apt = MTA;
} }
static void COMPOBJ_InitProcess( void )
{
WNDCLASSW wclass;
/* Dispatching to the correct thread in an apartment is done through
* window messages rather than RPC transports. When an interface is
* marshalled into another apartment in the same process, a window of the
* following class is created. The *caller* of CoMarshalInterface (i.e., the
* application) is responsible for pumping the message loop in that thread.
* The WM_USER messages which point to the RPCs are then dispatched to
* apartment_wndproc by the user's code from the apartment in which the
* interface was unmarshalled.
*/
memset(&wclass, 0, sizeof(wclass));
wclass.lpfnWndProc = apartment_wndproc;
wclass.hInstance = hProxyDll;
wclass.lpszClassName = wszAptWinClass;
RegisterClassW(&wclass);
}
static void COMPOBJ_UninitProcess( void )
{
UnregisterClassW(wszAptWinClass, hProxyDll);
}
static void COM_TlsDestroy(void) static void COM_TlsDestroy(void)
{ {
struct oletls *info = NtCurrentTeb()->ReservedForOle; struct oletls *info = NtCurrentTeb()->ReservedForOle;
...@@ -4585,13 +4586,12 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved) ...@@ -4585,13 +4586,12 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved)
switch(fdwReason) { switch(fdwReason) {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
hProxyDll = hinstDLL; hProxyDll = hinstDLL;
COMPOBJ_InitProcess();
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
if (reserved) break; if (reserved) break;
release_std_git(); release_std_git();
COMPOBJ_UninitProcess(); UnregisterClassW( wszAptWinClass, hProxyDll );
RPC_UnregisterAllChannelHooks(); RPC_UnregisterAllChannelHooks();
COMPOBJ_DllList_Free(); COMPOBJ_DllList_Free();
DeleteCriticalSection(&csRegisteredClassList); DeleteCriticalSection(&csRegisteredClassList);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment