Module: wine Branch: refs/heads/master Commit: cd2fafb7753baf3d8e6fd6f8122ed5999f8ac381 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=cd2fafb7753baf3d8e6fd6f8...
Author: Robert Shearman rob@codeweavers.com Date: Tue Jan 10 20:09:08 2006 +0100
ole: Defer apartment window creation until the first object is marshalled.
---
dlls/ole32/compobj.c | 26 +++++++++++++++++++++++--- dlls/ole32/compobj_private.h | 3 ++- dlls/ole32/marshal.c | 4 ++++ 3 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index 8283312..a06879e 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -236,9 +236,6 @@ static APARTMENT *apartment_construct(DW { /* 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_wndpro } }
+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); diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h index bb54e3b..2e86a99 100644 --- a/dlls/ole32/compobj_private.h +++ b/dlls/ole32/compobj_private.h @@ -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( *oxid = apt->oxid; return S_OK; } +HRESULT apartment_createwindowifneeded(struct apartment *apt); HWND apartment_getwindow(struct apartment *apt); void apartment_joinmta(void);
diff --git a/dlls/ole32/marshal.c b/dlls/ole32/marshal.c index 6b4679d..313cbd2 100644 --- a/dlls/ole32/marshal.c +++ b/dlls/ole32/marshal.c @@ -98,6 +98,10 @@ HRESULT marshal_object(APARTMENT *apt, S 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) {