| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 
 |    2 // Use of this source code is governed by a BSD-style license that can be | 
 |    3 // found in the LICENSE file. | 
 |    4  | 
 |    5 #include <list> | 
 |    6  | 
 |    7 #include "base/singleton.h" | 
 |    8 #include "base/string_util.h" | 
 |    9 #include "base/window_impl.h" | 
 |   10 #include "base/win_util.h" | 
 |   11  | 
 |   12 namespace base { | 
 |   13  | 
 |   14 static const DWORD kWindowDefaultChildStyle = | 
 |   15     WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; | 
 |   16 static const DWORD kWindowDefaultStyle = WS_OVERLAPPEDWINDOW; | 
 |   17 static const DWORD kWindowDefaultExStyle = 0; | 
 |   18  | 
 |   19 /////////////////////////////////////////////////////////////////////////////// | 
 |   20 // WindowImpl class tracking. | 
 |   21  | 
 |   22 // static | 
 |   23 const wchar_t* const WindowImpl::kBaseClassName = L"Chrome_WindowImpl_"; | 
 |   24  | 
 |   25 // WindowImpl class information used for registering unique windows. | 
 |   26 struct ClassInfo { | 
 |   27   UINT style; | 
 |   28   HBRUSH background; | 
 |   29  | 
 |   30   explicit ClassInfo(int style) | 
 |   31       : style(style), | 
 |   32         background(NULL) {} | 
 |   33  | 
 |   34   // Compares two ClassInfos. Returns true if all members match. | 
 |   35   bool Equals(const ClassInfo& other) const { | 
 |   36     return (other.style == style && other.background == background); | 
 |   37   } | 
 |   38 }; | 
 |   39  | 
 |   40 class ClassRegistrar { | 
 |   41  public: | 
 |   42   ~ClassRegistrar() { | 
 |   43     for (RegisteredClasses::iterator i = registered_classes_.begin(); | 
 |   44          i != registered_classes_.end(); ++i) { | 
 |   45       UnregisterClass(i->name.c_str(), NULL); | 
 |   46     } | 
 |   47   } | 
 |   48  | 
 |   49   // Puts the name for the class matching |class_info| in |class_name|, creating | 
 |   50   // a new name if the class is not yet known. | 
 |   51   // Returns true if this class was already known, false otherwise. | 
 |   52   bool RetrieveClassName(const ClassInfo& class_info, std::wstring* name) { | 
 |   53     for (RegisteredClasses::const_iterator i = registered_classes_.begin(); | 
 |   54          i != registered_classes_.end(); ++i) { | 
 |   55       if (class_info.Equals(i->info)) { | 
 |   56         name->assign(i->name); | 
 |   57         return true; | 
 |   58       } | 
 |   59     } | 
 |   60  | 
 |   61     name->assign(std::wstring(WindowImpl::kBaseClassName) + | 
 |   62         IntToWString(registered_count_++)); | 
 |   63     return false; | 
 |   64   } | 
 |   65  | 
 |   66   void RegisterClass(const ClassInfo& class_info, | 
 |   67                      const std::wstring& name, | 
 |   68                      ATOM atom) { | 
 |   69     registered_classes_.push_back(RegisteredClass(class_info, name, atom)); | 
 |   70   } | 
 |   71  | 
 |   72  private: | 
 |   73   // Represents a registered window class. | 
 |   74   struct RegisteredClass { | 
 |   75     RegisteredClass(const ClassInfo& info, | 
 |   76                     const std::wstring& name, | 
 |   77                     ATOM atom) | 
 |   78         : info(info), | 
 |   79           name(name), | 
 |   80           atom(atom) { | 
 |   81     } | 
 |   82  | 
 |   83     // Info used to create the class. | 
 |   84     ClassInfo info; | 
 |   85  | 
 |   86     // The name given to the window. | 
 |   87     std::wstring name; | 
 |   88  | 
 |   89     // The ATOM returned from creating the window. | 
 |   90     ATOM atom; | 
 |   91   }; | 
 |   92  | 
 |   93   ClassRegistrar() : registered_count_(0) { } | 
 |   94   friend struct DefaultSingletonTraits<ClassRegistrar>; | 
 |   95  | 
 |   96   typedef std::list<RegisteredClass> RegisteredClasses; | 
 |   97   RegisteredClasses registered_classes_; | 
 |   98  | 
 |   99   // Counter of how many classes have ben registered so far. | 
 |  100   int registered_count_; | 
 |  101  | 
 |  102   DISALLOW_COPY_AND_ASSIGN(ClassRegistrar); | 
 |  103 }; | 
 |  104  | 
 |  105 /////////////////////////////////////////////////////////////////////////////// | 
 |  106 // WindowImpl, public | 
 |  107  | 
 |  108 WindowImpl::WindowImpl() | 
 |  109     : window_style_(0), | 
 |  110       window_ex_style_(kWindowDefaultExStyle), | 
 |  111       class_style_(CS_DBLCLKS), | 
 |  112       hwnd_(NULL) { | 
 |  113 } | 
 |  114  | 
 |  115 WindowImpl::~WindowImpl() { | 
 |  116 } | 
 |  117  | 
 |  118 void WindowImpl::Init(HWND parent, const gfx::Rect& bounds) { | 
 |  119   if (window_style_ == 0) | 
 |  120     window_style_ = parent ? kWindowDefaultChildStyle : kWindowDefaultStyle; | 
 |  121  | 
 |  122   // Ensures the parent we have been passed is valid, otherwise CreateWindowEx | 
 |  123   // will fail. | 
 |  124   if (parent && !::IsWindow(parent)) { | 
 |  125     NOTREACHED() << "invalid parent window specified."; | 
 |  126     parent = NULL; | 
 |  127   } | 
 |  128  | 
 |  129   hwnd_ = CreateWindowEx(window_ex_style_, GetWindowClassName().c_str(), L"", | 
 |  130                          window_style_, bounds.x(), bounds.y(), bounds.width(), | 
 |  131                          bounds.height(), parent, NULL, NULL, this); | 
 |  132   DCHECK(hwnd_); | 
 |  133  | 
 |  134   // The window procedure should have set the data for us. | 
 |  135   DCHECK(win_util::GetWindowUserData(hwnd_) == this); | 
 |  136 } | 
 |  137  | 
 |  138 gfx::NativeView WindowImpl::GetNativeView() const { | 
 |  139   return hwnd_; | 
 |  140 } | 
 |  141  | 
 |  142 HICON WindowImpl::GetDefaultWindowIcon() const { | 
 |  143   return NULL; | 
 |  144 } | 
 |  145  | 
 |  146 BOOL WindowImpl::DestroyWindow() { | 
 |  147   DCHECK(::IsWindow(GetNativeView())); | 
 |  148   return ::DestroyWindow(GetNativeView()); | 
 |  149 } | 
 |  150  | 
 |  151 LRESULT WindowImpl::OnWndProc(UINT message, WPARAM w_param, LPARAM l_param) { | 
 |  152   HWND window = GetNativeView(); | 
 |  153   LRESULT result = 0; | 
 |  154  | 
 |  155   // Handle the message if it's in our message map; otherwise, let the system | 
 |  156   // handle it. | 
 |  157   if (!ProcessWindowMessage(window, message, w_param, l_param, result)) | 
 |  158     result = DefWindowProc(window, message, w_param, l_param); | 
 |  159  | 
 |  160   return result; | 
 |  161 } | 
 |  162  | 
 |  163 // static | 
 |  164 LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, | 
 |  165                                      UINT message, | 
 |  166                                      WPARAM w_param, | 
 |  167                                      LPARAM l_param) { | 
 |  168   if (message == WM_NCCREATE) { | 
 |  169     CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(l_param); | 
 |  170     WindowImpl* window = reinterpret_cast<WindowImpl*>(cs->lpCreateParams); | 
 |  171     DCHECK(window); | 
 |  172     win_util::SetWindowUserData(hwnd, window); | 
 |  173     window->hwnd_ = hwnd; | 
 |  174     return TRUE; | 
 |  175   } | 
 |  176  | 
 |  177   WindowImpl* window = reinterpret_cast<WindowImpl*>( | 
 |  178       win_util::GetWindowUserData(hwnd)); | 
 |  179   if (!window) | 
 |  180     return 0; | 
 |  181  | 
 |  182   return window->OnWndProc(message, w_param, l_param); | 
 |  183 } | 
 |  184  | 
 |  185 std::wstring WindowImpl::GetWindowClassName() { | 
 |  186   ClassInfo class_info(initial_class_style()); | 
 |  187   std::wstring name; | 
 |  188   if (Singleton<ClassRegistrar>()->RetrieveClassName(class_info, &name)) | 
 |  189     return name; | 
 |  190  | 
 |  191   // No class found, need to register one. | 
 |  192   WNDCLASSEX class_ex; | 
 |  193   class_ex.cbSize = sizeof(WNDCLASSEX); | 
 |  194   class_ex.style = class_info.style; | 
 |  195   class_ex.lpfnWndProc = &WindowImpl::WndProc; | 
 |  196   class_ex.cbClsExtra = 0; | 
 |  197   class_ex.cbWndExtra = 0; | 
 |  198   class_ex.hInstance = NULL; | 
 |  199   class_ex.hIcon = GetDefaultWindowIcon(); | 
 |  200   class_ex.hCursor = LoadCursor(NULL, IDC_ARROW); | 
 |  201   class_ex.hbrBackground = reinterpret_cast<HBRUSH>(class_info.background + 1); | 
 |  202   class_ex.lpszMenuName = NULL; | 
 |  203   class_ex.lpszClassName = name.c_str(); | 
 |  204   class_ex.hIconSm = class_ex.hIcon; | 
 |  205   ATOM atom = RegisterClassEx(&class_ex); | 
 |  206   DCHECK(atom); | 
 |  207  | 
 |  208   Singleton<ClassRegistrar>()->RegisterClass(class_info, name, atom); | 
 |  209  | 
 |  210   return name; | 
 |  211 } | 
 |  212  | 
 |  213 }  // namespace base | 
| OLD | NEW |