summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoratwilson@chromium.org <atwilson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-20 18:58:20 +0000
committeratwilson@chromium.org <atwilson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-20 18:58:20 +0000
commit36ce377fcd89640c698c6094af6cc9d7c3113e88 (patch)
tree6411a380202be1f4c207c248161953828a2cca36
parent87b762f2d95922e2f17c42e8277c2d6c00515728 (diff)
downloadchromium_src-36ce377fcd89640c698c6094af6cc9d7c3113e88.zip
chromium_src-36ce377fcd89640c698c6094af6cc9d7c3113e88.tar.gz
chromium_src-36ce377fcd89640c698c6094af6cc9d7c3113e88.tar.bz2
Hook TaskbarCreated message to recreate status tray icons.
This allows Chrome to recreate its status tray icons on Windows in the case that explorer.exe is restarted, or isn't running yet at the time that chrome starts up. BUG=69972 TEST=Run chrome without explorer.exe running, then start explorer.exe Review URL: http://codereview.chromium.org/6289010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71974 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/ui/views/status_icons/status_icon_win.cc30
-rw-r--r--chrome/browser/ui/views/status_icons/status_icon_win.h3
-rw-r--r--chrome/browser/ui/views/status_icons/status_tray_win.cc63
-rw-r--r--chrome/browser/ui/views/status_icons/status_tray_win.h5
4 files changed, 75 insertions, 26 deletions
diff --git a/chrome/browser/ui/views/status_icons/status_icon_win.cc b/chrome/browser/ui/views/status_icons/status_icon_win.cc
index c9b4f8c..4edb20c 100644
--- a/chrome/browser/ui/views/status_icons/status_icon_win.cc
+++ b/chrome/browser/ui/views/status_icons/status_icon_win.cc
@@ -19,7 +19,10 @@ StatusIconWin::StatusIconWin(UINT id, HWND window, UINT message)
icon_data.uFlags = NIF_MESSAGE;
icon_data.uCallbackMessage = message_id_;
BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data);
- DCHECK(result);
+ // This can happen if the explorer process isn't running when we try to
+ // create the icon for some reason (for example, at startup).
+ if (!result)
+ LOG(WARNING) << "Unable to create status tray icon.";
}
StatusIconWin::~StatusIconWin() {
@@ -37,7 +40,27 @@ void StatusIconWin::SetImage(const SkBitmap& image) {
icon_.Set(IconUtil::CreateHICONFromSkBitmap(image));
icon_data.hIcon = icon_.Get();
BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
- DCHECK(result);
+ if (!result)
+ LOG(WARNING) << "Error setting status tray icon image";
+}
+
+void StatusIconWin::ResetIcon() {
+ NOTIFYICONDATA icon_data;
+ InitIconData(&icon_data);
+ // Delete any previously existing icon.
+ Shell_NotifyIcon(NIM_DELETE, &icon_data);
+ InitIconData(&icon_data);
+ icon_data.uFlags = NIF_MESSAGE;
+ icon_data.uCallbackMessage = message_id_;
+ icon_data.hIcon = icon_.Get();
+ // If we have an image, then set the NIF_ICON flag, which tells
+ // Shell_NotifyIcon() to set the image for the status icon it creates.
+ if (icon_data.hIcon)
+ icon_data.uFlags |= NIF_ICON;
+ // Re-add our icon.
+ BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data);
+ if (!result)
+ LOG(WARNING) << "Unable to re-create status tray icon.";
}
void StatusIconWin::SetPressedImage(const SkBitmap& image) {
@@ -52,7 +75,8 @@ void StatusIconWin::SetToolTip(const string16& tool_tip) {
icon_data.uFlags = NIF_TIP;
wcscpy_s(icon_data.szTip, tool_tip.c_str());
BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
- DCHECK(result);
+ if (!result)
+ LOG(WARNING) << "Unable to set tooltip for status tray icon";
}
void StatusIconWin::InitIconData(NOTIFYICONDATA* icon_data) {
diff --git a/chrome/browser/ui/views/status_icons/status_icon_win.h b/chrome/browser/ui/views/status_icons/status_icon_win.h
index e353023..a4582ba 100644
--- a/chrome/browser/ui/views/status_icons/status_icon_win.h
+++ b/chrome/browser/ui/views/status_icons/status_icon_win.h
@@ -37,6 +37,9 @@ class StatusIconWin : public StatusIcon {
// otherwise displays the context menu if there is one.
void HandleClickEvent(int x, int y, bool left_button_click);
+ // Re-creates the status tray icon now after the taskbar has been created.
+ void ResetIcon();
+
protected:
// Overridden from StatusIcon.
virtual void UpdatePlatformContextMenu(ui::MenuModel* menu);
diff --git a/chrome/browser/ui/views/status_icons/status_tray_win.cc b/chrome/browser/ui/views/status_icons/status_tray_win.cc
index 83a12e1..2fa679e 100644
--- a/chrome/browser/ui/views/status_icons/status_tray_win.cc
+++ b/chrome/browser/ui/views/status_icons/status_tray_win.cc
@@ -22,9 +22,16 @@ StatusTrayWin::StatusTrayWin()
ATOM clazz = RegisterClassEx(&wc);
DCHECK(clazz);
- // Create an offscreen window for handling messages for the status icons.
+ // If the taskbar is re-created after we start up, we have to rebuild all of
+ // our icons.
+ taskbar_created_message_ = RegisterWindowMessage(TEXT("TaskbarCreated"));
+
+ // Create an offscreen window for handling messages for the status icons. We
+ // create a hidden WS_POPUP window instead of an HWND_MESSAGE window, because
+ // only top-level windows such as popups can receive broadcast messages like
+ // "TaskbarCreated".
window_ = CreateWindow(chrome::kStatusTrayWindowClass,
- 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, 0);
+ 0, WS_POPUP, 0, 0, 0, 0, 0, 0, hinst, 0);
ui::SetWindowUserData(window_, this);
}
@@ -34,34 +41,44 @@ LRESULT CALLBACK StatusTrayWin::WndProcStatic(HWND hwnd,
LPARAM lparam) {
StatusTrayWin* msg_wnd = reinterpret_cast<StatusTrayWin*>(
GetWindowLongPtr(hwnd, GWLP_USERDATA));
- return msg_wnd->WndProc(hwnd, message, wparam, lparam);
+ if (msg_wnd)
+ return msg_wnd->WndProc(hwnd, message, wparam, lparam);
+ else
+ return ::DefWindowProc(hwnd, message, wparam, lparam);
}
LRESULT CALLBACK StatusTrayWin::WndProc(HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam) {
- switch (message) {
- case kStatusIconMessage:
- switch (lparam) {
- case WM_LBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_CONTEXTMENU:
- // Walk our icons, find which one was clicked on, and invoke its
- // HandleClickEvent() method.
- for (StatusIconList::const_iterator iter = status_icons().begin();
- iter != status_icons().end();
- ++iter) {
- StatusIconWin* win_icon = static_cast<StatusIconWin*>(*iter);
- if (win_icon->icon_id() == wparam) {
- POINT p;
- GetCursorPos(&p);
- win_icon->HandleClickEvent(p.x, p.y, lparam == WM_LBUTTONDOWN);
- }
+ if (message == taskbar_created_message_) {
+ // We need to reset all of our icons because the taskbar went away.
+ for (StatusIconList::const_iterator iter = status_icons().begin();
+ iter != status_icons().end();
+ ++iter) {
+ StatusIconWin* win_icon = static_cast<StatusIconWin*>(*iter);
+ win_icon->ResetIcon();
+ }
+ return TRUE;
+ } else if (message == kStatusIconMessage) {
+ switch (lparam) {
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_CONTEXTMENU:
+ // Walk our icons, find which one was clicked on, and invoke its
+ // HandleClickEvent() method.
+ for (StatusIconList::const_iterator iter = status_icons().begin();
+ iter != status_icons().end();
+ ++iter) {
+ StatusIconWin* win_icon = static_cast<StatusIconWin*>(*iter);
+ if (win_icon->icon_id() == wparam) {
+ POINT p;
+ GetCursorPos(&p);
+ win_icon->HandleClickEvent(p.x, p.y, lparam == WM_LBUTTONDOWN);
}
- return TRUE;
- }
- break;
+ }
+ return TRUE;
+ }
}
return ::DefWindowProc(hwnd, message, wparam, lparam);
}
diff --git a/chrome/browser/ui/views/status_icons/status_tray_win.h b/chrome/browser/ui/views/status_icons/status_tray_win.h
index c6d3c52..fe4f87b 100644
--- a/chrome/browser/ui/views/status_icons/status_tray_win.h
+++ b/chrome/browser/ui/views/status_icons/status_tray_win.h
@@ -33,9 +33,14 @@ class StatusTrayWin : public StatusTray {
// The unique icon ID we will assign to the next icon.
UINT next_icon_id_;
+
// The window used for processing events.
HWND window_;
+ // The message ID of the "TaskbarCreated" message, sent to us when we need to
+ // reset our status icons.
+ UINT taskbar_created_message_;
+
DISALLOW_COPY_AND_ASSIGN(StatusTrayWin);
};