From: Cheng Zhao Date: Thu, 3 Oct 2013 15:34:42 +0000 (+0800) Subject: win: Respond to events of window menu. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a2f679e4bd24935fe283f3f54d53098023e07bf1;p=platform%2Fframework%2Fweb%2Fcrosswalk-tizen.git win: Respond to events of window menu. --- diff --git a/browser/native_window_win.cc b/browser/native_window_win.cc index 57c5edf..4bacb0b 100644 --- a/browser/native_window_win.cc +++ b/browser/native_window_win.cc @@ -7,6 +7,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "browser/ui/win/menu_2.h" +#include "browser/ui/win/native_menu_win.h" #include "common/draggable_region.h" #include "common/options_switches.h" #include "content/public/browser/native_web_keyboard_event.h" @@ -17,6 +18,7 @@ #include "ui/gfx/path.h" #include "ui/views/controls/webview/webview.h" #include "ui/views/widget/widget.h" +#include "ui/views/widget/native_widget_win.h" #include "ui/views/window/client_view.h" #include "ui/views/window/native_frame_view.h" @@ -27,6 +29,35 @@ namespace { const int kResizeInsideBoundsSize = 5; const int kResizeAreaCornerSize = 16; +// Wrapper of NativeWidgetWin to handle WM_MENUCOMMAND messages, which are +// triggered by window menus. +class MenuCommandNativeWidget : public views::NativeWidgetWin { + public: + explicit MenuCommandNativeWidget(NativeWindowWin* delegate) + : views::NativeWidgetWin(delegate->window()), + delegate_(delegate) {} + virtual ~MenuCommandNativeWidget() {} + + protected: + virtual bool PreHandleMSG(UINT message, + WPARAM w_param, + LPARAM l_param, + LRESULT* result) OVERRIDE { + if (message == WM_MENUCOMMAND) { + delegate_->OnMenuCommand(w_param, reinterpret_cast(l_param)); + *result = 0; + return true; + } else { + return false; + } + } + + private: + NativeWindowWin* delegate_; + + DISALLOW_COPY_AND_ASSIGN(MenuCommandNativeWidget); +}; + class NativeWindowClientView : public views::ClientView { public: NativeWindowClientView(views::Widget* widget, @@ -174,6 +205,7 @@ NativeWindowWin::NativeWindowWin(content::WebContents* web_contents, resizable_(true) { views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); params.delegate = this; + params.native_widget = new MenuCommandNativeWidget(this); params.remove_standard_frame = !has_frame_; params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; window_->set_frame_type(views::Widget::FRAME_TYPE_FORCE_NATIVE); @@ -326,6 +358,11 @@ gfx::NativeWindow NativeWindowWin::GetNativeWindow() { return window_->GetNativeView(); } +void NativeWindowWin::OnMenuCommand(int position, HMENU menu) { + DCHECK(menu_); + menu_->wrapper()->OnMenuCommand(position, menu); +} + void NativeWindowWin::SetMenu(ui::MenuModel* menu_model) { menu_.reset(new atom::Menu2(menu_model, true)); ::SetMenu(GetNativeWindow(), menu_->GetNativeMenu()); diff --git a/browser/native_window_win.h b/browser/native_window_win.h index e5cdad1..a4406fc 100644 --- a/browser/native_window_win.h +++ b/browser/native_window_win.h @@ -66,9 +66,12 @@ class NativeWindowWin : public NativeWindow, virtual bool IsKiosk() OVERRIDE; virtual gfx::NativeWindow GetNativeWindow() OVERRIDE; + void OnMenuCommand(int position, HMENU menu); + // Set the native window menu. void SetMenu(ui::MenuModel* menu_model); + views::Widget* window() const { return window_.get(); } SkRegion* draggable_region() { return draggable_region_.get(); } protected: diff --git a/browser/ui/win/menu_2.h b/browser/ui/win/menu_2.h index 8877cda..67a80e2 100644 --- a/browser/ui/win/menu_2.h +++ b/browser/ui/win/menu_2.h @@ -77,6 +77,7 @@ class Menu2 { // Accessors. ui::MenuModel* model() const { return model_; } + NativeMenuWin* wrapper() const { return wrapper_.get(); } // Sets the minimum width of the menu. void SetMinimumWidth(int width); diff --git a/browser/ui/win/native_menu_win.cc b/browser/ui/win/native_menu_win.cc index f4c2369..5a9bf64 100644 --- a/browser/ui/win/native_menu_win.cc +++ b/browser/ui/win/native_menu_win.cc @@ -92,6 +92,20 @@ class NativeMenuWin::MenuHostWindow { DestroyWindow(hwnd_); } + // Called when the user selects a specific item. + void OnMenuCommand(int position, HMENU menu) { + NativeMenuWin* menu_win = GetNativeMenuWinFromHMENU(menu); + ui::MenuModel* model = menu_win->model_; + NativeMenuWin* root_menu = menu_win; + while (root_menu->parent_) + root_menu = root_menu->parent_; + + // Only notify the model if it didn't already send out notification. + // See comment in MenuMessageHook for details. + if (root_menu->menu_action_ == MENU_ACTION_NONE) + model->ActivatedAt(position); + } + HWND hwnd() const { return hwnd_; } private: @@ -146,20 +160,6 @@ class NativeMenuWin::MenuHostWindow { return reinterpret_cast(item_data); } - // Called when the user selects a specific item. - void OnMenuCommand(int position, HMENU menu) { - NativeMenuWin* menu_win = GetNativeMenuWinFromHMENU(menu); - ui::MenuModel* model = menu_win->model_; - NativeMenuWin* root_menu = menu_win; - while (root_menu->parent_) - root_menu = root_menu->parent_; - - // Only notify the model if it didn't already send out notification. - // See comment in MenuMessageHook for details. - if (root_menu->menu_action_ == MENU_ACTION_NONE) - model->ActivatedAt(position); - } - // Called as the user moves their mouse or arrows through the contents of the // menu. void OnMenuSelect(WPARAM w_param, HMENU menu) { @@ -529,6 +529,10 @@ void NativeMenuWin::SetMinimumWidth(int width) { NOTIMPLEMENTED(); } +void NativeMenuWin::OnMenuCommand(int position, HMENU menu) { + host_window_->OnMenuCommand(position, menu); +} + //////////////////////////////////////////////////////////////////////////////// // NativeMenuWin, private: diff --git a/browser/ui/win/native_menu_win.h b/browser/ui/win/native_menu_win.h index 078bfac..b74c654 100644 --- a/browser/ui/win/native_menu_win.h +++ b/browser/ui/win/native_menu_win.h @@ -56,6 +56,9 @@ class NativeMenuWin { void RemoveMenuListener(views::MenuListener* listener); void SetMinimumWidth(int width); + // Called by user to generate a menu command event. + void OnMenuCommand(int position, HMENU menu); + // Flag to create a window menu instead of popup menu. void set_create_as_window_menu(bool flag) { create_as_window_menu_ = flag; } bool create_as_window_menu() const { return create_as_window_menu_; }