| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/child/npapi/webplugin_delegate_impl.h" | 5 #include "content/child/npapi/webplugin_delegate_impl.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "content/child/npapi/plugin_lib.h" | 26 #include "content/child/npapi/plugin_lib.h" |
| 27 #include "content/child/npapi/plugin_stream_url.h" | 27 #include "content/child/npapi/plugin_stream_url.h" |
| 28 #include "content/child/npapi/webplugin.h" | 28 #include "content/child/npapi/webplugin.h" |
| 29 #include "content/child/npapi/webplugin_ime_win.h" | 29 #include "content/child/npapi/webplugin_ime_win.h" |
| 30 #include "content/common/plugin_constants_win.h" | 30 #include "content/common/plugin_constants_win.h" |
| 31 #include "skia/ext/platform_canvas.h" | 31 #include "skia/ext/platform_canvas.h" |
| 32 #include "third_party/WebKit/public/web/WebInputEvent.h" | 32 #include "third_party/WebKit/public/web/WebInputEvent.h" |
| 33 #include "ui/base/win/dpi.h" | 33 #include "ui/base/win/dpi.h" |
| 34 #include "ui/base/win/hwnd_util.h" | 34 #include "ui/base/win/hwnd_util.h" |
| 35 #include "webkit/common/cursors/webcursor.h" | 35 #include "webkit/common/cursors/webcursor.h" |
| 36 #include "webkit/plugins/npapi/plugin_utils.h" | |
| 37 #include "webkit/plugins/plugin_constants.h" | 36 #include "webkit/plugins/plugin_constants.h" |
| 38 | 37 |
| 39 using WebKit::WebKeyboardEvent; | 38 using WebKit::WebKeyboardEvent; |
| 40 using WebKit::WebInputEvent; | 39 using WebKit::WebInputEvent; |
| 41 using WebKit::WebMouseEvent; | 40 using WebKit::WebMouseEvent; |
| 42 using webkit::WebPluginInfo; | 41 using webkit::WebPluginInfo; |
| 43 | 42 |
| 44 namespace content { | 43 namespace content { |
| 45 | 44 |
| 46 namespace { | 45 namespace { |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 if (result != STATUS_SUCCESS) | 181 if (result != STATUS_SUCCESS) |
| 183 return L""; | 182 return L""; |
| 184 | 183 |
| 185 KEY_NAME_INFORMATION* info = | 184 KEY_NAME_INFORMATION* info = |
| 186 reinterpret_cast<KEY_NAME_INFORMATION*>(buffer.get()); | 185 reinterpret_cast<KEY_NAME_INFORMATION*>(buffer.get()); |
| 187 return std::wstring(info->Name, info->NameLength / sizeof(wchar_t)); | 186 return std::wstring(info->Name, info->NameLength / sizeof(wchar_t)); |
| 188 } | 187 } |
| 189 | 188 |
| 190 int GetPluginMajorVersion(const WebPluginInfo& plugin_info) { | 189 int GetPluginMajorVersion(const WebPluginInfo& plugin_info) { |
| 191 Version plugin_version; | 190 Version plugin_version; |
| 192 webkit::npapi::CreateVersionFromString(plugin_info.version, &plugin_version); | 191 webkit::WebPluginInfo::CreateVersionFromString( |
| 192 plugin_info.version, &plugin_version); |
| 193 | 193 |
| 194 int major_version = 0; | 194 int major_version = 0; |
| 195 if (plugin_version.IsValid()) | 195 if (plugin_version.IsValid()) |
| 196 major_version = plugin_version.components()[0]; | 196 major_version = plugin_version.components()[0]; |
| 197 | 197 |
| 198 return major_version; | 198 return major_version; |
| 199 } | 199 } |
| 200 | 200 |
| 201 } // namespace | 201 } // namespace |
| 202 | 202 |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 } | 451 } |
| 452 | 452 |
| 453 bool WebPluginDelegateImpl::WindowedCreatePlugin() { | 453 bool WebPluginDelegateImpl::WindowedCreatePlugin() { |
| 454 DCHECK(!windowed_handle_); | 454 DCHECK(!windowed_handle_); |
| 455 | 455 |
| 456 RegisterNativeWindowClass(); | 456 RegisterNativeWindowClass(); |
| 457 | 457 |
| 458 // The window will be sized and shown later. | 458 // The window will be sized and shown later. |
| 459 windowed_handle_ = CreateWindowEx( | 459 windowed_handle_ = CreateWindowEx( |
| 460 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR, | 460 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR, |
| 461 webkit::npapi::kNativeWindowClassName, | 461 kNativeWindowClassName, |
| 462 0, | 462 0, |
| 463 WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, | 463 WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, |
| 464 0, | 464 0, |
| 465 0, | 465 0, |
| 466 0, | 466 0, |
| 467 0, | 467 0, |
| 468 webkit::npapi::GetDefaultWindowParent(), | 468 GetDesktopWindow(), |
| 469 0, | 469 0, |
| 470 GetModuleHandle(NULL), | 470 GetModuleHandle(NULL), |
| 471 0); | 471 0); |
| 472 if (windowed_handle_ == 0) | 472 if (windowed_handle_ == 0) |
| 473 return false; | 473 return false; |
| 474 | 474 |
| 475 // This is a tricky workaround for Issue 2673 in chromium "Flash: IME not | 475 // This is a tricky workaround for Issue 2673 in chromium "Flash: IME not |
| 476 // available". To use IMEs in this window, we have to make Windows attach | 476 // available". To use IMEs in this window, we have to make Windows attach |
| 477 // IMEs to this window (i.e. load IME DLLs, attach them to this process, and | 477 // IMEs to this window (i.e. load IME DLLs, attach them to this process, and |
| 478 // add their message hooks to this window). Windows attaches IMEs while this | 478 // add their message hooks to this window). Windows attaches IMEs while this |
| (...skipping 12 matching lines...) Expand all Loading... |
| 491 // window property. Use atoms so that other processes can access the name and | 491 // window property. Use atoms so that other processes can access the name and |
| 492 // version of the plugin that this window is hosting. | 492 // version of the plugin that this window is hosting. |
| 493 if (instance_ != NULL) { | 493 if (instance_ != NULL) { |
| 494 PluginLib* plugin_lib = instance()->plugin_lib(); | 494 PluginLib* plugin_lib = instance()->plugin_lib(); |
| 495 if (plugin_lib != NULL) { | 495 if (plugin_lib != NULL) { |
| 496 std::wstring plugin_name = plugin_lib->plugin_info().name; | 496 std::wstring plugin_name = plugin_lib->plugin_info().name; |
| 497 if (!plugin_name.empty()) { | 497 if (!plugin_name.empty()) { |
| 498 ATOM plugin_name_atom = GlobalAddAtomW(plugin_name.c_str()); | 498 ATOM plugin_name_atom = GlobalAddAtomW(plugin_name.c_str()); |
| 499 DCHECK_NE(0, plugin_name_atom); | 499 DCHECK_NE(0, plugin_name_atom); |
| 500 result = SetProp(windowed_handle_, | 500 result = SetProp(windowed_handle_, |
| 501 webkit::npapi::kPluginNameAtomProperty, | 501 kPluginNameAtomProperty, |
| 502 reinterpret_cast<HANDLE>(plugin_name_atom)); | 502 reinterpret_cast<HANDLE>(plugin_name_atom)); |
| 503 DCHECK(result == TRUE) << "SetProp failed, last error = " << | 503 DCHECK(result == TRUE) << "SetProp failed, last error = " << |
| 504 GetLastError(); | 504 GetLastError(); |
| 505 } | 505 } |
| 506 base::string16 plugin_version = plugin_lib->plugin_info().version; | 506 base::string16 plugin_version = plugin_lib->plugin_info().version; |
| 507 if (!plugin_version.empty()) { | 507 if (!plugin_version.empty()) { |
| 508 ATOM plugin_version_atom = GlobalAddAtomW(plugin_version.c_str()); | 508 ATOM plugin_version_atom = GlobalAddAtomW(plugin_version.c_str()); |
| 509 DCHECK_NE(0, plugin_version_atom); | 509 DCHECK_NE(0, plugin_version_atom); |
| 510 result = SetProp(windowed_handle_, | 510 result = SetProp(windowed_handle_, |
| 511 webkit::npapi::kPluginVersionAtomProperty, | 511 kPluginVersionAtomProperty, |
| 512 reinterpret_cast<HANDLE>(plugin_version_atom)); | 512 reinterpret_cast<HANDLE>(plugin_version_atom)); |
| 513 DCHECK(result == TRUE) << "SetProp failed, last error = " << | 513 DCHECK(result == TRUE) << "SetProp failed, last error = " << |
| 514 GetLastError(); | 514 GetLastError(); |
| 515 } | 515 } |
| 516 } | 516 } |
| 517 } | 517 } |
| 518 | 518 |
| 519 // Calling SetWindowLongPtrA here makes the window proc ASCII, which is | 519 // Calling SetWindowLongPtrA here makes the window proc ASCII, which is |
| 520 // required by at least the Shockwave Director plug-in. | 520 // required by at least the Shockwave Director plug-in. |
| 521 SetWindowLongPtrA( | 521 SetWindowLongPtrA( |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 | 725 |
| 726 return TRUE; | 726 return TRUE; |
| 727 } | 727 } |
| 728 | 728 |
| 729 bool WebPluginDelegateImpl::CreateDummyWindowForActivation() { | 729 bool WebPluginDelegateImpl::CreateDummyWindowForActivation() { |
| 730 DCHECK(!dummy_window_for_activation_); | 730 DCHECK(!dummy_window_for_activation_); |
| 731 | 731 |
| 732 dummy_window_for_activation_ = CreateWindowEx( | 732 dummy_window_for_activation_ = CreateWindowEx( |
| 733 0, | 733 0, |
| 734 L"Static", | 734 L"Static", |
| 735 webkit::npapi::kDummyActivationWindowName, | 735 kDummyActivationWindowName, |
| 736 WS_CHILD, | 736 WS_CHILD, |
| 737 0, | 737 0, |
| 738 0, | 738 0, |
| 739 0, | 739 0, |
| 740 0, | 740 0, |
| 741 // We don't know the parent of the dummy window yet, so just set it to the | 741 // We don't know the parent of the dummy window yet, so just set it to the |
| 742 // desktop and it'll get parented by the browser. | 742 // desktop and it'll get parented by the browser. |
| 743 webkit::npapi::GetDefaultWindowParent(), | 743 GetDesktopWindow(), |
| 744 0, | 744 0, |
| 745 GetModuleHandle(NULL), | 745 GetModuleHandle(NULL), |
| 746 0); | 746 0); |
| 747 | 747 |
| 748 if (dummy_window_for_activation_ == 0) | 748 if (dummy_window_for_activation_ == 0) |
| 749 return false; | 749 return false; |
| 750 | 750 |
| 751 BOOL result = SetProp(dummy_window_for_activation_, | 751 BOOL result = SetProp(dummy_window_for_activation_, |
| 752 kWebPluginDelegateProperty, this); | 752 kWebPluginDelegateProperty, this); |
| 753 DCHECK(result == TRUE) << "SetProp failed, last error = " << GetLastError(); | 753 DCHECK(result == TRUE) << "SetProp failed, last error = " << GetLastError(); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 wcex.hInstance = GetModuleHandle(NULL); | 866 wcex.hInstance = GetModuleHandle(NULL); |
| 867 wcex.hIcon = 0; | 867 wcex.hIcon = 0; |
| 868 wcex.hCursor = 0; | 868 wcex.hCursor = 0; |
| 869 // Some plugins like windows media player 11 create child windows parented | 869 // Some plugins like windows media player 11 create child windows parented |
| 870 // by our plugin window, where the media content is rendered. These plugins | 870 // by our plugin window, where the media content is rendered. These plugins |
| 871 // dont implement WM_ERASEBKGND, which causes painting issues, when the | 871 // dont implement WM_ERASEBKGND, which causes painting issues, when the |
| 872 // window where the media is rendered is moved around. DefWindowProc does | 872 // window where the media is rendered is moved around. DefWindowProc does |
| 873 // implement WM_ERASEBKGND correctly if we have a valid background brush. | 873 // implement WM_ERASEBKGND correctly if we have a valid background brush. |
| 874 wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1); | 874 wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1); |
| 875 wcex.lpszMenuName = 0; | 875 wcex.lpszMenuName = 0; |
| 876 wcex.lpszClassName = webkit::npapi::kNativeWindowClassName; | 876 wcex.lpszClassName = kNativeWindowClassName; |
| 877 wcex.hIconSm = 0; | 877 wcex.hIconSm = 0; |
| 878 | 878 |
| 879 return RegisterClassEx(&wcex); | 879 return RegisterClassEx(&wcex); |
| 880 } | 880 } |
| 881 | 881 |
| 882 LRESULT CALLBACK WebPluginDelegateImpl::WrapperWindowProc( | 882 LRESULT CALLBACK WebPluginDelegateImpl::WrapperWindowProc( |
| 883 HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { | 883 HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { |
| 884 // This is another workaround for Issue 2673 in chromium "Flash: IME not | 884 // This is another workaround for Issue 2673 in chromium "Flash: IME not |
| 885 // available". Somehow, the CallWindowProc() function does not dispatch | 885 // available". Somehow, the CallWindowProc() function does not dispatch |
| 886 // window messages when its first parameter is a handle representing the | 886 // window messages when its first parameter is a handle representing the |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 | 999 |
| 1000 result = CallWindowProc( | 1000 result = CallWindowProc( |
| 1001 delegate->plugin_wnd_proc_, hwnd, message, wparam, lparam); | 1001 delegate->plugin_wnd_proc_, hwnd, message, wparam, lparam); |
| 1002 | 1002 |
| 1003 delegate->is_calling_wndproc = false; | 1003 delegate->is_calling_wndproc = false; |
| 1004 g_current_plugin_instance = last_plugin_instance; | 1004 g_current_plugin_instance = last_plugin_instance; |
| 1005 | 1005 |
| 1006 if (message == WM_NCDESTROY) { | 1006 if (message == WM_NCDESTROY) { |
| 1007 RemoveProp(hwnd, kWebPluginDelegateProperty); | 1007 RemoveProp(hwnd, kWebPluginDelegateProperty); |
| 1008 ATOM plugin_name_atom = reinterpret_cast<ATOM>( | 1008 ATOM plugin_name_atom = reinterpret_cast<ATOM>( |
| 1009 RemoveProp(hwnd, webkit::npapi::kPluginNameAtomProperty)); | 1009 RemoveProp(hwnd, kPluginNameAtomProperty)); |
| 1010 if (plugin_name_atom != 0) | 1010 if (plugin_name_atom != 0) |
| 1011 GlobalDeleteAtom(plugin_name_atom); | 1011 GlobalDeleteAtom(plugin_name_atom); |
| 1012 ATOM plugin_version_atom = reinterpret_cast<ATOM>( | 1012 ATOM plugin_version_atom = reinterpret_cast<ATOM>( |
| 1013 RemoveProp(hwnd, webkit::npapi::kPluginVersionAtomProperty)); | 1013 RemoveProp(hwnd, kPluginVersionAtomProperty)); |
| 1014 if (plugin_version_atom != 0) | 1014 if (plugin_version_atom != 0) |
| 1015 GlobalDeleteAtom(plugin_version_atom); | 1015 GlobalDeleteAtom(plugin_version_atom); |
| 1016 ClearThrottleQueueForWindow(hwnd); | 1016 ClearThrottleQueueForWindow(hwnd); |
| 1017 } | 1017 } |
| 1018 } | 1018 } |
| 1019 delegate->last_message_ = old_message; | 1019 delegate->last_message_ = old_message; |
| 1020 return result; | 1020 return result; |
| 1021 } | 1021 } |
| 1022 | 1022 |
| 1023 void WebPluginDelegateImpl::WindowlessUpdateGeometry( | 1023 void WebPluginDelegateImpl::WindowlessUpdateGeometry( |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1246 // the message filter hook. | 1246 // the message filter hook. |
| 1247 handle_event_message_filter_hook_ = | 1247 handle_event_message_filter_hook_ = |
| 1248 SetWindowsHookEx(WH_MSGFILTER, HandleEventMessageFilterHook, NULL, | 1248 SetWindowsHookEx(WH_MSGFILTER, HandleEventMessageFilterHook, NULL, |
| 1249 GetCurrentThreadId()); | 1249 GetCurrentThreadId()); |
| 1250 // To ensure that the plugin receives keyboard events we set focus to the | 1250 // To ensure that the plugin receives keyboard events we set focus to the |
| 1251 // dummy window. | 1251 // dummy window. |
| 1252 // TODO(iyengar) We need a framework in the renderer to identify which | 1252 // TODO(iyengar) We need a framework in the renderer to identify which |
| 1253 // windowless plugin is under the mouse and to handle this. This would | 1253 // windowless plugin is under the mouse and to handle this. This would |
| 1254 // also require some changes in RenderWidgetHost to detect this in the | 1254 // also require some changes in RenderWidgetHost to detect this in the |
| 1255 // WM_MOUSEACTIVATE handler and inform the renderer accordingly. | 1255 // WM_MOUSEACTIVATE handler and inform the renderer accordingly. |
| 1256 bool valid = | 1256 bool valid = GetParent(dummy_window_for_activation_) != GetDesktopWindow(); |
| 1257 GetParent(dummy_window_for_activation_) != | |
| 1258 webkit::npapi::GetDefaultWindowParent(); | |
| 1259 if (valid) { | 1257 if (valid) { |
| 1260 last_focus_window = ::SetFocus(dummy_window_for_activation_); | 1258 last_focus_window = ::SetFocus(dummy_window_for_activation_); |
| 1261 } else { | 1259 } else { |
| 1262 NOTREACHED() << "Dummy window not parented"; | 1260 NOTREACHED() << "Dummy window not parented"; |
| 1263 } | 1261 } |
| 1264 } | 1262 } |
| 1265 | 1263 |
| 1266 bool old_task_reentrancy_state = | 1264 bool old_task_reentrancy_state = |
| 1267 base::MessageLoop::current()->NestableTasksAllowed(); | 1265 base::MessageLoop::current()->NestableTasksAllowed(); |
| 1268 | 1266 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1372 | 1370 |
| 1373 if (g_current_plugin_instance) { | 1371 if (g_current_plugin_instance) { |
| 1374 unsigned long window_process_id = 0; | 1372 unsigned long window_process_id = 0; |
| 1375 unsigned long window_thread_id = | 1373 unsigned long window_thread_id = |
| 1376 GetWindowThreadProcessId(window, &window_process_id); | 1374 GetWindowThreadProcessId(window, &window_process_id); |
| 1377 // TrackPopupMenu fails if the window passed in belongs to a different | 1375 // TrackPopupMenu fails if the window passed in belongs to a different |
| 1378 // thread. | 1376 // thread. |
| 1379 if (::GetCurrentThreadId() != window_thread_id) { | 1377 if (::GetCurrentThreadId() != window_thread_id) { |
| 1380 bool valid = | 1378 bool valid = |
| 1381 GetParent(g_current_plugin_instance->dummy_window_for_activation_) != | 1379 GetParent(g_current_plugin_instance->dummy_window_for_activation_) != |
| 1382 webkit::npapi::GetDefaultWindowParent(); | 1380 GetDesktopWindow(); |
| 1383 if (valid) { | 1381 if (valid) { |
| 1384 window = g_current_plugin_instance->dummy_window_for_activation_; | 1382 window = g_current_plugin_instance->dummy_window_for_activation_; |
| 1385 } else { | 1383 } else { |
| 1386 NOTREACHED() << "Dummy window not parented"; | 1384 NOTREACHED() << "Dummy window not parented"; |
| 1387 } | 1385 } |
| 1388 } | 1386 } |
| 1389 } | 1387 } |
| 1390 | 1388 |
| 1391 BOOL result = TrackPopupMenu(menu, flags, x, y, reserved, window, rect); | 1389 BOOL result = TrackPopupMenu(menu, flags, x, y, reserved, window, rect); |
| 1392 return result; | 1390 return result; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1456 FARPROC WINAPI WebPluginDelegateImpl::GetProcAddressPatch(HMODULE module, | 1454 FARPROC WINAPI WebPluginDelegateImpl::GetProcAddressPatch(HMODULE module, |
| 1457 LPCSTR name) { | 1455 LPCSTR name) { |
| 1458 FARPROC imm_function = WebPluginIMEWin::GetProcAddress(name); | 1456 FARPROC imm_function = WebPluginIMEWin::GetProcAddress(name); |
| 1459 if (imm_function) | 1457 if (imm_function) |
| 1460 return imm_function; | 1458 return imm_function; |
| 1461 return ::GetProcAddress(module, name); | 1459 return ::GetProcAddress(module, name); |
| 1462 } | 1460 } |
| 1463 | 1461 |
| 1464 void WebPluginDelegateImpl::HandleCaptureForMessage(HWND window, | 1462 void WebPluginDelegateImpl::HandleCaptureForMessage(HWND window, |
| 1465 UINT message) { | 1463 UINT message) { |
| 1466 if (!webkit::npapi::IsPluginDelegateWindow(window)) | 1464 if (ui::GetClassName(window) != base::string16(kNativeWindowClassName)) |
| 1467 return; | 1465 return; |
| 1468 | 1466 |
| 1469 switch (message) { | 1467 switch (message) { |
| 1470 case WM_LBUTTONDOWN: | 1468 case WM_LBUTTONDOWN: |
| 1471 case WM_MBUTTONDOWN: | 1469 case WM_MBUTTONDOWN: |
| 1472 case WM_RBUTTONDOWN: | 1470 case WM_RBUTTONDOWN: |
| 1473 ::SetCapture(window); | 1471 ::SetCapture(window); |
| 1474 // As per documentation the WM_PARENTNOTIFY message is sent to the parent | 1472 // As per documentation the WM_PARENTNOTIFY message is sent to the parent |
| 1475 // window chain if mouse input is received by the child window. However | 1473 // window chain if mouse input is received by the child window. However |
| 1476 // the parent receives the WM_PARENTNOTIFY message only if we doubleclick | 1474 // the parent receives the WM_PARENTNOTIFY message only if we doubleclick |
| 1477 // on the window. We send the WM_PARENTNOTIFY message for mouse input | 1475 // on the window. We send the WM_PARENTNOTIFY message for mouse input |
| 1478 // messages to the parent to indicate that user action is expected. | 1476 // messages to the parent to indicate that user action is expected. |
| 1479 ::SendMessage(::GetParent(window), WM_PARENTNOTIFY, message, 0); | 1477 ::SendMessage(::GetParent(window), WM_PARENTNOTIFY, message, 0); |
| 1480 break; | 1478 break; |
| 1481 | 1479 |
| 1482 case WM_LBUTTONUP: | 1480 case WM_LBUTTONUP: |
| 1483 case WM_MBUTTONUP: | 1481 case WM_MBUTTONUP: |
| 1484 case WM_RBUTTONUP: | 1482 case WM_RBUTTONUP: |
| 1485 ::ReleaseCapture(); | 1483 ::ReleaseCapture(); |
| 1486 break; | 1484 break; |
| 1487 | 1485 |
| 1488 default: | 1486 default: |
| 1489 break; | 1487 break; |
| 1490 } | 1488 } |
| 1491 } | 1489 } |
| 1492 | 1490 |
| 1493 } // namespace content | 1491 } // namespace content |
| OLD | NEW |