1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <windows.h>
6
7#include "base/bind.h"
8#include "base/callback.h"
9#include "base/compiler_specific.h"
10#include "base/location.h"
11#include "base/logging.h"
12#include "base/process/memory.h"
13#include "base/single_thread_task_runner.h"
14#include "base/strings/utf_string_conversions.h"
15#include "remoting/host/continue_window.h"
16#include "remoting/host/win/core_resource.h"
17
18namespace remoting {
19
20namespace {
21
22class ContinueWindowWin : public ContinueWindow {
23 public:
24  ContinueWindowWin();
25  virtual ~ContinueWindowWin();
26
27 protected:
28  // ContinueWindow overrides.
29  virtual void ShowUi() OVERRIDE;
30  virtual void HideUi() OVERRIDE;
31
32 private:
33  static BOOL CALLBACK DialogProc(HWND hwmd, UINT msg, WPARAM wParam,
34                                  LPARAM lParam);
35
36  BOOL OnDialogMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
37
38  void EndDialog();
39
40  HWND hwnd_;
41
42  DISALLOW_COPY_AND_ASSIGN(ContinueWindowWin);
43};
44
45ContinueWindowWin::ContinueWindowWin()
46    : hwnd_(NULL) {
47}
48
49ContinueWindowWin::~ContinueWindowWin() {
50  EndDialog();
51}
52
53void ContinueWindowWin::ShowUi() {
54  DCHECK(CalledOnValidThread());
55  DCHECK(!hwnd_);
56
57  HMODULE instance = base::GetModuleFromAddress(&DialogProc);
58  hwnd_ = CreateDialogParam(instance, MAKEINTRESOURCE(IDD_CONTINUE), NULL,
59                            (DLGPROC)DialogProc, (LPARAM)this);
60  if (!hwnd_) {
61    LOG(ERROR) << "Unable to create Disconnect dialog for remoting.";
62    return;
63  }
64
65  ShowWindow(hwnd_, SW_SHOW);
66}
67
68void ContinueWindowWin::HideUi() {
69  DCHECK(CalledOnValidThread());
70
71  EndDialog();
72}
73
74BOOL CALLBACK ContinueWindowWin::DialogProc(HWND hwnd, UINT msg,
75                                            WPARAM wParam, LPARAM lParam) {
76  ContinueWindowWin* win = NULL;
77  if (msg == WM_INITDIALOG) {
78    win = reinterpret_cast<ContinueWindowWin*>(lParam);
79    CHECK(win);
80    SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)win);
81  } else {
82    LONG_PTR lp = GetWindowLongPtr(hwnd, DWLP_USER);
83    win = reinterpret_cast<ContinueWindowWin*>(lp);
84  }
85  if (win == NULL)
86    return FALSE;
87  return win->OnDialogMessage(hwnd, msg, wParam, lParam);
88}
89
90BOOL ContinueWindowWin::OnDialogMessage(HWND hwnd, UINT msg,
91                                        WPARAM wParam, LPARAM lParam) {
92  DCHECK(CalledOnValidThread());
93
94  switch (msg) {
95    case WM_CLOSE:
96      // Ignore close messages.
97      return TRUE;
98    case WM_DESTROY:
99      // Ensure we don't try to use the HWND anymore.
100      hwnd_ = NULL;
101      return TRUE;
102    case WM_COMMAND:
103      switch (LOWORD(wParam)) {
104        case IDC_CONTINUE_DEFAULT:
105          ContinueSession();
106          ::EndDialog(hwnd, LOWORD(wParam));
107          hwnd_ = NULL;
108          return TRUE;
109        case IDC_CONTINUE_CANCEL:
110          DisconnectSession();
111          ::EndDialog(hwnd, LOWORD(wParam));
112          hwnd_ = NULL;
113          return TRUE;
114      }
115  }
116  return FALSE;
117}
118
119void ContinueWindowWin::EndDialog() {
120  DCHECK(CalledOnValidThread());
121
122  if (hwnd_) {
123    ::DestroyWindow(hwnd_);
124    hwnd_ = NULL;
125  }
126}
127
128}  // namespace
129
130// static
131scoped_ptr<HostWindow> HostWindow::CreateContinueWindow() {
132  return scoped_ptr<HostWindow>(new ContinueWindowWin());
133}
134
135}  // namespace remoting
136