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