Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: chrome_frame/in_place_menu.h

Issue 218019: Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome_frame/iids.cc ('k') | chrome_frame/installer_util/test.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2008, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 #ifndef CHROME_FRAME_IN_PLACE_MENU_H_
31 #define CHROME_FRAME_IN_PLACE_MENU_H_
32
33 // in_place_menu.h : menu merging implementation
34 //
35 // This file is a modified version of the menu.h file, which is
36 // part of the ActiveDoc MSDN sample. The modifications are largely
37 // conversions to Google coding guidelines. Below is the original header
38 // from the file.
39
40 // This is a part of the Active Template Library.
41 // Copyright (c) Microsoft Corporation. All rights reserved.
42 //
43 // This source code is only intended as a supplement to the
44 // Active Template Library Reference and related
45 // electronic documentation provided with the library.
46 // See these sources for detailed information regarding the
47 // Active Template Library product.
48
49 #include "base/logging.h"
50 #include "base/scoped_comptr_win.h"
51
52 template <class T>
53 class InPlaceMenu {
54 public:
55 InPlaceMenu() : shared_menu_(NULL), ole_menu_(NULL), our_menu_(NULL) {
56 }
57
58 ~InPlaceMenu() {
59 InPlaceMenuDestroy();
60 }
61
62 HRESULT InPlaceMenuCreate(LPCWSTR menu_name) {
63 // We might already have an in-place menu set, because we set menus
64 // IOleDocumentView::UIActivate as well as in
65 // IOleInPlaceActiveObject::OnDocWindowActivate. If we have already
66 // done our work, just return silently
67 if (ole_menu_ || shared_menu_)
68 return S_OK;
69
70 ScopedComPtr<IOleInPlaceFrame> in_place_frame;
71 GetInPlaceFrame(in_place_frame.Receive());
72 // We have no IOleInPlaceFrame, no menu merging possible
73 if (!in_place_frame) {
74 NOTREACHED();
75 return E_FAIL;
76 }
77 // Create a blank menu and ask the container to add
78 // its menus into the OLEMENUGROUPWIDTHS structure
79 shared_menu_ = ::CreateMenu();
80 OLEMENUGROUPWIDTHS mgw = {0};
81 HRESULT hr = in_place_frame->InsertMenus(shared_menu_, &mgw);
82 if (FAILED(hr)) {
83 ::DestroyMenu(shared_menu_);
84 shared_menu_ = NULL;
85 return hr;
86 }
87 // Insert our menus
88 our_menu_ = LoadMenu(_AtlBaseModule.GetResourceInstance(),menu_name);
89 MergeMenus(shared_menu_, our_menu_, &mgw.width[0], 1);
90 // Send the menu to the client
91 ole_menu_ = (HMENU)OleCreateMenuDescriptor(shared_menu_, &mgw);
92 T* t = static_cast<T*>(this);
93 in_place_frame->SetMenu(shared_menu_, ole_menu_, t->m_hWnd);
94 return S_OK;
95 }
96
97 HRESULT InPlaceMenuDestroy() {
98 ScopedComPtr<IOleInPlaceFrame> in_place_frame;
99 GetInPlaceFrame(in_place_frame.Receive());
100 if (in_place_frame) {
101 in_place_frame->RemoveMenus(shared_menu_);
102 in_place_frame->SetMenu(NULL, NULL, NULL);
103 }
104 if (ole_menu_) {
105 OleDestroyMenuDescriptor(ole_menu_);
106 ole_menu_ = NULL;
107 }
108 if (shared_menu_) {
109 UnmergeMenus(shared_menu_, our_menu_);
110 DestroyMenu(shared_menu_);
111 shared_menu_ = NULL;
112 }
113 if (our_menu_) {
114 DestroyMenu(our_menu_);
115 our_menu_ = NULL;
116 }
117 return S_OK;
118 }
119
120 void MergeMenus(HMENU shared_menu, HMENU source_menu, LONG* menu_widths,
121 unsigned int width_index) {
122 // Copy the popups from the source menu
123 // Insert at appropriate spot depending on width_index
124 DCHECK(width_index == 0 || width_index == 1);
125 int position = 0;
126 if (width_index == 1)
127 position = (int)menu_widths[0];
128 int group_width = 0;
129 int menu_items = GetMenuItemCount(source_menu);
130 for (int index = 0; index < menu_items; index++) {
131 // Get the HMENU of the popup
132 HMENU popup_menu = ::GetSubMenu(source_menu, index);
133 // Separators move us to next group
134 UINT state = GetMenuState(source_menu, index, MF_BYPOSITION);
135 if (!popup_menu && (state & MF_SEPARATOR)) {
136 // Servers should not touch past 5
137 DCHECK(width_index <= 5);
138 menu_widths[width_index] = group_width;
139 group_width = 0;
140 if (width_index < 5)
141 position += static_cast<int>(menu_widths[width_index+1]);
142 width_index += 2;
143 } else {
144 // Get the menu item text
145 TCHAR item_text[256] = {0};
146 int text_length = GetMenuString(source_menu, index, item_text,
147 ARRAYSIZE(item_text), MF_BYPOSITION);
148 // Popups are handled differently than normal menu items
149 if (popup_menu) {
150 if (::GetMenuItemCount(popup_menu) != 0) {
151 // Strip the HIBYTE because it contains a count of items
152 state = LOBYTE(state) | MF_POPUP; // Must be popup
153 // Non-empty popup -- add it to the shared menu bar
154 InsertMenu(shared_menu, position, state|MF_BYPOSITION,
155 reinterpret_cast<UINT_PTR>(popup_menu), item_text);
156 ++position;
157 ++group_width;
158 }
159 } else if (text_length > 0) {
160 // only non-empty items are added
161 DCHECK(item_text[0] != 0);
162 // here the state does not contain a count in the HIBYTE
163 InsertMenu(shared_menu, position, state|MF_BYPOSITION,
164 GetMenuItemID(source_menu, index), item_text);
165 ++position;
166 ++group_width;
167 }
168 }
169 }
170 }
171
172 void UnmergeMenus(HMENU shared_menu, HMENU source_menu) {
173 int our_item_count = GetMenuItemCount(source_menu);
174 int shared_item_count = GetMenuItemCount(shared_menu);
175
176 for (int index = shared_item_count - 1; index >= 0; index--) {
177 // Check the popup menus
178 HMENU popup_menu = ::GetSubMenu(shared_menu, index);
179 if (popup_menu) {
180 // If it is one of ours, remove it from the shared menu
181 for (int sub_index = 0; sub_index < our_item_count; sub_index++) {
182 if (::GetSubMenu(source_menu, sub_index) == popup_menu) {
183 // Remove the menu from hMenuShared
184 RemoveMenu(shared_menu, index, MF_BYPOSITION);
185 break;
186 }
187 }
188 }
189 }
190 }
191
192 protected:
193 HRESULT GetInPlaceFrame(IOleInPlaceFrame** in_place_frame) {
194 if (!in_place_frame) {
195 NOTREACHED();
196 return E_POINTER;
197 }
198 T* t = static_cast<T*>(this);
199 HRESULT hr = E_FAIL;
200 if (!t->in_place_frame_) {
201 // We weren't given an IOleInPlaceFrame pointer, so
202 // we'll have to get it ourselves.
203 if (t->m_spInPlaceSite) {
204 t->frame_info_.cb = sizeof(OLEINPLACEFRAMEINFO);
205 ScopedComPtr<IOleInPlaceUIWindow> in_place_ui_window;
206 RECT position_rect = {0};
207 RECT clip_rect = {0};
208 hr = t->m_spInPlaceSite->GetWindowContext(in_place_frame,
209 in_place_ui_window.Receive(),
210 &position_rect, &clip_rect,
211 &t->frame_info_);
212 }
213 } else {
214 *in_place_frame = t->in_place_frame_;
215 (*in_place_frame)->AddRef();
216 hr = S_OK;
217 }
218 return hr;
219 }
220
221 protected:
222 // The OLE menu descriptor created by the OleCreateMenuDescriptor
223 HMENU ole_menu_;
224 // The shared menu that we pass to IOleInPlaceFrame::SetMenu
225 HMENU shared_menu_;
226 // Our menu resource that we want to insert
227 HMENU our_menu_;
228 };
229
230 #endif // CHROME_FRAME_IN_PLACE_MENU_H_
231
OLDNEW
« no previous file with comments | « chrome_frame/iids.cc ('k') | chrome_frame/installer_util/test.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698