diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/app.gyp | 10 | ||||
-rw-r--r-- | app/gfx/blit.h | 2 | ||||
-rw-r--r-- | app/gfx/gtk_native_view_id_manager.cc | 145 | ||||
-rw-r--r-- | app/gfx/gtk_native_view_id_manager.h | 91 | ||||
-rw-r--r-- | app/gfx/native_widget_types.h | 143 | ||||
-rw-r--r-- | app/gfx/native_widget_types_gtk.cc | 16 | ||||
-rw-r--r-- | app/win/window_impl.cc | 214 | ||||
-rw-r--r-- | app/win/window_impl.h | 110 |
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_ |