mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-16 20:20:51 +01:00
- cefclient: Windows: Introduce RootWindow concept and associated window/client object hierarchy (issue #1500).
- cefclient: Remove locking from ClientHandlerShared that was only required for the Windows implementation (issue #1500). - Add CefDeleteOnThread helper for deleting ref-counted types on a named CEF thread. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2001 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
bcab7e0ebd
commit
fd5ededb27
@ -156,8 +156,6 @@
|
||||
'tests/cefclient/client_app_delegates.cc',
|
||||
'tests/cefclient/client_handler.cc',
|
||||
'tests/cefclient/client_handler.h',
|
||||
'tests/cefclient/client_handler_shared.cc',
|
||||
'tests/cefclient/client_handler_shared.h',
|
||||
'tests/cefclient/client_renderer.cc',
|
||||
'tests/cefclient/client_renderer.h',
|
||||
'tests/cefclient/client_switches.cc',
|
||||
@ -189,27 +187,47 @@
|
||||
'<@(cefclient_bundle_resources_common)',
|
||||
],
|
||||
'cefclient_sources_win': [
|
||||
'tests/cefclient/browser_window_osr_win.cc',
|
||||
'tests/cefclient/browser_window_osr_win.h',
|
||||
'tests/cefclient/browser_window_std_win.cc',
|
||||
'tests/cefclient/browser_window_std_win.h',
|
||||
'tests/cefclient/browser_window_win.cc',
|
||||
'tests/cefclient/browser_window_win.h',
|
||||
'tests/cefclient/cefclient.exe.manifest',
|
||||
'tests/cefclient/cefclient.rc',
|
||||
'tests/cefclient/cefclient_win.cc',
|
||||
'tests/cefclient/client_handler_shared_win.cc',
|
||||
'tests/cefclient/client_handler_osr.cc',
|
||||
'tests/cefclient/client_handler_osr.h',
|
||||
'tests/cefclient/client_handler_single.cc',
|
||||
'tests/cefclient/client_handler_single.h',
|
||||
'tests/cefclient/client_handler_std.cc',
|
||||
'tests/cefclient/client_handler_std.h',
|
||||
'tests/cefclient/main_context_impl_win.cc',
|
||||
'tests/cefclient/main_message_loop_multithreaded_win.h',
|
||||
'tests/cefclient/main_message_loop_multithreaded_win.cc',
|
||||
'tests/cefclient/osr_dragdrop_win.h',
|
||||
'tests/cefclient/main_message_loop_multithreaded_win.h',
|
||||
'tests/cefclient/osr_dragdrop_win.cc',
|
||||
'tests/cefclient/osr_widget_win.h',
|
||||
'tests/cefclient/osr_widget_win.cc',
|
||||
'tests/cefclient/osr_dragdrop_win.h',
|
||||
'tests/cefclient/osr_window_win.cc',
|
||||
'tests/cefclient/osr_window_win.h',
|
||||
'tests/cefclient/resource.h',
|
||||
'tests/cefclient/res/cefclient.ico',
|
||||
'tests/cefclient/res/small.ico',
|
||||
'tests/cefclient/resource_util_win.cc',
|
||||
'tests/cefclient/util_win.h',
|
||||
'tests/cefclient/root_window.h',
|
||||
'tests/cefclient/root_window_manager.cc',
|
||||
'tests/cefclient/root_window_manager.h',
|
||||
'tests/cefclient/root_window_win.cc',
|
||||
'tests/cefclient/root_window_win.h',
|
||||
'tests/cefclient/temp_window_win.cc',
|
||||
'tests/cefclient/temp_window_win.h',
|
||||
'tests/cefclient/util_win.cc',
|
||||
'tests/cefclient/util_win.h',
|
||||
'tests/cefclient/window_test_win.cc',
|
||||
],
|
||||
'cefclient_sources_mac': [
|
||||
'tests/cefclient/cefclient_mac.mm',
|
||||
'tests/cefclient/client_handler_shared.cc',
|
||||
'tests/cefclient/client_handler_shared.h',
|
||||
'tests/cefclient/client_handler_shared_mac.mm',
|
||||
'tests/cefclient/main_context_impl_posix.cc',
|
||||
'tests/cefclient/osr_widget_mac.h',
|
||||
@ -261,6 +279,8 @@
|
||||
],
|
||||
'cefclient_sources_linux': [
|
||||
'tests/cefclient/cefclient_gtk.cc',
|
||||
'tests/cefclient/client_handler_shared.cc',
|
||||
'tests/cefclient/client_handler_shared.h',
|
||||
'tests/cefclient/client_handler_shared_gtk.cc',
|
||||
'tests/cefclient/dialog_handler_gtk.cc',
|
||||
'tests/cefclient/dialog_handler_gtk.h',
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/base/cef_logging.h"
|
||||
#include "include/base/cef_macros.h"
|
||||
#include "include/cef_task.h"
|
||||
@ -50,6 +51,46 @@
|
||||
#define CEF_REQUIRE_FILE_THREAD() DCHECK(CefCurrentlyOn(TID_FILE));
|
||||
#define CEF_REQUIRE_RENDERER_THREAD() DCHECK(CefCurrentlyOn(TID_RENDERER));
|
||||
|
||||
|
||||
// Use this struct in conjuction with refcounted types to ensure that an
|
||||
// object is deleted on the specified thread. For example:
|
||||
//
|
||||
// class Foo : public base::RefCountedThreadSafe<Foo, CefDeleteOnUIThread> {
|
||||
// public:
|
||||
// Foo();
|
||||
// void DoSomething();
|
||||
//
|
||||
// private:
|
||||
// // Allow deletion via scoped_refptr only.
|
||||
// friend struct CefDeleteOnThread<TID_UI>;
|
||||
// friend class base::RefCountedThreadSafe<Foo, CefDeleteOnUIThread>;
|
||||
//
|
||||
// virtual ~Foo() {}
|
||||
// };
|
||||
//
|
||||
// base::scoped_refptr<Foo> foo = new Foo();
|
||||
// foo->DoSomething();
|
||||
// foo = NULL; // Deletion of |foo| will occur on the UI thread.
|
||||
//
|
||||
template<CefThreadId thread>
|
||||
struct CefDeleteOnThread {
|
||||
template<typename T>
|
||||
static void Destruct(const T* x) {
|
||||
if (CefCurrentlyOn(thread)) {
|
||||
delete x;
|
||||
} else {
|
||||
CefPostTask(thread,
|
||||
base::Bind(&CefDeleteOnThread<thread>::Destruct<T>, x));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct CefDeleteOnUIThread : public CefDeleteOnThread<TID_UI> { };
|
||||
struct CefDeleteOnIOThread : public CefDeleteOnThread<TID_IO> { };
|
||||
struct CefDeleteOnFileThread : public CefDeleteOnThread<TID_FILE> { };
|
||||
struct CefDeleteOnRendererThread : public CefDeleteOnThread<TID_RENDERER> { };
|
||||
|
||||
|
||||
///
|
||||
// Helper class to manage a scoped copy of |argv|.
|
||||
///
|
||||
|
92
tests/cefclient/browser_window_osr_win.cc
Normal file
92
tests/cefclient/browser_window_osr_win.cc
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/browser_window_osr_win.h"
|
||||
|
||||
#include "cefclient/main_message_loop.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
BrowserWindowOsrWin::BrowserWindowOsrWin(BrowserWindowWin::Delegate* delegate,
|
||||
const std::string& startup_url,
|
||||
bool transparent,
|
||||
bool show_update_rect)
|
||||
: BrowserWindowWin(delegate),
|
||||
transparent_(transparent),
|
||||
osr_hwnd_(NULL) {
|
||||
osr_window_ = new OsrWindowWin(this, transparent, show_update_rect);
|
||||
client_handler_ = new ClientHandlerOsr(this, osr_window_.get(), startup_url);
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::CreateBrowser(HWND parent_hwnd,
|
||||
const RECT& rect,
|
||||
const CefBrowserSettings& settings) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Create the new browser and native window on the UI thread.
|
||||
osr_window_->CreateBrowser(parent_hwnd, rect, client_handler_, settings,
|
||||
client_handler_->startup_url());
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::GetPopupConfig(HWND temp_hwnd,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) {
|
||||
// Note: This method may be called on any thread.
|
||||
windowInfo.SetAsWindowless(temp_hwnd, transparent_);
|
||||
client = client_handler_;
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::ShowPopup(HWND parent_hwnd,
|
||||
int x, int y, size_t width, size_t height) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
if (osr_window_)
|
||||
osr_window_->ShowPopup(parent_hwnd, x, y, width, height);
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::Show() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
if (osr_window_)
|
||||
osr_window_->Show();
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::Hide() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
if (osr_window_)
|
||||
osr_window_->Hide();
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::SetBounds(int x, int y, size_t width, size_t height) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
if (osr_window_)
|
||||
osr_window_->SetBounds(x, y, width, height);
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::SetFocus() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
if (osr_window_)
|
||||
osr_window_->SetFocus();
|
||||
}
|
||||
|
||||
HWND BrowserWindowOsrWin::GetHWND() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
return osr_hwnd_;
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::OnBrowserClosed(CefRefPtr<CefBrowser> browser) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Release the OSR window reference. It will be deleted on the UI thread.
|
||||
osr_window_ = NULL;
|
||||
|
||||
BrowserWindowWin::OnBrowserClosed(browser);
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::OnOsrNativeWindowCreated(HWND hwnd) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
DCHECK(!osr_hwnd_);
|
||||
osr_hwnd_ = hwnd;
|
||||
}
|
||||
|
||||
} // namespace client
|
60
tests/cefclient/browser_window_osr_win.h
Normal file
60
tests/cefclient/browser_window_osr_win.h
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_OSR_WIN_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_OSR_WIN_H_
|
||||
|
||||
#include "cefclient/browser_window_win.h"
|
||||
#include "cefclient/osr_window_win.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Represents a native child window hosting a single off-screen browser
|
||||
// instance. The methods of this class must be called on the main thread unless
|
||||
// otherwise indicated.
|
||||
class BrowserWindowOsrWin : public BrowserWindowWin,
|
||||
OsrWindowWin::Delegate {
|
||||
public:
|
||||
// Constructor may be called on any thread.
|
||||
// |delegate| must outlive this object.
|
||||
BrowserWindowOsrWin(BrowserWindowWin::Delegate* delegate,
|
||||
const std::string& startup_url,
|
||||
bool transparent,
|
||||
bool show_update_rect);
|
||||
|
||||
// BrowserWindowWin methods.
|
||||
void CreateBrowser(HWND parent_hwnd,
|
||||
const RECT& rect,
|
||||
const CefBrowserSettings& settings) OVERRIDE;
|
||||
void GetPopupConfig(HWND temp_hwnd,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) OVERRIDE;
|
||||
void ShowPopup(HWND parent_hwnd,
|
||||
int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void Show() OVERRIDE;
|
||||
void Hide() OVERRIDE;
|
||||
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void SetFocus() OVERRIDE;
|
||||
HWND GetHWND() const OVERRIDE;
|
||||
|
||||
private:
|
||||
// ClientHandler::Delegate methods.
|
||||
void OnBrowserClosed(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
|
||||
// OsrWindowWin::Delegate methods.
|
||||
void OnOsrNativeWindowCreated(HWND hwnd) OVERRIDE;
|
||||
|
||||
const bool transparent_;
|
||||
|
||||
// The below members are only accessed on the main thread.
|
||||
scoped_refptr<OsrWindowWin> osr_window_;
|
||||
HWND osr_hwnd_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BrowserWindowOsrWin);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_OSR_WIN_H_
|
101
tests/cefclient/browser_window_std_win.cc
Normal file
101
tests/cefclient/browser_window_std_win.cc
Normal file
@ -0,0 +1,101 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/browser_window_std_win.h"
|
||||
|
||||
#include "cefclient/client_handler_std.h"
|
||||
#include "cefclient/main_message_loop.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
BrowserWindowStdWin::BrowserWindowStdWin(Delegate* delegate,
|
||||
const std::string& startup_url)
|
||||
: BrowserWindowWin(delegate) {
|
||||
client_handler_ = new ClientHandlerStd(this, startup_url);
|
||||
}
|
||||
|
||||
void BrowserWindowStdWin::CreateBrowser(HWND parent_hwnd,
|
||||
const RECT& rect,
|
||||
const CefBrowserSettings& settings) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
CefWindowInfo window_info;
|
||||
window_info.SetAsChild(parent_hwnd, rect);
|
||||
|
||||
CefBrowserHost::CreateBrowser(window_info, client_handler_,
|
||||
client_handler_->startup_url(),
|
||||
settings, NULL);
|
||||
}
|
||||
|
||||
void BrowserWindowStdWin::GetPopupConfig(HWND temp_hwnd,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) {
|
||||
// Note: This method may be called on any thread.
|
||||
// The window will be properly sized after the browser is created.
|
||||
windowInfo.SetAsChild(temp_hwnd, RECT());
|
||||
client = client_handler_;
|
||||
}
|
||||
|
||||
void BrowserWindowStdWin::ShowPopup(HWND parent_hwnd,
|
||||
int x, int y, size_t width, size_t height) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
HWND hwnd = GetHWND();
|
||||
if (hwnd) {
|
||||
SetParent(hwnd, parent_hwnd);
|
||||
SetWindowPos(hwnd, NULL, x, y, width, height, SWP_NOZORDER);
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindowStdWin::Show() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
HWND hwnd = GetHWND();
|
||||
if (hwnd && !::IsWindowVisible(hwnd))
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
}
|
||||
|
||||
void BrowserWindowStdWin::Hide() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
HWND hwnd = GetHWND();
|
||||
if (hwnd) {
|
||||
// When the frame window is minimized set the browser window size to 0x0 to
|
||||
// reduce resource usage.
|
||||
SetWindowPos(hwnd, NULL,
|
||||
0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindowStdWin::SetBounds(int x, int y, size_t width, size_t height) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
HWND hwnd = GetHWND();
|
||||
if (hwnd) {
|
||||
// Set the browser window bounds.
|
||||
SetWindowPos(hwnd, NULL, x, y, width, height, SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindowStdWin::SetFocus() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (browser_) {
|
||||
// Give focus to the browser window.
|
||||
browser_->GetHost()->SetFocus(true);
|
||||
}
|
||||
}
|
||||
|
||||
HWND BrowserWindowStdWin::GetHWND() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (browser_)
|
||||
return browser_->GetHost()->GetWindowHandle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
} // namespace client
|
44
tests/cefclient/browser_window_std_win.h
Normal file
44
tests/cefclient/browser_window_std_win.h
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_STD_WIN_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_STD_WIN_H_
|
||||
|
||||
#include "cefclient/browser_window_win.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Represents a native child window hosting a single windowed browser instance.
|
||||
// The methods of this class must be called on the main thread unless otherwise
|
||||
// indicated.
|
||||
class BrowserWindowStdWin : public BrowserWindowWin {
|
||||
public:
|
||||
// Constructor may be called on any thread.
|
||||
// |delegate| must outlive this object.
|
||||
BrowserWindowStdWin(Delegate* delegate,
|
||||
const std::string& startup_url);
|
||||
|
||||
// BrowserWindowWin methods.
|
||||
void CreateBrowser(HWND parent_hwnd,
|
||||
const RECT& rect,
|
||||
const CefBrowserSettings& settings) OVERRIDE;
|
||||
void GetPopupConfig(HWND temp_hwnd,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) OVERRIDE;
|
||||
void ShowPopup(HWND parent_hwnd,
|
||||
int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void Show() OVERRIDE;
|
||||
void Hide() OVERRIDE;
|
||||
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void SetFocus() OVERRIDE;
|
||||
HWND GetHWND() const OVERRIDE;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(BrowserWindowStdWin);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_STD_WIN_H_
|
71
tests/cefclient/browser_window_win.cc
Normal file
71
tests/cefclient/browser_window_win.cc
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/browser_window_win.h"
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "cefclient/main_message_loop.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
BrowserWindowWin::BrowserWindowWin(Delegate* delegate)
|
||||
: delegate_(delegate),
|
||||
is_closing_(false) {
|
||||
DCHECK(delegate_);
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowser> BrowserWindowWin::GetBrowser() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
return browser_;
|
||||
}
|
||||
|
||||
bool BrowserWindowWin::IsClosing() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
return is_closing_;
|
||||
}
|
||||
|
||||
void BrowserWindowWin::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
DCHECK(!browser_);
|
||||
browser_ = browser;
|
||||
|
||||
delegate_->OnBrowserCreated(browser);
|
||||
}
|
||||
|
||||
void BrowserWindowWin::OnBrowserClosing(CefRefPtr<CefBrowser> browser) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
DCHECK_EQ(browser->GetIdentifier(), browser_->GetIdentifier());
|
||||
is_closing_ = true;
|
||||
}
|
||||
|
||||
void BrowserWindowWin::OnBrowserClosed(CefRefPtr<CefBrowser> browser) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
DCHECK_EQ(browser->GetIdentifier(), browser_->GetIdentifier());
|
||||
browser_ = NULL;
|
||||
|
||||
client_handler_->DetachDelegate();
|
||||
client_handler_ = NULL;
|
||||
|
||||
// |this| may be deleted.
|
||||
delegate_->OnBrowserWindowDestroyed();
|
||||
}
|
||||
|
||||
void BrowserWindowWin::OnSetAddress(const std::string& url) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
delegate_->OnSetAddress(url);
|
||||
}
|
||||
|
||||
void BrowserWindowWin::OnSetTitle(const std::string& title) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
delegate_->OnSetTitle(title);
|
||||
}
|
||||
|
||||
void BrowserWindowWin::OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
delegate_->OnSetLoadingState(isLoading, canGoBack, canGoForward);
|
||||
}
|
||||
|
||||
} // namespace client
|
112
tests/cefclient/browser_window_win.h
Normal file
112
tests/cefclient/browser_window_win.h
Normal file
@ -0,0 +1,112 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_WIN_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_WIN_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "include/base/cef_scoped_ptr.h"
|
||||
#include "include/cef_browser.h"
|
||||
#include "cefclient/client_handler_single.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Represents a native child window hosting a single browser instance. The
|
||||
// methods of this class must be called on the main thread unless otherwise
|
||||
// indicated.
|
||||
class BrowserWindowWin : public ClientHandlerSingle::Delegate {
|
||||
public:
|
||||
// This interface is implemented by the owner of the BrowserWindowWin. The
|
||||
// methods of this class will be called on the main thread.
|
||||
class Delegate {
|
||||
public:
|
||||
// Called when the browser has been created.
|
||||
virtual void OnBrowserCreated(CefRefPtr<CefBrowser> browser) = 0;
|
||||
|
||||
// Called when the BrowserWindowWin has been destroyed.
|
||||
virtual void OnBrowserWindowDestroyed() = 0;
|
||||
|
||||
// Set the window URL address.
|
||||
virtual void OnSetAddress(const std::string& url) = 0;
|
||||
|
||||
// Set the window title.
|
||||
virtual void OnSetTitle(const std::string& title) = 0;
|
||||
|
||||
// Set the loading state.
|
||||
virtual void OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Delegate() {}
|
||||
};
|
||||
|
||||
// Create a new browser and native window.
|
||||
virtual void CreateBrowser(HWND parent_hwnd,
|
||||
const RECT& rect,
|
||||
const CefBrowserSettings& settings) = 0;
|
||||
|
||||
// Retrieve the configuration that will be used when creating a popup window.
|
||||
// The native window will be created later after the browser has been created.
|
||||
// This method may be called on any thread.
|
||||
virtual void GetPopupConfig(HWND temp_hwnd,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) = 0;
|
||||
|
||||
// Show the popup window with correct parent and bounds in parent coordinates.
|
||||
virtual void ShowPopup(HWND parent_hwnd,
|
||||
int x, int y, size_t width, size_t height) = 0;
|
||||
|
||||
// Show the window.
|
||||
virtual void Show() = 0;
|
||||
|
||||
// Hide the window.
|
||||
virtual void Hide() = 0;
|
||||
|
||||
// Set the window bounds in parent coordinates.
|
||||
virtual void SetBounds(int x, int y, size_t width, size_t height) = 0;
|
||||
|
||||
// Set focus to the window.
|
||||
virtual void SetFocus() = 0;
|
||||
|
||||
// Returns the window handle.
|
||||
virtual HWND GetHWND() const = 0;
|
||||
|
||||
// Returns the browser owned by the window.
|
||||
CefRefPtr<CefBrowser> GetBrowser() const;
|
||||
|
||||
// Returns true if the browser is closing.
|
||||
bool IsClosing() const;
|
||||
|
||||
protected:
|
||||
// Allow deletion via scoped_ptr only.
|
||||
friend struct base::DefaultDeleter<BrowserWindowWin>;
|
||||
|
||||
// Constructor may be called on any thread.
|
||||
// |root_window| and |delegate| must outlive this object.
|
||||
explicit BrowserWindowWin(Delegate* delegate);
|
||||
|
||||
// ClientHandlerSingle::Delegate methods.
|
||||
void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
void OnBrowserClosing(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
void OnBrowserClosed(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
void OnSetAddress(const std::string& url) OVERRIDE;
|
||||
void OnSetTitle(const std::string& title) OVERRIDE;
|
||||
void OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) OVERRIDE;
|
||||
|
||||
Delegate* delegate_;
|
||||
CefRefPtr<CefBrowser> browser_;
|
||||
CefRefPtr<ClientHandlerSingle> client_handler_;
|
||||
bool is_closing_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BrowserWindowWin);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_WIN_H_
|
@ -1,32 +1,17 @@
|
||||
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include <windows.h>
|
||||
#include <commdlg.h>
|
||||
#include <shellapi.h>
|
||||
#include <direct.h>
|
||||
#include <shlobj.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/cef_app.h"
|
||||
#include "include/cef_browser.h"
|
||||
#include "include/cef_frame.h"
|
||||
#include "include/base/cef_scoped_ptr.h"
|
||||
#include "include/cef_sandbox_win.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "cefclient/client_app.h"
|
||||
#include "cefclient/client_handler_shared.h"
|
||||
#include "cefclient/client_switches.h"
|
||||
#include "cefclient/main_context_impl.h"
|
||||
#include "cefclient/main_message_loop_multithreaded_win.h"
|
||||
#include "cefclient/main_message_loop_std.h"
|
||||
#include "cefclient/osr_widget_win.h"
|
||||
#include "cefclient/resource.h"
|
||||
#include "cefclient/root_window_manager.h"
|
||||
#include "cefclient/test_runner.h"
|
||||
#include "cefclient/util_win.h"
|
||||
|
||||
|
||||
// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
|
||||
// automatically if using the required compiler version. Pass -DUSE_SANDBOX=OFF
|
||||
@ -43,40 +28,6 @@
|
||||
namespace client {
|
||||
namespace {
|
||||
|
||||
#define MAX_LOADSTRING 100
|
||||
#define MAX_URL_LENGTH 255
|
||||
#define BUTTON_WIDTH 72
|
||||
#define URLBAR_HEIGHT 24
|
||||
|
||||
// Global Variables:
|
||||
HINSTANCE hInst; // current instance
|
||||
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
|
||||
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
|
||||
TCHAR szOSRWindowClass[MAX_LOADSTRING]; // the OSR window class name
|
||||
UINT uFindMsg; // Message identifier for find events.
|
||||
HWND hFindDlg = NULL; // Handle for the find dialog.
|
||||
|
||||
// Forward declarations of functions included in this code module.
|
||||
ATOM RegisterMainClass(HINSTANCE hInstance);
|
||||
BOOL CreateMainWindow(HINSTANCE, int);
|
||||
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
LRESULT CALLBACK FindWndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
INT_PTR CALLBACK AboutWndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
// The global ClientHandlerShared reference.
|
||||
CefRefPtr<ClientHandlerShared> g_handler;
|
||||
|
||||
// Used by off-screen rendering to find the associated CefBrowser.
|
||||
class MainBrowserProvider : public OSRBrowserProvider {
|
||||
virtual CefRefPtr<CefBrowser> GetBrowser() {
|
||||
if (g_handler.get())
|
||||
return g_handler->GetBrowser();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
} g_main_browser_provider;
|
||||
|
||||
|
||||
int RunMain(HINSTANCE hInstance, int nCmdShow) {
|
||||
void* sandbox_info = NULL;
|
||||
|
||||
@ -96,7 +47,7 @@ int RunMain(HINSTANCE hInstance, int nCmdShow) {
|
||||
return exit_code;
|
||||
|
||||
// Create the main context object.
|
||||
scoped_ptr<MainContextImpl> context(new MainContextImpl(0, NULL));
|
||||
scoped_ptr<MainContextImpl> context(new MainContextImpl(0, NULL, true));
|
||||
|
||||
CefSettings settings;
|
||||
|
||||
@ -120,20 +71,15 @@ int RunMain(HINSTANCE hInstance, int nCmdShow) {
|
||||
// Register scheme handlers.
|
||||
test_runner::RegisterSchemeHandlers();
|
||||
|
||||
// Initialize global strings
|
||||
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
|
||||
LoadString(hInstance, IDC_CEFCLIENT, szWindowClass, MAX_LOADSTRING);
|
||||
LoadString(hInstance, IDS_OSR_WIDGET_CLASS, szOSRWindowClass, MAX_LOADSTRING);
|
||||
RegisterMainClass(hInstance);
|
||||
// Create the first window.
|
||||
context->GetRootWindowManager()->CreateRootWindow(
|
||||
true, // Show controls.
|
||||
settings.windowless_rendering_enabled ? true : false,
|
||||
CefRect(), // Use default system size.
|
||||
std::string()); // Use default URL.
|
||||
|
||||
// Perform application initialization
|
||||
if (!CreateMainWindow(hInstance, nCmdShow))
|
||||
return FALSE;
|
||||
|
||||
// Register the find event message.
|
||||
uFindMsg = RegisterWindowMessage(FINDMSGSTRING);
|
||||
|
||||
// Run the message loop. This will block until Quit() is called.
|
||||
// Run the message loop. This will block until Quit() is called by the
|
||||
// RootWindowManager after all windows have been destroyed.
|
||||
int result = message_loop->Run();
|
||||
|
||||
// Shut down CEF.
|
||||
@ -146,462 +92,6 @@ int RunMain(HINSTANCE hInstance, int nCmdShow) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Register the main window class.
|
||||
ATOM RegisterMainClass(HINSTANCE hInstance) {
|
||||
WNDCLASSEX wcex;
|
||||
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = MainWndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = hInstance;
|
||||
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CEFCLIENT));
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
||||
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_CEFCLIENT);
|
||||
wcex.lpszClassName = szWindowClass;
|
||||
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
|
||||
|
||||
return RegisterClassEx(&wcex);
|
||||
}
|
||||
|
||||
// Create and show the main window.
|
||||
BOOL CreateMainWindow(HINSTANCE hInstance, int nCmdShow) {
|
||||
HWND hWnd;
|
||||
|
||||
hInst = hInstance; // Store instance handle in our global variable
|
||||
|
||||
hWnd = CreateWindow(szWindowClass, szTitle,
|
||||
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, 0,
|
||||
CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
|
||||
|
||||
if (!hWnd)
|
||||
return FALSE;
|
||||
|
||||
ShowWindow(hWnd, nCmdShow);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Set focus to |browser| on the UI thread.
|
||||
static void SetFocusToBrowser(CefRefPtr<CefBrowser> browser) {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
// Execute on the UI thread.
|
||||
CefPostTask(TID_UI, base::Bind(&SetFocusToBrowser, browser));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_handler)
|
||||
return;
|
||||
|
||||
if (g_handler->is_osr()) {
|
||||
// Give focus to the OSR window.
|
||||
CefRefPtr<OSRWindow> osr_window =
|
||||
OSRWindow::From(g_handler->GetOSRHandler());
|
||||
if (osr_window)
|
||||
::SetFocus(osr_window->hwnd());
|
||||
} else {
|
||||
// Give focus to the browser.
|
||||
browser->GetHost()->SetFocus(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Window procedure for the main window.
|
||||
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam,
|
||||
LPARAM lParam) {
|
||||
static HWND backWnd = NULL, forwardWnd = NULL, reloadWnd = NULL,
|
||||
stopWnd = NULL, editWnd = NULL;
|
||||
static WNDPROC editWndOldProc = NULL;
|
||||
|
||||
// Static members used for the find dialog.
|
||||
static FINDREPLACE fr;
|
||||
static WCHAR szFindWhat[80] = {0};
|
||||
static WCHAR szLastFindWhat[80] = {0};
|
||||
static bool findNext = false;
|
||||
static bool lastMatchCase = false;
|
||||
|
||||
int wmId, wmEvent;
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc;
|
||||
|
||||
if (hWnd == editWnd) {
|
||||
// Callback for the edit window
|
||||
switch (message) {
|
||||
case WM_CHAR:
|
||||
if (wParam == VK_RETURN && g_handler.get()) {
|
||||
// When the user hits the enter key load the URL
|
||||
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
|
||||
wchar_t strPtr[MAX_URL_LENGTH+1] = {0};
|
||||
*((LPWORD)strPtr) = MAX_URL_LENGTH;
|
||||
LRESULT strLen = SendMessage(hWnd, EM_GETLINE, 0, (LPARAM)strPtr);
|
||||
if (strLen > 0) {
|
||||
strPtr[strLen] = 0;
|
||||
browser->GetMainFrame()->LoadURL(strPtr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (LRESULT)CallWindowProc(editWndOldProc, hWnd, message, wParam,
|
||||
lParam);
|
||||
} else if (message == uFindMsg) {
|
||||
// Find event.
|
||||
LPFINDREPLACE lpfr = (LPFINDREPLACE)lParam;
|
||||
|
||||
if (lpfr->Flags & FR_DIALOGTERM) {
|
||||
// The find dialog box has been dismissed so invalidate the handle and
|
||||
// reset the search results.
|
||||
hFindDlg = NULL;
|
||||
if (g_handler.get()) {
|
||||
g_handler->GetBrowser()->GetHost()->StopFinding(true);
|
||||
szLastFindWhat[0] = 0;
|
||||
findNext = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((lpfr->Flags & FR_FINDNEXT) && g_handler.get()) {
|
||||
// Search for the requested string.
|
||||
bool matchCase = (lpfr->Flags & FR_MATCHCASE?true:false);
|
||||
if (matchCase != lastMatchCase ||
|
||||
(matchCase && wcsncmp(szFindWhat, szLastFindWhat,
|
||||
sizeof(szLastFindWhat)/sizeof(WCHAR)) != 0) ||
|
||||
(!matchCase && _wcsnicmp(szFindWhat, szLastFindWhat,
|
||||
sizeof(szLastFindWhat)/sizeof(WCHAR)) != 0)) {
|
||||
// The search string has changed, so reset the search results.
|
||||
if (szLastFindWhat[0] != 0) {
|
||||
g_handler->GetBrowser()->GetHost()->StopFinding(true);
|
||||
findNext = false;
|
||||
}
|
||||
lastMatchCase = matchCase;
|
||||
wcscpy_s(szLastFindWhat, sizeof(szLastFindWhat)/sizeof(WCHAR),
|
||||
szFindWhat);
|
||||
}
|
||||
|
||||
g_handler->GetBrowser()->GetHost()->Find(0, lpfr->lpstrFindWhat,
|
||||
(lpfr->Flags & FR_DOWN)?true:false, matchCase, findNext);
|
||||
if (!findNext)
|
||||
findNext = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
// Callback for the main window
|
||||
switch (message) {
|
||||
case WM_CREATE: {
|
||||
// Create the single static handler class instance
|
||||
g_handler = new ClientHandlerShared();
|
||||
g_handler->SetMainWindowHandle(hWnd);
|
||||
|
||||
// Create the child windows used for navigation
|
||||
RECT rect;
|
||||
int x = 0;
|
||||
|
||||
GetClientRect(hWnd, &rect);
|
||||
|
||||
backWnd = CreateWindow(L"BUTTON", L"Back",
|
||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
|
||||
| WS_DISABLED, x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
|
||||
hWnd, (HMENU) IDC_NAV_BACK, hInst, 0);
|
||||
x += BUTTON_WIDTH;
|
||||
|
||||
forwardWnd = CreateWindow(L"BUTTON", L"Forward",
|
||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
|
||||
| WS_DISABLED, x, 0, BUTTON_WIDTH,
|
||||
URLBAR_HEIGHT, hWnd, (HMENU) IDC_NAV_FORWARD,
|
||||
hInst, 0);
|
||||
x += BUTTON_WIDTH;
|
||||
|
||||
reloadWnd = CreateWindow(L"BUTTON", L"Reload",
|
||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
|
||||
| WS_DISABLED, x, 0, BUTTON_WIDTH,
|
||||
URLBAR_HEIGHT, hWnd, (HMENU) IDC_NAV_RELOAD,
|
||||
hInst, 0);
|
||||
x += BUTTON_WIDTH;
|
||||
|
||||
stopWnd = CreateWindow(L"BUTTON", L"Stop",
|
||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
|
||||
| WS_DISABLED, x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
|
||||
hWnd, (HMENU) IDC_NAV_STOP, hInst, 0);
|
||||
x += BUTTON_WIDTH;
|
||||
|
||||
editWnd = CreateWindow(L"EDIT", 0,
|
||||
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT |
|
||||
ES_AUTOVSCROLL | ES_AUTOHSCROLL| WS_DISABLED,
|
||||
x, 0, rect.right - BUTTON_WIDTH * 4,
|
||||
URLBAR_HEIGHT, hWnd, 0, hInst, 0);
|
||||
|
||||
// Assign the edit window's WNDPROC to this function so that we can
|
||||
// capture the enter key
|
||||
editWndOldProc =
|
||||
reinterpret_cast<WNDPROC>(GetWindowLongPtr(editWnd, GWLP_WNDPROC));
|
||||
SetWindowLongPtr(editWnd, GWLP_WNDPROC,
|
||||
reinterpret_cast<LONG_PTR>(MainWndProc));
|
||||
g_handler->SetUXWindowHandles(
|
||||
editWnd, backWnd, forwardWnd, reloadWnd, stopWnd);
|
||||
|
||||
rect.top += URLBAR_HEIGHT;
|
||||
|
||||
CefWindowInfo info;
|
||||
CefBrowserSettings settings;
|
||||
|
||||
// Populate the browser settings based on command line arguments.
|
||||
MainContext::Get()->PopulateBrowserSettings(&settings);
|
||||
|
||||
if (g_handler->is_osr()) {
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
CefCommandLine::GetGlobalCommandLine();
|
||||
const bool transparent =
|
||||
command_line->HasSwitch(switches::kTransparentPaintingEnabled);
|
||||
const bool show_update_rect =
|
||||
command_line->HasSwitch(switches::kShowUpdateRect);
|
||||
|
||||
CefRefPtr<OSRWindow> osr_window =
|
||||
OSRWindow::Create(&g_main_browser_provider, transparent,
|
||||
show_update_rect);
|
||||
osr_window->CreateWidget(hWnd, rect, hInst, szOSRWindowClass);
|
||||
info.SetAsWindowless(osr_window->hwnd(), transparent);
|
||||
g_handler->SetOSRHandler(osr_window.get());
|
||||
} else {
|
||||
// Initialize window info to the defaults for a child window.
|
||||
info.SetAsChild(hWnd, rect);
|
||||
}
|
||||
|
||||
// Creat the new child browser window
|
||||
CefBrowserHost::CreateBrowser(info, g_handler.get(),
|
||||
g_handler->startup_url(), settings, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_COMMAND: {
|
||||
CefRefPtr<CefBrowser> browser;
|
||||
if (g_handler.get())
|
||||
browser = g_handler->GetBrowser();
|
||||
|
||||
wmId = LOWORD(wParam);
|
||||
wmEvent = HIWORD(wParam);
|
||||
|
||||
if (wmId >= ID_TESTS_FIRST && wmId <= ID_TESTS_LAST) {
|
||||
test_runner::RunTest(browser, wmId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse the menu selections:
|
||||
switch (wmId) {
|
||||
case IDM_ABOUT:
|
||||
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, AboutWndProc);
|
||||
return 0;
|
||||
case IDM_EXIT:
|
||||
if (g_handler.get())
|
||||
g_handler->CloseAllBrowsers(false);
|
||||
return 0;
|
||||
case ID_FIND:
|
||||
if (!hFindDlg) {
|
||||
// Create the find dialog.
|
||||
ZeroMemory(&fr, sizeof(fr));
|
||||
fr.lStructSize = sizeof(fr);
|
||||
fr.hwndOwner = hWnd;
|
||||
fr.lpstrFindWhat = szFindWhat;
|
||||
fr.wFindWhatLen = sizeof(szFindWhat);
|
||||
fr.Flags = FR_HIDEWHOLEWORD | FR_DOWN;
|
||||
|
||||
hFindDlg = FindText(&fr);
|
||||
|
||||
// Override the dialog's window procedure.
|
||||
WNDPROC wndproc_old = SetWndProcPtr(hFindDlg, FindWndProc);
|
||||
|
||||
// Associate |wndproc_old| with the dialog.
|
||||
SetUserDataPtr(hFindDlg, wndproc_old);
|
||||
} else {
|
||||
// Give focus to the existing find dialog.
|
||||
::SetFocus(hFindDlg);
|
||||
}
|
||||
return 0;
|
||||
case IDC_NAV_BACK: // Back button
|
||||
if (browser.get())
|
||||
browser->GoBack();
|
||||
return 0;
|
||||
case IDC_NAV_FORWARD: // Forward button
|
||||
if (browser.get())
|
||||
browser->GoForward();
|
||||
return 0;
|
||||
case IDC_NAV_RELOAD: // Reload button
|
||||
if (browser.get())
|
||||
browser->Reload();
|
||||
return 0;
|
||||
case IDC_NAV_STOP: // Stop button
|
||||
if (browser.get())
|
||||
browser->StopLoad();
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_PAINT:
|
||||
hdc = BeginPaint(hWnd, &ps);
|
||||
EndPaint(hWnd, &ps);
|
||||
return 0;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
if (g_handler.get()) {
|
||||
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
|
||||
if (browser)
|
||||
SetFocusToBrowser(browser);
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_SIZE: {
|
||||
if (!g_handler.get())
|
||||
break;
|
||||
|
||||
// For off-screen browsers when the frame window is minimized set the
|
||||
// browser as hidden to reduce resource usage.
|
||||
const bool offscreen = g_handler->is_osr();
|
||||
if (offscreen) {
|
||||
CefRefPtr<OSRWindow> osr_window =
|
||||
OSRWindow::From(g_handler->GetOSRHandler());
|
||||
if (osr_window)
|
||||
osr_window->WasHidden(wParam == SIZE_MINIMIZED);
|
||||
}
|
||||
|
||||
if (g_handler->GetBrowser()) {
|
||||
// Retrieve the window handle (parent window with off-screen rendering).
|
||||
CefWindowHandle hwnd =
|
||||
g_handler->GetBrowser()->GetHost()->GetWindowHandle();
|
||||
if (hwnd) {
|
||||
if (wParam == SIZE_MINIMIZED) {
|
||||
// For windowed browsers when the frame window is minimized set the
|
||||
// browser window size to 0x0 to reduce resource usage.
|
||||
if (!offscreen) {
|
||||
SetWindowPos(hwnd, NULL,
|
||||
0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
|
||||
}
|
||||
} else {
|
||||
// Resize the window and address bar to match the new frame size.
|
||||
RECT rect;
|
||||
GetClientRect(hWnd, &rect);
|
||||
rect.top += URLBAR_HEIGHT;
|
||||
|
||||
int urloffset = rect.left + BUTTON_WIDTH * 4;
|
||||
|
||||
HDWP hdwp = BeginDeferWindowPos(1);
|
||||
hdwp = DeferWindowPos(hdwp, editWnd, NULL, urloffset,
|
||||
0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER);
|
||||
hdwp = DeferWindowPos(hdwp, hwnd, NULL,
|
||||
rect.left, rect.top, rect.right - rect.left,
|
||||
rect.bottom - rect.top, SWP_NOZORDER);
|
||||
EndDeferWindowPos(hdwp);
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case WM_MOVING:
|
||||
case WM_MOVE:
|
||||
// Notify the browser of move events so that popup windows are displayed
|
||||
// in the correct location and dismissed when the window moves.
|
||||
if (g_handler.get() && g_handler->GetBrowser())
|
||||
g_handler->GetBrowser()->GetHost()->NotifyMoveOrResizeStarted();
|
||||
return 0;
|
||||
|
||||
case WM_ERASEBKGND:
|
||||
if (g_handler.get() && g_handler->GetBrowser()) {
|
||||
CefWindowHandle hwnd =
|
||||
g_handler->GetBrowser()->GetHost()->GetWindowHandle();
|
||||
if (hwnd) {
|
||||
// Dont erase the background if the browser window has been loaded
|
||||
// (this avoids flashing)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_ENTERMENULOOP:
|
||||
if (!wParam) {
|
||||
// Entering the menu loop for the application menu.
|
||||
CefSetOSModalLoop(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_EXITMENULOOP:
|
||||
if (!wParam) {
|
||||
// Exiting the menu loop for the application menu.
|
||||
CefSetOSModalLoop(false);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
if (g_handler.get() && !g_handler->IsClosing()) {
|
||||
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
|
||||
if (browser.get()) {
|
||||
// Notify the browser window that we would like to close it. This
|
||||
// will result in a call to ClientHandler::DoClose() if the
|
||||
// JavaScript 'onbeforeunload' event handler allows it.
|
||||
browser->GetHost()->CloseBrowser(false);
|
||||
|
||||
// Cancel the close.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the close.
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
// Quitting CEF is handled in ClientHandler::OnBeforeClose().
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
// Window procedure for the find dialog.
|
||||
LRESULT CALLBACK FindWndProc(HWND hWnd, UINT message, WPARAM wParam,
|
||||
LPARAM lParam) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
WNDPROC old_wndproc = GetUserDataPtr<WNDPROC>(hWnd);
|
||||
DCHECK(old_wndproc);
|
||||
|
||||
switch (message) {
|
||||
case WM_ACTIVATE:
|
||||
// Set this dialog as current when activated.
|
||||
MainMessageLoop::Get()->SetCurrentModelessDialog(
|
||||
wParam == 0 ? NULL : hWnd);
|
||||
return FALSE;
|
||||
case WM_NCDESTROY:
|
||||
// Clear the reference to |old_wndproc|.
|
||||
SetUserDataPtr(hWnd, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return CallWindowProc(old_wndproc, hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
// Window procedure for the about dialog.
|
||||
INT_PTR CALLBACK AboutWndProc(HWND hDlg, UINT message, WPARAM wParam,
|
||||
LPARAM lParam) {
|
||||
UNREFERENCED_PARAMETER(lParam);
|
||||
switch (message) {
|
||||
case WM_INITDIALOG:
|
||||
return (INT_PTR)TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
|
||||
EndDialog(hDlg, LOWORD(wParam));
|
||||
return (INT_PTR)TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (INT_PTR)FALSE;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace client
|
||||
|
||||
|
@ -264,7 +264,8 @@ bool ClientHandler::OnBeforePopup(CefRefPtr<CefBrowser> browser,
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
// Return true to cancel the popup window.
|
||||
return !CreatePopupWindow(false, popupFeatures, windowInfo, client, settings);
|
||||
return !CreatePopupWindow(browser, false, popupFeatures, windowInfo, client,
|
||||
settings);
|
||||
}
|
||||
|
||||
void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
||||
@ -464,7 +465,7 @@ void ClientHandler::ShowDevTools(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefClient> client;
|
||||
CefBrowserSettings settings;
|
||||
|
||||
if (CreatePopupWindow(true, CefPopupFeatures(), windowInfo, client,
|
||||
if (CreatePopupWindow(browser, true, CefPopupFeatures(), windowInfo, client,
|
||||
settings)) {
|
||||
browser->GetHost()->ShowDevTools(windowInfo, client, settings,
|
||||
inspect_element_at);
|
||||
|
@ -235,6 +235,7 @@ class ClientHandler : public CefClient,
|
||||
// proceed with popup browser creation or false to cancel the popup browser.
|
||||
// May be called on any thead.
|
||||
virtual bool CreatePopupWindow(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
bool is_devtools,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
|
138
tests/cefclient/client_handler_osr.cc
Normal file
138
tests/cefclient/client_handler_osr.cc
Normal file
@ -0,0 +1,138 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/client_handler_osr.h"
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
ClientHandlerOsr::ClientHandlerOsr(Delegate* delegate,
|
||||
OsrDelegate* osr_delegate,
|
||||
const std::string& startup_url)
|
||||
: ClientHandlerSingle(delegate, true, startup_url),
|
||||
osr_delegate_(osr_delegate) {
|
||||
DCHECK(osr_delegate_);
|
||||
}
|
||||
|
||||
void ClientHandlerOsr::DetachOsrDelegate() {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
// Execute this method on the UI thread.
|
||||
CefPostTask(TID_UI, base::Bind(&ClientHandlerOsr::DetachOsrDelegate, this));
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(osr_delegate_);
|
||||
osr_delegate_ = NULL;
|
||||
}
|
||||
|
||||
void ClientHandlerOsr::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (osr_delegate_)
|
||||
osr_delegate_->OnAfterCreated(browser);
|
||||
ClientHandlerSingle::OnAfterCreated(browser);
|
||||
}
|
||||
|
||||
void ClientHandlerOsr::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (osr_delegate_)
|
||||
osr_delegate_->OnBeforeClose(browser);
|
||||
ClientHandlerSingle::OnBeforeClose(browser);
|
||||
}
|
||||
|
||||
bool ClientHandlerOsr::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (!osr_delegate_)
|
||||
return false;
|
||||
return osr_delegate_->GetRootScreenRect(browser, rect);
|
||||
}
|
||||
|
||||
bool ClientHandlerOsr::GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (!osr_delegate_)
|
||||
return false;
|
||||
return osr_delegate_->GetViewRect(browser, rect);
|
||||
}
|
||||
|
||||
bool ClientHandlerOsr::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||
int viewX,
|
||||
int viewY,
|
||||
int& screenX,
|
||||
int& screenY) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (!osr_delegate_)
|
||||
return false;
|
||||
return osr_delegate_->GetScreenPoint(browser, viewX, viewY, screenX, screenY);
|
||||
}
|
||||
|
||||
bool ClientHandlerOsr::GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
||||
CefScreenInfo& screen_info) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (!osr_delegate_)
|
||||
return false;
|
||||
return osr_delegate_->GetScreenInfo(browser, screen_info);
|
||||
}
|
||||
|
||||
void ClientHandlerOsr::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||
bool show) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (!osr_delegate_)
|
||||
return;
|
||||
return osr_delegate_->OnPopupShow(browser, show);
|
||||
}
|
||||
|
||||
void ClientHandlerOsr::OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||
const CefRect& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (!osr_delegate_)
|
||||
return;
|
||||
return osr_delegate_->OnPopupSize(browser, rect);
|
||||
}
|
||||
|
||||
void ClientHandlerOsr::OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
PaintElementType type,
|
||||
const RectList& dirtyRects,
|
||||
const void* buffer,
|
||||
int width,
|
||||
int height) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (!osr_delegate_)
|
||||
return;
|
||||
osr_delegate_->OnPaint(browser, type, dirtyRects, buffer, width, height);
|
||||
}
|
||||
|
||||
void ClientHandlerOsr::OnCursorChange(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor,
|
||||
CursorType type,
|
||||
const CefCursorInfo& custom_cursor_info) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (!osr_delegate_)
|
||||
return;
|
||||
osr_delegate_->OnCursorChange(browser, cursor, type, custom_cursor_info);
|
||||
}
|
||||
|
||||
bool ClientHandlerOsr::StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (!osr_delegate_)
|
||||
return false;
|
||||
return osr_delegate_->StartDragging(browser, drag_data, allowed_ops, x, y);
|
||||
}
|
||||
|
||||
void ClientHandlerOsr::UpdateDragCursor(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (!osr_delegate_)
|
||||
return;
|
||||
osr_delegate_->UpdateDragCursor(browser, operation);
|
||||
}
|
||||
|
||||
} // namespace client
|
123
tests/cefclient/client_handler_osr.h
Normal file
123
tests/cefclient/client_handler_osr.h
Normal file
@ -0,0 +1,123 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_OSR_H_
|
||||
#define CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_OSR_H_
|
||||
|
||||
#include "cefclient/client_handler_single.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Client handler implementation for windowless browsers. There will only ever
|
||||
// be one browser per handler instance.
|
||||
class ClientHandlerOsr : public ClientHandlerSingle,
|
||||
public CefRenderHandler {
|
||||
public:
|
||||
// Implement this interface to receive notification of ClientHandlerOsr
|
||||
// events. The methods of this class will be called on the CEF UI thread.
|
||||
class OsrDelegate {
|
||||
public:
|
||||
// These methods match the CefLifeSpanHandler interface.
|
||||
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) = 0;
|
||||
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) = 0;
|
||||
|
||||
// These methods match the CefRenderHandler interface.
|
||||
virtual bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) = 0;
|
||||
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) = 0;
|
||||
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||
int viewX,
|
||||
int viewY,
|
||||
int& screenX,
|
||||
int& screenY) = 0;
|
||||
virtual bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
||||
CefScreenInfo& screen_info) = 0;
|
||||
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) = 0;
|
||||
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||
const CefRect& rect) = 0;
|
||||
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
PaintElementType type,
|
||||
const RectList& dirtyRects,
|
||||
const void* buffer,
|
||||
int width,
|
||||
int height) = 0;
|
||||
virtual void OnCursorChange(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor,
|
||||
CefRenderHandler::CursorType type,
|
||||
const CefCursorInfo& custom_cursor_info) = 0;
|
||||
virtual bool StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) = 0;
|
||||
virtual void UpdateDragCursor(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~OsrDelegate() {}
|
||||
};
|
||||
|
||||
ClientHandlerOsr(Delegate* delegate,
|
||||
OsrDelegate* osr_delegate,
|
||||
const std::string& startup_url);
|
||||
|
||||
// This object may outlive the OsrDelegate object so it's necessary for the
|
||||
// OsrDelegate to detach itself before destruction.
|
||||
void DetachOsrDelegate();
|
||||
|
||||
// CefClient methods.
|
||||
CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE {
|
||||
return this;
|
||||
}
|
||||
|
||||
// CefLifeSpanHandler methods.
|
||||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
|
||||
// CefRenderHandler methods.
|
||||
bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) OVERRIDE;
|
||||
bool GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) OVERRIDE;
|
||||
bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||
int viewX,
|
||||
int viewY,
|
||||
int& screenX,
|
||||
int& screenY) OVERRIDE;
|
||||
bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
||||
CefScreenInfo& screen_info) OVERRIDE;
|
||||
void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE;
|
||||
void OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||
const CefRect& rect) OVERRIDE;
|
||||
void OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::PaintElementType type,
|
||||
const CefRenderHandler::RectList& dirtyRects,
|
||||
const void* buffer,
|
||||
int width,
|
||||
int height) OVERRIDE;
|
||||
void OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor,
|
||||
CursorType type,
|
||||
const CefCursorInfo& custom_cursor_info) OVERRIDE;
|
||||
bool StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) OVERRIDE;
|
||||
void UpdateDragCursor(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) OVERRIDE;
|
||||
|
||||
private:
|
||||
// Only accessed on the UI thread.
|
||||
OsrDelegate* osr_delegate_;
|
||||
|
||||
// Include the default reference counting implementation.
|
||||
IMPLEMENT_REFCOUNTING(ClientHandlerOsr);
|
||||
DISALLOW_COPY_AND_ASSIGN(ClientHandlerOsr);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_OSR_H_
|
@ -40,12 +40,7 @@ void ClientHandlerShared::BrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
if (browser_id_ == 0) {
|
||||
// Keep references to the browser hosted in the main window.
|
||||
browser_id_ = browser->GetIdentifier();
|
||||
{
|
||||
// Protect modification of |browser_| with a lock because it may be
|
||||
// accessed from different threads.
|
||||
base::AutoLock lock_scope(lock_);
|
||||
browser_ = browser;
|
||||
}
|
||||
browser_ = browser;
|
||||
} else if (browser->IsPopup()) {
|
||||
// Add to the list of popup browsers.
|
||||
popup_browsers_.push_back(browser);
|
||||
@ -64,9 +59,6 @@ void ClientHandlerShared::BrowserClosing(CefRefPtr<CefBrowser> browser) {
|
||||
// documentation in the CEF header for a detailed destription of this
|
||||
// process.
|
||||
if (browser_id_ == browser->GetIdentifier()) {
|
||||
// Protect modification of |is_closing_| with a lock because it may be
|
||||
// accessed from different threads.
|
||||
base::AutoLock lock_scope(lock_);
|
||||
// Set a flag to indicate that the window close should be allowed.
|
||||
is_closing_ = true;
|
||||
}
|
||||
@ -76,20 +68,11 @@ void ClientHandlerShared::BrowserClosed(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (browser_id_ == browser->GetIdentifier()) {
|
||||
{
|
||||
// Protect modification of |browser_| with a lock because it may be
|
||||
// accessed from different threads.
|
||||
base::AutoLock lock_scope(lock_);
|
||||
// Free the browser pointer so that the browser can be destroyed.
|
||||
browser_ = NULL;
|
||||
}
|
||||
// Free the browser pointer so that the browser can be destroyed.
|
||||
browser_ = NULL;
|
||||
|
||||
if (osr_handler_.get()) {
|
||||
osr_handler_->OnBeforeClose(browser);
|
||||
|
||||
// Protect modification of |osr_handler_| with a lock because it may be
|
||||
// accessed from different threads.
|
||||
base::AutoLock lock_scope(lock_);
|
||||
osr_handler_ = NULL;
|
||||
}
|
||||
|
||||
@ -112,6 +95,7 @@ void ClientHandlerShared::BrowserClosed(CefRefPtr<CefBrowser> browser) {
|
||||
}
|
||||
|
||||
bool ClientHandlerShared::CreatePopupWindow(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
bool is_devtools,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
@ -120,6 +104,8 @@ bool ClientHandlerShared::CreatePopupWindow(
|
||||
// Note: This method will be called on multiple threads.
|
||||
|
||||
if (is_devtools) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
// Create DevTools as a windowed popup browser using the same client.
|
||||
#if defined(OS_WIN)
|
||||
windowInfo.SetAsPopup(GetMainWindowHandle(), "DevTools");
|
||||
@ -127,7 +113,7 @@ bool ClientHandlerShared::CreatePopupWindow(
|
||||
client = this;
|
||||
} else if (is_osr()) {
|
||||
CefPostTask(TID_UI,
|
||||
base::Bind(test_runner::Alert, GetBrowser(),
|
||||
base::Bind(test_runner::Alert, browser,
|
||||
"Popup windows are disabled with off-screen rendering."));
|
||||
|
||||
// Cancel popups in off-screen rendering mode.
|
||||
@ -143,14 +129,7 @@ void ClientHandlerShared::SetUXWindowHandles(
|
||||
ClientWindowHandle forwardHandle,
|
||||
ClientWindowHandle reloadHandle,
|
||||
ClientWindowHandle stopHandle) {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
// Execute on the UI thread.
|
||||
CefPostTask(TID_UI,
|
||||
base::Bind(&ClientHandlerShared::SetUXWindowHandles, this,
|
||||
editHandle, backHandle, forwardHandle, reloadHandle,
|
||||
stopHandle));
|
||||
return;
|
||||
}
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
edit_handle_ = editHandle;
|
||||
back_handle_ = backHandle;
|
||||
@ -161,50 +140,31 @@ void ClientHandlerShared::SetUXWindowHandles(
|
||||
|
||||
CefRefPtr<ClientHandlerShared::RenderHandler>
|
||||
ClientHandlerShared::GetOSRHandler() const {
|
||||
if (CefCurrentlyOn(TID_UI)) {
|
||||
// No need for locking because |osr_handler_| will only be modified on this
|
||||
// thread.
|
||||
return osr_handler_;
|
||||
} else {
|
||||
// Use a lock to protect |osr_handler_| from being modified while we're
|
||||
// accessing it from a different thread.
|
||||
base::AutoLock lock_scope(lock_);
|
||||
return osr_handler_;
|
||||
}
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
return osr_handler_;
|
||||
}
|
||||
|
||||
void ClientHandlerShared::SetOSRHandler(CefRefPtr<RenderHandler> handler) {
|
||||
// Protect modification of |osr_handler_| with a lock because it may be
|
||||
// accessed from different threads.
|
||||
base::AutoLock lock_scope(lock_);
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
osr_handler_ = handler;
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowser> ClientHandlerShared::GetBrowser() const {
|
||||
if (CefCurrentlyOn(TID_UI)) {
|
||||
// No need for locking because |browser_| will only be modified on this
|
||||
// thread.
|
||||
return browser_;
|
||||
} else {
|
||||
// Use a lock to protect |browser_| from being modified while we're
|
||||
// accessing it from a different thread.
|
||||
base::AutoLock lock_scope(lock_);
|
||||
return browser_;
|
||||
}
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
return browser_;
|
||||
}
|
||||
|
||||
int ClientHandlerShared::GetBrowserId() const {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
return browser_id_;
|
||||
}
|
||||
|
||||
void ClientHandlerShared::CloseAllBrowsers(bool force_close) {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
// Execute on the UI thread.
|
||||
CefPostTask(TID_UI,
|
||||
base::Bind(&ClientHandlerShared::CloseAllBrowsers, this, force_close));
|
||||
return;
|
||||
}
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (!popup_browsers_.empty()) {
|
||||
// Request that any popup browsers close.
|
||||
@ -220,16 +180,9 @@ void ClientHandlerShared::CloseAllBrowsers(bool force_close) {
|
||||
}
|
||||
|
||||
bool ClientHandlerShared::IsClosing() const {
|
||||
if (CefCurrentlyOn(TID_UI)) {
|
||||
// No need for locking because |is_closing_| will only be modified on this
|
||||
// thread.
|
||||
return is_closing_;
|
||||
} else {
|
||||
// Use a lock to protect |is_closing_| from being modified while we're
|
||||
// accessing it from a different thread.
|
||||
base::AutoLock lock_scope(lock_);
|
||||
return is_closing_;
|
||||
}
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
return is_closing_;
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
|
@ -9,12 +9,12 @@
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "include/base/cef_lock.h"
|
||||
#include "cefclient/client_handler.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Client handler implementation that is shared by all existing browsers.
|
||||
// Client handler implementation that is shared by all existing browsers. All
|
||||
// methods must be called on the CEF UI thread unless otherwise indicated.
|
||||
class ClientHandlerShared : public ClientHandler {
|
||||
public:
|
||||
// Interface implemented to handle off-screen rendering.
|
||||
@ -44,6 +44,7 @@ class ClientHandlerShared : public ClientHandler {
|
||||
bool canGoBack,
|
||||
bool canGoForward) OVERRIDE;
|
||||
bool CreatePopupWindow(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
bool is_devtools,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
@ -59,12 +60,11 @@ class ClientHandlerShared : public ClientHandler {
|
||||
CefRefPtr<RenderHandler> GetOSRHandler() const;
|
||||
void SetOSRHandler(CefRefPtr<RenderHandler> handler);
|
||||
|
||||
// Get the main (non-popup) browser associated with this client. Safe to call
|
||||
// on any thread.
|
||||
// Get the main (non-popup) browser associated with this client.
|
||||
CefRefPtr<CefBrowser> GetBrowser() const;
|
||||
|
||||
// Get the main (non-popup) browser ID. Will return non-0 if the main browser
|
||||
// currently exists. Should only be called on the CEF UI thread.
|
||||
// currently exists.
|
||||
int GetBrowserId() const;
|
||||
|
||||
// Request that all existing browser windows close.
|
||||
@ -72,21 +72,11 @@ class ClientHandlerShared : public ClientHandler {
|
||||
|
||||
// Returns true if the main browser window is currently closing. Used in
|
||||
// combination with DoClose() and the OS close notification to properly handle
|
||||
// 'onbeforeunload' JavaScript events during window close. Safe to call on any
|
||||
// thread.
|
||||
// 'onbeforeunload' JavaScript events during window close.
|
||||
bool IsClosing() const;
|
||||
|
||||
private:
|
||||
// Lock used to protect members accessed on multiple threads. Make it mutable
|
||||
// so that it can be used from const methods.
|
||||
mutable base::Lock lock_;
|
||||
|
||||
// LOCK PROTECTED MEMBERS
|
||||
// Setting the following members or accessing them from a thread other than
|
||||
// the CEF UI thread must be protected by |lock_|. Most platforms will only
|
||||
// access them from the UI thread but on Windows they will be accessed from
|
||||
// the main application thread when using using multi-threaded message loop
|
||||
// mode.
|
||||
// The following members will only be accessed on the CEF UI thread.
|
||||
|
||||
// The handler for off-screen rendering, if any.
|
||||
CefRefPtr<RenderHandler> osr_handler_;
|
||||
@ -97,9 +87,6 @@ class ClientHandlerShared : public ClientHandler {
|
||||
// True if the main browser window is currently closing.
|
||||
bool is_closing_;
|
||||
|
||||
// UI THREAD MEMBERS
|
||||
// The following members will only be accessed on the CEF UI thread.
|
||||
|
||||
// The child browser id.
|
||||
int browser_id_;
|
||||
|
||||
|
@ -1,55 +0,0 @@
|
||||
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/client_handler_shared.h"
|
||||
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
|
||||
#include "include/cef_browser.h"
|
||||
#include "cefclient/resource.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
void ClientHandlerShared::SetAddress(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& url) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (browser_id_ == browser->GetIdentifier()) {
|
||||
// Set the edit window text for the main (top-level) browser.
|
||||
SetWindowText(edit_handle_, std::wstring(url).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void ClientHandlerShared::SetTitle(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& title) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
// Set the frame window title bar.
|
||||
CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle();
|
||||
if (browser_id_ == browser->GetIdentifier()) {
|
||||
// For the main (top-level) browser the frame window will be the parent of
|
||||
// the browser window.
|
||||
hwnd = GetParent(hwnd);
|
||||
}
|
||||
SetWindowText(hwnd, std::wstring(title).c_str());
|
||||
}
|
||||
|
||||
void ClientHandlerShared::SetLoadingState(CefRefPtr<CefBrowser> browser,
|
||||
bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (browser_id_ == browser->GetIdentifier()) {
|
||||
// Set UX control state for the main (top-level) browser.
|
||||
EnableWindow(edit_handle_, TRUE);
|
||||
EnableWindow(reload_handle_, !isLoading);
|
||||
EnableWindow(stop_handle_, isLoading);
|
||||
EnableWindow(back_handle_, canGoBack);
|
||||
EnableWindow(forward_handle_, canGoForward);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace client
|
166
tests/cefclient/client_handler_single.cc
Normal file
166
tests/cefclient/client_handler_single.cc
Normal file
@ -0,0 +1,166 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/client_handler_single.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/cef_command_line.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "cefclient/main_context.h"
|
||||
#include "cefclient/main_message_loop.h"
|
||||
#include "cefclient/root_window_manager.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
ClientHandlerSingle::ClientHandlerSingle(Delegate* delegate,
|
||||
bool is_osr,
|
||||
const std::string& startup_url)
|
||||
: ClientHandler(startup_url, is_osr),
|
||||
delegate_(delegate) {
|
||||
DCHECK(delegate_);
|
||||
}
|
||||
|
||||
void ClientHandlerSingle::DetachDelegate() {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(base::Bind(&ClientHandlerSingle::DetachDelegate, this));
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(delegate_);
|
||||
delegate_ = NULL;
|
||||
}
|
||||
|
||||
void ClientHandlerSingle::BrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
NotifyBrowserCreated(browser);
|
||||
}
|
||||
|
||||
void ClientHandlerSingle::BrowserClosing(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
NotifyBrowserClosing(browser);
|
||||
}
|
||||
|
||||
void ClientHandlerSingle::BrowserClosed(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
NotifyBrowserClosed(browser);
|
||||
}
|
||||
|
||||
void ClientHandlerSingle::SetAddress(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& url) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
NotifyAddress(url);
|
||||
}
|
||||
|
||||
void ClientHandlerSingle::SetTitle(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& title) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
NotifyTitle(title);
|
||||
}
|
||||
|
||||
void ClientHandlerSingle::SetLoadingState(CefRefPtr<CefBrowser> browser,
|
||||
bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
NotifyLoadingState(isLoading, canGoBack, canGoForward);
|
||||
}
|
||||
|
||||
bool ClientHandlerSingle::CreatePopupWindow(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
bool is_devtools,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) {
|
||||
// Note: This method will be called on multiple threads.
|
||||
|
||||
// The popup browser will be parented to a new native window.
|
||||
// Don't show URL bar and navigation buttons on DevTools windows.
|
||||
MainContext::Get()->GetRootWindowManager()->CreateRootWindowAsPopup(
|
||||
!is_devtools, is_osr(), popupFeatures, windowInfo, client, settings);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClientHandlerSingle::NotifyBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(
|
||||
base::Bind(&ClientHandlerSingle::NotifyBrowserCreated, this, browser));
|
||||
return;
|
||||
}
|
||||
|
||||
if (delegate_)
|
||||
delegate_->OnBrowserCreated(browser);
|
||||
}
|
||||
|
||||
void ClientHandlerSingle::NotifyBrowserClosing(CefRefPtr<CefBrowser> browser) {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(
|
||||
base::Bind(&ClientHandlerSingle::NotifyBrowserClosing, this, browser));
|
||||
return;
|
||||
}
|
||||
|
||||
if (delegate_)
|
||||
delegate_->OnBrowserClosing(browser);
|
||||
}
|
||||
|
||||
void ClientHandlerSingle::NotifyBrowserClosed(CefRefPtr<CefBrowser> browser) {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(
|
||||
base::Bind(&ClientHandlerSingle::NotifyBrowserClosed, this, browser));
|
||||
return;
|
||||
}
|
||||
|
||||
if (delegate_)
|
||||
delegate_->OnBrowserClosed(browser);
|
||||
}
|
||||
|
||||
void ClientHandlerSingle::NotifyAddress(const CefString& url) {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(
|
||||
base::Bind(&ClientHandlerSingle::NotifyAddress, this, url));
|
||||
return;
|
||||
}
|
||||
|
||||
if (delegate_)
|
||||
delegate_->OnSetAddress(url);
|
||||
}
|
||||
|
||||
void ClientHandlerSingle::NotifyTitle(const CefString& title) {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(
|
||||
base::Bind(&ClientHandlerSingle::NotifyTitle, this, title));
|
||||
return;
|
||||
}
|
||||
|
||||
if (delegate_)
|
||||
delegate_->OnSetTitle(title);
|
||||
}
|
||||
|
||||
void ClientHandlerSingle::NotifyLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(
|
||||
base::Bind(&ClientHandlerSingle::NotifyLoadingState, this,
|
||||
isLoading, canGoBack, canGoForward));
|
||||
return;
|
||||
}
|
||||
|
||||
if (delegate_)
|
||||
delegate_->OnSetLoadingState(isLoading, canGoBack, canGoForward);
|
||||
}
|
||||
|
||||
} // namespace client
|
97
tests/cefclient/client_handler_single.h
Normal file
97
tests/cefclient/client_handler_single.h
Normal file
@ -0,0 +1,97 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_SINGLE_H_
|
||||
#define CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_SINGLE_H_
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "include/base/cef_lock.h"
|
||||
#include "cefclient/client_handler.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Client handler implementation that is used by a single browser.
|
||||
class ClientHandlerSingle : public ClientHandler {
|
||||
public:
|
||||
// Implement this interface to receive notification of ClientHandlerSingle
|
||||
// events. The methods of this class will be called on the main thread.
|
||||
class Delegate {
|
||||
public:
|
||||
// Called when the browser is created.
|
||||
virtual void OnBrowserCreated(CefRefPtr<CefBrowser> browser) = 0;
|
||||
|
||||
// Called when the browser is closing.
|
||||
virtual void OnBrowserClosing(CefRefPtr<CefBrowser> browser) = 0;
|
||||
|
||||
// Called when the browser has been closed.
|
||||
virtual void OnBrowserClosed(CefRefPtr<CefBrowser> browser) = 0;
|
||||
|
||||
// Set the window URL address.
|
||||
virtual void OnSetAddress(const std::string& url) = 0;
|
||||
|
||||
// Set the window title.
|
||||
virtual void OnSetTitle(const std::string& title) = 0;
|
||||
|
||||
// Set the loading state.
|
||||
virtual void OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Delegate() {}
|
||||
};
|
||||
|
||||
// This object may outlive the Delegate object so it's necessary for the
|
||||
// Delegate to detach itself before destruction.
|
||||
void DetachDelegate();
|
||||
|
||||
protected:
|
||||
// Constructor may be called on any thread.
|
||||
// |delegate| must outlive this object or DetachDelegate() must be called.
|
||||
ClientHandlerSingle(Delegate* delegate,
|
||||
bool is_osr,
|
||||
const std::string& startup_url);
|
||||
|
||||
// ClientHandler methods
|
||||
void BrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
void BrowserClosing(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
void BrowserClosed(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
void SetAddress(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& url) OVERRIDE;
|
||||
void SetTitle(CefRefPtr<CefBrowser> browser,
|
||||
const CefString& title) OVERRIDE;
|
||||
void SetLoadingState(CefRefPtr<CefBrowser> browser,
|
||||
bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) OVERRIDE;
|
||||
bool CreatePopupWindow(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
bool is_devtools,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) OVERRIDE;
|
||||
|
||||
private:
|
||||
void NotifyBrowserCreated(CefRefPtr<CefBrowser> browser);
|
||||
void NotifyBrowserClosing(CefRefPtr<CefBrowser> browser);
|
||||
void NotifyBrowserClosed(CefRefPtr<CefBrowser> browser);
|
||||
void NotifyAddress(const CefString& url);
|
||||
void NotifyTitle(const CefString& title);
|
||||
void NotifyLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward);
|
||||
|
||||
// Only accessed on the main thread.
|
||||
Delegate* delegate_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ClientHandlerSingle);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_SINGLE_H_
|
14
tests/cefclient/client_handler_std.cc
Normal file
14
tests/cefclient/client_handler_std.cc
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/client_handler_std.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
ClientHandlerStd::ClientHandlerStd(Delegate* delegate,
|
||||
const std::string& startup_url)
|
||||
: ClientHandlerSingle(delegate, false, startup_url) {
|
||||
}
|
||||
|
||||
} // namespace client
|
27
tests/cefclient/client_handler_std.h
Normal file
27
tests/cefclient/client_handler_std.h
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_STD_H_
|
||||
#define CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_STD_H_
|
||||
|
||||
#include "cefclient/client_handler_single.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Client handler implementation for windowed browsers. There will only ever be
|
||||
// one browser per handler instance.
|
||||
class ClientHandlerStd : public ClientHandlerSingle {
|
||||
public:
|
||||
ClientHandlerStd(Delegate* delegate,
|
||||
const std::string& startup_url);
|
||||
|
||||
private:
|
||||
// Include the default reference counting implementation.
|
||||
IMPLEMENT_REFCOUNTING(ClientHandlerStd);
|
||||
DISALLOW_COPY_AND_ASSIGN(ClientHandlerStd);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_STD_H_
|
@ -12,6 +12,10 @@
|
||||
|
||||
namespace client {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
class RootWindowManager;
|
||||
#endif
|
||||
|
||||
// Used to store global context in the browser process. The methods of this
|
||||
// class are thread-safe unless otherwise indicated.
|
||||
class MainContext {
|
||||
@ -35,6 +39,11 @@ class MainContext {
|
||||
virtual void PopulateSettings(CefSettings* settings) = 0;
|
||||
virtual void PopulateBrowserSettings(CefBrowserSettings* settings) = 0;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Returns the object used to create/manage RootWindow instances.
|
||||
virtual RootWindowManager* GetRootWindowManager() = 0;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
MainContext();
|
||||
virtual ~MainContext();
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
#include "cefclient/client_switches.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "cefclient/root_window_manager.h"
|
||||
#endif
|
||||
namespace client {
|
||||
|
||||
namespace {
|
||||
@ -16,7 +19,11 @@ const char kDefaultUrl[] = "http://www.google.com";
|
||||
} // namespace
|
||||
|
||||
MainContextImpl::MainContextImpl(int argc,
|
||||
const char* const* argv) {
|
||||
const char* const* argv
|
||||
#if defined(OS_WIN)
|
||||
, bool terminate_when_all_windows_closed
|
||||
#endif
|
||||
) {
|
||||
// Parse the command line.
|
||||
command_line_ = CefCommandLine::CreateCommandLine();
|
||||
#if defined(OS_WIN)
|
||||
@ -30,6 +37,11 @@ MainContextImpl::MainContextImpl(int argc,
|
||||
main_url_ = command_line_->GetSwitchValue(switches::kUrl);
|
||||
if (main_url_.empty())
|
||||
main_url_ = kDefaultUrl;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
root_window_manager_.reset(
|
||||
new RootWindowManager(terminate_when_all_windows_closed));
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string MainContextImpl::GetConsoleLogPath() {
|
||||
@ -60,4 +72,10 @@ void MainContextImpl::PopulateBrowserSettings(CefBrowserSettings* settings) {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
RootWindowManager* MainContextImpl::GetRootWindowManager() {
|
||||
return root_window_manager_.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace client
|
||||
|
@ -15,7 +15,11 @@ namespace client {
|
||||
class MainContextImpl : public MainContext {
|
||||
public:
|
||||
MainContextImpl(int argc,
|
||||
const char* const* argv);
|
||||
const char* const* argv
|
||||
#if defined(OS_WIN)
|
||||
, bool terminate_when_all_windows_closed
|
||||
#endif
|
||||
);
|
||||
|
||||
// MainContext members.
|
||||
std::string GetConsoleLogPath() OVERRIDE;
|
||||
@ -24,6 +28,9 @@ class MainContextImpl : public MainContext {
|
||||
std::string GetMainURL() OVERRIDE;
|
||||
void PopulateSettings(CefSettings* settings) OVERRIDE;
|
||||
void PopulateBrowserSettings(CefBrowserSettings* settings) OVERRIDE;
|
||||
#if defined(OS_WIN)
|
||||
RootWindowManager* GetRootWindowManager() OVERRIDE;
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Allow deletion via scoped_ptr only.
|
||||
@ -34,6 +41,10 @@ class MainContextImpl : public MainContext {
|
||||
CefRefPtr<CefCommandLine> command_line_;
|
||||
std::string main_url_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
scoped_ptr<RootWindowManager> root_window_manager_;
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MainContextImpl);
|
||||
};
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <direct.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
#include "cefclient/root_window_manager.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
std::string MainContextImpl::GetDownloadPath(const std::string& file_name) {
|
||||
|
@ -48,14 +48,6 @@ class MainMessageLoop {
|
||||
// Post a closure for execution on the main message loop.
|
||||
void PostClosure(const base::Closure& closure);
|
||||
|
||||
// Used in combination with DeleteOnMainThread to delete |object| on the
|
||||
// correct thread.
|
||||
template<class T>
|
||||
void DeleteSoon(const T* object) {
|
||||
// Execute DeleteHelper on the main thread.
|
||||
PostClosure(base::Bind(&MainMessageLoop::DeleteHelper, object));
|
||||
}
|
||||
|
||||
protected:
|
||||
// Only allow deletion via scoped_ptr.
|
||||
friend struct base::DefaultDeleter<MainMessageLoop>;
|
||||
@ -64,12 +56,6 @@ class MainMessageLoop {
|
||||
virtual ~MainMessageLoop();
|
||||
|
||||
private:
|
||||
// Helper for deleting |object|.
|
||||
template<class T>
|
||||
static void DeleteHelper(const T* object) {
|
||||
delete object;
|
||||
}
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MainMessageLoop);
|
||||
};
|
||||
|
||||
@ -110,7 +96,8 @@ struct DeleteOnMainThread {
|
||||
if (CURRENTLY_ON_MAIN_THREAD()) {
|
||||
delete x;
|
||||
} else {
|
||||
client::MainMessageLoop::Get()->DeleteSoon(x);
|
||||
client::MainMessageLoop::Get()->PostClosure(
|
||||
base::Bind(&DeleteOnMainThread::Destruct<T>, x));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,681 +0,0 @@
|
||||
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/osr_widget_win.h"
|
||||
|
||||
#include <windowsx.h>
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/base/cef_build.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "cefclient/resource.h"
|
||||
#include "cefclient/util_win.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
namespace {
|
||||
|
||||
class ScopedGLContext {
|
||||
public:
|
||||
ScopedGLContext(HDC hdc, HGLRC hglrc, bool swap_buffers)
|
||||
: hdc_(hdc),
|
||||
swap_buffers_(swap_buffers) {
|
||||
BOOL result = wglMakeCurrent(hdc, hglrc);
|
||||
ALLOW_UNUSED_LOCAL(result);
|
||||
DCHECK(result);
|
||||
}
|
||||
~ScopedGLContext() {
|
||||
BOOL result = wglMakeCurrent(NULL, NULL);
|
||||
DCHECK(result);
|
||||
if (swap_buffers_) {
|
||||
result = SwapBuffers(hdc_);
|
||||
DCHECK(result);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const HDC hdc_;
|
||||
const bool swap_buffers_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
CefRefPtr<OSRWindow> OSRWindow::Create(
|
||||
OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect) {
|
||||
DCHECK(browser_provider);
|
||||
if (!browser_provider)
|
||||
return NULL;
|
||||
|
||||
return new OSRWindow(browser_provider, transparent, show_update_rect);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<OSRWindow> OSRWindow::From(
|
||||
CefRefPtr<ClientHandlerShared::RenderHandler> renderHandler) {
|
||||
return static_cast<OSRWindow*>(renderHandler.get());
|
||||
}
|
||||
|
||||
bool OSRWindow::CreateWidget(HWND hWndParent, const RECT& rect,
|
||||
HINSTANCE hInst, LPCTSTR className) {
|
||||
DCHECK(hWnd_ == NULL && hDC_ == NULL && hRC_ == NULL);
|
||||
|
||||
RegisterOSRClass(hInst, className);
|
||||
hWnd_ = ::CreateWindow(className, 0,
|
||||
WS_BORDER | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
|
||||
hWndParent, 0, hInst, 0);
|
||||
|
||||
if (!hWnd_)
|
||||
return false;
|
||||
|
||||
SetWindowLongPtr(hWnd_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
|
||||
|
||||
// Reference released in OnDestroyed().
|
||||
AddRef();
|
||||
|
||||
#if defined(CEF_USE_ATL)
|
||||
drop_target_ = DropTargetWin::Create(this, hWnd_);
|
||||
HRESULT register_res = RegisterDragDrop(hWnd_, drop_target_);
|
||||
DCHECK_EQ(register_res, S_OK);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OSRWindow::DestroyWidget() {
|
||||
if (IsWindow(hWnd_))
|
||||
DestroyWindow(hWnd_);
|
||||
}
|
||||
|
||||
void OSRWindow::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
#if defined(CEF_USE_ATL)
|
||||
RevokeDragDrop(hWnd_);
|
||||
drop_target_ = NULL;
|
||||
#endif
|
||||
|
||||
DisableGL();
|
||||
::DestroyWindow(hWnd_);
|
||||
}
|
||||
|
||||
bool OSRWindow::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) {
|
||||
RECT window_rect = {0};
|
||||
HWND root_window = GetAncestor(hWnd_, GA_ROOT);
|
||||
if (::GetWindowRect(root_window, &window_rect)) {
|
||||
rect = CefRect(window_rect.left,
|
||||
window_rect.top,
|
||||
window_rect.right - window_rect.left,
|
||||
window_rect.bottom - window_rect.top);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OSRWindow::GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) {
|
||||
RECT clientRect;
|
||||
if (!::GetClientRect(hWnd_, &clientRect))
|
||||
return false;
|
||||
rect.x = rect.y = 0;
|
||||
rect.width = clientRect.right;
|
||||
rect.height = clientRect.bottom;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OSRWindow::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||
int viewX,
|
||||
int viewY,
|
||||
int& screenX,
|
||||
int& screenY) {
|
||||
if (!::IsWindow(hWnd_))
|
||||
return false;
|
||||
|
||||
// Convert the point from view coordinates to actual screen coordinates.
|
||||
POINT screen_pt = {viewX, viewY};
|
||||
ClientToScreen(hWnd_, &screen_pt);
|
||||
screenX = screen_pt.x;
|
||||
screenY = screen_pt.y;
|
||||
return true;
|
||||
}
|
||||
|
||||
void OSRWindow::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||
bool show) {
|
||||
if (!show) {
|
||||
renderer_.ClearPopupRects();
|
||||
browser->GetHost()->Invalidate(PET_VIEW);
|
||||
}
|
||||
renderer_.OnPopupShow(browser, show);
|
||||
}
|
||||
|
||||
void OSRWindow::OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||
const CefRect& rect) {
|
||||
renderer_.OnPopupSize(browser, rect);
|
||||
}
|
||||
|
||||
void OSRWindow::OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
PaintElementType type,
|
||||
const RectList& dirtyRects,
|
||||
const void* buffer,
|
||||
int width, int height) {
|
||||
if (painting_popup_) {
|
||||
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
|
||||
return;
|
||||
}
|
||||
if (!hDC_)
|
||||
EnableGL();
|
||||
|
||||
{
|
||||
ScopedGLContext scoped_gl_context(hDC_, hRC_, true);
|
||||
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
|
||||
if (type == PET_VIEW && !renderer_.popup_rect().IsEmpty()) {
|
||||
painting_popup_ = true;
|
||||
browser->GetHost()->Invalidate(PET_POPUP);
|
||||
painting_popup_ = false;
|
||||
}
|
||||
renderer_.Render();
|
||||
}
|
||||
}
|
||||
|
||||
void OSRWindow::OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor,
|
||||
CursorType type,
|
||||
const CefCursorInfo& custom_cursor_info) {
|
||||
if (!::IsWindow(hWnd_))
|
||||
return;
|
||||
|
||||
// Change the plugin window's cursor.
|
||||
SetClassLongPtr(hWnd_, GCLP_HCURSOR,
|
||||
static_cast<LONG>(reinterpret_cast<LONG_PTR>(cursor)));
|
||||
SetCursor(cursor);
|
||||
}
|
||||
|
||||
bool OSRWindow::StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) {
|
||||
#if defined(CEF_USE_ATL)
|
||||
if (!drop_target_)
|
||||
return false;
|
||||
current_drag_op_ = DRAG_OPERATION_NONE;
|
||||
CefBrowserHost::DragOperationsMask result =
|
||||
drop_target_->StartDragging(browser, drag_data, allowed_ops, x, y);
|
||||
current_drag_op_ = DRAG_OPERATION_NONE;
|
||||
POINT pt = {};
|
||||
GetCursorPos(&pt);
|
||||
ScreenToClient(hWnd_, &pt);
|
||||
browser->GetHost()->DragSourceEndedAt(pt.x, pt.y, result);
|
||||
browser->GetHost()->DragSourceSystemDragEnded();
|
||||
return true;
|
||||
#else
|
||||
// Cancel the drag. The dragging implementation requires ATL support.
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void OSRWindow::UpdateDragCursor(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) {
|
||||
#if defined(CEF_USE_ATL)
|
||||
current_drag_op_ = operation;
|
||||
#endif
|
||||
}
|
||||
|
||||
void OSRWindow::Invalidate() {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
CefPostTask(TID_UI, base::Bind(&OSRWindow::Invalidate, this));
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't post another task if the previous task is still pending.
|
||||
if (render_task_pending_)
|
||||
return;
|
||||
|
||||
render_task_pending_ = true;
|
||||
|
||||
// Render at 30fps.
|
||||
static const int kRenderDelay = 1000 / 30;
|
||||
CefPostDelayedTask(TID_UI, base::Bind(&OSRWindow::Render, this),
|
||||
kRenderDelay);
|
||||
}
|
||||
|
||||
void OSRWindow::WasHidden(bool hidden) {
|
||||
if (hidden == hidden_)
|
||||
return;
|
||||
CefRefPtr<CefBrowser> browser = browser_provider_->GetBrowser();
|
||||
if (!browser)
|
||||
return;
|
||||
browser->GetHost()->WasHidden(hidden);
|
||||
hidden_ = hidden;
|
||||
}
|
||||
|
||||
#if defined(CEF_USE_ATL)
|
||||
|
||||
CefBrowserHost::DragOperationsMask
|
||||
OSRWindow::OnDragEnter(CefRefPtr<CefDragData> drag_data,
|
||||
CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) {
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragEnter(
|
||||
drag_data, ev, effect);
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragOver(ev, effect);
|
||||
return current_drag_op_;
|
||||
}
|
||||
|
||||
CefBrowserHost::DragOperationsMask OSRWindow::OnDragOver(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) {
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragOver(ev, effect);
|
||||
return current_drag_op_;
|
||||
}
|
||||
|
||||
void OSRWindow::OnDragLeave() {
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragLeave();
|
||||
}
|
||||
|
||||
CefBrowserHost::DragOperationsMask
|
||||
OSRWindow::OnDrop(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) {
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragOver(ev, effect);
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDrop(ev);
|
||||
return current_drag_op_;
|
||||
}
|
||||
|
||||
#endif // defined(CEF_USE_ATL)
|
||||
|
||||
OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect)
|
||||
: renderer_(transparent, show_update_rect),
|
||||
browser_provider_(browser_provider),
|
||||
hWnd_(NULL),
|
||||
hDC_(NULL),
|
||||
hRC_(NULL),
|
||||
#if defined(CEF_USE_ATL)
|
||||
current_drag_op_(DRAG_OPERATION_NONE),
|
||||
#endif
|
||||
painting_popup_(false),
|
||||
render_task_pending_(false),
|
||||
hidden_(false) {
|
||||
}
|
||||
|
||||
OSRWindow::~OSRWindow() {
|
||||
DestroyWidget();
|
||||
}
|
||||
|
||||
void OSRWindow::Render() {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (render_task_pending_)
|
||||
render_task_pending_ = false;
|
||||
|
||||
if (!hDC_)
|
||||
EnableGL();
|
||||
|
||||
ScopedGLContext scoped_gl_context(hDC_, hRC_, true);
|
||||
renderer_.Render();
|
||||
}
|
||||
|
||||
void OSRWindow::EnableGL() {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
int format;
|
||||
|
||||
// Get the device context.
|
||||
hDC_ = GetDC(hWnd_);
|
||||
|
||||
// Set the pixel format for the DC.
|
||||
ZeroMemory(&pfd, sizeof(pfd));
|
||||
pfd.nSize = sizeof(pfd);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 24;
|
||||
pfd.cDepthBits = 16;
|
||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||
format = ChoosePixelFormat(hDC_, &pfd);
|
||||
SetPixelFormat(hDC_, format, &pfd);
|
||||
|
||||
// Create and enable the render context.
|
||||
hRC_ = wglCreateContext(hDC_);
|
||||
|
||||
ScopedGLContext scoped_gl_context(hDC_, hRC_, false);
|
||||
renderer_.Initialize();
|
||||
}
|
||||
|
||||
void OSRWindow::DisableGL() {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (!hDC_)
|
||||
return;
|
||||
|
||||
{
|
||||
ScopedGLContext scoped_gl_context(hDC_, hRC_, false);
|
||||
renderer_.Cleanup();
|
||||
}
|
||||
|
||||
if (IsWindow(hWnd_)) {
|
||||
// wglDeleteContext will make the context not current before deleting it.
|
||||
BOOL result = wglDeleteContext(hRC_);
|
||||
ALLOW_UNUSED_LOCAL(result);
|
||||
DCHECK(result);
|
||||
ReleaseDC(hWnd_, hDC_);
|
||||
}
|
||||
|
||||
hDC_ = NULL;
|
||||
hRC_ = NULL;
|
||||
}
|
||||
|
||||
void OSRWindow::OnDestroyed() {
|
||||
SetWindowLongPtr(hWnd_, GWLP_USERDATA, 0L);
|
||||
hWnd_ = NULL;
|
||||
Release();
|
||||
}
|
||||
|
||||
ATOM OSRWindow::RegisterOSRClass(HINSTANCE hInstance, LPCTSTR className) {
|
||||
WNDCLASSEX wcex;
|
||||
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_OWNDC;
|
||||
wcex.lpfnWndProc = &OSRWindow::WndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = hInstance;
|
||||
wcex.hIcon = NULL;
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = className;
|
||||
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
|
||||
return RegisterClassEx(&wcex);
|
||||
}
|
||||
|
||||
bool OSRWindow::IsOverPopupWidget(int x, int y) const {
|
||||
const CefRect& rc = renderer_.popup_rect();
|
||||
int popup_right = rc.x + rc.width;
|
||||
int popup_bottom = rc.y + rc.height;
|
||||
return (x >= rc.x) && (x < popup_right) &&
|
||||
(y >= rc.y) && (y < popup_bottom);
|
||||
}
|
||||
|
||||
int OSRWindow::GetPopupXOffset() const {
|
||||
return renderer_.original_popup_rect().x - renderer_.popup_rect().x;
|
||||
}
|
||||
|
||||
int OSRWindow::GetPopupYOffset() const {
|
||||
return renderer_.original_popup_rect().y - renderer_.popup_rect().y;
|
||||
}
|
||||
|
||||
void OSRWindow::ApplyPopupOffset(int& x, int& y) const {
|
||||
if (IsOverPopupWidget(x, y)) {
|
||||
x += GetPopupXOffset();
|
||||
y += GetPopupYOffset();
|
||||
}
|
||||
}
|
||||
|
||||
// Plugin window procedure.
|
||||
// static
|
||||
LRESULT CALLBACK OSRWindow::WndProc(HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam) {
|
||||
static POINT lastMousePos, curMousePos;
|
||||
static bool mouseRotation = false;
|
||||
static bool mouseTracking = false;
|
||||
|
||||
static int lastClickX = 0;
|
||||
static int lastClickY = 0;
|
||||
static CefBrowserHost::MouseButtonType lastClickButton = MBT_LEFT;
|
||||
static int gLastClickCount = 0;
|
||||
static double gLastClickTime = 0;
|
||||
|
||||
static bool gLastMouseDownOnView = false;
|
||||
|
||||
OSRWindow* window =
|
||||
reinterpret_cast<OSRWindow*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
|
||||
CefRefPtr<CefBrowserHost> browser;
|
||||
if (window && window->browser_provider_->GetBrowser().get())
|
||||
browser = window->browser_provider_->GetBrowser()->GetHost();
|
||||
|
||||
LONG currentTime = 0;
|
||||
bool cancelPreviousClick = false;
|
||||
|
||||
if (message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN ||
|
||||
message == WM_MBUTTONDOWN || message == WM_MOUSEMOVE ||
|
||||
message == WM_MOUSELEAVE) {
|
||||
currentTime = GetMessageTime();
|
||||
int x = GET_X_LPARAM(lParam);
|
||||
int y = GET_Y_LPARAM(lParam);
|
||||
cancelPreviousClick =
|
||||
(abs(lastClickX - x) > (GetSystemMetrics(SM_CXDOUBLECLK) / 2))
|
||||
|| (abs(lastClickY - y) > (GetSystemMetrics(SM_CYDOUBLECLK) / 2))
|
||||
|| ((currentTime - gLastClickTime) > GetDoubleClickTime());
|
||||
if (cancelPreviousClick &&
|
||||
(message == WM_MOUSEMOVE || message == WM_MOUSELEAVE)) {
|
||||
gLastClickCount = 0;
|
||||
lastClickX = 0;
|
||||
lastClickY = 0;
|
||||
gLastClickTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (message) {
|
||||
case WM_DESTROY:
|
||||
if (window)
|
||||
window->OnDestroyed();
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN: {
|
||||
SetCapture(hWnd);
|
||||
SetFocus(hWnd);
|
||||
int x = GET_X_LPARAM(lParam);
|
||||
int y = GET_Y_LPARAM(lParam);
|
||||
if (wParam & MK_SHIFT) {
|
||||
// Start rotation effect.
|
||||
lastMousePos.x = curMousePos.x = x;
|
||||
lastMousePos.y = curMousePos.y = y;
|
||||
mouseRotation = true;
|
||||
} else {
|
||||
CefBrowserHost::MouseButtonType btnType =
|
||||
(message == WM_LBUTTONDOWN ? MBT_LEFT : (
|
||||
message == WM_RBUTTONDOWN ? MBT_RIGHT : MBT_MIDDLE));
|
||||
if (!cancelPreviousClick && (btnType == lastClickButton)) {
|
||||
++gLastClickCount;
|
||||
} else {
|
||||
gLastClickCount = 1;
|
||||
lastClickX = x;
|
||||
lastClickY = y;
|
||||
}
|
||||
gLastClickTime = currentTime;
|
||||
lastClickButton = btnType;
|
||||
|
||||
if (browser.get()) {
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = x;
|
||||
mouse_event.y = y;
|
||||
gLastMouseDownOnView = !window->IsOverPopupWidget(x, y);
|
||||
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
browser->SendMouseClickEvent(mouse_event, btnType, false,
|
||||
gLastClickCount);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
if (GetCapture() == hWnd)
|
||||
ReleaseCapture();
|
||||
if (mouseRotation) {
|
||||
// End rotation effect.
|
||||
mouseRotation = false;
|
||||
window->renderer_.SetSpin(0, 0);
|
||||
window->Invalidate();
|
||||
} else {
|
||||
int x = GET_X_LPARAM(lParam);
|
||||
int y = GET_Y_LPARAM(lParam);
|
||||
CefBrowserHost::MouseButtonType btnType =
|
||||
(message == WM_LBUTTONUP ? MBT_LEFT : (
|
||||
message == WM_RBUTTONUP ? MBT_RIGHT : MBT_MIDDLE));
|
||||
if (browser.get()) {
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = x;
|
||||
mouse_event.y = y;
|
||||
if (gLastMouseDownOnView &&
|
||||
window->IsOverPopupWidget(x, y) &&
|
||||
(window->GetPopupXOffset() || window->GetPopupYOffset())) {
|
||||
break;
|
||||
}
|
||||
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
browser->SendMouseClickEvent(mouse_event, btnType, true,
|
||||
gLastClickCount);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEMOVE: {
|
||||
int x = GET_X_LPARAM(lParam);
|
||||
int y = GET_Y_LPARAM(lParam);
|
||||
if (mouseRotation) {
|
||||
// Apply rotation effect.
|
||||
curMousePos.x = x;
|
||||
curMousePos.y = y;
|
||||
window->renderer_.IncrementSpin((curMousePos.x - lastMousePos.x),
|
||||
(curMousePos.y - lastMousePos.y));
|
||||
lastMousePos.x = curMousePos.x;
|
||||
lastMousePos.y = curMousePos.y;
|
||||
window->Invalidate();
|
||||
} else {
|
||||
if (!mouseTracking) {
|
||||
// Start tracking mouse leave. Required for the WM_MOUSELEAVE event to
|
||||
// be generated.
|
||||
TRACKMOUSEEVENT tme;
|
||||
tme.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
tme.hwndTrack = hWnd;
|
||||
TrackMouseEvent(&tme);
|
||||
mouseTracking = true;
|
||||
}
|
||||
if (browser.get()) {
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = x;
|
||||
mouse_event.y = y;
|
||||
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
browser->SendMouseMoveEvent(mouse_event, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSELEAVE:
|
||||
if (mouseTracking) {
|
||||
// Stop tracking mouse leave.
|
||||
TRACKMOUSEEVENT tme;
|
||||
tme.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||
tme.dwFlags = TME_LEAVE & TME_CANCEL;
|
||||
tme.hwndTrack = hWnd;
|
||||
TrackMouseEvent(&tme);
|
||||
mouseTracking = false;
|
||||
}
|
||||
if (browser.get()) {
|
||||
// Determine the cursor position in screen coordinates.
|
||||
POINT p;
|
||||
::GetCursorPos(&p);
|
||||
::ScreenToClient(hWnd, &p);
|
||||
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = p.x;
|
||||
mouse_event.y = p.y;
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
browser->SendMouseMoveEvent(mouse_event, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
if (browser.get()) {
|
||||
POINT screen_point = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||
HWND scrolled_wnd = ::WindowFromPoint(screen_point);
|
||||
if (scrolled_wnd != hWnd) {
|
||||
break;
|
||||
}
|
||||
ScreenToClient(hWnd, &screen_point);
|
||||
int delta = GET_WHEEL_DELTA_WPARAM(wParam);
|
||||
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = screen_point.x;
|
||||
mouse_event.y = screen_point.y;
|
||||
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
|
||||
browser->SendMouseWheelEvent(mouse_event,
|
||||
IsKeyDown(VK_SHIFT) ? delta : 0,
|
||||
!IsKeyDown(VK_SHIFT) ? delta : 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
if (browser.get())
|
||||
browser->WasResized();
|
||||
break;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
case WM_KILLFOCUS:
|
||||
if (browser.get())
|
||||
browser->SendFocusEvent(message == WM_SETFOCUS);
|
||||
break;
|
||||
|
||||
case WM_CAPTURECHANGED:
|
||||
case WM_CANCELMODE:
|
||||
if (!mouseRotation) {
|
||||
if (browser.get())
|
||||
browser->SendCaptureLostEvent();
|
||||
}
|
||||
break;
|
||||
case WM_SYSCHAR:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
case WM_CHAR: {
|
||||
CefKeyEvent event;
|
||||
event.windows_key_code = wParam;
|
||||
event.native_key_code = lParam;
|
||||
event.is_system_key = message == WM_SYSCHAR ||
|
||||
message == WM_SYSKEYDOWN ||
|
||||
message == WM_SYSKEYUP;
|
||||
|
||||
if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
|
||||
event.type = KEYEVENT_RAWKEYDOWN;
|
||||
else if (message == WM_KEYUP || message == WM_SYSKEYUP)
|
||||
event.type = KEYEVENT_KEYUP;
|
||||
else
|
||||
event.type = KEYEVENT_CHAR;
|
||||
event.modifiers = GetCefKeyboardModifiers(wParam, lParam);
|
||||
if (browser.get())
|
||||
browser->SendKeyEvent(event);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_PAINT: {
|
||||
PAINTSTRUCT ps;
|
||||
RECT rc;
|
||||
BeginPaint(hWnd, &ps);
|
||||
rc = ps.rcPaint;
|
||||
EndPaint(hWnd, &ps);
|
||||
if (browser.get())
|
||||
browser->Invalidate(PET_VIEW);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_ERASEBKGND:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
} // namespace client
|
@ -1,140 +0,0 @@
|
||||
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_OSR_WIDGET_WIN_H_
|
||||
#define CEF_TESTS_CEFCLIENT_OSR_WIDGET_WIN_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_render_handler.h"
|
||||
#include "cefclient/client_handler_shared.h"
|
||||
#include "cefclient/osr_dragdrop_win.h"
|
||||
#include "cefclient/osr_renderer.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
class OSRBrowserProvider {
|
||||
public:
|
||||
virtual CefRefPtr<CefBrowser> GetBrowser() =0;
|
||||
|
||||
protected:
|
||||
virtual ~OSRBrowserProvider() {}
|
||||
};
|
||||
|
||||
class OSRWindow : public ClientHandlerShared::RenderHandler
|
||||
#if defined(CEF_USE_ATL)
|
||||
, public OsrDragEvents
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
// Create a new OSRWindow instance. |browser_provider| must outlive this
|
||||
// object.
|
||||
static CefRefPtr<OSRWindow> Create(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect);
|
||||
|
||||
static CefRefPtr<OSRWindow> From(
|
||||
CefRefPtr<ClientHandlerShared::RenderHandler> renderHandler);
|
||||
|
||||
// Create the underlying window.
|
||||
bool CreateWidget(HWND hWndParent, const RECT& rect,
|
||||
HINSTANCE hInst, LPCTSTR className);
|
||||
|
||||
// Destroy the underlying window.
|
||||
void DestroyWidget();
|
||||
|
||||
HWND hwnd() const {
|
||||
return hWnd_;
|
||||
}
|
||||
|
||||
// ClientHandlerShared::RenderHandler methods
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
|
||||
// CefRenderHandler methods
|
||||
bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) OVERRIDE;
|
||||
bool GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) OVERRIDE;
|
||||
bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||
int viewX,
|
||||
int viewY,
|
||||
int& screenX,
|
||||
int& screenY) OVERRIDE;
|
||||
void OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||
bool show) OVERRIDE;
|
||||
void OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||
const CefRect& rect) OVERRIDE;
|
||||
void OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
PaintElementType type,
|
||||
const RectList& dirtyRects,
|
||||
const void* buffer,
|
||||
int width,
|
||||
int height) OVERRIDE;
|
||||
void OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor,
|
||||
CursorType type,
|
||||
const CefCursorInfo& custom_cursor_info) OVERRIDE;
|
||||
bool StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) OVERRIDE;
|
||||
void UpdateDragCursor(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) OVERRIDE;
|
||||
|
||||
#if defined(CEF_USE_ATL)
|
||||
// OsrDragEvents methods
|
||||
CefBrowserHost::DragOperationsMask OnDragEnter(
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) OVERRIDE;
|
||||
CefBrowserHost::DragOperationsMask OnDragOver(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) OVERRIDE;
|
||||
void OnDragLeave() OVERRIDE;
|
||||
CefBrowserHost::DragOperationsMask OnDrop(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) OVERRIDE;
|
||||
#endif // defined(CEF_USE_ATL)
|
||||
|
||||
void Invalidate();
|
||||
void WasHidden(bool hidden);
|
||||
|
||||
private:
|
||||
OSRWindow(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect);
|
||||
~OSRWindow();
|
||||
|
||||
void Render();
|
||||
void EnableGL();
|
||||
void DisableGL();
|
||||
void OnDestroyed();
|
||||
static ATOM RegisterOSRClass(HINSTANCE hInstance, LPCTSTR className);
|
||||
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
bool IsOverPopupWidget(int x, int y) const;
|
||||
int GetPopupXOffset() const;
|
||||
int GetPopupYOffset() const;
|
||||
void ApplyPopupOffset(int& x, int& y) const;
|
||||
|
||||
OsrRenderer renderer_;
|
||||
OSRBrowserProvider* browser_provider_;
|
||||
HWND hWnd_;
|
||||
HDC hDC_;
|
||||
HGLRC hRC_;
|
||||
|
||||
#if defined(CEF_USE_ATL)
|
||||
CComPtr<DropTargetWin> drop_target_;
|
||||
CefRenderHandler::DragOperation current_drag_op_;
|
||||
#endif
|
||||
|
||||
bool painting_popup_;
|
||||
bool render_task_pending_;
|
||||
bool hidden_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(OSRWindow);
|
||||
DISALLOW_COPY_AND_ASSIGN(OSRWindow);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_OSR_WIDGET_WIN_H_
|
903
tests/cefclient/osr_window_win.cc
Normal file
903
tests/cefclient/osr_window_win.cc
Normal file
@ -0,0 +1,903 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/osr_window_win.h"
|
||||
|
||||
#include <windowsx.h>
|
||||
|
||||
#include "include/base/cef_build.h"
|
||||
#include "cefclient/main_message_loop.h"
|
||||
#include "cefclient/resource.h"
|
||||
#include "cefclient/util_win.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
namespace {
|
||||
|
||||
const wchar_t kWndClass[] = L"Client_OsrWindow";
|
||||
|
||||
// Render at 30fps during rotation.
|
||||
const int kRenderDelay = 1000 / 30;
|
||||
|
||||
// Helper that calls wglMakeCurrent.
|
||||
class ScopedGLContext {
|
||||
public:
|
||||
ScopedGLContext(HDC hdc, HGLRC hglrc, bool swap_buffers)
|
||||
: hdc_(hdc),
|
||||
swap_buffers_(swap_buffers) {
|
||||
BOOL result = wglMakeCurrent(hdc, hglrc);
|
||||
ALLOW_UNUSED_LOCAL(result);
|
||||
DCHECK(result);
|
||||
}
|
||||
~ScopedGLContext() {
|
||||
BOOL result = wglMakeCurrent(NULL, NULL);
|
||||
DCHECK(result);
|
||||
if (swap_buffers_) {
|
||||
result = SwapBuffers(hdc_);
|
||||
DCHECK(result);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const HDC hdc_;
|
||||
const bool swap_buffers_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
OsrWindowWin::OsrWindowWin(Delegate* delegate,
|
||||
bool transparent,
|
||||
bool show_update_rect)
|
||||
: delegate_(delegate),
|
||||
renderer_(transparent, show_update_rect),
|
||||
hwnd_(NULL),
|
||||
hdc_(NULL),
|
||||
hrc_(NULL),
|
||||
client_rect_(),
|
||||
painting_popup_(false),
|
||||
render_task_pending_(false),
|
||||
hidden_(false),
|
||||
last_mouse_pos_(),
|
||||
current_mouse_pos_(),
|
||||
mouse_rotation_(false),
|
||||
mouse_tracking_(false),
|
||||
last_click_x_(0),
|
||||
last_click_y_(0),
|
||||
last_click_button_(MBT_LEFT),
|
||||
last_click_count_(0),
|
||||
last_click_time_(0),
|
||||
last_mouse_down_on_view_(false) {
|
||||
DCHECK(delegate_);
|
||||
}
|
||||
|
||||
OsrWindowWin::~OsrWindowWin() {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
// The native window should have already been destroyed.
|
||||
DCHECK(!hwnd_);
|
||||
}
|
||||
|
||||
void OsrWindowWin::CreateBrowser(HWND parent_hwnd,
|
||||
const RECT& rect,
|
||||
CefRefPtr<CefClient> handler,
|
||||
const CefBrowserSettings& settings,
|
||||
const std::string& startup_url) {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
// Execute this method on the UI thread.
|
||||
CefPostTask(TID_UI, base::Bind(&OsrWindowWin::CreateBrowser, this,
|
||||
parent_hwnd, rect, handler, settings,
|
||||
startup_url));
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the native window.
|
||||
Create(parent_hwnd, rect);
|
||||
|
||||
CefWindowInfo window_info;
|
||||
window_info.SetAsWindowless(hwnd_, renderer_.IsTransparent());
|
||||
|
||||
// Create the browser asynchronously.
|
||||
CefBrowserHost::CreateBrowser(window_info, handler, startup_url, settings,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void OsrWindowWin::ShowPopup(HWND parent_hwnd,
|
||||
int x, int y, size_t width, size_t height) {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
// Execute this method on the UI thread.
|
||||
CefPostTask(TID_UI, base::Bind(&OsrWindowWin::ShowPopup, this,
|
||||
parent_hwnd, x, y, width, height));
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(browser_.get());
|
||||
|
||||
// Create the native window.
|
||||
const RECT rect = {x, y, x + width, y + height};
|
||||
Create(parent_hwnd, rect);
|
||||
|
||||
// Send resize notification so the compositor is assigned the correct
|
||||
// viewport size and begins rendering.
|
||||
browser_->GetHost()->WasResized();
|
||||
|
||||
Show();
|
||||
}
|
||||
|
||||
void OsrWindowWin::Show() {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
// Execute this method on the UI thread.
|
||||
CefPostTask(TID_UI, base::Bind(&OsrWindowWin::Show, this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!browser_)
|
||||
return;
|
||||
|
||||
// Show the native window if not currently visible.
|
||||
if (hwnd_ && !::IsWindowVisible(hwnd_))
|
||||
ShowWindow(hwnd_, SW_SHOW);
|
||||
|
||||
if (hidden_) {
|
||||
// Set the browser as visible.
|
||||
browser_->GetHost()->WasHidden(false);
|
||||
hidden_ = false;
|
||||
}
|
||||
|
||||
// Give focus to the browser.
|
||||
browser_->GetHost()->SendFocusEvent(true);
|
||||
}
|
||||
|
||||
void OsrWindowWin::Hide() {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
// Execute this method on the UI thread.
|
||||
CefPostTask(TID_UI, base::Bind(&OsrWindowWin::Hide, this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!browser_)
|
||||
return;
|
||||
|
||||
// Remove focus from the browser.
|
||||
browser_->GetHost()->SendFocusEvent(false);
|
||||
|
||||
if (!hidden_) {
|
||||
// Set the browser as hidden.
|
||||
browser_->GetHost()->WasHidden(true);
|
||||
hidden_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OsrWindowWin::SetBounds(int x, int y, size_t width, size_t height) {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
// Execute this method on the UI thread.
|
||||
CefPostTask(TID_UI, base::Bind(&OsrWindowWin::SetBounds, this, x, y, width,
|
||||
height));
|
||||
return;
|
||||
}
|
||||
|
||||
if (hwnd_) {
|
||||
// Set the browser window bounds.
|
||||
::SetWindowPos(hwnd_, NULL, x, y, width, height, SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
|
||||
void OsrWindowWin::SetFocus() {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
// Execute this method on the UI thread.
|
||||
CefPostTask(TID_UI, base::Bind(&OsrWindowWin::SetFocus, this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (hwnd_) {
|
||||
// Give focus to the native window.
|
||||
::SetFocus(hwnd_);
|
||||
}
|
||||
}
|
||||
|
||||
void OsrWindowWin::Create(HWND parent_hwnd, const RECT& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
DCHECK(!hwnd_ && !hdc_ && !hrc_);
|
||||
DCHECK(parent_hwnd);
|
||||
DCHECK(!::IsRectEmpty(&rect));
|
||||
|
||||
HINSTANCE hInst = ::GetModuleHandle(NULL);
|
||||
|
||||
RegisterOsrClass(hInst);
|
||||
|
||||
// Create the native window with a border so it's easier to visually identify
|
||||
// OSR windows.
|
||||
hwnd_ = ::CreateWindow(kWndClass, 0,
|
||||
WS_BORDER | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
|
||||
parent_hwnd, 0, hInst, 0);
|
||||
CHECK(hwnd_);
|
||||
|
||||
client_rect_ = rect;
|
||||
|
||||
// Associate |this| with the window.
|
||||
SetUserDataPtr(hwnd_, this);
|
||||
|
||||
#if defined(CEF_USE_ATL)
|
||||
// Create/register the drag&drop handler.
|
||||
drop_target_ = DropTargetWin::Create(this, hwnd_);
|
||||
HRESULT register_res = RegisterDragDrop(hwnd_, drop_target_);
|
||||
DCHECK_EQ(register_res, S_OK);
|
||||
#endif
|
||||
|
||||
// Notify the window owner.
|
||||
NotifyNativeWindowCreated(hwnd_);
|
||||
}
|
||||
|
||||
void OsrWindowWin::Destroy() {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
DCHECK(hwnd_ != NULL);
|
||||
|
||||
#if defined(CEF_USE_ATL)
|
||||
// Revoke/delete the drag&drop handler.
|
||||
RevokeDragDrop(hwnd_);
|
||||
drop_target_ = NULL;
|
||||
#endif
|
||||
|
||||
DisableGL();
|
||||
|
||||
// Destroy the native window.
|
||||
::DestroyWindow(hwnd_);
|
||||
hwnd_ = NULL;
|
||||
}
|
||||
|
||||
void OsrWindowWin::EnableGL() {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
int format;
|
||||
|
||||
// Get the device context.
|
||||
hdc_ = GetDC(hwnd_);
|
||||
|
||||
// Set the pixel format for the DC.
|
||||
ZeroMemory(&pfd, sizeof(pfd));
|
||||
pfd.nSize = sizeof(pfd);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 24;
|
||||
pfd.cDepthBits = 16;
|
||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||
format = ChoosePixelFormat(hdc_, &pfd);
|
||||
SetPixelFormat(hdc_, format, &pfd);
|
||||
|
||||
// Create and enable the render context.
|
||||
hrc_ = wglCreateContext(hdc_);
|
||||
|
||||
ScopedGLContext scoped_gl_context(hdc_, hrc_, false);
|
||||
renderer_.Initialize();
|
||||
}
|
||||
|
||||
void OsrWindowWin::DisableGL() {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (!hdc_)
|
||||
return;
|
||||
|
||||
{
|
||||
ScopedGLContext scoped_gl_context(hdc_, hrc_, false);
|
||||
renderer_.Cleanup();
|
||||
}
|
||||
|
||||
if (IsWindow(hwnd_)) {
|
||||
// wglDeleteContext will make the context not current before deleting it.
|
||||
BOOL result = wglDeleteContext(hrc_);
|
||||
ALLOW_UNUSED_LOCAL(result);
|
||||
DCHECK(result);
|
||||
ReleaseDC(hwnd_, hdc_);
|
||||
}
|
||||
|
||||
hdc_ = NULL;
|
||||
hrc_ = NULL;
|
||||
}
|
||||
|
||||
void OsrWindowWin::Invalidate() {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
// Don't post another task if the previous task is still pending.
|
||||
if (render_task_pending_)
|
||||
return;
|
||||
render_task_pending_ = true;
|
||||
|
||||
CefPostDelayedTask(TID_UI, base::Bind(&OsrWindowWin::Render, this),
|
||||
kRenderDelay);
|
||||
}
|
||||
|
||||
void OsrWindowWin::Render() {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (render_task_pending_)
|
||||
render_task_pending_ = false;
|
||||
|
||||
if (!hdc_)
|
||||
EnableGL();
|
||||
|
||||
ScopedGLContext scoped_gl_context(hdc_, hrc_, true);
|
||||
renderer_.Render();
|
||||
}
|
||||
|
||||
void OsrWindowWin::NotifyNativeWindowCreated(HWND hwnd) {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(
|
||||
base::Bind(&OsrWindowWin::NotifyNativeWindowCreated, this, hwnd));
|
||||
return;
|
||||
}
|
||||
|
||||
delegate_->OnOsrNativeWindowCreated(hwnd);
|
||||
}
|
||||
|
||||
// static
|
||||
void OsrWindowWin::RegisterOsrClass(HINSTANCE hInstance) {
|
||||
// Only register the class one time.
|
||||
static bool class_registered = false;
|
||||
if (class_registered)
|
||||
return;
|
||||
class_registered = true;
|
||||
|
||||
WNDCLASSEX wcex;
|
||||
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_OWNDC;
|
||||
wcex.lpfnWndProc = OsrWndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = hInstance;
|
||||
wcex.hIcon = NULL;
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = kWndClass;
|
||||
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
|
||||
|
||||
RegisterClassEx(&wcex);
|
||||
}
|
||||
|
||||
// static
|
||||
LRESULT CALLBACK OsrWindowWin::OsrWndProc(HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
OsrWindowWin* self = GetUserDataPtr<OsrWindowWin*>(hWnd);
|
||||
if (!self)
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
|
||||
switch (message) {
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_MOUSELEAVE:
|
||||
case WM_MOUSEWHEEL:
|
||||
if (self)
|
||||
self->OnMouseEvent(message, wParam, lParam);
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
if (self)
|
||||
self->OnSize();
|
||||
break;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
case WM_KILLFOCUS:
|
||||
if (self)
|
||||
self->OnFocus(message == WM_SETFOCUS);
|
||||
break;
|
||||
|
||||
case WM_CAPTURECHANGED:
|
||||
case WM_CANCELMODE:
|
||||
if (self)
|
||||
self->OnCaptureLost();
|
||||
break;
|
||||
|
||||
case WM_SYSCHAR:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
case WM_CHAR:
|
||||
if (self)
|
||||
self->OnKeyEvent(message, wParam, lParam);
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
if (self)
|
||||
self->OnPaint();
|
||||
return 0;
|
||||
|
||||
case WM_ERASEBKGND:
|
||||
// Never erase the background.
|
||||
return 0;
|
||||
|
||||
case WM_NCDESTROY:
|
||||
// Clear the reference to |self|.
|
||||
SetUserDataPtr(hWnd, NULL);
|
||||
self->hwnd_ = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
CefRefPtr<CefBrowserHost> browser_host;
|
||||
if (browser_)
|
||||
browser_host = browser_->GetHost();
|
||||
|
||||
LONG currentTime = 0;
|
||||
bool cancelPreviousClick = false;
|
||||
|
||||
if (message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN ||
|
||||
message == WM_MBUTTONDOWN || message == WM_MOUSEMOVE ||
|
||||
message == WM_MOUSELEAVE) {
|
||||
currentTime = GetMessageTime();
|
||||
int x = GET_X_LPARAM(lParam);
|
||||
int y = GET_Y_LPARAM(lParam);
|
||||
cancelPreviousClick =
|
||||
(abs(last_click_x_ - x) > (GetSystemMetrics(SM_CXDOUBLECLK) / 2))
|
||||
|| (abs(last_click_y_ - y) > (GetSystemMetrics(SM_CYDOUBLECLK) / 2))
|
||||
|| ((currentTime - last_click_time_) > GetDoubleClickTime());
|
||||
if (cancelPreviousClick &&
|
||||
(message == WM_MOUSEMOVE || message == WM_MOUSELEAVE)) {
|
||||
last_click_count_ = 0;
|
||||
last_click_x_ = 0;
|
||||
last_click_y_ = 0;
|
||||
last_click_time_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch(message) {
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN: {
|
||||
::SetCapture(hwnd_);
|
||||
::SetFocus(hwnd_);
|
||||
int x = GET_X_LPARAM(lParam);
|
||||
int y = GET_Y_LPARAM(lParam);
|
||||
if (wParam & MK_SHIFT) {
|
||||
// Start rotation effect.
|
||||
last_mouse_pos_.x = current_mouse_pos_.x = x;
|
||||
last_mouse_pos_.y = current_mouse_pos_.y = y;
|
||||
mouse_rotation_ = true;
|
||||
} else {
|
||||
CefBrowserHost::MouseButtonType btnType =
|
||||
(message == WM_LBUTTONDOWN ? MBT_LEFT : (
|
||||
message == WM_RBUTTONDOWN ? MBT_RIGHT : MBT_MIDDLE));
|
||||
if (!cancelPreviousClick && (btnType == last_click_button_)) {
|
||||
++last_click_count_;
|
||||
} else {
|
||||
last_click_count_ = 1;
|
||||
last_click_x_ = x;
|
||||
last_click_y_ = y;
|
||||
}
|
||||
last_click_time_ = currentTime;
|
||||
last_click_button_ = btnType;
|
||||
|
||||
CefRefPtr<CefBrowserHost> browser_host = browser_->GetHost();
|
||||
if (browser_host) {
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = x;
|
||||
mouse_event.y = y;
|
||||
last_mouse_down_on_view_ = !IsOverPopupWidget(x, y);
|
||||
ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
browser_host->SendMouseClickEvent(mouse_event, btnType, false,
|
||||
last_click_count_);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
if (GetCapture() == hwnd_)
|
||||
ReleaseCapture();
|
||||
if (mouse_rotation_) {
|
||||
// End rotation effect.
|
||||
mouse_rotation_ = false;
|
||||
renderer_.SetSpin(0, 0);
|
||||
Invalidate();
|
||||
} else {
|
||||
int x = GET_X_LPARAM(lParam);
|
||||
int y = GET_Y_LPARAM(lParam);
|
||||
CefBrowserHost::MouseButtonType btnType =
|
||||
(message == WM_LBUTTONUP ? MBT_LEFT : (
|
||||
message == WM_RBUTTONUP ? MBT_RIGHT : MBT_MIDDLE));
|
||||
if (browser_host) {
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = x;
|
||||
mouse_event.y = y;
|
||||
if (last_mouse_down_on_view_ &&
|
||||
IsOverPopupWidget(x, y) &&
|
||||
(GetPopupXOffset() || GetPopupYOffset())) {
|
||||
break;
|
||||
}
|
||||
ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
browser_host->SendMouseClickEvent(mouse_event, btnType, true,
|
||||
last_click_count_);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEMOVE: {
|
||||
int x = GET_X_LPARAM(lParam);
|
||||
int y = GET_Y_LPARAM(lParam);
|
||||
if (mouse_rotation_) {
|
||||
// Apply rotation effect.
|
||||
current_mouse_pos_.x = x;
|
||||
current_mouse_pos_.y = y;
|
||||
renderer_.IncrementSpin(
|
||||
current_mouse_pos_.x - last_mouse_pos_.x,
|
||||
current_mouse_pos_.y - last_mouse_pos_.y);
|
||||
last_mouse_pos_.x = current_mouse_pos_.x;
|
||||
last_mouse_pos_.y = current_mouse_pos_.y;
|
||||
Invalidate();
|
||||
} else {
|
||||
if (!mouse_tracking_) {
|
||||
// Start tracking mouse leave. Required for the WM_MOUSELEAVE event to
|
||||
// be generated.
|
||||
TRACKMOUSEEVENT tme;
|
||||
tme.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
tme.hwndTrack = hwnd_;
|
||||
TrackMouseEvent(&tme);
|
||||
mouse_tracking_ = true;
|
||||
}
|
||||
|
||||
if (browser_host) {
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = x;
|
||||
mouse_event.y = y;
|
||||
ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
browser_host->SendMouseMoveEvent(mouse_event, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSELEAVE: {
|
||||
if (mouse_tracking_) {
|
||||
// Stop tracking mouse leave.
|
||||
TRACKMOUSEEVENT tme;
|
||||
tme.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||
tme.dwFlags = TME_LEAVE & TME_CANCEL;
|
||||
tme.hwndTrack = hwnd_;
|
||||
TrackMouseEvent(&tme);
|
||||
mouse_tracking_ = false;
|
||||
}
|
||||
|
||||
if (browser_host) {
|
||||
// Determine the cursor position in screen coordinates.
|
||||
POINT p;
|
||||
::GetCursorPos(&p);
|
||||
::ScreenToClient(hwnd_, &p);
|
||||
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = p.x;
|
||||
mouse_event.y = p.y;
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
browser_host->SendMouseMoveEvent(mouse_event, true);
|
||||
}
|
||||
} break;
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
if (browser_host) {
|
||||
POINT screen_point = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||
HWND scrolled_wnd = ::WindowFromPoint(screen_point);
|
||||
if (scrolled_wnd != hwnd_)
|
||||
break;
|
||||
|
||||
ScreenToClient(hwnd_, &screen_point);
|
||||
int delta = GET_WHEEL_DELTA_WPARAM(wParam);
|
||||
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = screen_point.x;
|
||||
mouse_event.y = screen_point.y;
|
||||
ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
|
||||
browser_host->SendMouseWheelEvent(mouse_event,
|
||||
IsKeyDown(VK_SHIFT) ? delta : 0,
|
||||
!IsKeyDown(VK_SHIFT) ? delta : 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnSize() {
|
||||
// Keep |client_rect_| up to date.
|
||||
::GetClientRect(hwnd_, &client_rect_);
|
||||
|
||||
if (browser_)
|
||||
browser_->GetHost()->WasResized();
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnFocus(bool setFocus) {
|
||||
if (browser_)
|
||||
browser_->GetHost()->SendFocusEvent(setFocus);
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnCaptureLost() {
|
||||
if (mouse_rotation_)
|
||||
return;
|
||||
|
||||
if (browser_)
|
||||
browser_->GetHost()->SendCaptureLostEvent();
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnKeyEvent(UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
if (!browser_)
|
||||
return;
|
||||
|
||||
CefKeyEvent event;
|
||||
event.windows_key_code = wParam;
|
||||
event.native_key_code = lParam;
|
||||
event.is_system_key = message == WM_SYSCHAR ||
|
||||
message == WM_SYSKEYDOWN ||
|
||||
message == WM_SYSKEYUP;
|
||||
|
||||
if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
|
||||
event.type = KEYEVENT_RAWKEYDOWN;
|
||||
else if (message == WM_KEYUP || message == WM_SYSKEYUP)
|
||||
event.type = KEYEVENT_KEYUP;
|
||||
else
|
||||
event.type = KEYEVENT_CHAR;
|
||||
event.modifiers = GetCefKeyboardModifiers(wParam, lParam);
|
||||
|
||||
browser_->GetHost()->SendKeyEvent(event);
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnPaint() {
|
||||
// Paint nothing here. Invalidate will cause OnPaint to be called for the
|
||||
// render handler.
|
||||
PAINTSTRUCT ps;
|
||||
BeginPaint(hwnd_, &ps);
|
||||
EndPaint(hwnd_, &ps);
|
||||
|
||||
if (browser_)
|
||||
browser_->GetHost()->Invalidate(PET_VIEW);
|
||||
}
|
||||
|
||||
bool OsrWindowWin::IsOverPopupWidget(int x, int y) const {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
const CefRect& rc = renderer_.popup_rect();
|
||||
int popup_right = rc.x + rc.width;
|
||||
int popup_bottom = rc.y + rc.height;
|
||||
return (x >= rc.x) && (x < popup_right) &&
|
||||
(y >= rc.y) && (y < popup_bottom);
|
||||
}
|
||||
|
||||
int OsrWindowWin::GetPopupXOffset() const {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
return renderer_.original_popup_rect().x - renderer_.popup_rect().x;
|
||||
}
|
||||
|
||||
int OsrWindowWin::GetPopupYOffset() const {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
return renderer_.original_popup_rect().y - renderer_.popup_rect().y;
|
||||
}
|
||||
|
||||
void OsrWindowWin::ApplyPopupOffset(int& x, int& y) const {
|
||||
if (IsOverPopupWidget(x, y)) {
|
||||
x += GetPopupXOffset();
|
||||
y += GetPopupYOffset();
|
||||
}
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
DCHECK(!browser_);
|
||||
browser_ = browser;
|
||||
|
||||
if (hwnd_) {
|
||||
// Show the browser window. Called asynchronously so that the browser has
|
||||
// time to create associated internal objects.
|
||||
CefPostTask(TID_UI, base::Bind(&OsrWindowWin::Show, this));
|
||||
}
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
// Detach |this| from the ClientHandler.
|
||||
static_cast<ClientHandlerOsr*>(browser_->GetHost()->GetClient().get())->
|
||||
DetachOsrDelegate();
|
||||
browser_ = NULL;
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool OsrWindowWin::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
RECT window_rect = {0};
|
||||
HWND root_window = GetAncestor(hwnd_, GA_ROOT);
|
||||
if (::GetWindowRect(root_window, &window_rect)) {
|
||||
rect = CefRect(window_rect.left,
|
||||
window_rect.top,
|
||||
window_rect.right - window_rect.left,
|
||||
window_rect.bottom - window_rect.top);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OsrWindowWin::GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
rect.x = rect.y = 0;
|
||||
rect.width = client_rect_.right - client_rect_.left;
|
||||
rect.height = client_rect_.bottom - client_rect_.top;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OsrWindowWin::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||
int viewX,
|
||||
int viewY,
|
||||
int& screenX,
|
||||
int& screenY) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (!::IsWindow(hwnd_))
|
||||
return false;
|
||||
|
||||
// Convert the point from view coordinates to actual screen coordinates.
|
||||
POINT screen_pt = {viewX, viewY};
|
||||
ClientToScreen(hwnd_, &screen_pt);
|
||||
screenX = screen_pt.x;
|
||||
screenY = screen_pt.y;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OsrWindowWin::GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
||||
CefScreenInfo& screen_info) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||
bool show) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (!show) {
|
||||
renderer_.ClearPopupRects();
|
||||
browser->GetHost()->Invalidate(PET_VIEW);
|
||||
}
|
||||
renderer_.OnPopupShow(browser, show);
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||
const CefRect& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
renderer_.OnPopupSize(browser, rect);
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::PaintElementType type,
|
||||
const CefRenderHandler::RectList& dirtyRects,
|
||||
const void* buffer,
|
||||
int width,
|
||||
int height) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (painting_popup_) {
|
||||
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
|
||||
return;
|
||||
}
|
||||
if (!hdc_)
|
||||
EnableGL();
|
||||
|
||||
ScopedGLContext scoped_gl_context(hdc_, hrc_, true);
|
||||
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
|
||||
if (type == PET_VIEW && !renderer_.popup_rect().IsEmpty()) {
|
||||
painting_popup_ = true;
|
||||
browser->GetHost()->Invalidate(PET_POPUP);
|
||||
painting_popup_ = false;
|
||||
}
|
||||
renderer_.Render();
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnCursorChange(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor,
|
||||
CefRenderHandler::CursorType type,
|
||||
const CefCursorInfo& custom_cursor_info) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (!::IsWindow(hwnd_))
|
||||
return;
|
||||
|
||||
// Change the plugin window's cursor.
|
||||
SetClassLongPtr(hwnd_, GCLP_HCURSOR,
|
||||
static_cast<LONG>(reinterpret_cast<LONG_PTR>(cursor)));
|
||||
SetCursor(cursor);
|
||||
}
|
||||
|
||||
bool OsrWindowWin::StartDragging(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
#if defined(CEF_USE_ATL)
|
||||
if (!drop_target_)
|
||||
return false;
|
||||
current_drag_op_ = DRAG_OPERATION_NONE;
|
||||
CefBrowserHost::DragOperationsMask result =
|
||||
drop_target_->StartDragging(browser, drag_data, allowed_ops, x, y);
|
||||
current_drag_op_ = DRAG_OPERATION_NONE;
|
||||
POINT pt = {};
|
||||
GetCursorPos(&pt);
|
||||
ScreenToClient(hwnd_, &pt);
|
||||
browser->GetHost()->DragSourceEndedAt(pt.x, pt.y, result);
|
||||
browser->GetHost()->DragSourceSystemDragEnded();
|
||||
return true;
|
||||
#else
|
||||
// Cancel the drag. The dragging implementation requires ATL support.
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void OsrWindowWin::UpdateDragCursor(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
#if defined(CEF_USE_ATL)
|
||||
current_drag_op_ = operation;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CEF_USE_ATL)
|
||||
|
||||
CefBrowserHost::DragOperationsMask
|
||||
OsrWindowWin::OnDragEnter(CefRefPtr<CefDragData> drag_data,
|
||||
CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) {
|
||||
if (browser_) {
|
||||
browser_->GetHost()->DragTargetDragEnter(drag_data, ev, effect);
|
||||
browser_->GetHost()->DragTargetDragOver(ev, effect);
|
||||
}
|
||||
return current_drag_op_;
|
||||
}
|
||||
|
||||
CefBrowserHost::DragOperationsMask
|
||||
OsrWindowWin::OnDragOver(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) {
|
||||
if (browser_)
|
||||
browser_->GetHost()->DragTargetDragOver(ev, effect);
|
||||
return current_drag_op_;
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnDragLeave() {
|
||||
if (browser_)
|
||||
browser_->GetHost()->DragTargetDragLeave();
|
||||
}
|
||||
|
||||
CefBrowserHost::DragOperationsMask
|
||||
OsrWindowWin::OnDrop(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) {
|
||||
if (browser_) {
|
||||
browser_->GetHost()->DragTargetDragOver(ev, effect);
|
||||
browser_->GetHost()->DragTargetDrop(ev);
|
||||
}
|
||||
return current_drag_op_;
|
||||
}
|
||||
|
||||
#endif // defined(CEF_USE_ATL)
|
||||
|
||||
} // namespace client
|
185
tests/cefclient/osr_window_win.h
Normal file
185
tests/cefclient/osr_window_win.h
Normal file
@ -0,0 +1,185 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_OSR_WINDOW_WIN_H_
|
||||
#define CEF_TESTS_CEFCLIENT_OSR_WINDOW_WIN_H_
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/base/cef_ref_counted.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
#include "cefclient/client_handler_osr.h"
|
||||
#include "cefclient/osr_dragdrop_win.h"
|
||||
#include "cefclient/osr_renderer.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Represents the native parent window for an off-screen browser. This object
|
||||
// must live on the CEF UI thread in order to handle CefRenderHandler callbacks.
|
||||
// The methods of this class are thread-safe unless otherwise indicated.
|
||||
class OsrWindowWin :
|
||||
public base::RefCountedThreadSafe<OsrWindowWin, CefDeleteOnUIThread>,
|
||||
public ClientHandlerOsr::OsrDelegate
|
||||
#if defined(CEF_USE_ATL)
|
||||
, public OsrDragEvents
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
// This interface is implemented by the owner of the OsrWindowWin. The
|
||||
// methods of this class will be called on the main thread.
|
||||
class Delegate {
|
||||
public:
|
||||
// Called after the native window has been created.
|
||||
virtual void OnOsrNativeWindowCreated(HWND hwnd) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Delegate() {}
|
||||
};
|
||||
|
||||
// |delegate| must outlive this object.
|
||||
OsrWindowWin(Delegate* delegate,
|
||||
bool transparent,
|
||||
bool show_update_rect);
|
||||
|
||||
// Create a new browser and native window.
|
||||
void CreateBrowser(HWND parent_hwnd,
|
||||
const RECT& rect,
|
||||
CefRefPtr<CefClient> handler,
|
||||
const CefBrowserSettings& settings,
|
||||
const std::string& startup_url);
|
||||
|
||||
// Show the popup window with correct parent and bounds in parent coordinates.
|
||||
void ShowPopup(HWND parent_hwnd, int x, int y, size_t width, size_t height);
|
||||
|
||||
void Show();
|
||||
void Hide();
|
||||
void SetBounds(int x, int y, size_t width, size_t height);
|
||||
void SetFocus();
|
||||
|
||||
private:
|
||||
// Only allow deletion via scoped_refptr.
|
||||
friend struct CefDeleteOnThread<TID_UI>;
|
||||
friend class base::RefCountedThreadSafe<OsrWindowWin, CefDeleteOnUIThread>;
|
||||
|
||||
~OsrWindowWin();
|
||||
|
||||
// Manage native window lifespan.
|
||||
void Create(HWND parent_hwnd, const RECT& rect);
|
||||
void Destroy();
|
||||
|
||||
// Manage GL context lifespan.
|
||||
void EnableGL();
|
||||
void DisableGL();
|
||||
|
||||
// Redraw what is currently in the texture.
|
||||
void Invalidate();
|
||||
void Render();
|
||||
|
||||
void NotifyNativeWindowCreated(HWND hwnd);
|
||||
|
||||
static void RegisterOsrClass(HINSTANCE hInstance);
|
||||
static LRESULT CALLBACK OsrWndProc(HWND hWnd, UINT message, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
// WndProc message handlers.
|
||||
void OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
void OnSize();
|
||||
void OnFocus(bool setFocus);
|
||||
void OnCaptureLost();
|
||||
void OnKeyEvent(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
void OnPaint();
|
||||
|
||||
// Manage popup bounds.
|
||||
bool IsOverPopupWidget(int x, int y) const;
|
||||
int GetPopupXOffset() const;
|
||||
int GetPopupYOffset() const;
|
||||
void ApplyPopupOffset(int& x, int& y) const;
|
||||
|
||||
// ClientHandlerOsr::Delegate methods.
|
||||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) OVERRIDE;
|
||||
bool GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) OVERRIDE;
|
||||
bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||
int viewX,
|
||||
int viewY,
|
||||
int& screenX,
|
||||
int& screenY) OVERRIDE;
|
||||
bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
||||
CefScreenInfo& screen_info) OVERRIDE;
|
||||
void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE;
|
||||
void OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||
const CefRect& rect) OVERRIDE;
|
||||
void OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::PaintElementType type,
|
||||
const CefRenderHandler::RectList& dirtyRects,
|
||||
const void* buffer,
|
||||
int width,
|
||||
int height) OVERRIDE;
|
||||
void OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor,
|
||||
CefRenderHandler::CursorType type,
|
||||
const CefCursorInfo& custom_cursor_info) OVERRIDE;
|
||||
bool StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) OVERRIDE;
|
||||
void UpdateDragCursor(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) OVERRIDE;
|
||||
|
||||
#if defined(CEF_USE_ATL)
|
||||
// OsrDragEvents methods.
|
||||
CefBrowserHost::DragOperationsMask OnDragEnter(
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) OVERRIDE;
|
||||
CefBrowserHost::DragOperationsMask OnDragOver(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) OVERRIDE;
|
||||
void OnDragLeave() OVERRIDE;
|
||||
CefBrowserHost::DragOperationsMask OnDrop(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) OVERRIDE;
|
||||
#endif // defined(CEF_USE_ATL)
|
||||
|
||||
// Only accessed on the main thread.
|
||||
Delegate* delegate_;
|
||||
|
||||
// The below members are only accessed on the UI thread.
|
||||
OsrRenderer renderer_;
|
||||
HWND hwnd_;
|
||||
HDC hdc_;
|
||||
HGLRC hrc_;
|
||||
|
||||
RECT client_rect_;
|
||||
|
||||
CefRefPtr<CefBrowser> browser_;
|
||||
|
||||
#if defined(CEF_USE_ATL)
|
||||
CComPtr<DropTargetWin> drop_target_;
|
||||
CefRenderHandler::DragOperation current_drag_op_;
|
||||
#endif
|
||||
|
||||
bool painting_popup_;
|
||||
bool render_task_pending_;
|
||||
bool hidden_;
|
||||
|
||||
// Mouse state tracking.
|
||||
POINT last_mouse_pos_;
|
||||
POINT current_mouse_pos_;
|
||||
bool mouse_rotation_;
|
||||
bool mouse_tracking_;
|
||||
int last_click_x_;
|
||||
int last_click_y_;
|
||||
CefBrowserHost::MouseButtonType last_click_button_;
|
||||
int last_click_count_;
|
||||
double last_click_time_;
|
||||
bool last_mouse_down_on_view_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(OsrWindowWin);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_OSR_WINDOW_WIN_H_
|
105
tests/cefclient/root_window.h
Normal file
105
tests/cefclient/root_window.h
Normal file
@ -0,0 +1,105 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_ROOT_WINDOW_H_
|
||||
#define CEF_TESTS_CEFCLIENT_ROOT_WINDOW_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "include/base/cef_ref_counted.h"
|
||||
#include "include/cef_browser.h"
|
||||
#include "cefclient/main_message_loop.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Represents a top-level native window in the browser process. While references
|
||||
// to this object are thread-safe the methods must be called on the main thread
|
||||
// unless otherwise indicated.
|
||||
class RootWindow :
|
||||
public base::RefCountedThreadSafe<RootWindow, DeleteOnMainThread> {
|
||||
public:
|
||||
// This interface is implemented by the owner of the RootWindow. The methods
|
||||
// of this class will be called on the main thread.
|
||||
class Delegate {
|
||||
public:
|
||||
// Called to execute a test. See resource.h for |test_id| values.
|
||||
virtual void OnTest(RootWindow* root_window, int test_id) = 0;
|
||||
|
||||
// Called to exit the application.
|
||||
virtual void OnExit(RootWindow* root_window) = 0;
|
||||
|
||||
// Called when the RootWindow has been destroyed.
|
||||
virtual void OnRootWindowDestroyed(RootWindow* root_window) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Delegate() {}
|
||||
};
|
||||
|
||||
// Create a new RootWindow object. This method may be called on any thread.
|
||||
// Use RootWindowManager::CreateRootWindow() or CreateRootWindowAsPopup()
|
||||
// instead of calling this method directly.
|
||||
static scoped_refptr<RootWindow> Create();
|
||||
|
||||
// Initialize as a normal window. This will create and show a browser window.
|
||||
// This method may be called on any thread.
|
||||
// |delegate| must be non-NULL and outlive this object.
|
||||
// Use RootWindowManager::CreateRootWindow() instead of calling this method
|
||||
// directly.
|
||||
virtual void Init(RootWindow::Delegate* delegate,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefRect& bounds,
|
||||
const CefBrowserSettings& settings,
|
||||
const std::string& url) = 0;
|
||||
|
||||
// Initialize as a popup window. This is used to attach a browser window that
|
||||
// will be created later. The window will be shown once the browser is
|
||||
// available. This method may be called on any thread.
|
||||
// |delegate| must be non-NULL and outlive this object.
|
||||
// Use RootWindowManager::CreateRootWindowAsPopup() instead of calling this
|
||||
// method directly.
|
||||
virtual void InitAsPopup(RootWindow::Delegate* delegate,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) = 0;
|
||||
|
||||
enum ShowMode {
|
||||
ShowNormal,
|
||||
ShowMinimized,
|
||||
ShowMaximized,
|
||||
};
|
||||
|
||||
// Show the window.
|
||||
virtual void Show(ShowMode mode) = 0;
|
||||
|
||||
// Hide the window.
|
||||
virtual void Hide() = 0;
|
||||
|
||||
// Set the window bounds in screen coordinates.
|
||||
virtual void SetBounds(int x, int y, size_t width, size_t height) = 0;
|
||||
|
||||
// Close the window. If |force| is true onunload handlers will not be
|
||||
// executed.
|
||||
virtual void Close(bool force) = 0;
|
||||
|
||||
// Returns the browser that this window contains, if any.
|
||||
virtual CefRefPtr<CefBrowser> GetBrowser() const = 0;
|
||||
|
||||
// Returns the handle for this window, if any.
|
||||
virtual CefWindowHandle GetWindowHandle() const = 0;
|
||||
|
||||
protected:
|
||||
// Allow deletion via scoped_refptr only.
|
||||
friend struct DeleteOnMainThread;
|
||||
friend class base::RefCountedThreadSafe<RootWindow, DeleteOnMainThread>;
|
||||
|
||||
virtual ~RootWindow() {}
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_ROOT_WINDOW_H_
|
129
tests/cefclient/root_window_manager.cc
Normal file
129
tests/cefclient/root_window_manager.cc
Normal file
@ -0,0 +1,129 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/root_window_manager.h"
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
#include "cefclient/main_context.h"
|
||||
#include "cefclient/test_runner.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
RootWindowManager::RootWindowManager(bool terminate_when_all_windows_closed)
|
||||
: terminate_when_all_windows_closed_(terminate_when_all_windows_closed) {
|
||||
}
|
||||
|
||||
RootWindowManager::~RootWindowManager() {
|
||||
// All root windows should already have been destroyed.
|
||||
DCHECK(root_windows_.empty());
|
||||
}
|
||||
|
||||
scoped_refptr<RootWindow> RootWindowManager::CreateRootWindow(
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefRect& bounds,
|
||||
const std::string& url) {
|
||||
CefBrowserSettings settings;
|
||||
MainContext::Get()->PopulateBrowserSettings(&settings);
|
||||
|
||||
scoped_refptr<RootWindow> root_window = RootWindow::Create();
|
||||
root_window->Init(this, with_controls, with_osr, bounds, settings,
|
||||
url.empty() ? MainContext::Get()->GetMainURL() : url);
|
||||
|
||||
// Store a reference to the root window on the main thread.
|
||||
OnRootWindowCreated(root_window);
|
||||
|
||||
return root_window;
|
||||
}
|
||||
|
||||
scoped_refptr<RootWindow> RootWindowManager::CreateRootWindowAsPopup(
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) {
|
||||
MainContext::Get()->PopulateBrowserSettings(&settings);
|
||||
|
||||
scoped_refptr<RootWindow> root_window = RootWindow::Create();
|
||||
root_window->InitAsPopup(this, with_controls, with_osr,
|
||||
popupFeatures, windowInfo, client, settings);
|
||||
|
||||
// Store a reference to the root window on the main thread.
|
||||
OnRootWindowCreated(root_window);
|
||||
|
||||
return root_window;
|
||||
}
|
||||
|
||||
scoped_refptr<RootWindow> RootWindowManager::GetWindowForBrowser(
|
||||
int browser_id) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
RootWindowSet::const_iterator it = root_windows_.begin();
|
||||
for (; it != root_windows_.end(); ++it) {
|
||||
CefRefPtr<CefBrowser> browser = (*it)->GetBrowser();
|
||||
if (browser.get() && browser->GetIdentifier() == browser_id)
|
||||
return *it;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void RootWindowManager::CloseAllWindows(bool force) {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(
|
||||
base::Bind(&RootWindowManager::CloseAllWindows, base::Unretained(this),
|
||||
force));
|
||||
return;
|
||||
}
|
||||
|
||||
if (root_windows_.empty())
|
||||
return;
|
||||
|
||||
RootWindowSet::const_iterator it = root_windows_.begin();
|
||||
for (; it != root_windows_.end(); ++it)
|
||||
(*it)->Close(force);
|
||||
}
|
||||
|
||||
void RootWindowManager::OnRootWindowCreated(
|
||||
scoped_refptr<RootWindow> root_window) {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(
|
||||
base::Bind(&RootWindowManager::OnRootWindowCreated,
|
||||
base::Unretained(this), root_window));
|
||||
return;
|
||||
}
|
||||
|
||||
root_windows_.insert(root_window);
|
||||
}
|
||||
|
||||
void RootWindowManager::OnTest(RootWindow* root_window, int test_id) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
test_runner::RunTest(root_window->GetBrowser(), test_id);
|
||||
}
|
||||
|
||||
void RootWindowManager::OnExit(RootWindow* root_window) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
CloseAllWindows(false);
|
||||
}
|
||||
|
||||
void RootWindowManager::OnRootWindowDestroyed(RootWindow* root_window) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
RootWindowSet::iterator it = root_windows_.find(root_window);
|
||||
DCHECK(it != root_windows_.end());
|
||||
if (it != root_windows_.end())
|
||||
root_windows_.erase(it);
|
||||
|
||||
if (terminate_when_all_windows_closed_ && root_windows_.empty()) {
|
||||
// Quit the main message loop after all windows have closed.
|
||||
MainMessageLoop::Get()->Quit();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace client
|
89
tests/cefclient/root_window_manager.h
Normal file
89
tests/cefclient/root_window_manager.h
Normal file
@ -0,0 +1,89 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_ROOT_WINDOW_MANAGER_H_
|
||||
#define CEF_TESTS_CEFCLIENT_ROOT_WINDOW_MANAGER_H_
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "include/base/cef_scoped_ptr.h"
|
||||
#include "include/cef_command_line.h"
|
||||
#include "cefclient/root_window.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "cefclient/temp_window_win.h"
|
||||
#endif
|
||||
|
||||
namespace client {
|
||||
|
||||
// Used to create/manage RootWindow instances. The methods of this class can be
|
||||
// called from any browser process thread unless otherwise indicated.
|
||||
class RootWindowManager : public RootWindow::Delegate {
|
||||
public:
|
||||
// If |terminate_when_all_windows_closed| is true quit the main message loop
|
||||
// after all windows have closed.
|
||||
explicit RootWindowManager(bool terminate_when_all_windows_closed);
|
||||
|
||||
// Create a new top-level native window that loads |url|.
|
||||
// If |with_controls| is true the window will show controls.
|
||||
// If |with_osr| is true the window will use off-screen rendering.
|
||||
// If |bounds| is empty the default window size will be used.
|
||||
// This method can be called from anywhere to create a new top-level window.
|
||||
scoped_refptr<RootWindow> CreateRootWindow(
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefRect& bounds,
|
||||
const std::string& url);
|
||||
|
||||
// Create a new native popup window.
|
||||
// If |with_controls| is true the window will show controls.
|
||||
// If |with_osr| is true the window will use off-screen rendering.
|
||||
// This method is called from ClientHandlerSingle::CreatePopupWindow() to
|
||||
// create a new popup or DevTools window.
|
||||
scoped_refptr<RootWindow> CreateRootWindowAsPopup(
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings);
|
||||
|
||||
// Returns the RootWindow associated with the specified browser ID. Must be
|
||||
// called on the main thread.
|
||||
scoped_refptr<RootWindow> GetWindowForBrowser(int browser_id);
|
||||
|
||||
// Close all existing windows. If |force| is true onunload handlers will not
|
||||
// be executed.
|
||||
void CloseAllWindows(bool force);
|
||||
|
||||
private:
|
||||
// Allow deletion via scoped_ptr only.
|
||||
friend struct base::DefaultDeleter<RootWindowManager>;
|
||||
|
||||
~RootWindowManager();
|
||||
|
||||
void OnRootWindowCreated(scoped_refptr<RootWindow> root_window);
|
||||
|
||||
// RootWindow::Delegate methods.
|
||||
void OnTest(RootWindow* root_window, int test_id) OVERRIDE;
|
||||
void OnExit(RootWindow* root_window) OVERRIDE;
|
||||
void OnRootWindowDestroyed(RootWindow* root_window) OVERRIDE;
|
||||
|
||||
const bool terminate_when_all_windows_closed_;
|
||||
|
||||
// Existing root windows. Only accessed on the main thread.
|
||||
typedef std::set<scoped_refptr<RootWindow> > RootWindowSet;
|
||||
RootWindowSet root_windows_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Singleton window used as the temporary parent for popup browsers.
|
||||
TempWindowWin temp_window_win_;
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RootWindowManager);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_ROOT_WINDOW_MANAGER_H_
|
750
tests/cefclient/root_window_win.cc
Normal file
750
tests/cefclient/root_window_win.cc
Normal file
@ -0,0 +1,750 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/root_window_win.h"
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/cef_app.h"
|
||||
#include "cefclient/browser_window_osr_win.h"
|
||||
#include "cefclient/browser_window_std_win.h"
|
||||
#include "cefclient/client_switches.h"
|
||||
#include "cefclient/main_message_loop.h"
|
||||
#include "cefclient/resource.h"
|
||||
#include "cefclient/temp_window_win.h"
|
||||
#include "cefclient/util_win.h"
|
||||
|
||||
#define MAX_URL_LENGTH 255
|
||||
#define BUTTON_WIDTH 72
|
||||
#define URLBAR_HEIGHT 24
|
||||
|
||||
namespace client {
|
||||
|
||||
namespace {
|
||||
|
||||
// Message handler for the About box.
|
||||
INT_PTR CALLBACK AboutWndProc(HWND hDlg, UINT message,
|
||||
WPARAM wParam, LPARAM lParam) {
|
||||
UNREFERENCED_PARAMETER(lParam);
|
||||
switch (message) {
|
||||
case WM_INITDIALOG:
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
|
||||
EndDialog(hDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
RootWindowWin::RootWindowWin()
|
||||
: delegate_(NULL),
|
||||
with_controls_(false),
|
||||
is_popup_(false),
|
||||
start_rect_(),
|
||||
initialized_(false),
|
||||
hwnd_(NULL),
|
||||
back_hwnd_(NULL),
|
||||
forward_hwnd_(NULL),
|
||||
reload_hwnd_(NULL),
|
||||
stop_hwnd_(NULL),
|
||||
edit_hwnd_(NULL),
|
||||
edit_wndproc_old_(NULL),
|
||||
find_hwnd_(NULL),
|
||||
find_message_id_(0),
|
||||
find_wndproc_old_(NULL),
|
||||
find_state_(),
|
||||
find_buff_(),
|
||||
find_next_(false),
|
||||
find_match_case_last_(false),
|
||||
window_destroyed_(false),
|
||||
browser_destroyed_(false) {
|
||||
}
|
||||
|
||||
RootWindowWin::~RootWindowWin() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// The window and browser should already have been destroyed.
|
||||
DCHECK(window_destroyed_);
|
||||
DCHECK(browser_destroyed_);
|
||||
}
|
||||
|
||||
void RootWindowWin::Init(RootWindow::Delegate* delegate,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefRect& bounds,
|
||||
const CefBrowserSettings& settings,
|
||||
const std::string& url) {
|
||||
DCHECK(delegate);
|
||||
DCHECK(!initialized_);
|
||||
|
||||
delegate_ = delegate;
|
||||
with_controls_ = with_controls;
|
||||
|
||||
start_rect_.left = bounds.x;
|
||||
start_rect_.top = bounds.y;
|
||||
start_rect_.right = bounds.x + bounds.width;
|
||||
start_rect_.bottom = bounds.y + bounds.height;
|
||||
|
||||
CreateBrowserWindow(with_osr, url);
|
||||
|
||||
initialized_ = true;
|
||||
|
||||
// Create the native root window on the main thread.
|
||||
if (CURRENTLY_ON_MAIN_THREAD()) {
|
||||
CreateRootWindow(settings);
|
||||
} else {
|
||||
MAIN_POST_CLOSURE(
|
||||
base::Bind(&RootWindowWin::CreateRootWindow, this, settings));
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowWin::InitAsPopup(RootWindow::Delegate* delegate,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) {
|
||||
DCHECK(delegate);
|
||||
DCHECK(!initialized_);
|
||||
|
||||
delegate_ = delegate;
|
||||
with_controls_ = with_controls;
|
||||
is_popup_ = true;
|
||||
|
||||
if (popupFeatures.xSet)
|
||||
start_rect_.left = popupFeatures.x;
|
||||
if (popupFeatures.ySet)
|
||||
start_rect_.top = popupFeatures.y;
|
||||
if (popupFeatures.widthSet)
|
||||
start_rect_.right = start_rect_.left + popupFeatures.width;
|
||||
if (popupFeatures.heightSet)
|
||||
start_rect_.bottom = start_rect_.top + popupFeatures.height;
|
||||
|
||||
CreateBrowserWindow(with_osr, std::string());
|
||||
|
||||
initialized_ = true;
|
||||
|
||||
// The new popup is initially parented to a temporary window. The native root
|
||||
// window will be created after the browser is created and the popup window
|
||||
// will be re-parented to it at that time.
|
||||
browser_window_->GetPopupConfig(TempWindowWin::GetHWND(),
|
||||
windowInfo, client, settings);
|
||||
}
|
||||
|
||||
void RootWindowWin::Show(ShowMode mode) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (!hwnd_)
|
||||
return;
|
||||
|
||||
int nCmdShow = SW_SHOWNORMAL;
|
||||
switch (mode) {
|
||||
case ShowMinimized:
|
||||
nCmdShow = SW_SHOWNORMAL;
|
||||
break;
|
||||
case ShowMaximized:
|
||||
nCmdShow = SW_SHOWNORMAL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ShowWindow(hwnd_, nCmdShow);
|
||||
UpdateWindow(hwnd_);
|
||||
}
|
||||
|
||||
void RootWindowWin::Hide() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (hwnd_)
|
||||
ShowWindow(hwnd_, SW_HIDE);
|
||||
}
|
||||
|
||||
void RootWindowWin::SetBounds(int x, int y, size_t width, size_t height) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (hwnd_)
|
||||
SetWindowPos(hwnd_, NULL, 0, 0, 0, 0, SWP_NOZORDER);
|
||||
}
|
||||
|
||||
void RootWindowWin::Close(bool force) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (hwnd_) {
|
||||
if (force)
|
||||
DestroyWindow(hwnd_);
|
||||
else
|
||||
PostMessage(hwnd_, WM_CLOSE, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowser> RootWindowWin::GetBrowser() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (browser_window_)
|
||||
return browser_window_->GetBrowser();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CefWindowHandle RootWindowWin::GetWindowHandle() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
return hwnd_;
|
||||
}
|
||||
|
||||
void RootWindowWin::CreateBrowserWindow(bool with_osr,
|
||||
const std::string& startup_url) {
|
||||
if (with_osr) {
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
CefCommandLine::GetGlobalCommandLine();
|
||||
const bool transparent =
|
||||
command_line->HasSwitch(switches::kTransparentPaintingEnabled);
|
||||
const bool show_update_rect =
|
||||
command_line->HasSwitch(switches::kShowUpdateRect);
|
||||
browser_window_.reset(new BrowserWindowOsrWin(this, startup_url,
|
||||
transparent,
|
||||
show_update_rect));
|
||||
} else {
|
||||
browser_window_.reset(new BrowserWindowStdWin(this, startup_url));
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
DCHECK(!hwnd_);
|
||||
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
|
||||
// Load strings from the resource file.
|
||||
const std::wstring& window_title = GetResourceString(IDS_APP_TITLE);
|
||||
const std::wstring& window_class = GetResourceString(IDC_CEFCLIENT);
|
||||
|
||||
// Register the window class.
|
||||
RegisterRootClass(hInstance, window_class);
|
||||
|
||||
// Register the message used with the find dialog.
|
||||
find_message_id_ = RegisterWindowMessage(FINDMSGSTRING);
|
||||
CHECK(find_message_id_);
|
||||
|
||||
const DWORD dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
|
||||
|
||||
int x, y, width, height;
|
||||
if (::IsRectEmpty(&start_rect_)) {
|
||||
// Use the default window position/size.
|
||||
x = y = width = height = CW_USEDEFAULT;
|
||||
} else {
|
||||
// Adjust the window size to account for window frame and controls.
|
||||
RECT window_rect = start_rect_;
|
||||
::AdjustWindowRectEx(&window_rect, dwStyle, with_controls_, 0);
|
||||
if (with_controls_)
|
||||
window_rect.bottom += URLBAR_HEIGHT;
|
||||
|
||||
x = start_rect_.left;
|
||||
y = start_rect_.top;
|
||||
width = window_rect.right - window_rect.left;
|
||||
height = window_rect.bottom - window_rect.top;
|
||||
}
|
||||
|
||||
// Create the main window initially hidden.
|
||||
hwnd_ = CreateWindow(window_class.c_str(), window_title.c_str(),
|
||||
dwStyle,
|
||||
x, y, width, height,
|
||||
NULL, NULL, hInstance, NULL);
|
||||
CHECK(hwnd_);
|
||||
|
||||
// Associate |this| with the main window.
|
||||
SetUserDataPtr(hwnd_, this);
|
||||
|
||||
RECT rect;
|
||||
GetClientRect(hwnd_, &rect);
|
||||
|
||||
if (with_controls_) {
|
||||
// Create the child controls.
|
||||
int x = 0;
|
||||
|
||||
back_hwnd_ = CreateWindow(
|
||||
L"BUTTON", L"Back",
|
||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
||||
x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
|
||||
hwnd_, reinterpret_cast<HMENU>(IDC_NAV_BACK), hInstance, 0);
|
||||
CHECK(back_hwnd_);
|
||||
x += BUTTON_WIDTH;
|
||||
|
||||
forward_hwnd_ = CreateWindow(
|
||||
L"BUTTON", L"Forward",
|
||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
||||
x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
|
||||
hwnd_, reinterpret_cast<HMENU>(IDC_NAV_FORWARD), hInstance, 0);
|
||||
CHECK(forward_hwnd_);
|
||||
x += BUTTON_WIDTH;
|
||||
|
||||
reload_hwnd_ = CreateWindow(
|
||||
L"BUTTON", L"Reload",
|
||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON| WS_DISABLED,
|
||||
x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
|
||||
hwnd_, reinterpret_cast<HMENU>(IDC_NAV_RELOAD), hInstance, 0);
|
||||
CHECK(reload_hwnd_);
|
||||
x += BUTTON_WIDTH;
|
||||
|
||||
stop_hwnd_ = CreateWindow(
|
||||
L"BUTTON", L"Stop",
|
||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
||||
x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
|
||||
hwnd_, reinterpret_cast<HMENU>(IDC_NAV_STOP), hInstance, 0);
|
||||
CHECK(stop_hwnd_);
|
||||
x += BUTTON_WIDTH;
|
||||
|
||||
edit_hwnd_ = CreateWindow(
|
||||
L"EDIT", 0,
|
||||
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL |
|
||||
ES_AUTOHSCROLL| WS_DISABLED,
|
||||
x, 0, rect.right - BUTTON_WIDTH * 4, URLBAR_HEIGHT,
|
||||
hwnd_, 0, hInstance, 0);
|
||||
CHECK(edit_hwnd_);
|
||||
|
||||
// Override the edit control's window procedure.
|
||||
edit_wndproc_old_ = SetWndProcPtr(edit_hwnd_, EditWndProc);
|
||||
|
||||
// Associate |this| with the edit window.
|
||||
SetUserDataPtr(edit_hwnd_, this);
|
||||
|
||||
rect.top += URLBAR_HEIGHT;
|
||||
} else {
|
||||
// No controls so also remove the default menu.
|
||||
::SetMenu(hwnd_, NULL);
|
||||
}
|
||||
|
||||
if (!is_popup_) {
|
||||
// Create the browser window.
|
||||
browser_window_->CreateBrowser(hwnd_, rect, settings);
|
||||
} else {
|
||||
// With popups we already have a browser window. Parent the browser window
|
||||
// to the root window and show it in the correct location.
|
||||
browser_window_->ShowPopup(hwnd_,
|
||||
rect.left, rect.top,
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top);
|
||||
}
|
||||
|
||||
// Show this window.
|
||||
Show(ShowNormal);
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowWin::RegisterRootClass(HINSTANCE hInstance,
|
||||
const std::wstring& window_class) {
|
||||
// Only register the class one time.
|
||||
static bool class_registered = false;
|
||||
if (class_registered)
|
||||
return;
|
||||
class_registered = true;
|
||||
|
||||
WNDCLASSEX wcex;
|
||||
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = RootWndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = hInstance;
|
||||
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CEFCLIENT));
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
||||
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_CEFCLIENT);
|
||||
wcex.lpszClassName = window_class.c_str();
|
||||
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
|
||||
|
||||
RegisterClassEx(&wcex);
|
||||
}
|
||||
|
||||
// static
|
||||
LRESULT CALLBACK RootWindowWin::EditWndProc(HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
RootWindowWin* self = GetUserDataPtr<RootWindowWin*>(hWnd);
|
||||
DCHECK(self);
|
||||
DCHECK(hWnd == self->edit_hwnd_);
|
||||
|
||||
switch (message) {
|
||||
case WM_CHAR:
|
||||
if (wParam == VK_RETURN) {
|
||||
// When the user hits the enter key load the URL.
|
||||
CefRefPtr<CefBrowser> browser = self->GetBrowser();
|
||||
if (browser) {
|
||||
wchar_t strPtr[MAX_URL_LENGTH+1] = {0};
|
||||
*((LPWORD)strPtr) = MAX_URL_LENGTH;
|
||||
LRESULT strLen = SendMessage(hWnd, EM_GETLINE, 0, (LPARAM)strPtr);
|
||||
if (strLen > 0) {
|
||||
strPtr[strLen] = 0;
|
||||
browser->GetMainFrame()->LoadURL(strPtr);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_NCDESTROY:
|
||||
// Clear the reference to |self|.
|
||||
SetUserDataPtr(hWnd, NULL);
|
||||
self->edit_hwnd_ = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return CallWindowProc(self->edit_wndproc_old_, hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
// static
|
||||
LRESULT CALLBACK RootWindowWin::FindWndProc(HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
RootWindowWin* self = GetUserDataPtr<RootWindowWin*>(hWnd);
|
||||
DCHECK(self);
|
||||
DCHECK(hWnd == self->find_hwnd_);
|
||||
|
||||
switch (message) {
|
||||
case WM_ACTIVATE:
|
||||
// Set this dialog as current when activated.
|
||||
MainMessageLoop::Get()->SetCurrentModelessDialog(
|
||||
wParam == 0 ? NULL : hWnd);
|
||||
return FALSE;
|
||||
case WM_NCDESTROY:
|
||||
// Clear the reference to |self|.
|
||||
SetUserDataPtr(hWnd, NULL);
|
||||
self->find_hwnd_ = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return CallWindowProc(self->find_wndproc_old_, hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
// static
|
||||
LRESULT CALLBACK RootWindowWin::RootWndProc(HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
RootWindowWin* self = GetUserDataPtr<RootWindowWin*>(hWnd);
|
||||
if (!self)
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
DCHECK(hWnd == self->hwnd_);
|
||||
|
||||
if (message == self->find_message_id_) {
|
||||
// Message targeting the find dialog.
|
||||
LPFINDREPLACE lpfr = reinterpret_cast<LPFINDREPLACE>(lParam);
|
||||
CHECK(lpfr == &self->find_state_);
|
||||
self->OnFindEvent();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Callback for the main window
|
||||
switch (message) {
|
||||
case WM_COMMAND:
|
||||
if (self->OnCommand(LOWORD(wParam)))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
self->OnPaint();
|
||||
return 0;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
self->OnFocus();
|
||||
return 0;
|
||||
|
||||
case WM_SIZE:
|
||||
self->OnSize(wParam == SIZE_MINIMIZED);
|
||||
break;
|
||||
|
||||
case WM_MOVING:
|
||||
case WM_MOVE:
|
||||
self->OnMove();
|
||||
return 0;
|
||||
|
||||
case WM_ERASEBKGND:
|
||||
// Never erase the background.
|
||||
return 0;
|
||||
|
||||
case WM_ENTERMENULOOP:
|
||||
if (!wParam) {
|
||||
// Entering the menu loop for the application menu.
|
||||
CefSetOSModalLoop(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_EXITMENULOOP:
|
||||
if (!wParam) {
|
||||
// Exiting the menu loop for the application menu.
|
||||
CefSetOSModalLoop(false);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
if (self->OnClose())
|
||||
return 0; // Cancel the close.
|
||||
break;
|
||||
|
||||
case WM_NCDESTROY:
|
||||
// Clear the reference to |self|.
|
||||
SetUserDataPtr(hWnd, NULL);
|
||||
self->hwnd_ = NULL;
|
||||
self->OnDestroyed();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
void RootWindowWin::OnPaint() {
|
||||
PAINTSTRUCT ps;
|
||||
BeginPaint(hwnd_, &ps);
|
||||
EndPaint(hwnd_, &ps);
|
||||
}
|
||||
|
||||
void RootWindowWin::OnFocus() {
|
||||
if (browser_window_)
|
||||
browser_window_->SetFocus();
|
||||
}
|
||||
|
||||
void RootWindowWin::OnSize(bool minimized) {
|
||||
if (minimized) {
|
||||
// Notify the browser window that it was hidden and do nothing further.
|
||||
if (browser_window_)
|
||||
browser_window_->Hide();
|
||||
return;
|
||||
}
|
||||
|
||||
if (browser_window_)
|
||||
browser_window_->Show();
|
||||
|
||||
RECT rect;
|
||||
GetClientRect(hwnd_, &rect);
|
||||
|
||||
if (with_controls_) {
|
||||
// Resize the window and address bar to match the new frame size.
|
||||
rect.top += URLBAR_HEIGHT;
|
||||
|
||||
int urloffset = rect.left + BUTTON_WIDTH * 4;
|
||||
|
||||
if (browser_window_) {
|
||||
HWND browser_hwnd = browser_window_->GetHWND();
|
||||
HDWP hdwp = BeginDeferWindowPos(1);
|
||||
hdwp = DeferWindowPos(hdwp, edit_hwnd_, NULL, urloffset,
|
||||
0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER);
|
||||
hdwp = DeferWindowPos(hdwp, browser_hwnd, NULL,
|
||||
rect.left, rect.top, rect.right - rect.left,
|
||||
rect.bottom - rect.top, SWP_NOZORDER);
|
||||
EndDeferWindowPos(hdwp);
|
||||
} else {
|
||||
SetWindowPos(edit_hwnd_, NULL, urloffset,
|
||||
0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER);
|
||||
}
|
||||
} else if (browser_window_) {
|
||||
// Size the browser window to the whole client area.
|
||||
browser_window_->SetBounds(0, 0, rect.right, rect.bottom);
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowWin::OnMove() {
|
||||
// Notify the browser of move events so that popup windows are displayed
|
||||
// in the correct location and dismissed when the window moves.
|
||||
CefRefPtr<CefBrowser> browser = GetBrowser();
|
||||
if (browser)
|
||||
browser->GetHost()->NotifyMoveOrResizeStarted();
|
||||
}
|
||||
|
||||
bool RootWindowWin::OnCommand(UINT id) {
|
||||
if (id >= ID_TESTS_FIRST && id <= ID_TESTS_LAST) {
|
||||
delegate_->OnTest(this, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case IDM_ABOUT:
|
||||
OnAbout();
|
||||
return true;
|
||||
case IDM_EXIT:
|
||||
delegate_->OnExit(this);
|
||||
return true;
|
||||
case ID_FIND:
|
||||
OnFind();
|
||||
return true;
|
||||
case IDC_NAV_BACK: // Back button
|
||||
if (CefRefPtr<CefBrowser> browser = GetBrowser())
|
||||
browser->GoBack();
|
||||
return true;
|
||||
case IDC_NAV_FORWARD: // Forward button
|
||||
if (CefRefPtr<CefBrowser> browser = GetBrowser())
|
||||
browser->GoForward();
|
||||
return true;
|
||||
case IDC_NAV_RELOAD: // Reload button
|
||||
if (CefRefPtr<CefBrowser> browser = GetBrowser())
|
||||
browser->Reload();
|
||||
return true;
|
||||
case IDC_NAV_STOP: // Stop button
|
||||
if (CefRefPtr<CefBrowser> browser = GetBrowser())
|
||||
browser->StopLoad();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RootWindowWin::OnFind() {
|
||||
if (find_hwnd_) {
|
||||
// Give focus to the existing find dialog.
|
||||
::SetFocus(find_hwnd_);
|
||||
return;
|
||||
}
|
||||
|
||||
// Configure dialog state.
|
||||
ZeroMemory(&find_state_, sizeof(find_state_));
|
||||
find_state_.lStructSize = sizeof(find_state_);
|
||||
find_state_.hwndOwner = hwnd_;
|
||||
find_state_.lpstrFindWhat = find_buff_;
|
||||
find_state_.wFindWhatLen = sizeof(find_buff_);
|
||||
find_state_.Flags = FR_HIDEWHOLEWORD | FR_DOWN;
|
||||
|
||||
// Create the dialog.
|
||||
find_hwnd_ = FindText(&find_state_);
|
||||
|
||||
// Override the dialog's window procedure.
|
||||
find_wndproc_old_ = SetWndProcPtr(find_hwnd_, FindWndProc);
|
||||
|
||||
// Associate |self| with the dialog.
|
||||
SetUserDataPtr(find_hwnd_, this);
|
||||
}
|
||||
|
||||
void RootWindowWin::OnFindEvent() {
|
||||
CefRefPtr<CefBrowser> browser = GetBrowser();
|
||||
|
||||
if (find_state_.Flags & FR_DIALOGTERM) {
|
||||
// The find dialog box has been dismissed so invalidate the handle and
|
||||
// reset the search results.
|
||||
if (browser) {
|
||||
browser->GetHost()->StopFinding(true);
|
||||
find_what_last_.clear();
|
||||
find_next_ = false;
|
||||
}
|
||||
} else if ((find_state_.Flags & FR_FINDNEXT) && browser) {
|
||||
// Search for the requested string.
|
||||
bool match_case = ((find_state_.Flags & FR_MATCHCASE) ? true : false);
|
||||
const std::wstring& find_what = find_buff_;
|
||||
if (match_case != find_match_case_last_ || find_what != find_what_last_) {
|
||||
// The search string has changed, so reset the search results.
|
||||
if (!find_what.empty()) {
|
||||
browser->GetHost()->StopFinding(true);
|
||||
find_next_ = false;
|
||||
}
|
||||
find_match_case_last_ = match_case;
|
||||
find_what_last_ = find_buff_;
|
||||
}
|
||||
|
||||
browser->GetHost()->Find(0, find_what,
|
||||
(find_state_.Flags & FR_DOWN) ? true : false,
|
||||
match_case, find_next_);
|
||||
if (!find_next_)
|
||||
find_next_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowWin::OnAbout() {
|
||||
// Show the about box.
|
||||
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd_,
|
||||
AboutWndProc);
|
||||
}
|
||||
|
||||
bool RootWindowWin::OnClose() {
|
||||
if (browser_window_ && !browser_window_->IsClosing()) {
|
||||
CefRefPtr<CefBrowser> browser = GetBrowser();
|
||||
if (browser) {
|
||||
// Notify the browser window that we would like to close it. This
|
||||
// will result in a call to ClientHandler::DoClose() if the
|
||||
// JavaScript 'onbeforeunload' event handler allows it.
|
||||
browser->GetHost()->CloseBrowser(false);
|
||||
|
||||
// Cancel the close.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the close.
|
||||
return false;
|
||||
}
|
||||
|
||||
void RootWindowWin::OnDestroyed() {
|
||||
window_destroyed_ = true;
|
||||
NotifyDestroyedIfDone();
|
||||
}
|
||||
|
||||
void RootWindowWin::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// For popup browsers create the root window once the browser has been
|
||||
// created.
|
||||
if (is_popup_)
|
||||
CreateRootWindow(CefBrowserSettings());
|
||||
}
|
||||
|
||||
void RootWindowWin::OnBrowserWindowDestroyed() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
browser_window_.reset();
|
||||
browser_destroyed_ = true;
|
||||
|
||||
if (!window_destroyed_) {
|
||||
// The browser was destroyed first. This could be due to the use of
|
||||
// off-screen rendering or execution of JavaScript window.close().
|
||||
// Close the RootWindow asynchronously.
|
||||
Close(false);
|
||||
}
|
||||
|
||||
NotifyDestroyedIfDone();
|
||||
}
|
||||
|
||||
void RootWindowWin::OnSetAddress(const std::string& url) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (edit_hwnd_)
|
||||
SetWindowText(edit_hwnd_, CefString(url).ToWString().c_str());
|
||||
}
|
||||
|
||||
void RootWindowWin::OnSetTitle(const std::string& title) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (hwnd_)
|
||||
SetWindowText(hwnd_, CefString(title).ToWString().c_str());
|
||||
}
|
||||
|
||||
void RootWindowWin::OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (with_controls_) {
|
||||
EnableWindow(back_hwnd_, canGoBack);
|
||||
EnableWindow(forward_hwnd_, canGoForward);
|
||||
EnableWindow(reload_hwnd_, !isLoading);
|
||||
EnableWindow(stop_hwnd_, isLoading);
|
||||
EnableWindow(edit_hwnd_, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowWin::NotifyDestroyedIfDone() {
|
||||
// Notify once both the window and the browser have been destroyed.
|
||||
if (window_destroyed_ && browser_destroyed_)
|
||||
delegate_->OnRootWindowDestroyed(this);
|
||||
}
|
||||
|
||||
// static
|
||||
scoped_refptr<RootWindow> RootWindow::Create() {
|
||||
return new RootWindowWin();
|
||||
}
|
||||
|
||||
} // namespace client
|
135
tests/cefclient/root_window_win.h
Normal file
135
tests/cefclient/root_window_win.h
Normal file
@ -0,0 +1,135 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_ROOT_WINDOW_WIN_H_
|
||||
#define CEF_TESTS_CEFCLIENT_ROOT_WINDOW_WIN_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <commdlg.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "include/base/cef_scoped_ptr.h"
|
||||
#include "cefclient/browser_window_win.h"
|
||||
#include "cefclient/root_window.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Windows implementation of a top-level native window in the browser process.
|
||||
// The methods of this class must be called on the main thread unless otherwise
|
||||
// indicated.
|
||||
class RootWindowWin : public RootWindow,
|
||||
public BrowserWindowWin::Delegate {
|
||||
public:
|
||||
// Constructor may be called on any thread.
|
||||
RootWindowWin();
|
||||
~RootWindowWin();
|
||||
|
||||
// RootWindow methods.
|
||||
void Init(RootWindow::Delegate* delegate,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefRect& rect,
|
||||
const CefBrowserSettings& settings,
|
||||
const std::string& url) OVERRIDE;
|
||||
void InitAsPopup(RootWindow::Delegate* delegate,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) OVERRIDE;
|
||||
void Show(ShowMode mode) OVERRIDE;
|
||||
void Hide() OVERRIDE;
|
||||
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void Close(bool force) OVERRIDE;
|
||||
CefRefPtr<CefBrowser> GetBrowser() const OVERRIDE;
|
||||
CefWindowHandle GetWindowHandle() const OVERRIDE;
|
||||
|
||||
private:
|
||||
void CreateBrowserWindow(bool with_osr, const std::string& startup_url);
|
||||
void CreateRootWindow(const CefBrowserSettings& settings);
|
||||
|
||||
// Register the root window class.
|
||||
static void RegisterRootClass(HINSTANCE hInstance,
|
||||
const std::wstring& window_class);
|
||||
|
||||
// Window procedure for the edit field.
|
||||
static LRESULT CALLBACK EditWndProc(HWND hWnd, UINT message, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
// Window procedure for the find dialog.
|
||||
static LRESULT CALLBACK FindWndProc(HWND hWnd, UINT message, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
// Window procedure for the root window.
|
||||
static LRESULT CALLBACK RootWndProc(HWND hWnd, UINT message, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
// Event handlers.
|
||||
void OnPaint();
|
||||
void OnFocus();
|
||||
void OnSize(bool minimized);
|
||||
void OnMove();
|
||||
bool OnCommand(UINT id);
|
||||
void OnFind();
|
||||
void OnFindEvent();
|
||||
void OnAbout();
|
||||
bool OnClose();
|
||||
void OnDestroyed();
|
||||
|
||||
// BrowserWindowWin::Delegate methods.
|
||||
void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
void OnBrowserWindowDestroyed() OVERRIDE;
|
||||
void OnSetAddress(const std::string& url) OVERRIDE;
|
||||
void OnSetTitle(const std::string& title) OVERRIDE;
|
||||
void OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) OVERRIDE;
|
||||
|
||||
void NotifyDestroyedIfDone();
|
||||
|
||||
// After initialization all members are only accessed on the main thread.
|
||||
// Members set during initialization.
|
||||
RootWindow::Delegate* delegate_;
|
||||
bool with_controls_;
|
||||
bool is_popup_;
|
||||
RECT start_rect_;
|
||||
scoped_ptr<BrowserWindowWin> browser_window_;
|
||||
bool initialized_;
|
||||
|
||||
// Main window.
|
||||
HWND hwnd_;
|
||||
|
||||
// Buttons.
|
||||
HWND back_hwnd_;
|
||||
HWND forward_hwnd_;
|
||||
HWND reload_hwnd_;
|
||||
HWND stop_hwnd_;
|
||||
|
||||
// URL text field.
|
||||
HWND edit_hwnd_;
|
||||
WNDPROC edit_wndproc_old_;
|
||||
|
||||
// Find dialog.
|
||||
HWND find_hwnd_;
|
||||
UINT find_message_id_;
|
||||
WNDPROC find_wndproc_old_;
|
||||
|
||||
// Find dialog state.
|
||||
FINDREPLACE find_state_;
|
||||
WCHAR find_buff_[80];
|
||||
std::wstring find_what_last_;
|
||||
bool find_next_;
|
||||
bool find_match_case_last_;
|
||||
|
||||
bool window_destroyed_;
|
||||
bool browser_destroyed_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RootWindowWin);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_ROOT_WINDOW_WIN_H_
|
58
tests/cefclient/temp_window_win.cc
Normal file
58
tests/cefclient/temp_window_win.cc
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/temp_window_win.h"
|
||||
|
||||
#include "include/base/cef_logging.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
namespace {
|
||||
|
||||
const wchar_t kWndClass[] = L"Client_TempWindow";
|
||||
|
||||
// Create the temp window.
|
||||
HWND CreateTempWindow() {
|
||||
HINSTANCE hInstance = ::GetModuleHandle(NULL);
|
||||
|
||||
WNDCLASSEX wc = {0};
|
||||
wc.cbSize = sizeof(wc);
|
||||
wc.lpfnWndProc = DefWindowProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.lpszClassName = kWndClass;
|
||||
RegisterClassEx(&wc);
|
||||
|
||||
// Create a 1x1 pixel hidden window.
|
||||
return CreateWindow(kWndClass, 0,
|
||||
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
||||
0, 0, 1, 1,
|
||||
NULL, NULL, hInstance, NULL);
|
||||
}
|
||||
|
||||
TempWindowWin* g_temp_window = NULL;
|
||||
|
||||
} // namespace
|
||||
|
||||
TempWindowWin::TempWindowWin()
|
||||
: hwnd_(NULL) {
|
||||
DCHECK(!g_temp_window);
|
||||
g_temp_window = this;
|
||||
|
||||
hwnd_ = CreateTempWindow();
|
||||
CHECK(hwnd_);
|
||||
}
|
||||
|
||||
TempWindowWin::~TempWindowWin() {
|
||||
g_temp_window = NULL;
|
||||
DCHECK(hwnd_);
|
||||
DestroyWindow(hwnd_);
|
||||
}
|
||||
|
||||
// static
|
||||
HWND TempWindowWin::GetHWND() {
|
||||
DCHECK(g_temp_window);
|
||||
return g_temp_window->hwnd_;
|
||||
}
|
||||
|
||||
} // namespace client
|
35
tests/cefclient/temp_window_win.h
Normal file
35
tests/cefclient/temp_window_win.h
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_TEMP_WINDOW_WIN_H_
|
||||
#define CEF_TESTS_CEFCLIENT_TEMP_WINDOW_WIN_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "cefclient/main_message_loop.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Represents a singleton hidden window that acts at temporary parent for
|
||||
// popup browsers.
|
||||
class TempWindowWin {
|
||||
public:
|
||||
// Returns the singleton window HWND.
|
||||
static HWND GetHWND();
|
||||
|
||||
private:
|
||||
// A single instance will be created/owned by RootWindowManager.
|
||||
friend class RootWindowManager;
|
||||
|
||||
TempWindowWin();
|
||||
~TempWindowWin();
|
||||
|
||||
HWND hwnd_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TempWindowWin);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_TEMP_WINDOW_WIN_H_
|
@ -26,6 +26,13 @@ WNDPROC SetWndProcPtr(HWND hWnd, WNDPROC wndProc) {
|
||||
return old;
|
||||
}
|
||||
|
||||
std::wstring GetResourceString(UINT id) {
|
||||
#define MAX_LOADSTRING 100
|
||||
TCHAR buff[MAX_LOADSTRING] = {0};
|
||||
LoadString(::GetModuleHandle(NULL), id, buff, MAX_LOADSTRING);
|
||||
return buff;
|
||||
}
|
||||
|
||||
int GetCefMouseModifiers(WPARAM wparam) {
|
||||
int modifiers = 0;
|
||||
if (wparam & MK_CONTROL)
|
||||
|
@ -19,6 +19,9 @@ T GetUserDataPtr(HWND hWnd) {
|
||||
// Set the window's window procedure pointer and return the old value.
|
||||
WNDPROC SetWndProcPtr(HWND hWnd, WNDPROC wndProc);
|
||||
|
||||
// Return the resource string with the specified id.
|
||||
std::wstring GetResourceString(UINT id);
|
||||
|
||||
int GetCefMouseModifiers(WPARAM wparam);
|
||||
int GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam);
|
||||
bool IsKeyDown(WPARAM wparam);
|
||||
|
Loading…
x
Reference in New Issue
Block a user