ole: Defer apartment window creation until the first object is marshalled.

This commit is contained in:
Robert Shearman 2006-01-10 20:09:08 +01:00 committed by Alexandre Julliard
parent fcba783fc7
commit cd2fafb775
3 changed files with 29 additions and 4 deletions

View File

@ -236,9 +236,6 @@ static APARTMENT *apartment_construct(DWORD model)
{
/* FIXME: should be randomly generated by in an RPC call to rpcss */
apt->oxid = ((OXID)GetCurrentProcessId() << 32) | GetCurrentThreadId();
apt->win = CreateWindowW(wszAptWinClass, NULL, 0,
0, 0, 0, 0,
0, 0, OLE32_hInstance, NULL);
}
else
{
@ -422,6 +419,29 @@ static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LP
}
}
HRESULT apartment_createwindowifneeded(struct apartment *apt)
{
if (!(apt->model & COINIT_APARTMENTTHREADED))
return S_OK;
if (!apt->win)
{
HWND hwnd = CreateWindowW(wszAptWinClass, NULL, 0,
0, 0, 0, 0,
0, 0, OLE32_hInstance, NULL);
if (!hwnd)
{
ERR("CreateWindow failed with error %ld\n", GetLastError());
return HRESULT_FROM_WIN32(GetLastError());
}
if (InterlockedCompareExchangePointer((PVOID *)&apt->win, hwnd, NULL))
/* someone beat us to it */
DestroyWindow(hwnd);
}
return S_OK;
}
HWND apartment_getwindow(struct apartment *apt)
{
assert(apt->model & COINIT_APARTMENTTHREADED);

View File

@ -139,7 +139,7 @@ struct apartment
DWORD tid; /* thread id (RO) */
OXID oxid; /* object exporter ID (RO) */
LONG ipidc; /* interface pointer ID counter, starts at 1 (LOCK) */
HWND win; /* message window (RO) */
HWND win; /* message window (LOCK) */
CRITICAL_SECTION cs; /* thread safety */
LPMESSAGEFILTER filter; /* message filter (CS cs) */
struct list proxies; /* imported objects (CS cs) */
@ -230,6 +230,7 @@ static inline HRESULT apartment_getoxid(struct apartment *apt, OXID *oxid)
*oxid = apt->oxid;
return S_OK;
}
HRESULT apartment_createwindowifneeded(struct apartment *apt);
HWND apartment_getwindow(struct apartment *apt);
void apartment_joinmta(void);

View File

@ -98,6 +98,10 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
if (hr != S_OK)
return hr;
hr = apartment_createwindowifneeded(apt);
if (hr != S_OK)
return hr;
hr = IUnknown_QueryInterface(object, riid, (void **)&iobject);
if (hr != S_OK)
{