Robert Shearman : ole: Defer apartment window creation until the
first object is marshalled.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Jan 10 14:14:20 CST 2006
Module: wine
Branch: refs/heads/master
Commit: cd2fafb7753baf3d8e6fd6f8122ed5999f8ac381
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=cd2fafb7753baf3d8e6fd6f8122ed5999f8ac381
Author: Robert Shearman <rob at 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)
{
More information about the wine-cvs
mailing list