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