172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/status_icons/status_tray_win.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/win/wrapped_window_proc.h" 872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/status_icons/status_icon_win.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_constants.h" 1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/win/hwnd_util.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const UINT kStatusIconMessage = WM_APP + 1; 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochStatusTrayWin::StatusTrayWin() 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : next_icon_id_(1) { 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Register our window class 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HINSTANCE hinst = GetModuleHandle(NULL); 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WNDCLASSEX wc = {0}; 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wc.cbSize = sizeof(wc); 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen wc.lpfnWndProc = base::win::WrappedWindowProc<StatusTrayWin::WndProcStatic>; 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wc.hInstance = hinst; 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wc.lpszClassName = chrome::kStatusTrayWindowClass; 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ATOM clazz = RegisterClassEx(&wc); 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(clazz); 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // If the taskbar is re-created after we start up, we have to rebuild all of 2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // our icons. 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen taskbar_created_message_ = RegisterWindowMessage(TEXT("TaskbarCreated")); 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Create an offscreen window for handling messages for the status icons. We 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // create a hidden WS_POPUP window instead of an HWND_MESSAGE window, because 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // only top-level windows such as popups can receive broadcast messages like 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // "TaskbarCreated". 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch window_ = CreateWindow(chrome::kStatusTrayWindowClass, 3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 0, WS_POPUP, 0, 0, 0, 0, 0, 0, hinst, 0); 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ui::CheckWindowCreated(window_); 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::SetWindowUserData(window_, this); 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT CALLBACK StatusTrayWin::WndProcStatic(HWND hwnd, 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UINT message, 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WPARAM wparam, 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LPARAM lparam) { 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StatusTrayWin* msg_wnd = reinterpret_cast<StatusTrayWin*>( 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetWindowLongPtr(hwnd, GWLP_USERDATA)); 4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (msg_wnd) 4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return msg_wnd->WndProc(hwnd, message, wparam, lparam); 4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen else 4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ::DefWindowProc(hwnd, message, wparam, lparam); 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT CALLBACK StatusTrayWin::WndProc(HWND hwnd, 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UINT message, 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WPARAM wparam, 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LPARAM lparam) { 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (message == taskbar_created_message_) { 5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We need to reset all of our icons because the taskbar went away. 5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (StatusIconList::const_iterator iter = status_icons().begin(); 5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen iter != status_icons().end(); 6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ++iter) { 6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen StatusIconWin* win_icon = static_cast<StatusIconWin*>(*iter); 6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen win_icon->ResetIcon(); 6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return TRUE; 6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else if (message == kStatusIconMessage) { 6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen switch (lparam) { 6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case WM_LBUTTONDOWN: 6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case WM_RBUTTONDOWN: 6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case WM_CONTEXTMENU: 7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Walk our icons, find which one was clicked on, and invoke its 7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // HandleClickEvent() method. 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (StatusIconList::const_iterator iter = status_icons().begin(); 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen iter != status_icons().end(); 7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ++iter) { 7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen StatusIconWin* win_icon = static_cast<StatusIconWin*>(*iter); 7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (win_icon->icon_id() == wparam) { 7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen POINT p; 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen GetCursorPos(&p); 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen win_icon->HandleClickEvent(p.x, p.y, lparam == WM_LBUTTONDOWN); 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return TRUE; 8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ::DefWindowProc(hwnd, message, wparam, lparam); 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochStatusTrayWin::~StatusTrayWin() { 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (window_) 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DestroyWindow(window_); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UnregisterClass(chrome::kStatusTrayWindowClass, GetModuleHandle(NULL)); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 943345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickStatusIcon* StatusTrayWin::CreatePlatformStatusIcon() { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new StatusIconWin(next_icon_id_++, window_, kStatusIconMessage); 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochStatusTray* StatusTray::Create() { 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new StatusTrayWin(); 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 101