diff options
author | slightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-24 05:11:58 +0000 |
---|---|---|
committer | slightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-24 05:11:58 +0000 |
commit | f781782dd67077478e117c61dca4ea5eefce3544 (patch) | |
tree | 4801f724123cfdcbb69c4e7fe40a565b331723ae /chrome_frame/chrome_frame_plugin.h | |
parent | 63cf4759efa2373e33436fb5df6849f930081226 (diff) | |
download | chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.zip chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.gz chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.bz2 |
Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming in a separate CL.
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/218019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/chrome_frame_plugin.h')
-rw-r--r-- | chrome_frame/chrome_frame_plugin.h | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/chrome_frame/chrome_frame_plugin.h b/chrome_frame/chrome_frame_plugin.h new file mode 100644 index 0000000..b0814bb --- /dev/null +++ b/chrome_frame/chrome_frame_plugin.h @@ -0,0 +1,214 @@ +// Copyright (c) 2009 The Chromium 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 CHROME_FRAME_CHROME_FRAME_PLUGIN_H_ +#define CHROME_FRAME_CHROME_FRAME_PLUGIN_H_ + +#include "base/win_util.h" +#include "chrome_frame/chrome_frame_automation.h" +#include "chrome_frame/utils.h" + +#define IDC_ABOUT_CHROME_FRAME 40018 + +// A class to implement common functionality for all types of +// plugins: NPAPI. ActiveX and ActiveDoc +template <typename T> +class ChromeFramePlugin : public ChromeFrameDelegateImpl { + public: + ChromeFramePlugin() + : ignore_setfocus_(false), + is_privileged_(false) { + } + ~ChromeFramePlugin() { + Uninitialize(); + } + +BEGIN_MSG_MAP(ChromeFrameActivex) + MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_PARENTNOTIFY, OnParentNotify) +END_MSG_MAP() + + bool Initialize() { + DCHECK(!automation_client_.get()); + automation_client_.reset(CreateAutomationClient()); + if (!automation_client_.get()) { + NOTREACHED() << "new ChromeFrameAutomationClient"; + return false; + } + + return true; + } + + void Uninitialize() { + if (automation_client_.get()) { + automation_client_->Uninitialize(); + automation_client_.reset(); + } + } + + bool InitializeAutomation(const std::wstring& profile_name, + const std::wstring& extra_chrome_arguments, + bool incognito) { + // We don't want to do incognito when privileged, since we're + // running in browser chrome or some other privileged context. + bool incognito_mode = !is_privileged_ && incognito; + return automation_client_->Initialize(this, kCommandExecutionTimeout, true, + profile_name, extra_chrome_arguments, + incognito_mode); + } + + // ChromeFrameDelegate implementation + virtual WindowType GetWindow() const { + return (static_cast<const T*>(this))->m_hWnd; + } + + virtual void GetBounds(RECT* bounds) { + if (bounds) { + if (::IsWindow(GetWindow())) { + (static_cast<T*>(this))->GetClientRect(bounds); + } + } + } + virtual std::string GetDocumentUrl() { + return document_url_; + } + virtual void OnAutomationServerReady() { + // Issue the extension automation request if we're privileged to + // allow this control to handle extension requests from Chrome. + if (is_privileged_) + automation_client_->SetEnableExtensionAutomation(true); + } + + virtual bool IsValid() const { + return automation_client_.get() != NULL; + } + + protected: + virtual void OnNavigationFailed(int tab_handle, int error_code, + const GURL& gurl) { + OnLoadFailed(error_code, gurl.spec()); + } + + virtual void OnHandleContextMenu(int tab_handle, HANDLE menu_handle, + int x_pos, int y_pos, int align_flags) { + if (!menu_handle || !automation_client_.get()) { + NOTREACHED(); + return; + } + + // TrackPopupMenuEx call will fail on IE on Vista running + // in low integrity mode. We DO seem to be able to enumerate the menu + // though, so just clone it and show the copy: + HMENU copy = UtilCloneContextMenu(static_cast<HMENU>(menu_handle)); + if (!copy) + return; + + T* pThis = static_cast<T*>(this); + if (pThis->PreProcessContextMenu(copy)) { + UINT flags = align_flags | TPM_LEFTBUTTON | TPM_RETURNCMD | TPM_RECURSE; + UINT selected = TrackPopupMenuEx(copy, flags, x_pos, y_pos, GetWindow(), + NULL); + if (selected != 0 && !pThis->HandleContextMenuCommand(selected)) { + automation_client_->SendContextMenuCommandToChromeFrame(selected); + } + } + + DestroyMenu(copy); + } + + LRESULT OnSetFocus(UINT message, WPARAM wparam, LPARAM lparam, + BOOL& handled) { // NO_LINT + if (!ignore_setfocus_ && automation_client_ != NULL) { + TabProxy* tab = automation_client_->tab(); + HWND chrome_window = automation_client_->tab_window(); + if (tab && ::IsWindow(chrome_window)) { + DLOG(INFO) << "Setting initial focus"; + tab->SetInitialFocus(win_util::IsShiftPressed()); + } + } + + return 0; + } + + LRESULT OnSize(UINT message, WPARAM wparam, LPARAM lparam, + BOOL& handled) { // NO_LINT + handled = FALSE; + // When we get resized, we need to resize the external tab window too. + if (automation_client_.get()) + automation_client_->Resize(LOWORD(lparam), HIWORD(lparam), + SWP_NOACTIVATE | SWP_NOZORDER); + return 0; + } + + LRESULT OnParentNotify(UINT message, WPARAM wparam, LPARAM lparam, + BOOL& handled) { // NO_LINT + switch (LOWORD(wparam)) { + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_XBUTTONDOWN: { + // If we got activated via mouse click on the external tab, + // we need to update the state of this thread and tell the + // browser that we now have the focus. + HWND focus = ::GetFocus(); + HWND plugin_window = GetWindow(); + if (focus != plugin_window && !IsChild(plugin_window, focus)) { + ignore_setfocus_ = true; + SetFocus(plugin_window); + ignore_setfocus_ = false; + } + break; + } + } + + return 0; + } + + // Return true if context menu should be displayed. The menu could be + // modified as well (enable/disable commands, add/remove items). + // Override in most-derived class if needed. + bool PreProcessContextMenu(HMENU menu) { + // Add an "About" item. + // TODO: The string should be localized and menu should + // be modified in ExternalTabContainer:: once we go public. + AppendMenu(menu, MF_STRING, IDC_ABOUT_CHROME_FRAME, + L"About Chrome Frame..."); + return true; + } + + // Return true if menu command is processed, otherwise the command will be + // passed to Chrome for execution. Override in most-derived class if needed. + bool HandleContextMenuCommand(UINT cmd) { + return false; + } + + // Allow overriding the type of automation client used, for unit tests. + virtual ChromeFrameAutomationClient* CreateAutomationClient() { + return new ChromeFrameAutomationClient; + } + + protected: + // Our gateway to chrome land + scoped_ptr<ChromeFrameAutomationClient> automation_client_; + + // Url of the containing document. + std::string document_url_; + + // We set this flag when we're taking the focus ourselves + // and notifying the host browser that we're doing so. + // When the flag is not set, we transfer the focus to chrome. + bool ignore_setfocus_; + + // The plugin is privileged if it is: + // * Invoked by a window running under the system principal in FireFox. + // * Being hosted by a custom host exposing the SID_ChromeFramePrivileged + // service. + // + // When privileged, additional interfaces are made available to the user. + bool is_privileged_; +}; + +#endif // CHROME_FRAME_CHROME_FRAME_PLUGIN_H_ + |