1/* 2 * libjingle 3 * Copyright 2004--2005, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include "talk/base/common.h" 29#include "talk/base/logging.h" 30#include "talk/base/win32window.h" 31 32namespace talk_base { 33 34/////////////////////////////////////////////////////////////////////////////// 35// Win32Window 36/////////////////////////////////////////////////////////////////////////////// 37 38static const wchar_t kWindowBaseClassName[] = L"WindowBaseClass"; 39HINSTANCE Win32Window::instance_ = GetModuleHandle(NULL); 40ATOM Win32Window::window_class_ = 0; 41 42Win32Window::Win32Window() : wnd_(NULL) { 43} 44 45Win32Window::~Win32Window() { 46 ASSERT(NULL == wnd_); 47} 48 49bool Win32Window::Create(HWND parent, const wchar_t* title, DWORD style, 50 DWORD exstyle, int x, int y, int cx, int cy) { 51 if (wnd_) { 52 // Window already exists. 53 return false; 54 } 55 56 if (!window_class_) { 57 // Class not registered, register it. 58 WNDCLASSEX wcex; 59 memset(&wcex, 0, sizeof(wcex)); 60 wcex.cbSize = sizeof(wcex); 61 wcex.hInstance = instance_; 62 wcex.lpfnWndProc = &Win32Window::WndProc; 63 wcex.lpszClassName = kWindowBaseClassName; 64 window_class_ = ::RegisterClassEx(&wcex); 65 if (!window_class_) { 66 LOG_GLE(LS_ERROR) << "RegisterClassEx failed"; 67 return false; 68 } 69 } 70 wnd_ = ::CreateWindowEx(exstyle, kWindowBaseClassName, title, style, 71 x, y, cx, cy, parent, NULL, instance_, this); 72 return (NULL != wnd_); 73} 74 75void Win32Window::Destroy() { 76 VERIFY(::DestroyWindow(wnd_) != FALSE); 77} 78 79void Win32Window::SetInstance(HINSTANCE instance) { 80 instance_ = instance; 81} 82 83void Win32Window::Shutdown() { 84 if (window_class_) { 85 ::UnregisterClass(MAKEINTATOM(window_class_), instance_); 86 window_class_ = 0; 87 } 88} 89 90bool Win32Window::OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, 91 LRESULT& result) { 92 switch (uMsg) { 93 case WM_CLOSE: 94 if (!OnClose()) { 95 result = 0; 96 return true; 97 } 98 break; 99 } 100 return false; 101} 102 103LRESULT Win32Window::WndProc(HWND hwnd, UINT uMsg, 104 WPARAM wParam, LPARAM lParam) { 105 Win32Window* that = reinterpret_cast<Win32Window*>( 106 ::GetWindowLongPtr(hwnd, GWL_USERDATA)); 107 if (!that && (WM_CREATE == uMsg)) { 108 CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lParam); 109 that = static_cast<Win32Window*>(cs->lpCreateParams); 110 that->wnd_ = hwnd; 111 ::SetWindowLongPtr(hwnd, GWL_USERDATA, reinterpret_cast<LONG_PTR>(that)); 112 } 113 if (that) { 114 LRESULT result; 115 bool handled = that->OnMessage(uMsg, wParam, lParam, result); 116 if (WM_DESTROY == uMsg) { 117 for (HWND child = ::GetWindow(hwnd, GW_CHILD); child; 118 child = ::GetWindow(child, GW_HWNDNEXT)) { 119 LOG(LS_INFO) << "Child window: " << static_cast<void*>(child); 120 } 121 } 122 if (WM_NCDESTROY == uMsg) { 123 ::SetWindowLongPtr(hwnd, GWL_USERDATA, NULL); 124 that->wnd_ = NULL; 125 that->OnDestroyed(); 126 } 127 if (handled) { 128 return result; 129 } 130 } 131 return ::DefWindowProc(hwnd, uMsg, wParam, lParam); 132} 133 134} // namespace talk_base 135