From 52deb42efffa2b7f895bd9f7ca61e03f174300a5 Mon Sep 17 00:00:00 2001 From: "apatrick@google.com" Date: Fri, 2 Oct 2009 23:31:33 +0000 Subject: Workaround for Chromium bug. http://code.google.com/p/chromium/issues/detail?id=23694 Review URL: http://codereview.chromium.org/259027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27915 0039d316-1c4b-4281-b951-d872f2087c98 --- o3d/plugin/win/main_win.cc | 57 +++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 21 deletions(-) (limited to 'o3d') diff --git a/o3d/plugin/win/main_win.cc b/o3d/plugin/win/main_win.cc index 0fd3148..f8c6d20 100644 --- a/o3d/plugin/win/main_win.cc +++ b/o3d/plugin/win/main_win.cc @@ -89,6 +89,8 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, namespace { const wchar_t* const kO3DWindowClassName = L"O3DWindowClass"; +void CleanupAllWindows(PluginObject *obj); + // We would normally make this a stack variable in main(), but in a // plugin, that's not possible, so we make it a global. When the DLL is loaded // this it gets constructed and when it is unlooaded it is destructed. Note @@ -582,13 +584,19 @@ LRESULT CALLBACK PluginWindowInterposer(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { + PluginObject *obj = PluginObject::GetPluginProperty(hWnd); + + // Need to get the original window proc before potentially calling + // CleanupAllWindows which will clear it. + WNDPROC proc = static_cast(GetProp(hWnd, kOrigWndProcName)); + DCHECK(proc != NULL); + switch (Msg) { case WM_PAINT: { // For nicer startup appearance, allow the browser to paint the // plugin window until we start to draw 3D content. Forbid the // browser from painting once we have started to draw to prevent // a flash in Firefox upon our receiving focus the first time. - PluginObject *obj = PluginObject::GetPluginProperty(hWnd); if (obj != NULL && obj->renderer() != NULL) { if (obj->renderer()->presented_once()) { // Tell Windows we painted the window region. @@ -601,12 +609,16 @@ LRESULT CALLBACK PluginWindowInterposer(HWND hWnd, break; } + case WM_DESTROY: + if (obj != NULL) { + CleanupAllWindows(obj); + } + break; + default: break; } - WNDPROC proc = static_cast(GetProp(hWnd, kOrigWndProcName)); - DCHECK(proc != NULL); return CallWindowProc(proc, hWnd, Msg, wParam, lParam); } @@ -654,24 +666,27 @@ NPError InitializePlugin() { } void CleanupAllWindows(PluginObject *obj) { - DCHECK(obj->GetContentHWnd()); - DCHECK(obj->GetPluginHWnd()); - ::KillTimer(obj->GetContentHWnd(), 0); - - // Restore the original WNDPROC on the plugin window so that we - // don't attempt to call into the O3D DLL after it's been unloaded. - LONG_PTR origWndProc = reinterpret_cast( - GetProp(obj->GetPluginHWnd(), - kOrigWndProcName)); - DCHECK(origWndProc != NULL); - RemoveProp(obj->GetPluginHWnd(), kOrigWndProcName); - SetWindowLongPtr(obj->GetPluginHWnd(), GWLP_WNDPROC, origWndProc); - - PluginObject::ClearPluginProperty(obj->GetContentHWnd()); - PluginObject::ClearPluginProperty(obj->GetPluginHWnd()); - ::DestroyWindow(obj->GetContentHWnd()); - obj->SetContentHWnd(NULL); - obj->SetPluginHWnd(NULL); + if (obj->GetContentHWnd()) { + ::KillTimer(obj->GetContentHWnd(), 0); + PluginObject::ClearPluginProperty(obj->GetContentHWnd()); + ::DestroyWindow(obj->GetContentHWnd()); + obj->SetContentHWnd(NULL); + } + + if (obj->GetPluginHWnd()) { + // Restore the original WNDPROC on the plugin window so that we + // don't attempt to call into the O3D DLL after it's been unloaded. + LONG_PTR origWndProc = reinterpret_cast( + GetProp(obj->GetPluginHWnd(), + kOrigWndProcName)); + DCHECK(origWndProc != NULL); + RemoveProp(obj->GetPluginHWnd(), kOrigWndProcName); + SetWindowLongPtr(obj->GetPluginHWnd(), GWLP_WNDPROC, origWndProc); + + PluginObject::ClearPluginProperty(obj->GetPluginHWnd()); + obj->SetPluginHWnd(NULL); + } + obj->SetHWnd(NULL); } -- cgit v1.1