Home | History | Annotate | Download | only in base
      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 
     15 namespace rtc {
     16 
     17 ///////////////////////////////////////////////////////////////////////////////
     18 // Win32Window
     19 ///////////////////////////////////////////////////////////////////////////////
     20 
     21 static const wchar_t kWindowBaseClassName[] = L"WindowBaseClass";
     22 HINSTANCE Win32Window::instance_ = NULL;
     23 ATOM Win32Window::window_class_ = 0;
     24 
     25 Win32Window::Win32Window() : wnd_(NULL) {
     26 }
     27 
     28 Win32Window::~Win32Window() {
     29   ASSERT(NULL == wnd_);
     30 }
     31 
     32 bool 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 
     66 void Win32Window::Destroy() {
     67   VERIFY(::DestroyWindow(wnd_) != FALSE);
     68 }
     69 
     70 void Win32Window::Shutdown() {
     71   if (window_class_) {
     72     ::UnregisterClass(MAKEINTATOM(window_class_), instance_);
     73     window_class_ = 0;
     74   }
     75 }
     76 
     77 bool 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 
     90 LRESULT 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