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

Unified Diff: ui/views/win/hwnd_message_handler.cc

Issue 10870104: Fix max/min window menu items by calling the correct version of EnableMenuItem. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/win/hwnd_message_handler.cc
===================================================================
--- ui/views/win/hwnd_message_handler.cc (revision 153487)
+++ ui/views/win/hwnd_message_handler.cc (working copy)
@@ -78,6 +78,12 @@
return TRUE;
}
+// Enables or disables the menu item for the specified command and menu.
+void EnableMenuItemByCommand(HMENU menu, UINT command, bool enabled) {
+ UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED);
+ EnableMenuItem(menu, command, flags);
+}
+
// A custom MSAA object id used to determine if a screen reader is actively
// listening for MSAA events.
const int kCustomObjectID = 1;
@@ -87,6 +93,70 @@
} // namespace
+// A scoping class that prevents a window from being able to redraw in response
+// to invalidations that may occur within it for the lifetime of the object.
+//
+// Why would we want such a thing? Well, it turns out Windows has some
+// "unorthodox" behavior when it comes to painting its non-client areas.
+// Occasionally, Windows will paint portions of the default non-client area
+// right over the top of the custom frame. This is not simply fixed by handling
+// WM_NCPAINT/WM_PAINT, with some investigation it turns out that this
+// rendering is being done *inside* the default implementation of some message
+// handlers and functions:
+// . WM_SETTEXT
+// . WM_SETICON
+// . WM_NCLBUTTONDOWN
+// . EnableMenuItem, called from our WM_INITMENU handler
+// The solution is to handle these messages and call DefWindowProc ourselves,
+// but prevent the window from being able to update itself for the duration of
+// the call. We do this with this class, which automatically calls its
+// associated Window's lock and unlock functions as it is created and destroyed.
+// See documentation in those methods for the technique used.
+//
+// The lock only has an effect if the window was visible upon lock creation, as
+// it doesn't guard against direct visiblility changes, and multiple locks may
+// exist simultaneously to handle certain nested Windows messages.
+//
+// IMPORTANT: Do not use this scoping object for large scopes or periods of
+// time! IT WILL PREVENT THE WINDOW FROM BEING REDRAWN! (duh).
+//
+// I would love to hear Raymond Chen's explanation for all this. And maybe a
+// list of other messages that this applies to ;-)
+class HWNDMessageHandler::ScopedRedrawLock {
+ public:
+ explicit ScopedRedrawLock(HWNDMessageHandler* owner)
+ : owner_(owner),
+ hwnd_(owner_->hwnd()),
+ was_visible_(owner_->IsVisible()),
+ cancel_unlock_(false),
+ force_(!(GetWindowLong(hwnd_, GWL_STYLE) & WS_CAPTION)) {
+ if (was_visible_ && ::IsWindow(hwnd_))
+ owner_->LockUpdates(force_);
+ }
+
+ ~ScopedRedrawLock() {
+ if (!cancel_unlock_ && was_visible_ && ::IsWindow(hwnd_))
+ owner_->UnlockUpdates(force_);
+ }
+
+ // Cancel the unlock operation, call this if the Widget is being destroyed.
+ void CancelUnlockOperation() { cancel_unlock_ = true; }
+
+ private:
+ // The owner having its style changed.
+ HWNDMessageHandler* owner_;
+ // The owner's HWND, cached to avoid action after window destruction.
+ HWND hwnd_;
+ // Records the HWND visibility at the time of creation.
+ bool was_visible_;
+ // A flag indicating that the unlock operation was canceled.
+ bool cancel_unlock_;
+ // If true, perform the redraw lock regardless of Aero state.
+ bool force_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedRedrawLock);
+};
+
////////////////////////////////////////////////////////////////////////////////
// HWNDMessageHandler, public:
@@ -563,12 +633,14 @@
bool is_maximized = IsMaximized();
bool is_restored = !is_fullscreen && !is_minimized && !is_maximized;
- EnableMenuItem(menu, SC_RESTORE, is_minimized || is_maximized);
- EnableMenuItem(menu, SC_MOVE, is_restored);
- EnableMenuItem(menu, SC_SIZE, delegate_->CanResize() && is_restored);
- EnableMenuItem(menu, SC_MAXIMIZE, delegate_->CanMaximize() &&
- !is_fullscreen && !is_maximized);
- EnableMenuItem(menu, SC_MINIMIZE, delegate_->CanMaximize() && !is_minimized);
+ ScopedRedrawLock lock(this);
+ EnableMenuItemByCommand(menu, SC_RESTORE, is_minimized || is_maximized);
+ EnableMenuItemByCommand(menu, SC_MOVE, is_restored);
+ EnableMenuItemByCommand(menu, SC_SIZE, delegate_->CanResize() && is_restored);
+ EnableMenuItemByCommand(menu, SC_MAXIMIZE, delegate_->CanMaximize() &&
+ !is_fullscreen && !is_maximized);
+ EnableMenuItemByCommand(menu, SC_MINIMIZE, delegate_->CanMaximize() &&
+ !is_minimized);
}
void HWNDMessageHandler::OnInitMenuPopup() {
@@ -1288,70 +1360,6 @@
return gfx::Insets(0, 0, fullscreen_handler_->fullscreen() ? 0 : 1, 0);
}
-// A scoping class that prevents a window from being able to redraw in response
-// to invalidations that may occur within it for the lifetime of the object.
-//
-// Why would we want such a thing? Well, it turns out Windows has some
-// "unorthodox" behavior when it comes to painting its non-client areas.
-// Occasionally, Windows will paint portions of the default non-client area
-// right over the top of the custom frame. This is not simply fixed by handling
-// WM_NCPAINT/WM_PAINT, with some investigation it turns out that this
-// rendering is being done *inside* the default implementation of some message
-// handlers and functions:
-// . WM_SETTEXT
-// . WM_SETICON
-// . WM_NCLBUTTONDOWN
-// . EnableMenuItem, called from our WM_INITMENU handler
-// The solution is to handle these messages and call DefWindowProc ourselves,
-// but prevent the window from being able to update itself for the duration of
-// the call. We do this with this class, which automatically calls its
-// associated Window's lock and unlock functions as it is created and destroyed.
-// See documentation in those methods for the technique used.
-//
-// The lock only has an effect if the window was visible upon lock creation, as
-// it doesn't guard against direct visiblility changes, and multiple locks may
-// exist simultaneously to handle certain nested Windows messages.
-//
-// IMPORTANT: Do not use this scoping object for large scopes or periods of
-// time! IT WILL PREVENT THE WINDOW FROM BEING REDRAWN! (duh).
-//
-// I would love to hear Raymond Chen's explanation for all this. And maybe a
-// list of other messages that this applies to ;-)
-class HWNDMessageHandler::ScopedRedrawLock {
- public:
- explicit ScopedRedrawLock(HWNDMessageHandler* owner)
- : owner_(owner),
- hwnd_(owner_->hwnd()),
- was_visible_(owner_->IsVisible()),
- cancel_unlock_(false),
- force_(!(GetWindowLong(hwnd_, GWL_STYLE) & WS_CAPTION)) {
- if (was_visible_ && ::IsWindow(hwnd_))
- owner_->LockUpdates(force_);
- }
-
- ~ScopedRedrawLock() {
- if (!cancel_unlock_ && was_visible_ && ::IsWindow(hwnd_))
- owner_->UnlockUpdates(force_);
- }
-
- // Cancel the unlock operation, call this if the Widget is being destroyed.
- void CancelUnlockOperation() { cancel_unlock_ = true; }
-
- private:
- // The owner having its style changed.
- HWNDMessageHandler* owner_;
- // The owner's HWND, cached to avoid action after window destruction.
- HWND hwnd_;
- // Records the HWND visibility at the time of creation.
- bool was_visible_;
- // A flag indicating that the unlock operation was canceled.
- bool cancel_unlock_;
- // If true, perform the redraw lock regardless of Aero state.
- bool force_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedRedrawLock);
-};
-
LRESULT HWNDMessageHandler::DefWindowProcWithRedrawLock(UINT message,
WPARAM w_param,
LPARAM l_param) {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698