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 |