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