1/* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include "webrtc/base/common.h" 12#include "webrtc/base/logging.h" 13#include "webrtc/base/win32window.h" 14 15namespace rtc { 16 17/////////////////////////////////////////////////////////////////////////////// 18// Win32Window 19/////////////////////////////////////////////////////////////////////////////// 20 21static const wchar_t kWindowBaseClassName[] = L"WindowBaseClass"; 22HINSTANCE Win32Window::instance_ = NULL; 23ATOM Win32Window::window_class_ = 0; 24 25Win32Window::Win32Window() : wnd_(NULL) { 26} 27 28Win32Window::~Win32Window() { 29 ASSERT(NULL == wnd_); 30} 31 32bool Win32Window::Create(HWND parent, const wchar_t* title, DWORD style, 33 DWORD exstyle, int x, int y, int cx, int cy) { 34 if (wnd_) { 35 // Window already exists. 36 return false; 37 } 38 39 if (!window_class_) { 40 if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 41 GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 42 reinterpret_cast<LPCWSTR>(&Win32Window::WndProc), 43 &instance_)) { 44 LOG_GLE(LS_ERROR) << "GetModuleHandleEx failed"; 45 return false; 46 } 47 48 // Class not registered, register it. 49 WNDCLASSEX wcex; 50 memset(&wcex, 0, sizeof(wcex)); 51 wcex.cbSize = sizeof(wcex); 52 wcex.hInstance = instance_; 53 wcex.lpfnWndProc = &Win32Window::WndProc; 54 wcex.lpszClassName = kWindowBaseClassName; 55 window_class_ = ::RegisterClassEx(&wcex); 56 if (!window_class_) { 57 LOG_GLE(LS_ERROR) << "RegisterClassEx failed"; 58 return false; 59 } 60 } 61 wnd_ = ::CreateWindowEx(exstyle, kWindowBaseClassName, title, style, 62 x, y, cx, cy, parent, NULL, instance_, this); 63 return (NULL != wnd_); 64} 65 66void Win32Window::Destroy() { 67 VERIFY(::DestroyWindow(wnd_) != FALSE); 68} 69 70void Win32Window::Shutdown() { 71 if (window_class_) { 72 ::UnregisterClass(MAKEINTATOM(window_class_), instance_); 73 window_class_ = 0; 74 } 75} 76 77bool Win32Window::OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, 78 LRESULT& result) { 79 switch (uMsg) { 80 case WM_CLOSE: 81 if (!OnClose()) { 82 result = 0; 83 return true; 84 } 85 break; 86 } 87 return false; 88} 89 90LRESULT Win32Window::WndProc(HWND hwnd, UINT uMsg, 91 WPARAM wParam, LPARAM lParam) { 92 Win32Window* that = reinterpret_cast<Win32Window*>( 93 ::GetWindowLongPtr(hwnd, GWLP_USERDATA)); 94 if (!that && (WM_CREATE == uMsg)) { 95 CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lParam); 96 that = static_cast<Win32Window*>(cs->lpCreateParams); 97 that->wnd_ = hwnd; 98 ::SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(that)); 99 } 100 if (that) { 101 LRESULT result; 102 bool handled = that->OnMessage(uMsg, wParam, lParam, result); 103 if (WM_DESTROY == uMsg) { 104 for (HWND child = ::GetWindow(hwnd, GW_CHILD); child; 105 child = ::GetWindow(child, GW_HWNDNEXT)) { 106 LOG(LS_INFO) << "Child window: " << static_cast<void*>(child); 107 } 108 } 109 if (WM_NCDESTROY == uMsg) { 110 ::SetWindowLongPtr(hwnd, GWLP_USERDATA, NULL); 111 that->wnd_ = NULL; 112 that->OnNcDestroy(); 113 } 114 if (handled) { 115 return result; 116 } 117 } 118 return ::DefWindowProc(hwnd, uMsg, wParam, lParam); 119} 120 121} // namespace rtc 122