summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/app.gyp10
-rw-r--r--app/gfx/blit.h2
-rw-r--r--app/gfx/gtk_native_view_id_manager.cc145
-rw-r--r--app/gfx/gtk_native_view_id_manager.h91
-rw-r--r--app/gfx/native_widget_types.h143
-rw-r--r--app/gfx/native_widget_types_gtk.cc16
-rw-r--r--app/win/window_impl.cc214
-rw-r--r--app/win/window_impl.h110
8 files changed, 730 insertions, 1 deletions
diff --git a/app/app.gyp b/app/app.gyp
index c35ba0e..506ee8b 100644
--- a/app/app.gyp
+++ b/app/app.gyp
@@ -107,8 +107,12 @@
'gfx/icon_util.cc',
'gfx/icon_util.h',
'gfx/insets.h',
+ 'gfx/native_widget_types.h',
+ 'gfx/native_widget_types_gtk.cc',
'gfx/native_theme_win.cc',
'gfx/native_theme_win.h',
+ 'gfx/gtk_native_view_id_manager.cc',
+ 'gfx/gtk_native_view_id_manager.h',
'gfx/path_gtk.cc',
'gfx/path_win.cc',
'gfx/path.h',
@@ -154,6 +158,8 @@
'table_model.cc',
'table_model.h',
'table_model_observer.h',
+ 'win/window_impl.cc',
+ 'win/window_impl.h',
],
'direct_dependent_settings': {
'include_dirs': [
@@ -205,6 +211,8 @@
'gfx/native_theme_win.cc',
'gfx/native_theme_win.h',
'os_exchange_data.cc',
+ 'win/window_impl.cc',
+ 'win/window_impl.h',
],
}],
['OS!="linux"', {
@@ -241,6 +249,8 @@
'gfx/codec/png_codec_unittest.cc',
'gfx/color_utils_unittest.cc',
'gfx/font_unittest.cc',
+ 'gfx/gtk_native_view_id_manager.cc',
+ 'gfx/gtk_native_view_id_manager.h',
'gfx/icon_util_unittest.cc',
'gfx/native_theme_win_unittest.cc',
'gfx/skbitmap_operations_unittest.cc',
diff --git a/app/gfx/blit.h b/app/gfx/blit.h
index f2460ca..9eaa93e 100644
--- a/app/gfx/blit.h
+++ b/app/gfx/blit.h
@@ -5,7 +5,7 @@
#ifndef APP_GFX_BLIT_H_
#define APP_GFX_BLIT_H_
-#include "base/gfx/native_widget_types.h"
+#include "app/gfx/native_widget_types.h"
#include "base/gfx/point.h"
#include "base/gfx/rect.h"
diff --git a/app/gfx/gtk_native_view_id_manager.cc b/app/gfx/gtk_native_view_id_manager.cc
new file mode 100644
index 0000000..b0dcc10
--- /dev/null
+++ b/app/gfx/gtk_native_view_id_manager.cc
@@ -0,0 +1,145 @@
+// 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.
+
+#include "app/gfx/gtk_native_view_id_manager.h"
+
+#include "base/gfx/rect.h"
+#include "base/logging.h"
+#include "base/rand_util.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+// -----------------------------------------------------------------------------
+// Bounce functions for GTK to callback into a C++ object...
+
+static void OnRealize(gfx::NativeView widget, void* arg) {
+ GtkNativeViewManager* manager = reinterpret_cast<GtkNativeViewManager*>(arg);
+ manager->OnRealize(widget);
+}
+
+static void OnUnrealize(gfx::NativeView widget, void *arg) {
+ GtkNativeViewManager* manager = reinterpret_cast<GtkNativeViewManager*>(arg);
+ manager->OnUnrealize(widget);
+}
+
+static void OnDestroy(GtkObject* obj, void* arg) {
+ GtkNativeViewManager* manager = reinterpret_cast<GtkNativeViewManager*>(arg);
+ manager->OnDestroy(reinterpret_cast<GtkWidget*>(obj));
+}
+
+// -----------------------------------------------------------------------------
+
+
+// -----------------------------------------------------------------------------
+// Public functions...
+
+GtkNativeViewManager::GtkNativeViewManager() {
+}
+
+gfx::NativeViewId GtkNativeViewManager::GetIdForWidget(gfx::NativeView widget) {
+ // This is just for unit tests:
+ if (!widget)
+ return 0;
+
+ AutoLock locked(lock_);
+
+ std::map<gfx::NativeView, gfx::NativeViewId>::const_iterator i =
+ native_view_to_id_.find(widget);
+
+ if (i != native_view_to_id_.end())
+ return i->second;
+
+ gfx::NativeViewId new_id =
+ static_cast<gfx::NativeViewId>(base::RandUint64());
+ while (id_to_info_.find(new_id) != id_to_info_.end())
+ new_id = static_cast<gfx::NativeViewId>(base::RandUint64());
+
+ NativeViewInfo info;
+ if (GTK_WIDGET_REALIZED(widget)) {
+ GdkWindow *gdk_window = widget->window;
+ CHECK(gdk_window);
+ info.x_window_id = GDK_WINDOW_XID(gdk_window);
+ }
+
+ native_view_to_id_[widget] = new_id;
+ id_to_info_[new_id] = info;
+
+ g_signal_connect(widget, "realize", G_CALLBACK(::OnRealize), this);
+ g_signal_connect(widget, "unrealize", G_CALLBACK(::OnUnrealize), this);
+ g_signal_connect(widget, "destroy", G_CALLBACK(::OnDestroy), this);
+
+ return new_id;
+}
+
+bool GtkNativeViewManager::GetXIDForId(XID* output, gfx::NativeViewId id) {
+ AutoLock locked(lock_);
+
+ std::map<gfx::NativeViewId, NativeViewInfo>::const_iterator i =
+ id_to_info_.find(id);
+
+ if (i == id_to_info_.end())
+ return false;
+
+ *output = i->second.x_window_id;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+
+
+// -----------------------------------------------------------------------------
+// Private functions...
+
+gfx::NativeViewId GtkNativeViewManager::GetWidgetId(gfx::NativeView widget) {
+ lock_.AssertAcquired();
+
+ std::map<gfx::NativeView, gfx::NativeViewId>::const_iterator i =
+ native_view_to_id_.find(widget);
+
+ CHECK(i != native_view_to_id_.end());
+ return i->second;
+}
+
+void GtkNativeViewManager::OnRealize(gfx::NativeView widget) {
+ AutoLock locked(lock_);
+
+ const gfx::NativeViewId id = GetWidgetId(widget);
+ std::map<gfx::NativeViewId, NativeViewInfo>::iterator i =
+ id_to_info_.find(id);
+
+ CHECK(i != id_to_info_.end());
+ CHECK(widget->window);
+
+ i->second.x_window_id = GDK_WINDOW_XID(widget->window);
+}
+
+void GtkNativeViewManager::OnUnrealize(gfx::NativeView widget) {
+ AutoLock locked(lock_);
+
+ const gfx::NativeViewId id = GetWidgetId(widget);
+ std::map<gfx::NativeViewId, NativeViewInfo>::iterator i =
+ id_to_info_.find(id);
+
+ CHECK(i != id_to_info_.end());
+
+ i->second.x_window_id = 0;
+}
+
+void GtkNativeViewManager::OnDestroy(gfx::NativeView widget) {
+ AutoLock locked(lock_);
+
+ std::map<gfx::NativeView, gfx::NativeViewId>::iterator i =
+ native_view_to_id_.find(widget);
+ CHECK(i != native_view_to_id_.end());
+
+ std::map<gfx::NativeViewId, NativeViewInfo>::iterator j =
+ id_to_info_.find(i->second);
+ CHECK(j != id_to_info_.end());
+
+ native_view_to_id_.erase(i);
+ id_to_info_.erase(j);
+}
+
+// -----------------------------------------------------------------------------
diff --git a/app/gfx/gtk_native_view_id_manager.h b/app/gfx/gtk_native_view_id_manager.h
new file mode 100644
index 0000000..bb8f732
--- /dev/null
+++ b/app/gfx/gtk_native_view_id_manager.h
@@ -0,0 +1,91 @@
+// 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 APP_GFX_GTK_NATIVE_VIEW_ID_MANAGER_H_
+#define APP_GFX_GTK_NATIVE_VIEW_ID_MANAGER_H_
+
+#include <map>
+
+#include "app/gfx/native_widget_types.h"
+#include "base/singleton.h"
+
+typedef unsigned long XID;
+
+// NativeViewIds are the opaque values which the renderer holds as a reference
+// to a window. These ids are often used in sync calls from the renderer and
+// one cannot terminate sync calls on the UI thread as that can lead to
+// deadlocks.
+//
+// Because of this, we have the BACKGROUND_X11 thread for these calls and this
+// thread has a separate X connection in order to answer them. But one cannot
+// use GTK on multiple threads, so the BACKGROUND_X11 thread deals only in Xlib
+// calls and, thus, XIDs.
+//
+// So we could make NativeViewIds be the X id of the window. However, at the
+// time when we need to tell the renderer about its NativeViewId, an XID isn't
+// availible and it goes very much against the grain of the code to make it so.
+// Also, we worry that GTK might choose to change the underlying X window id
+// when, say, the widget is hidden or repacked. Finally, if we used XIDs then a
+// compromised renderer could start asking questions about any X windows on the
+// system.
+//
+// Thus, we have this object. It produces random NativeViewIds from GtkWidget
+// pointers and observes the various signals from the widget for when an X
+// window is created, destroyed etc. Thus it provides a thread safe mapping
+// from NativeViewIds to the current XID for that widget.
+//
+// You get a reference to the global instance with:
+// Singleton<GtkNativeViewManager>()
+class GtkNativeViewManager {
+ public:
+ // Must be called from the UI thread:
+ //
+ // Return a NativeViewId for the given widget and attach to the various
+ // signals emitted by that widget. The NativeViewId is pseudo-randomly
+ // allocated so that a compromised renderer trying to guess values will fail
+ // with high probability. The NativeViewId will not be reused for the
+ // lifetime of the GtkWidget.
+ gfx::NativeViewId GetIdForWidget(gfx::NativeView widget);
+
+ // May be called from any thread:
+ //
+ // xid: (output) the resulting X window ID, or 0
+ // id: a value previously returned from GetIdForWidget
+ // returns: true if |id| is a valid id, false otherwise.
+ //
+ // If the widget referenced by |id| does not current have an X window id,
+ // |*xid| is set to 0.
+ bool GetXIDForId(XID* xid, gfx::NativeViewId id);
+
+ // These are actually private functions, but need to be called from statics.
+ void OnRealize(gfx::NativeView widget);
+ void OnUnrealize(gfx::NativeView widget);
+ void OnDestroy(gfx::NativeView widget);
+
+ private:
+ // This object is a singleton:
+ GtkNativeViewManager();
+ friend struct DefaultSingletonTraits<GtkNativeViewManager>;
+
+ struct NativeViewInfo {
+ NativeViewInfo()
+ : x_window_id(0) {
+ }
+
+ XID x_window_id;
+ };
+
+ gfx::NativeViewId GetWidgetId(gfx::NativeView id);
+
+ // protects native_view_to_id_ and id_to_info_
+ Lock lock_;
+ // If asked for an id for the same widget twice, we want to return the same
+ // id. So this records the current mapping.
+ std::map<gfx::NativeView, gfx::NativeViewId> native_view_to_id_;
+ std::map<gfx::NativeViewId, NativeViewInfo> id_to_info_;
+
+ DISALLOW_COPY_AND_ASSIGN(GtkNativeViewManager);
+};
+
+#endif // APP_GFX_GTK_NATIVE_VIEW_ID_MANAGER_H_
diff --git a/app/gfx/native_widget_types.h b/app/gfx/native_widget_types.h
new file mode 100644
index 0000000..d116d9c
--- /dev/null
+++ b/app/gfx/native_widget_types.h
@@ -0,0 +1,143 @@
+// 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 APP_GFX_NATIVE_WIDGET_TYPES_H_
+#define APP_GFX_NATIVE_WIDGET_TYPES_H_
+
+#include "base/basictypes.h"
+#include "build/build_config.h"
+
+// This file provides cross platform typedefs for native widget types.
+// NativeWindow: this is a handle to a native, top-level window
+// NativeView: this is a handle to a native UI element. It may be the
+// same type as a NativeWindow on some platforms.
+// NativeViewId: Often, in our cross process model, we need to pass around a
+// reference to a "window". This reference will, say, be echoed back from a
+// renderer to the browser when it wishes to query it's size. On Windows, a
+// HWND can be used for this. On other platforms, we may wish to pass
+// around X window ids, or maybe abstract identifiers.
+//
+// As a rule of thumb - if you're in the renderer, you should be dealing
+// with NativeViewIds. This should remind you that you shouldn't be doing
+// direct operations on platform widgets from the renderer process.
+//
+// If you're in the browser, you're probably dealing with NativeViews,
+// unless you're in the IPC layer, which will be translating between
+// NativeViewIds from the renderer and NativeViews.
+//
+// NativeEditView: a handle to a native edit-box. The Mac folks wanted this
+// specific typedef.
+//
+// The name 'View' here meshes with OS X where the UI elements are called
+// 'views' and with our Chrome UI code where the elements are also called
+// 'views'.
+
+#if defined(OS_WIN)
+#include <windows.h>
+#elif defined(OS_MACOSX)
+struct CGContext;
+#ifdef __OBJC__
+@class NSView;
+@class NSWindow;
+@class NSTextField;
+#else
+class NSView;
+class NSWindow;
+class NSTextField;
+#endif // __OBJC__
+#elif defined(USE_X11)
+typedef struct _GdkCursor GdkCursor;
+typedef struct _GtkWidget GtkWidget;
+typedef struct _GtkWindow GtkWindow;
+typedef struct _cairo cairo_t;
+#endif
+
+namespace gfx {
+
+#if defined(OS_WIN)
+typedef HWND NativeView;
+typedef HWND NativeWindow;
+typedef HWND NativeEditView;
+typedef HDC NativeDrawingContext;
+typedef HCURSOR NativeCursor;
+typedef HMENU NativeMenu;
+#elif defined(OS_MACOSX)
+typedef NSView* NativeView;
+typedef NSWindow* NativeWindow;
+typedef NSTextField* NativeEditView;
+typedef CGContext* NativeDrawingContext;
+typedef void* NativeCursor;
+typedef void* NativeMenu;
+#elif defined(USE_X11)
+typedef GtkWidget* NativeView;
+typedef GtkWindow* NativeWindow;
+typedef GtkWidget* NativeEditView;
+typedef cairo_t* NativeDrawingContext;
+typedef GdkCursor* NativeCursor;
+typedef GtkWidget* NativeMenu;
+#endif
+
+// Note: for test_shell we're packing a pointer into the NativeViewId. So, if
+// you make it a type which is smaller than a pointer, you have to fix
+// test_shell.
+//
+// See comment at the top of the file for usage.
+typedef intptr_t NativeViewId;
+
+// Convert a NativeViewId to a NativeView.
+// On Windows, these are both HWNDS so it's just a cast.
+// On Mac, for now, we pass the NSView pointer into the renderer
+// On Linux we use an opaque id
+#if defined(OS_WIN)
+static inline NativeView NativeViewFromId(NativeViewId id) {
+ return reinterpret_cast<NativeView>(id);
+}
+#elif defined(OS_MACOSX)
+
+// A recent CL removed the need for Mac to actually convert
+// NativeViewId to NativeView. Until other platforms make changes,
+// the platform-independent code cannot be removed. The following is
+// to discourage new platform-independent uses.
+
+#define NativeViewFromId(x) NATIVE_VIEW_FROM_ID_NOT_AVAILABLE_ON_MAC
+
+#elif defined(USE_X11)
+// A NativeView on Linux is a GtkWidget*. However, we can't go directly from an
+// X window ID to a GtkWidget. Thus, functions which handle NativeViewIds from
+// the renderer have to use Xlib. This is fine since these functions are
+// generally performed on the BACKGROUND_X thread which can't use GTK anyway.
+
+#define NativeViewFromId(x) NATIVE_VIEW_FROM_ID_NOT_AVAILIBLE_ON_X11
+
+#endif // defined(USE_X11)
+
+// Convert a NativeView to a NativeViewId. See the comments above
+// NativeViewFromId.
+#if defined(OS_WIN) || defined(OS_MACOSX)
+static inline NativeViewId IdFromNativeView(NativeView view) {
+ return reinterpret_cast<NativeViewId>(view);
+}
+#elif defined(USE_X11)
+// Not inlined because it involves pulling too many headers.
+NativeViewId IdFromNativeView(NativeView view);
+#endif // defined(USE_X11)
+
+
+// PluginWindowHandle is an abstraction wrapping "the types of windows
+// used by NPAPI plugins". On Windows it's an HWND, on X it's an X
+// window id.
+#if defined(OS_WIN)
+ typedef HWND PluginWindowHandle;
+#elif defined(USE_X11)
+ typedef unsigned long PluginWindowHandle;
+#else
+ // On OS X we don't have windowed plugins.
+ // We use a NULL/0 PluginWindowHandle in shared code to indicate there
+ // is no window present, so mirror that behavior here.
+ typedef bool PluginWindowHandle;
+#endif
+
+} // namespace gfx
+
+#endif // APP_GFX_NATIVE_WIDGET_TYPES_H_
diff --git a/app/gfx/native_widget_types_gtk.cc b/app/gfx/native_widget_types_gtk.cc
new file mode 100644
index 0000000..34603d9
--- /dev/null
+++ b/app/gfx/native_widget_types_gtk.cc
@@ -0,0 +1,16 @@
+// 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.
+
+#include "app/gfx/native_widget_types.h"
+
+#include "app/gfx/gtk_native_view_id_manager.h"
+#include "base/logging.h"
+
+namespace gfx {
+
+NativeViewId IdFromNativeView(NativeView view) {
+ return Singleton<GtkNativeViewManager>()->GetIdForWidget(view);
+}
+
+} // namespace gfx
diff --git a/app/win/window_impl.cc b/app/win/window_impl.cc
new file mode 100644
index 0000000..b28eab5
--- /dev/null
+++ b/app/win/window_impl.cc
@@ -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.
+
+#include "app/win/window_impl.h"
+
+#include <list>
+
+#include "base/singleton.h"
+#include "base/string_util.h"
+#include "base/win_util.h"
+
+namespace app {
+
+static const DWORD kWindowDefaultChildStyle =
+ WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+static const DWORD kWindowDefaultStyle = WS_OVERLAPPEDWINDOW;
+static const DWORD kWindowDefaultExStyle = 0;
+
+///////////////////////////////////////////////////////////////////////////////
+// WindowImpl class tracking.
+
+// static
+const wchar_t* const WindowImpl::kBaseClassName = L"Chrome_WindowImpl_";
+
+// WindowImpl class information used for registering unique windows.
+struct ClassInfo {
+ UINT style;
+ HBRUSH background;
+
+ explicit ClassInfo(int style)
+ : style(style),
+ background(NULL) {}
+
+ // Compares two ClassInfos. Returns true if all members match.
+ bool Equals(const ClassInfo& other) const {
+ return (other.style == style && other.background == background);
+ }
+};
+
+class ClassRegistrar {
+ public:
+ ~ClassRegistrar() {
+ for (RegisteredClasses::iterator i = registered_classes_.begin();
+ i != registered_classes_.end(); ++i) {
+ UnregisterClass(i->name.c_str(), NULL);
+ }
+ }
+
+ // Puts the name for the class matching |class_info| in |class_name|, creating
+ // a new name if the class is not yet known.
+ // Returns true if this class was already known, false otherwise.
+ bool RetrieveClassName(const ClassInfo& class_info, std::wstring* name) {
+ for (RegisteredClasses::const_iterator i = registered_classes_.begin();
+ i != registered_classes_.end(); ++i) {
+ if (class_info.Equals(i->info)) {
+ name->assign(i->name);
+ return true;
+ }
+ }
+
+ name->assign(std::wstring(WindowImpl::kBaseClassName) +
+ IntToWString(registered_count_++));
+ return false;
+ }
+
+ void RegisterClass(const ClassInfo& class_info,
+ const std::wstring& name,
+ ATOM atom) {
+ registered_classes_.push_back(RegisteredClass(class_info, name, atom));
+ }
+
+ private:
+ // Represents a registered window class.
+ struct RegisteredClass {
+ RegisteredClass(const ClassInfo& info,
+ const std::wstring& name,
+ ATOM atom)
+ : info(info),
+ name(name),
+ atom(atom) {
+ }
+
+ // Info used to create the class.
+ ClassInfo info;
+
+ // The name given to the window.
+ std::wstring name;
+
+ // The ATOM returned from creating the window.
+ ATOM atom;
+ };
+
+ ClassRegistrar() : registered_count_(0) { }
+ friend struct DefaultSingletonTraits<ClassRegistrar>;
+
+ typedef std::list<RegisteredClass> RegisteredClasses;
+ RegisteredClasses registered_classes_;
+
+ // Counter of how many classes have been registered so far.
+ int registered_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(ClassRegistrar);
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// WindowImpl, public
+
+WindowImpl::WindowImpl()
+ : window_style_(0),
+ window_ex_style_(kWindowDefaultExStyle),
+ class_style_(CS_DBLCLKS),
+ hwnd_(NULL) {
+}
+
+WindowImpl::~WindowImpl() {
+}
+
+void WindowImpl::Init(HWND parent, const gfx::Rect& bounds) {
+ if (window_style_ == 0)
+ window_style_ = parent ? kWindowDefaultChildStyle : kWindowDefaultStyle;
+
+ // Ensures the parent we have been passed is valid, otherwise CreateWindowEx
+ // will fail.
+ if (parent && !::IsWindow(parent)) {
+ NOTREACHED() << "invalid parent window specified.";
+ parent = NULL;
+ }
+
+ int x, y, width, height;
+ if (bounds.IsEmpty()) {
+ x = y = width = height = CW_USEDEFAULT;
+ } else {
+ x = bounds.x();
+ y = bounds.y();
+ width = bounds.width();
+ height = bounds.height();
+ }
+
+ hwnd_ = CreateWindowEx(window_ex_style_, GetWindowClassName().c_str(), NULL,
+ window_style_, x, y, width, height,
+ parent, NULL, NULL, this);
+ DCHECK(hwnd_);
+
+ // The window procedure should have set the data for us.
+ DCHECK(win_util::GetWindowUserData(hwnd_) == this);
+}
+
+HICON WindowImpl::GetDefaultWindowIcon() const {
+ return NULL;
+}
+
+LRESULT WindowImpl::OnWndProc(UINT message, WPARAM w_param, LPARAM l_param) {
+ LRESULT result = 0;
+
+ // Handle the message if it's in our message map; otherwise, let the system
+ // handle it.
+ if (!ProcessWindowMessage(hwnd_, message, w_param, l_param, result))
+ result = DefWindowProc(hwnd_, message, w_param, l_param);
+
+ return result;
+}
+
+// static
+LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ if (message == WM_NCCREATE) {
+ CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(l_param);
+ WindowImpl* window = reinterpret_cast<WindowImpl*>(cs->lpCreateParams);
+ DCHECK(window);
+ win_util::SetWindowUserData(hwnd, window);
+ window->hwnd_ = hwnd;
+ return TRUE;
+ }
+
+ WindowImpl* window = reinterpret_cast<WindowImpl*>(
+ win_util::GetWindowUserData(hwnd));
+ if (!window)
+ return 0;
+
+ return window->OnWndProc(message, w_param, l_param);
+}
+
+std::wstring WindowImpl::GetWindowClassName() {
+ ClassInfo class_info(initial_class_style());
+ std::wstring name;
+ if (Singleton<ClassRegistrar>()->RetrieveClassName(class_info, &name))
+ return name;
+
+ // No class found, need to register one.
+ WNDCLASSEX class_ex;
+ class_ex.cbSize = sizeof(WNDCLASSEX);
+ class_ex.style = class_info.style;
+ class_ex.lpfnWndProc = &WindowImpl::WndProc;
+ class_ex.cbClsExtra = 0;
+ class_ex.cbWndExtra = 0;
+ class_ex.hInstance = NULL;
+ class_ex.hIcon = GetDefaultWindowIcon();
+ class_ex.hCursor = LoadCursor(NULL, IDC_ARROW);
+ class_ex.hbrBackground = reinterpret_cast<HBRUSH>(class_info.background + 1);
+ class_ex.lpszMenuName = NULL;
+ class_ex.lpszClassName = name.c_str();
+ class_ex.hIconSm = class_ex.hIcon;
+ ATOM atom = RegisterClassEx(&class_ex);
+ DCHECK(atom);
+
+ Singleton<ClassRegistrar>()->RegisterClass(class_info, name, atom);
+
+ return name;
+}
+
+} // namespace app
diff --git a/app/win/window_impl.h b/app/win/window_impl.h
new file mode 100644
index 0000000..fb5d512
--- /dev/null
+++ b/app/win/window_impl.h
@@ -0,0 +1,110 @@
+// 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 APP_WIN_WINDOW_IMPL_H_
+#define APP_WIN_WINDOW_IMPL_H_
+
+#include <atlbase.h>
+#include <atlapp.h>
+#include <atlmisc.h>
+#include <atlcrack.h>
+
+#include <string>
+
+#include "app/gfx/native_widget_types.h"
+#include "base/gfx/rect.h"
+#include "base/logging.h"
+
+namespace app {
+
+// An interface implemented by classes that use message maps.
+// ProcessWindowMessage is implemented by the BEGIN_MESSAGE_MAP_EX macro.
+class MessageMapInterface {
+ public:
+ // Processes one message from the window's message queue.
+ virtual BOOL ProcessWindowMessage(HWND window,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param,
+ LRESULT& result,
+ DWORD msg_mad_id = 0) = 0;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// WindowImpl
+// A convenience class that encapsulates the details of creating and
+// destroying a HWND. This class also hosts the windows procedure used by all
+// Windows.
+//
+///////////////////////////////////////////////////////////////////////////////
+class WindowImpl : public MessageMapInterface {
+ public:
+ WindowImpl();
+ virtual ~WindowImpl();
+
+ // Initializes the Window with a parent and an initial desired size.
+ void Init(HWND parent, const gfx::Rect& bounds);
+
+ // Retrieves the default window icon to use for windows if none is specified.
+ virtual HICON GetDefaultWindowIcon() const;
+
+ // Returns the HWND associated with this Window.
+ HWND hwnd() const { return hwnd_; }
+
+ // Sets the window styles. This is ONLY used when the window is created.
+ // In other words, if you invoke this after invoking Init, nothing happens.
+ void set_window_style(DWORD style) { window_style_ = style; }
+ DWORD window_style() const { return window_style_; }
+
+ // Sets the extended window styles. See comment about |set_window_style|.
+ void set_window_ex_style(DWORD style) { window_ex_style_ = style; }
+ DWORD window_ex_style() const { return window_ex_style_; }
+
+ // Sets the class style to use. The default is CS_DBLCLKS.
+ void set_initial_class_style(UINT class_style) {
+ // We dynamically generate the class name, so don't register it globally!
+ DCHECK_EQ((class_style & CS_GLOBALCLASS), 0);
+ class_style_ = class_style;
+ }
+ UINT initial_class_style() { return class_style_; }
+
+ protected:
+ // Handles the WndProc callback for this object.
+ virtual LRESULT OnWndProc(UINT message, WPARAM w_param, LPARAM l_param);
+
+ private:
+ friend class ClassRegistrar;
+
+ // The window procedure used by all Windows.
+ static LRESULT CALLBACK WndProc(HWND window,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param);
+
+ // Gets the window class name to use when creating the corresponding HWND.
+ // If necessary, this registers the window class.
+ std::wstring GetWindowClassName();
+
+ // All classes registered by WidgetWin start with this name.
+ static const wchar_t* const kBaseClassName;
+
+ // Window Styles used when creating the window.
+ DWORD window_style_;
+
+ // Window Extended Styles used when creating the window.
+ DWORD window_ex_style_;
+
+ // Style of the class to use.
+ UINT class_style_;
+
+ // Our hwnd.
+ HWND hwnd_;
+
+ DISALLOW_COPY_AND_ASSIGN(WindowImpl);
+};
+
+} // namespace app
+
+#endif // APP_WIN_WINDOW_IMPL_H_