blob: 4290894d266f7ae89c3a661c83383c4031e8330b [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:261/*
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
Mirko Bonadei92ea95e2017-09-15 04:47:3111#include "rtc_base/win32window.h"
12#include "rtc_base/checks.h"
13#include "rtc_base/logging.h"
henrike@webrtc.orgf0488722014-05-13 18:00:2614
15namespace rtc {
16
17///////////////////////////////////////////////////////////////////////////////
18// Win32Window
19///////////////////////////////////////////////////////////////////////////////
20
21static const wchar_t kWindowBaseClassName[] = L"WindowBaseClass";
deadbeef37f5ecf2017-02-27 22:06:4122HINSTANCE Win32Window::instance_ = nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:2623ATOM Win32Window::window_class_ = 0;
24
deadbeef37f5ecf2017-02-27 22:06:4125Win32Window::Win32Window() : wnd_(nullptr) {}
henrike@webrtc.orgf0488722014-05-13 18:00:2626
27Win32Window::~Win32Window() {
deadbeef37f5ecf2017-02-27 22:06:4128 RTC_DCHECK(nullptr == wnd_);
henrike@webrtc.orgf0488722014-05-13 18:00:2629}
30
Yves Gerey665174f2018-06-19 13:03:0531bool Win32Window::Create(HWND parent,
32 const wchar_t* title,
33 DWORD style,
34 DWORD exstyle,
35 int x,
36 int y,
37 int cx,
38 int cy) {
henrike@webrtc.orgf0488722014-05-13 18:00:2639 if (wnd_) {
40 // Window already exists.
41 return false;
42 }
43
44 if (!window_class_) {
45 if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
Yves Gerey665174f2018-06-19 13:03:0546 GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
henrike@webrtc.orgf0488722014-05-13 18:00:2647 reinterpret_cast<LPCWSTR>(&Win32Window::WndProc),
48 &instance_)) {
Mirko Bonadei675513b2017-11-09 10:09:2549 RTC_LOG_GLE(LS_ERROR) << "GetModuleHandleEx failed";
henrike@webrtc.orgf0488722014-05-13 18:00:2650 return false;
51 }
52
53 // Class not registered, register it.
54 WNDCLASSEX wcex;
55 memset(&wcex, 0, sizeof(wcex));
56 wcex.cbSize = sizeof(wcex);
57 wcex.hInstance = instance_;
58 wcex.lpfnWndProc = &Win32Window::WndProc;
59 wcex.lpszClassName = kWindowBaseClassName;
60 window_class_ = ::RegisterClassEx(&wcex);
61 if (!window_class_) {
Mirko Bonadei675513b2017-11-09 10:09:2562 RTC_LOG_GLE(LS_ERROR) << "RegisterClassEx failed";
henrike@webrtc.orgf0488722014-05-13 18:00:2663 return false;
64 }
65 }
deadbeef37f5ecf2017-02-27 22:06:4166 wnd_ = ::CreateWindowEx(exstyle, kWindowBaseClassName, title, style, x, y, cx,
67 cy, parent, nullptr, instance_, this);
68 return (nullptr != wnd_);
henrike@webrtc.orgf0488722014-05-13 18:00:2669}
70
71void Win32Window::Destroy() {
nissec16fa5e2017-02-07 15:18:4372 const bool success = ::DestroyWindow(wnd_);
73 RTC_DCHECK(success);
henrike@webrtc.orgf0488722014-05-13 18:00:2674}
75
76void Win32Window::Shutdown() {
77 if (window_class_) {
78 ::UnregisterClass(MAKEINTATOM(window_class_), instance_);
79 window_class_ = 0;
80 }
81}
82
Yves Gerey665174f2018-06-19 13:03:0583bool Win32Window::OnMessage(UINT uMsg,
84 WPARAM wParam,
85 LPARAM lParam,
henrike@webrtc.orgf0488722014-05-13 18:00:2686 LRESULT& result) {
87 switch (uMsg) {
Yves Gerey665174f2018-06-19 13:03:0588 case WM_CLOSE:
89 if (!OnClose()) {
90 result = 0;
91 return true;
92 }
93 break;
henrike@webrtc.orgf0488722014-05-13 18:00:2694 }
95 return false;
96}
97
Steve Anton9de3aac2017-10-24 17:08:2698bool Win32Window::OnClose() {
99 return true;
100}
101
102void Win32Window::OnNcDestroy() {
103 // Do nothing. }
104}
105
106LRESULT Win32Window::WndProc(HWND hwnd,
107 UINT uMsg,
108 WPARAM wParam,
109 LPARAM lParam) {
110 Win32Window* that =
111 reinterpret_cast<Win32Window*>(::GetWindowLongPtr(hwnd, GWLP_USERDATA));
henrike@webrtc.orgf0488722014-05-13 18:00:26112 if (!that && (WM_CREATE == uMsg)) {
113 CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lParam);
114 that = static_cast<Win32Window*>(cs->lpCreateParams);
115 that->wnd_ = hwnd;
116 ::SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(that));
117 }
118 if (that) {
119 LRESULT result;
120 bool handled = that->OnMessage(uMsg, wParam, lParam, result);
121 if (WM_DESTROY == uMsg) {
122 for (HWND child = ::GetWindow(hwnd, GW_CHILD); child;
123 child = ::GetWindow(child, GW_HWNDNEXT)) {
Mirko Bonadei675513b2017-11-09 10:09:25124 RTC_LOG(LS_INFO) << "Child window: " << static_cast<void*>(child);
henrike@webrtc.orgf0488722014-05-13 18:00:26125 }
126 }
127 if (WM_NCDESTROY == uMsg) {
128 ::SetWindowLongPtr(hwnd, GWLP_USERDATA, NULL);
deadbeef37f5ecf2017-02-27 22:06:41129 that->wnd_ = nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26130 that->OnNcDestroy();
131 }
132 if (handled) {
133 return result;
134 }
135 }
136 return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
137}
138
139} // namespace rtc