diff options
Diffstat (limited to 'webrtc/base/win32windowpicker.cc')
-rw-r--r-- | webrtc/base/win32windowpicker.cc | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/webrtc/base/win32windowpicker.cc b/webrtc/base/win32windowpicker.cc new file mode 100644 index 0000000000..b4550ae4a4 --- /dev/null +++ b/webrtc/base/win32windowpicker.cc @@ -0,0 +1,143 @@ +/* + * Copyright 2010 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include "webrtc/base/win32windowpicker.h" + +#include <string> +#include <vector> + +#include "webrtc/base/common.h" +#include "webrtc/base/logging.h" + +namespace rtc { + +namespace { + +// Window class names that we want to filter out. +const char kProgramManagerClass[] = "Progman"; +const char kButtonClass[] = "Button"; + +} // namespace + +BOOL CALLBACK Win32WindowPicker::EnumProc(HWND hwnd, LPARAM l_param) { + WindowDescriptionList* descriptions = + reinterpret_cast<WindowDescriptionList*>(l_param); + + // Skip windows that are invisible, minimized, have no title, or are owned, + // unless they have the app window style set. Except for minimized windows, + // this is what Alt-Tab does. + // TODO: Figure out how to grab a thumbnail of a minimized window and + // include them in the list. + int len = GetWindowTextLength(hwnd); + HWND owner = GetWindow(hwnd, GW_OWNER); + LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); + if (len == 0 || IsIconic(hwnd) || !IsWindowVisible(hwnd) || + (owner && !(exstyle & WS_EX_APPWINDOW))) { + // TODO: Investigate if windows without title still could be + // interesting to share. We could use the name of the process as title: + // + // GetWindowThreadProcessId() + // OpenProcess() + // QueryFullProcessImageName() + return TRUE; + } + + // Skip the Program Manager window and the Start button. + TCHAR class_name_w[500]; + ::GetClassName(hwnd, class_name_w, 500); + std::string class_name = ToUtf8(class_name_w); + if (class_name == kProgramManagerClass || class_name == kButtonClass) { + // We don't want the Program Manager window nor the Start button. + return TRUE; + } + + TCHAR window_title[500]; + GetWindowText(hwnd, window_title, ARRAY_SIZE(window_title)); + std::string title = ToUtf8(window_title); + + WindowId id(hwnd); + WindowDescription desc(id, title); + descriptions->push_back(desc); + return TRUE; +} + +BOOL CALLBACK Win32WindowPicker::MonitorEnumProc(HMONITOR h_monitor, + HDC hdc_monitor, + LPRECT lprc_monitor, + LPARAM l_param) { + DesktopDescriptionList* desktop_desc = + reinterpret_cast<DesktopDescriptionList*>(l_param); + + DesktopId id(h_monitor, static_cast<int>(desktop_desc->size())); + // TODO: Figure out an appropriate desktop title. + DesktopDescription desc(id, ""); + + // Determine whether it's the primary monitor. + MONITORINFO monitor_info = {0}; + monitor_info.cbSize = sizeof(monitor_info); + bool primary = (GetMonitorInfo(h_monitor, &monitor_info) && + (monitor_info.dwFlags & MONITORINFOF_PRIMARY) != 0); + desc.set_primary(primary); + + desktop_desc->push_back(desc); + return TRUE; +} + +Win32WindowPicker::Win32WindowPicker() { +} + +bool Win32WindowPicker::Init() { + return true; +} +// TODO: Consider changing enumeration to clear() descriptions +// before append(). +bool Win32WindowPicker::GetWindowList(WindowDescriptionList* descriptions) { + LPARAM desc = reinterpret_cast<LPARAM>(descriptions); + return EnumWindows(Win32WindowPicker::EnumProc, desc) != FALSE; +} + +bool Win32WindowPicker::GetDesktopList(DesktopDescriptionList* descriptions) { + // Create a fresh WindowDescriptionList so that we can use desktop_desc.size() + // in MonitorEnumProc to compute the desktop index. + DesktopDescriptionList desktop_desc; + HDC hdc = GetDC(NULL); + bool success = false; + if (EnumDisplayMonitors(hdc, NULL, Win32WindowPicker::MonitorEnumProc, + reinterpret_cast<LPARAM>(&desktop_desc)) != FALSE) { + // Append the desktop descriptions to the end of the returned descriptions. + descriptions->insert(descriptions->end(), desktop_desc.begin(), + desktop_desc.end()); + success = true; + } + ReleaseDC(NULL, hdc); + return success; +} + +bool Win32WindowPicker::GetDesktopDimensions(const DesktopId& id, + int* width, + int* height) { + MONITORINFOEX monitor_info; + monitor_info.cbSize = sizeof(MONITORINFOEX); + if (!GetMonitorInfo(id.id(), &monitor_info)) { + return false; + } + *width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left; + *height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top; + return true; +} + +bool Win32WindowPicker::IsVisible(const WindowId& id) { + return (::IsWindow(id.id()) != FALSE && ::IsWindowVisible(id.id()) != FALSE); +} + +bool Win32WindowPicker::MoveToFront(const WindowId& id) { + return SetForegroundWindow(id.id()) != FALSE; +} + +} // namespace rtc |