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.
This commit is contained in:
Henri Verbeet 2010-06-18 13:09:50 +02:00 committed by Alexandre Julliard
parent 25629eff96
commit e4a4065bbd
3 changed files with 42 additions and 49 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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;