From e4a4065bbd7ea0ea4e06c26df5ac07974ee34bc2 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 18 Jun 2010 13:09:50 +0200 Subject: [PATCH] ddraw: Register / unregister the ddraw window class from DllMain(). 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 a8dbafae2de..7d6558dcc6f 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 d6f4a57d0a0..1cb30702d93 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 591f46c5339..45a156f171a 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_
. 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;