00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "CMSWindowsClientTaskBarReceiver.h"
00016 #include "CClient.h"
00017 #include "CMSWindowsClipboard.h"
00018 #include "LogOutputters.h"
00019 #include "BasicTypes.h"
00020 #include "CArch.h"
00021 #include "CArchTaskBarWindows.h"
00022 #include "resource.h"
00023
00024
00025
00026
00027
00028 const UINT CMSWindowsClientTaskBarReceiver::s_stateToIconID[kMaxState] =
00029 {
00030 IDI_TASKBAR_NOT_RUNNING,
00031 IDI_TASKBAR_NOT_WORKING,
00032 IDI_TASKBAR_NOT_CONNECTED,
00033 IDI_TASKBAR_NOT_CONNECTED,
00034 IDI_TASKBAR_CONNECTED
00035 };
00036
00037 CMSWindowsClientTaskBarReceiver::CMSWindowsClientTaskBarReceiver(
00038 HINSTANCE appInstance, const CBufferedLogOutputter* logBuffer) :
00039 CClientTaskBarReceiver(),
00040 m_appInstance(appInstance),
00041 m_window(NULL),
00042 m_logBuffer(logBuffer)
00043 {
00044 for (UInt32 i = 0; i < kMaxState; ++i) {
00045 m_icon[i] = loadIcon(s_stateToIconID[i]);
00046 }
00047 m_menu = LoadMenu(m_appInstance, MAKEINTRESOURCE(IDR_TASKBAR));
00048
00049
00050
00051
00052
00053
00054
00055 ARCH->addReceiver(this);
00056 }
00057
00058 CMSWindowsClientTaskBarReceiver::~CMSWindowsClientTaskBarReceiver()
00059 {
00060 ARCH->removeReceiver(this);
00061 for (UInt32 i = 0; i < kMaxState; ++i) {
00062 deleteIcon(m_icon[i]);
00063 }
00064 DestroyMenu(m_menu);
00065 destroyWindow();
00066 }
00067
00068 void
00069 CMSWindowsClientTaskBarReceiver::showStatus()
00070 {
00071
00072 createWindow();
00073
00074
00075 lock();
00076
00077
00078 std::string status = getToolTip();
00079
00080
00081 unlock();
00082
00083
00084 HWND child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_STATUS);
00085 SendMessage(child, WM_SETTEXT, 0, (LPARAM)status.c_str());
00086
00087 if (!IsWindowVisible(m_window)) {
00088
00089 POINT cursorPos;
00090 GetCursorPos(&cursorPos);
00091 RECT windowRect;
00092 GetWindowRect(m_window, &windowRect);
00093 int x = cursorPos.x;
00094 int y = cursorPos.y;
00095 int fw = GetSystemMetrics(SM_CXDLGFRAME);
00096 int fh = GetSystemMetrics(SM_CYDLGFRAME);
00097 int ww = windowRect.right - windowRect.left;
00098 int wh = windowRect.bottom - windowRect.top;
00099 int sw = GetSystemMetrics(SM_CXFULLSCREEN);
00100 int sh = GetSystemMetrics(SM_CYFULLSCREEN);
00101 if (fw < 1) {
00102 fw = 1;
00103 }
00104 if (fh < 1) {
00105 fh = 1;
00106 }
00107 if (x + ww - fw > sw) {
00108 x -= ww - fw;
00109 }
00110 else {
00111 x -= fw;
00112 }
00113 if (x < 0) {
00114 x = 0;
00115 }
00116 if (y + wh - fh > sh) {
00117 y -= wh - fh;
00118 }
00119 else {
00120 y -= fh;
00121 }
00122 if (y < 0) {
00123 y = 0;
00124 }
00125 SetWindowPos(m_window, HWND_TOPMOST, x, y, ww, wh,
00126 SWP_SHOWWINDOW);
00127 }
00128 }
00129
00130 void
00131 CMSWindowsClientTaskBarReceiver::runMenu(int x, int y)
00132 {
00133
00134
00135
00136
00137
00138 createWindow();
00139 SetForegroundWindow(m_window);
00140 HMENU menu = GetSubMenu(m_menu, 0);
00141 SetMenuDefaultItem(menu, IDC_TASKBAR_STATUS, FALSE);
00142 HMENU logLevelMenu = GetSubMenu(menu, 3);
00143 CheckMenuRadioItem(logLevelMenu, 0, 6,
00144 CLOG->getFilter() - CLog::kERROR, MF_BYPOSITION);
00145 int n = TrackPopupMenu(menu,
00146 TPM_NONOTIFY |
00147 TPM_RETURNCMD |
00148 TPM_LEFTBUTTON |
00149 TPM_RIGHTBUTTON,
00150 x, y, 0, m_window, NULL);
00151 SendMessage(m_window, WM_NULL, 0, 0);
00152
00153
00154 switch (n) {
00155 case IDC_TASKBAR_STATUS:
00156 showStatus();
00157 break;
00158
00159 case IDC_TASKBAR_LOG:
00160 copyLog();
00161 break;
00162
00163 case IDC_TASKBAR_SHOW_LOG:
00164 ARCH->showConsole(true);
00165 break;
00166
00167 case IDC_TASKBAR_LOG_LEVEL_ERROR:
00168 CLOG->setFilter(CLog::kERROR);
00169 break;
00170
00171 case IDC_TASKBAR_LOG_LEVEL_WARNING:
00172 CLOG->setFilter(CLog::kWARNING);
00173 break;
00174
00175 case IDC_TASKBAR_LOG_LEVEL_NOTE:
00176 CLOG->setFilter(CLog::kNOTE);
00177 break;
00178
00179 case IDC_TASKBAR_LOG_LEVEL_INFO:
00180 CLOG->setFilter(CLog::kINFO);
00181 break;
00182
00183 case IDC_TASKBAR_LOG_LEVEL_DEBUG:
00184 CLOG->setFilter(CLog::kDEBUG);
00185 break;
00186
00187 case IDC_TASKBAR_LOG_LEVEL_DEBUG1:
00188 CLOG->setFilter(CLog::kDEBUG1);
00189 break;
00190
00191 case IDC_TASKBAR_LOG_LEVEL_DEBUG2:
00192 CLOG->setFilter(CLog::kDEBUG2);
00193 break;
00194
00195 case IDC_TASKBAR_QUIT:
00196 quit();
00197 break;
00198 }
00199 }
00200
00201 void
00202 CMSWindowsClientTaskBarReceiver::primaryAction()
00203 {
00204 showStatus();
00205 }
00206
00207 const IArchTaskBarReceiver::Icon
00208 CMSWindowsClientTaskBarReceiver::getIcon() const
00209 {
00210 return reinterpret_cast<Icon>(m_icon[getStatus()]);
00211 }
00212
00213 void
00214 CMSWindowsClientTaskBarReceiver::copyLog() const
00215 {
00216 if (m_logBuffer != NULL) {
00217
00218 CString data;
00219 for (CBufferedLogOutputter::const_iterator index = m_logBuffer->begin();
00220 index != m_logBuffer->end(); ++index) {
00221 data += *index;
00222 data += "\n";
00223 }
00224
00225
00226 if (!data.empty()) {
00227 CMSWindowsClipboard clipboard(m_window);
00228 clipboard.open(0);
00229 clipboard.emptyUnowned();
00230 clipboard.add(IClipboard::kText, data);
00231 clipboard.close();
00232 }
00233 }
00234 }
00235
00236 void
00237 CMSWindowsClientTaskBarReceiver::onStatusChanged()
00238 {
00239 if (IsWindowVisible(m_window)) {
00240 showStatus();
00241 }
00242 }
00243
00244 HICON
00245 CMSWindowsClientTaskBarReceiver::loadIcon(UINT id)
00246 {
00247 HANDLE icon = LoadImage(m_appInstance,
00248 MAKEINTRESOURCE(id),
00249 IMAGE_ICON,
00250 0, 0,
00251 LR_DEFAULTCOLOR);
00252 return reinterpret_cast<HICON>(icon);
00253 }
00254
00255 void
00256 CMSWindowsClientTaskBarReceiver::deleteIcon(HICON icon)
00257 {
00258 if (icon != NULL) {
00259 DestroyIcon(icon);
00260 }
00261 }
00262
00263 void
00264 CMSWindowsClientTaskBarReceiver::createWindow()
00265 {
00266
00267 if (m_window != NULL) {
00268 return;
00269 }
00270
00271
00272 m_window = CreateDialogParam(m_appInstance,
00273 MAKEINTRESOURCE(IDD_TASKBAR_STATUS),
00274 NULL,
00275 (DLGPROC)&CMSWindowsClientTaskBarReceiver::staticDlgProc,
00276 reinterpret_cast<LPARAM>(
00277 reinterpret_cast<void*>(this)));
00278
00279
00280
00281 LONG_PTR style = GetWindowLongPtr(m_window, GWL_EXSTYLE);
00282 style |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
00283 SetWindowLongPtr(m_window, GWL_EXSTYLE, style);
00284
00285
00286 CArchTaskBarWindows::addDialog(m_window);
00287 }
00288
00289 void
00290 CMSWindowsClientTaskBarReceiver::destroyWindow()
00291 {
00292 if (m_window != NULL) {
00293 CArchTaskBarWindows::removeDialog(m_window);
00294 DestroyWindow(m_window);
00295 m_window = NULL;
00296 }
00297 }
00298
00299 BOOL
00300 CMSWindowsClientTaskBarReceiver::dlgProc(HWND hwnd,
00301 UINT msg, WPARAM wParam, LPARAM)
00302 {
00303 switch (msg) {
00304 case WM_INITDIALOG:
00305
00306 return TRUE;
00307
00308 case WM_ACTIVATE:
00309
00310 if (LOWORD(wParam) == WA_INACTIVE) {
00311 ShowWindow(hwnd, SW_HIDE);
00312 }
00313 break;
00314 }
00315 return FALSE;
00316 }
00317
00318 BOOL CALLBACK
00319 CMSWindowsClientTaskBarReceiver::staticDlgProc(HWND hwnd,
00320 UINT msg, WPARAM wParam, LPARAM lParam)
00321 {
00322
00323
00324 CMSWindowsClientTaskBarReceiver* self = NULL;
00325 if (msg == WM_INITDIALOG) {
00326 self = reinterpret_cast<CMSWindowsClientTaskBarReceiver*>(
00327 reinterpret_cast<void*>(lParam));
00328 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) lParam);
00329 }
00330 else {
00331
00332 LONG_PTR data = GetWindowLongPtr(hwnd, GWLP_USERDATA);
00333 if (data != 0) {
00334 self = (CMSWindowsClientTaskBarReceiver*) data;
00335 }
00336 }
00337
00338
00339 if (self != NULL) {
00340 return self->dlgProc(hwnd, msg, wParam, lParam);
00341 }
00342 else {
00343 return (msg == WM_INITDIALOG) ? TRUE : FALSE;
00344 }
00345 }