blob: fc7b4c30997b3956530115e3233972a4f99a94a2 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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
Steve Anton10542f22019-01-11 09:11:00 -080011#include "rtc_base/win32_window.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020012#include "rtc_base/checks.h"
13#include "rtc_base/logging.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000014
15namespace rtc {
16
17///////////////////////////////////////////////////////////////////////////////
18// Win32Window
19///////////////////////////////////////////////////////////////////////////////
20
21static const wchar_t kWindowBaseClassName[] = L"WindowBaseClass";
deadbeef37f5ecf2017-02-27 14:06:41 -080022HINSTANCE Win32Window::instance_ = nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000023ATOM Win32Window::window_class_ = 0;
24
deadbeef37f5ecf2017-02-27 14:06:41 -080025Win32Window::Win32Window() : wnd_(nullptr) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000026
27Win32Window::~Win32Window() {
deadbeef37f5ecf2017-02-27 14:06:41 -080028 RTC_DCHECK(nullptr == wnd_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000029}
30
Yves Gerey665174f2018-06-19 15:03:05 +020031bool 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:26 +000039 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 15:03:05 +020046 GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000047 reinterpret_cast<LPCWSTR>(&Win32Window::WndProc),
48 &instance_)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010049 RTC_LOG_GLE(LS_ERROR) << "GetModuleHandleEx failed";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000050 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 11:09:25 +010062 RTC_LOG_GLE(LS_ERROR) << "RegisterClassEx failed";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000063 return false;
64 }
65 }
deadbeef37f5ecf2017-02-27 14:06:41 -080066 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:26 +000069}
70
71void Win32Window::Destroy() {
nissec16fa5e2017-02-07 07:18:43 -080072 const bool success = ::DestroyWindow(wnd_);
73 RTC_DCHECK(success);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000074}
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 15:03:05 +020083bool Win32Window::OnMessage(UINT uMsg,
84 WPARAM wParam,
85 LPARAM lParam,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000086 LRESULT& result) {
87 switch (uMsg) {
Yves Gerey665174f2018-06-19 15:03:05 +020088 case WM_CLOSE:
89 if (!OnClose()) {
90 result = 0;
91 return true;
92 }
93 break;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000094 }
95 return false;
96}
97
Steve Anton9de3aac2017-10-24 10:08:26 -070098bool 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:26 +0000112 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 11:09:25 +0100124 RTC_LOG(LS_INFO) << "Child window: " << static_cast<void*>(child);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000125 }
126 }
127 if (WM_NCDESTROY == uMsg) {
128 ::SetWindowLongPtr(hwnd, GWLP_USERDATA, NULL);
deadbeef37f5ecf2017-02-27 14:06:41 -0800129 that->wnd_ = nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000130 that->OnNcDestroy();
131 }
132 if (handled) {
133 return result;
134 }
135 }
136 return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
137}
138
139} // namespace rtc