[PATCH] ddraw: Register / unregister the ddraw window class from DllMain().
Henri Verbeet
hverbeet at codeweavers.com
Fri Jun 18 06:09:50 CDT 2010
This avoids failing in DDRAW_Create() if a previous IDirectDrawImpl object
with the same pointer value was imporperly cleaned up. The improper cleanup is
of course the larger problem, but I don't believe that can be fixed without
making more invasive changes to ddraw.
---
dlls/ddraw/ddraw.c | 30 +++++++++++++----------
dlls/ddraw/ddraw_private.h | 7 +----
dlls/ddraw/main.c | 54 ++++++++++++++++++-------------------------
3 files changed, 42 insertions(+), 49 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index a8dbafa..7d6558d 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -275,9 +275,6 @@ IDirectDrawImpl_Destroy(IDirectDrawImpl *This)
This->devicewindow = 0;
}
- /* Unregister the window class */
- UnregisterClassA(This->classname, 0);
-
EnterCriticalSection(&ddraw_cs);
list_remove(&This->ddraw_list_entry);
LeaveCriticalSection(&ddraw_cs);
@@ -504,11 +501,15 @@ IDirectDrawImpl_SetCooperativeLevel(IDirectDraw7 *iface,
/* Don't create a device window if a focus window is set */
if( !(This->focuswindow) )
{
- HWND devicewindow = CreateWindowExA(0, This->classname, "DDraw device window",
- WS_POPUP, 0, 0,
- GetSystemMetrics(SM_CXSCREEN),
- GetSystemMetrics(SM_CYSCREEN),
- NULL, NULL, GetModuleHandleA(0), NULL);
+ HWND devicewindow = CreateWindowExA(0, DDRAW_WINDOW_CLASS_NAME, "DDraw device window",
+ WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
+ NULL, NULL, NULL, NULL);
+ if (!devicewindow)
+ {
+ ERR("Failed to create window, last error %#x.\n", GetLastError());
+ LeaveCriticalSection(&ddraw_cs);
+ return E_FAIL;
+ }
ShowWindow(devicewindow, SW_SHOW); /* Just to be sure */
TRACE("(%p) Created a DDraw device window. HWND=%p\n", This, devicewindow);
@@ -2875,11 +2876,14 @@ IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl *This,
/* If there's no window, create a hidden window. WineD3D needs it */
if(window == 0 || window == GetDesktopWindow())
{
- window = CreateWindowExA(0, This->classname, "Hidden D3D Window",
- WS_DISABLED, 0, 0,
- GetSystemMetrics(SM_CXSCREEN),
- GetSystemMetrics(SM_CYSCREEN),
- NULL, NULL, GetModuleHandleA(0), NULL);
+ window = CreateWindowExA(0, DDRAW_WINDOW_CLASS_NAME, "Hidden D3D Window",
+ WS_DISABLED, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
+ NULL, NULL, NULL, NULL);
+ if (!window)
+ {
+ ERR("Failed to create window, last error %#x.\n", GetLastError());
+ return E_FAIL;
+ }
ShowWindow(window, SW_HIDE); /* Just to be sure */
WARN("(%p) No window for the Direct3DDevice, created a hidden window. HWND=%p\n", This, window);
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index d6f4a57..1cb3070 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -143,11 +143,6 @@ struct IDirectDrawImpl
/* The surface type to request */
WINED3DSURFTYPE ImplType;
-
- /* Our private window class */
- char classname[32];
- WNDCLASSA wnd_class;
-
/* Helpers for surface creation */
IDirectDrawSurfaceImpl *tex_root;
BOOL depthstencil;
@@ -165,6 +160,8 @@ struct IDirectDrawImpl
UINT numConvertedDecls, declArraySize;
};
+#define DDRAW_WINDOW_CLASS_NAME "ddraw_wc"
+
/* Declare the VTables. They can be found ddraw.c */
extern const IDirectDraw7Vtbl IDirectDraw7_Vtbl DECLSPEC_HIDDEN;
extern const IDirectDraw4Vtbl IDirectDraw4_Vtbl DECLSPEC_HIDDEN;
diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c
index 591f46c..45a156f 100644
--- a/dlls/ddraw/main.c
+++ b/dlls/ddraw/main.c
@@ -242,37 +242,6 @@ DDRAW_Create(const GUID *guid,
This->wineD3DDevice = wineD3DDevice;
TRACE("wineD3DDevice created at %p\n", This->wineD3DDevice);
- /* Register the window class
- *
- * It is used to create a hidden window for D3D
- * rendering, if the application didn't pass one.
- * It can also be used for Creating a device window
- * from SetCooperativeLevel
- *
- * The name: DDRAW_<address>. The classname is
- * 32 bit long, so a 64 bit address will fit nicely
- * (Will this be compiled for 64 bit anyway?)
- *
- */
- sprintf(This->classname, "DDRAW_%p", This);
-
- memset(&This->wnd_class, 0, sizeof(This->wnd_class));
- This->wnd_class.style = CS_HREDRAW | CS_VREDRAW;
- This->wnd_class.lpfnWndProc = DefWindowProcA;
- This->wnd_class.cbClsExtra = 0;
- This->wnd_class.cbWndExtra = 0;
- This->wnd_class.hInstance = GetModuleHandleA(0);
- This->wnd_class.hIcon = 0;
- This->wnd_class.hCursor = 0;
- This->wnd_class.hbrBackground = GetStockObject(BLACK_BRUSH);
- This->wnd_class.lpszMenuName = NULL;
- This->wnd_class.lpszClassName = This->classname;
- if(!RegisterClassA(&This->wnd_class))
- {
- ERR("RegisterClassA failed!\n");
- goto err_out;
- }
-
/* Get the amount of video memory */
This->total_vidmem = IWineD3DDevice_GetAvailableTextureMem(This->wineD3DDevice);
@@ -817,8 +786,28 @@ DllMain(HINSTANCE hInstDLL,
DWORD size = sizeof(buffer);
HKEY hkey = 0;
HKEY appkey = 0;
+ WNDCLASSA wc;
DWORD len;
+ /* Register the window class. This is used to create a hidden window
+ * for D3D rendering, if the application didn't pass one. It can also
+ * be used for creating a device window from SetCooperativeLevel(). */
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = DefWindowProcA;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = hInstDLL;
+ wc.hIcon = 0;
+ wc.hCursor = 0;
+ wc.hbrBackground = GetStockObject(BLACK_BRUSH);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = DDRAW_WINDOW_CLASS_NAME;
+ if (!RegisterClassA(&wc))
+ {
+ ERR("Failed to register ddraw window class, last error %#x.\n", GetLastError());
+ return FALSE;
+ }
+
/* @@ Wine registry key: HKCU\Software\Wine\Direct3D */
if ( RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Direct3D", &hkey ) ) hkey = 0;
@@ -955,6 +944,9 @@ DllMain(HINSTANCE hInstDLL,
while(IDirectDraw7_Release((IDirectDraw7 *)ddraw));
}
}
+
+ /* Unregister the window class. */
+ UnregisterClassA(DDRAW_WINDOW_CLASS_NAME, hInstDLL);
}
return TRUE;
--
1.6.4.4
More information about the wine-patches
mailing list