| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "views/controls/menu/menu_win.h" | 5 #include "views/controls/menu/menu_win.h" |
| 6 | 6 |
| 7 #include <atlbase.h> | |
| 8 #include <atlapp.h> | |
| 9 #include <atlwin.h> | |
| 10 #include <atlcrack.h> | |
| 11 #include <atlframe.h> | |
| 12 #include <atlmisc.h> | |
| 13 #include <string> | 7 #include <string> |
| 14 | 8 |
| 15 #include "app/gfx/canvas.h" | 9 #include "app/gfx/canvas.h" |
| 16 #include "app/gfx/font.h" | 10 #include "app/gfx/font.h" |
| 17 #include "app/l10n_util.h" | 11 #include "app/l10n_util.h" |
| 18 #include "app/l10n_util_win.h" | 12 #include "app/l10n_util_win.h" |
| 19 #include "base/gfx/rect.h" | 13 #include "base/gfx/rect.h" |
| 20 #include "base/logging.h" | 14 #include "base/logging.h" |
| 21 #include "base/stl_util-inl.h" | 15 #include "base/stl_util-inl.h" |
| 22 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 17 #include "base/window_impl.h" |
| 23 #include "views/accelerator.h" | 18 #include "views/accelerator.h" |
| 24 | 19 |
| 25 namespace views { | 20 namespace views { |
| 26 | 21 |
| 27 // The width of an icon, including the pixels between the icon and | 22 // The width of an icon, including the pixels between the icon and |
| 28 // the item label. | 23 // the item label. |
| 29 static const int kIconWidth = 23; | 24 static const int kIconWidth = 23; |
| 30 // Margins between the top of the item and the label. | 25 // Margins between the top of the item and the label. |
| 31 static const int kItemTopMargin = 3; | 26 static const int kItemTopMargin = 3; |
| 32 // Margins between the bottom of the item and the label. | 27 // Margins between the bottom of the item and the label. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 44 // The data of menu items needed to display. | 39 // The data of menu items needed to display. |
| 45 struct MenuWin::ItemData { | 40 struct MenuWin::ItemData { |
| 46 std::wstring label; | 41 std::wstring label; |
| 47 SkBitmap icon; | 42 SkBitmap icon; |
| 48 bool submenu; | 43 bool submenu; |
| 49 }; | 44 }; |
| 50 | 45 |
| 51 namespace { | 46 namespace { |
| 52 | 47 |
| 53 static int ChromeGetMenuItemID(HMENU hMenu, int pos) { | 48 static int ChromeGetMenuItemID(HMENU hMenu, int pos) { |
| 54 // The built-in Windows ::GetMenuItemID doesn't work for submenus, | 49 // The built-in Windows GetMenuItemID doesn't work for submenus, |
| 55 // so here's our own implementation. | 50 // so here's our own implementation. |
| 56 MENUITEMINFO mii = {0}; | 51 MENUITEMINFO mii = {0}; |
| 57 mii.cbSize = sizeof(mii); | 52 mii.cbSize = sizeof(mii); |
| 58 mii.fMask = MIIM_ID; | 53 mii.fMask = MIIM_ID; |
| 59 GetMenuItemInfo(hMenu, pos, TRUE, &mii); | 54 GetMenuItemInfo(hMenu, pos, TRUE, &mii); |
| 60 return mii.wID; | 55 return mii.wID; |
| 61 } | 56 } |
| 62 | 57 |
| 63 // MenuHostWindow ------------------------------------------------------------- | 58 // MenuHostWindow ------------------------------------------------------------- |
| 64 | 59 |
| 65 // MenuHostWindow is the HWND the HMENU is parented to. MenuHostWindow is used | 60 // MenuHostWindow is the HWND the HMENU is parented to. MenuHostWindow is used |
| 66 // to intercept right clicks on the HMENU and notify the delegate as well as | 61 // to intercept right clicks on the HMENU and notify the delegate as well as |
| 67 // for drawing icons. | 62 // for drawing icons. |
| 68 // | 63 // |
| 69 class MenuHostWindow : public CWindowImpl<MenuHostWindow, CWindow, | 64 class MenuHostWindow : public base::WindowImpl { |
| 70 CWinTraits<WS_CHILD>> { | |
| 71 public: | 65 public: |
| 72 MenuHostWindow(MenuWin* menu, HWND parent_window) : menu_(menu) { | 66 MenuHostWindow(MenuWin* menu, HWND parent_window) : menu_(menu) { |
| 73 int extended_style = 0; | 67 int extended_style = 0; |
| 74 // If the menu needs to be created with a right-to-left UI layout, we must | 68 // If the menu needs to be created with a right-to-left UI layout, we must |
| 75 // set the appropriate RTL flags (such as WS_EX_LAYOUTRTL) property for the | 69 // set the appropriate RTL flags (such as WS_EX_LAYOUTRTL) property for the |
| 76 // underlying HWND. | 70 // underlying HWND. |
| 77 if (menu_->delegate()->IsRightToLeftUILayout()) | 71 if (menu_->delegate()->IsRightToLeftUILayout()) |
| 78 extended_style |= l10n_util::GetExtendedStyles(); | 72 extended_style |= l10n_util::GetExtendedStyles(); |
| 79 Create(parent_window, gfx::Rect().ToRECT(), 0, 0, extended_style); | 73 set_window_style(WS_CHILD); |
| 74 set_window_ex_style(extended_style); |
| 75 Init(parent_window, gfx::Rect()); |
| 80 } | 76 } |
| 81 | 77 |
| 82 ~MenuHostWindow() { | 78 ~MenuHostWindow() { |
| 83 DestroyWindow(); | 79 DestroyWindow(hwnd()); |
| 84 } | 80 } |
| 85 | 81 |
| 86 DECLARE_FRAME_WND_CLASS(L"MenuHostWindow", NULL); | 82 BEGIN_MSG_MAP_EX(MenuHostWindow); |
| 87 BEGIN_MSG_MAP(MenuHostWindow); | |
| 88 MSG_WM_RBUTTONUP(OnRButtonUp) | 83 MSG_WM_RBUTTONUP(OnRButtonUp) |
| 89 MSG_WM_MEASUREITEM(OnMeasureItem) | 84 MSG_WM_MEASUREITEM(OnMeasureItem) |
| 90 MSG_WM_DRAWITEM(OnDrawItem) | 85 MSG_WM_DRAWITEM(OnDrawItem) |
| 91 END_MSG_MAP(); | 86 END_MSG_MAP(); |
| 92 | 87 |
| 93 private: | 88 private: |
| 94 // NOTE: I really REALLY tried to use WM_MENURBUTTONUP, but I ran into | 89 // NOTE: I really REALLY tried to use WM_MENURBUTTONUP, but I ran into |
| 95 // two problems in using it: | 90 // two problems in using it: |
| 96 // 1. It doesn't contain the coordinates of the mouse. | 91 // 1. It doesn't contain the coordinates of the mouse. |
| 97 // 2. It isn't invoked for menuitems representing a submenu that have children | 92 // 2. It isn't invoked for menuitems representing a submenu that have children |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 is_menu_visible_ = true; | 355 is_menu_visible_ = true; |
| 361 DCHECK(owner_); | 356 DCHECK(owner_); |
| 362 // In order for context menus on menus to work, the context menu needs to | 357 // In order for context menus on menus to work, the context menu needs to |
| 363 // share the same window as the first menu is parented to. | 358 // share the same window as the first menu is parented to. |
| 364 bool created_host = false; | 359 bool created_host = false; |
| 365 if (!active_host_window) { | 360 if (!active_host_window) { |
| 366 created_host = true; | 361 created_host = true; |
| 367 active_host_window = new MenuHostWindow(this, owner_); | 362 active_host_window = new MenuHostWindow(this, owner_); |
| 368 } | 363 } |
| 369 UINT selected_id = | 364 UINT selected_id = |
| 370 TrackPopupMenuEx(menu_, flags, x, y, active_host_window->m_hWnd, NULL); | 365 TrackPopupMenuEx(menu_, flags, x, y, active_host_window->hwnd(), NULL); |
| 371 if (created_host) { | 366 if (created_host) { |
| 372 delete active_host_window; | 367 delete active_host_window; |
| 373 active_host_window = NULL; | 368 active_host_window = NULL; |
| 374 } | 369 } |
| 375 is_menu_visible_ = false; | 370 is_menu_visible_ = false; |
| 376 | 371 |
| 377 // Execute the chosen command | 372 // Execute the chosen command |
| 378 if (selected_id != 0) | 373 if (selected_id != 0) |
| 379 delegate()->ExecuteCommand(selected_id); | 374 delegate()->ExecuteCommand(selected_id); |
| 380 } | 375 } |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 break; | 564 break; |
| 570 | 565 |
| 571 default: | 566 default: |
| 572 NOTREACHED(); | 567 NOTREACHED(); |
| 573 return 0; | 568 return 0; |
| 574 } | 569 } |
| 575 return align_flags; | 570 return align_flags; |
| 576 } | 571 } |
| 577 | 572 |
| 578 } // namespace views | 573 } // namespace views |
| OLD | NEW |