| 1 | /************************************************************************** |
|---|
| 2 | * Copyright (C) 2004-2007 by Michael Medin <michael@medin.name> * |
|---|
| 3 | * * |
|---|
| 4 | * This code is part of NSClient++ - http://trac.nakednuns.org/nscp * |
|---|
| 5 | * * |
|---|
| 6 | * This program is free software; you can redistribute it and/or modify * |
|---|
| 7 | * it under the terms of the GNU General Public License as published by * |
|---|
| 8 | * the Free Software Foundation; either version 2 of the License, or * |
|---|
| 9 | * (at your option) any later version. * |
|---|
| 10 | * * |
|---|
| 11 | * This program is distributed in the hope that it will be useful, * |
|---|
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
|---|
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
|---|
| 14 | * GNU General Public License for more details. * |
|---|
| 15 | * * |
|---|
| 16 | * You should have received a copy of the GNU General Public License * |
|---|
| 17 | * along with this program; if not, write to the * |
|---|
| 18 | * Free Software Foundation, Inc., * |
|---|
| 19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
|---|
| 20 | ***************************************************************************/ |
|---|
| 21 | #include "stdafx.h" |
|---|
| 22 | #include "trayicon.h" |
|---|
| 23 | #include "resource.h" |
|---|
| 24 | #include <commctrl.h> |
|---|
| 25 | #include <strEx.h> |
|---|
| 26 | #include <ShellAPI.h> |
|---|
| 27 | #include "SysTray.h" |
|---|
| 28 | #include <error.hpp> |
|---|
| 29 | |
|---|
| 30 | |
|---|
| 31 | extern SysTray gSysTray; |
|---|
| 32 | |
|---|
| 33 | //BOOL ChangeWindowMessageFilter(UINT message,DWORD dwFlag); |
|---|
| 34 | |
|---|
| 35 | unsigned IconWidget_::threadProc(LPVOID lpParameter) |
|---|
| 36 | { |
|---|
| 37 | createDialog(); |
|---|
| 38 | return 0; |
|---|
| 39 | } |
|---|
| 40 | |
|---|
| 41 | #ifdef WINVER < 0x0600 |
|---|
| 42 | #define MSGFLT_ADD 1 |
|---|
| 43 | #define MSGFLT_REMOVE 2 |
|---|
| 44 | typedef BOOL (WINAPI *LPFN_CHANGEWINDOWMESSAGEFILTER) (UINT, DWORD); |
|---|
| 45 | #endif |
|---|
| 46 | |
|---|
| 47 | LPFN_CHANGEWINDOWMESSAGEFILTER fnChangeWindowMessageFilter = NULL; |
|---|
| 48 | BOOL ChangeWindowMessageFilter_(UINT message, DWORD what) |
|---|
| 49 | { |
|---|
| 50 | if (fnChangeWindowMessageFilter == NULL) |
|---|
| 51 | fnChangeWindowMessageFilter = (LPFN_CHANGEWINDOWMESSAGEFILTER)GetProcAddress(GetModuleHandle(TEXT("user32")),"ChangeWindowMessageFilter"); |
|---|
| 52 | if (fnChangeWindowMessageFilter == NULL) { |
|---|
| 53 | NSC_DEBUG_MSG(_T("Failed to load: ChangeWindowMessageFilter aparently we are not on Vista...")); |
|---|
| 54 | return true; |
|---|
| 55 | } |
|---|
| 56 | NSC_DEBUG_MSG(_T("Chaning window message filters...")); |
|---|
| 57 | return fnChangeWindowMessageFilter(message,what); |
|---|
| 58 | } |
|---|
| 59 | |
|---|
| 60 | void test() { |
|---|
| 61 | /* error |
|---|
| 62 | WTSQueryUserToken(dwSessionId, &hToken); |
|---|
| 63 | DuplicateTokenEx(hTokenNew,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hTokenDup); |
|---|
| 64 | */ |
|---|
| 65 | /* |
|---|
| 66 | HANDLE hToken = NULL, hTokenDup = NULL; |
|---|
| 67 | HMODULE hmod = LoadLibrary("kernel32.dll"); |
|---|
| 68 | WTSGETACTIVECONSOLESESSIONID lpfnWTSGetActiveConsoleSessionId = (WTSGETACTIVECONSOLESESSIONID)GetProcAddress(hmod,"WTSGetActiveConsoleSessionId"); |
|---|
| 69 | DWORD dwSessionId = lpfnWTSGetActiveConsoleSessionId(); |
|---|
| 70 | WTSQueryUserToken(dwSessionId, &hToken); |
|---|
| 71 | //DuplicateTokenEx(hTokenNew,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hTokenDup); |
|---|
| 72 | // |
|---|
| 73 | WriteToLog("Calling lpfnCreateEnvironmentBlock"); |
|---|
| 74 | ZeroMemory( &si, sizeof( STARTUPINFO ) ); |
|---|
| 75 | si.cb = sizeof( STARTUPINFO ); |
|---|
| 76 | si.lpDesktop = "winsta0\\default"; |
|---|
| 77 | |
|---|
| 78 | |
|---|
| 79 | LPVOID pEnv = NULL; |
|---|
| 80 | DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; |
|---|
| 81 | HMODULE hModule = LoadLibrary("Userenv.dll"); |
|---|
| 82 | if(hModule ) |
|---|
| 83 | { |
|---|
| 84 | LPFN_CreateEnvironmentBlock lpfnCreateEnvironmentBlock = (LPFN_CreateEnvironmentBlock)GetProcAddress( hModule, "CreateEnvironmentBlock" ); |
|---|
| 85 | if( lpfnCreateEnvironmentBlock != NULL ) |
|---|
| 86 | { |
|---|
| 87 | if(lpfnCreateEnvironmentBlock(&pEnv, hTokenDup, FALSE)) |
|---|
| 88 | { |
|---|
| 89 | WriteToLog("CreateEnvironmentBlock Ok"); |
|---|
| 90 | dwCreationFlag |= CREATE_UNICODE_ENVIRONMENT; |
|---|
| 91 | } |
|---|
| 92 | else |
|---|
| 93 | { |
|---|
| 94 | pEnv = NULL; |
|---|
| 95 | } |
|---|
| 96 | } |
|---|
| 97 | } |
|---|
| 98 | // |
|---|
| 99 | ZeroMemory( &pi,sizeof(pi)); |
|---|
| 100 | |
|---|
| 101 | if ( !CreateProcessAsUser( |
|---|
| 102 | hTokenDup, |
|---|
| 103 | NULL, |
|---|
| 104 | ( char * )pszCmd, |
|---|
| 105 | NULL, |
|---|
| 106 | NULL, |
|---|
| 107 | FALSE, |
|---|
| 108 | dwCreationFlag, |
|---|
| 109 | pEnv, |
|---|
| 110 | NULL, |
|---|
| 111 | &si, |
|---|
| 112 | &pi |
|---|
| 113 | ) ) |
|---|
| 114 | { |
|---|
| 115 | |
|---|
| 116 | goto RESTORE; |
|---|
| 117 | } |
|---|
| 118 | */ |
|---|
| 119 | |
|---|
| 120 | } |
|---|
| 121 | |
|---|
| 122 | void IconWidget_::createDialog(void) { |
|---|
| 123 | hDlgWnd = ::CreateDialog(NSCModuleWrapper::getModule(),MAKEINTRESOURCE(IDD_NSTRAYDLG),NULL,TrayIcon::DialogProc); |
|---|
| 124 | if (hDlgWnd == NULL || !IsWindow(hDlgWnd)) { |
|---|
| 125 | NSC_LOG_ERROR_STD(_T("Failed to create windows: ") + error::lookup::last_error()); |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | UINT UDM_TASKBARCREATED = RegisterWindowMessage(_T("TaskbarCreated")); |
|---|
| 129 | if (UDM_TASKBARCREATED == 0) { |
|---|
| 130 | NSC_LOG_ERROR_STD(_T("Failed to register 'TaskbarCreated': ") + error::lookup::last_error()); |
|---|
| 131 | } |
|---|
| 132 | if (!ChangeWindowMessageFilter_(UDM_TASKBARCREATED, MSGFLT_ADD)) { |
|---|
| 133 | NSC_LOG_ERROR_STD(_T("Failed to cchange window filter: ") + error::lookup::last_error()); |
|---|
| 134 | } |
|---|
| 135 | |
|---|
| 136 | MSG Msg; |
|---|
| 137 | BOOL bRet; |
|---|
| 138 | while((bRet = ::GetMessage(&Msg, NULL, 0, 0)) != 0) |
|---|
| 139 | { |
|---|
| 140 | if (Msg.message == WM_MY_CLOSE) { |
|---|
| 141 | TrayIcon::removeIcon(Msg.hwnd); |
|---|
| 142 | ::DestroyWindow(hDlgWnd); |
|---|
| 143 | // } else if (Msg.message == WM_QUERYENDSESSION) { |
|---|
| 144 | // NSC_LOG_ERROR_STD(_T("Got WM_QUERYENDSESSION thingy...")); |
|---|
| 145 | } else if (Msg.message == UDM_TASKBARCREATED) { |
|---|
| 146 | NSC_LOG_MESSAGE_STD(_T("Recreating systray icon...")); |
|---|
| 147 | TrayIcon::addIcon(Msg.hwnd); |
|---|
| 148 | } else if (bRet == -1) { |
|---|
| 149 | // handle the error and possibly exit |
|---|
| 150 | NSC_LOG_ERROR_STD(_T("Wonder what this is... please let me know...")); |
|---|
| 151 | return; |
|---|
| 152 | } else { |
|---|
| 153 | //} else if (!::IsWindow(hDlgWnd) || !::IsDialogMessage(hDlgWnd, &Msg)) { |
|---|
| 154 | ::TranslateMessage(&Msg); |
|---|
| 155 | ::DispatchMessage(&Msg); |
|---|
| 156 | } |
|---|
| 157 | } |
|---|
| 158 | } |
|---|
| 159 | void IconWidget_::exitThread(void) { |
|---|
| 160 | ::PostMessage(hDlgWnd, WM_MY_CLOSE, NULL, NULL); |
|---|
| 161 | } |
|---|
| 162 | |
|---|
| 163 | namespace TrayIcon |
|---|
| 164 | { |
|---|
| 165 | std::wstring defaultCommand; |
|---|
| 166 | } |
|---|
| 167 | |
|---|
| 168 | std::wstring getDlgItemText(HWND hDlg, int nIDDlgItem) { |
|---|
| 169 | #define BUFF_LEN 4096 |
|---|
| 170 | std::wstring ret; |
|---|
| 171 | TCHAR *buffer = new TCHAR[BUFF_LEN+1]; |
|---|
| 172 | if (!GetDlgItemText(hDlg, nIDDlgItem, buffer, BUFF_LEN)) |
|---|
| 173 | buffer[0]=0; |
|---|
| 174 | ret = buffer; |
|---|
| 175 | delete [] buffer; |
|---|
| 176 | return ret; |
|---|
| 177 | } |
|---|
| 178 | void updateDescFromCmd(HWND hDlg, std::wstring cmd) { |
|---|
| 179 | std::wstring result = _T(""); |
|---|
| 180 | try { |
|---|
| 181 | result = NSCModuleHelper::describeCommand(cmd); |
|---|
| 182 | } catch (NSCModuleHelper::NSCMHExcpetion &e) { |
|---|
| 183 | result = _T("Error: ") + e.msg_; |
|---|
| 184 | } catch (...) { |
|---|
| 185 | result = _T("Unknown error!"); |
|---|
| 186 | } |
|---|
| 187 | SetDlgItemText(hDlg, IDC_DESCRIPTION, result.c_str()); |
|---|
| 188 | } |
|---|
| 189 | /* |
|---|
| 190 | INT_PTR CALLBACK DialogProc( HWND hwndDlg, |
|---|
| 191 | UINT uMsg, |
|---|
| 192 | WPARAM wParam, |
|---|
| 193 | LPARAM lParam |
|---|
| 194 | ); |
|---|
| 195 | */ |
|---|
| 196 | INT_PTR CALLBACK TrayIcon::InjectDialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) { |
|---|
| 197 | switch (uMsg) |
|---|
| 198 | { |
|---|
| 199 | case WM_INITDIALOG: |
|---|
| 200 | { |
|---|
| 201 | SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(NSCModuleWrapper::getModule(), MAKEINTRESOURCE(IDI_NSCP))); |
|---|
| 202 | SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(NSCModuleWrapper::getModule(), MAKEINTRESOURCE(IDI_NSCP))); |
|---|
| 203 | SetDlgItemText(hwndDlg, IDC_CMD_BOX, TrayIcon::defaultCommand.c_str()); |
|---|
| 204 | SetDlgItemText(hwndDlg, IDC_DESCRIPTION, _T("Loading commands, please wait...")); |
|---|
| 205 | |
|---|
| 206 | SendDlgItemMessage(hwndDlg, IDC_CMD_BOX, CB_RESETCONTENT, 0, 0); |
|---|
| 207 | std::wstring result = _T(""); |
|---|
| 208 | try { |
|---|
| 209 | std::list<std::wstring> lst = NSCModuleHelper::getAllCommandNames(); |
|---|
| 210 | for (std::list<std::wstring>::const_iterator cit = lst.begin(); cit != lst.end(); ++cit) { |
|---|
| 211 | SendDlgItemMessage(hwndDlg, IDC_CMD_BOX, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>( (*cit).c_str() )); |
|---|
| 212 | } |
|---|
| 213 | } catch (NSCModuleHelper::NSCMHExcpetion &e) { |
|---|
| 214 | result = _T("Error: ") + e.msg_; |
|---|
| 215 | } catch (...) { |
|---|
| 216 | result = _T("Unknown error!"); |
|---|
| 217 | } |
|---|
| 218 | SetDlgItemText(hwndDlg, IDC_DESCRIPTION, result.c_str()); |
|---|
| 219 | } |
|---|
| 220 | break; |
|---|
| 221 | case WM_COMMAND: |
|---|
| 222 | switch (LOWORD(wParam)) |
|---|
| 223 | { |
|---|
| 224 | case IDC_CMD_BOX: |
|---|
| 225 | switch(HIWORD(wParam)) |
|---|
| 226 | { |
|---|
| 227 | case CBN_SELCHANGE: |
|---|
| 228 | { |
|---|
| 229 | std::wstring cmd; |
|---|
| 230 | unsigned int id = SendDlgItemMessage(hwndDlg, IDC_CMD_BOX, CB_GETCURSEL, 0, 0); |
|---|
| 231 | unsigned int len = SendDlgItemMessage(hwndDlg, IDC_CMD_BOX, CB_GETLBTEXTLEN, id, 0); |
|---|
| 232 | TCHAR *buf = new TCHAR[len+2]; |
|---|
| 233 | LRESULT ret; |
|---|
| 234 | ret = SendDlgItemMessage(hwndDlg, IDC_CMD_BOX, CB_GETLBTEXT, id, reinterpret_cast<LPARAM>(buf)); |
|---|
| 235 | if (ret > 0 && ret <= len) { |
|---|
| 236 | cmd = buf; |
|---|
| 237 | updateDescFromCmd(hwndDlg, cmd); |
|---|
| 238 | } |
|---|
| 239 | delete [] buf; |
|---|
| 240 | } |
|---|
| 241 | break; |
|---|
| 242 | case CBN_KILLFOCUS: |
|---|
| 243 | updateDescFromCmd(hwndDlg, getDlgItemText(hwndDlg, IDC_CMD_BOX)); |
|---|
| 244 | break; |
|---|
| 245 | } |
|---|
| 246 | break; |
|---|
| 247 | case IDC_INJECT: |
|---|
| 248 | { |
|---|
| 249 | std::wstring result = _T(""); |
|---|
| 250 | std::wstring cmd = getDlgItemText(hwndDlg, IDC_CMD_BOX); |
|---|
| 251 | std::wstring args = getDlgItemText(hwndDlg, IDC_ARG_BOX); |
|---|
| 252 | std::wstring msg; |
|---|
| 253 | std::wstring perf; |
|---|
| 254 | try { |
|---|
| 255 | NSCAPI::nagiosReturn ret = NSCModuleHelper::InjectSplitAndCommand(cmd, args, ' ', msg, perf); |
|---|
| 256 | if (ret == NSCAPI::returnIgnored) { |
|---|
| 257 | result = _T("Command not found!"); |
|---|
| 258 | } else { |
|---|
| 259 | result = NSCHelper::translateReturn(ret); |
|---|
| 260 | } |
|---|
| 261 | } catch (NSCModuleHelper::NSCMHExcpetion &e) { |
|---|
| 262 | result = _T("Error: ") + e.msg_; |
|---|
| 263 | } catch (...) { |
|---|
| 264 | result = _T("Unknown error!"); |
|---|
| 265 | } |
|---|
| 266 | SetDlgItemText(hwndDlg, IDC_DESCRIPTION, result.c_str()); |
|---|
| 267 | SetDlgItemText(hwndDlg, IDC_MSG, msg.c_str()); |
|---|
| 268 | SetDlgItemText(hwndDlg, IDC_PERF, perf.c_str()); |
|---|
| 269 | } |
|---|
| 270 | break; |
|---|
| 271 | case IDOK: |
|---|
| 272 | { |
|---|
| 273 | TCHAR *c=new TCHAR[1024]; |
|---|
| 274 | if (GetDlgItemText(hwndDlg, IDC_COMMAND, c, 1023)) |
|---|
| 275 | TrayIcon::defaultCommand = c; |
|---|
| 276 | delete [] c; |
|---|
| 277 | } |
|---|
| 278 | |
|---|
| 279 | case IDCANCEL: |
|---|
| 280 | EndDialog(hwndDlg, wParam); |
|---|
| 281 | return TRUE; |
|---|
| 282 | } |
|---|
| 283 | } |
|---|
| 284 | return FALSE; |
|---|
| 285 | } |
|---|
| 286 | |
|---|
| 287 | |
|---|
| 288 | |
|---|
| 289 | void insert_logrecord(HWND hwndLV, const SysTray::log_entry &entry) { |
|---|
| 290 | LVITEM item; |
|---|
| 291 | item.mask = LVIF_TEXT; |
|---|
| 292 | std::wstring msg = NSCHelper::translateMessageType(entry.type); |
|---|
| 293 | item.pszText = const_cast<TCHAR*>(msg.c_str()); |
|---|
| 294 | item.iSubItem = 0; |
|---|
| 295 | item.iItem = 0; //ListView_GetItemCount(hwndLV); |
|---|
| 296 | int id = ListView_InsertItem(hwndLV, &item); |
|---|
| 297 | msg = entry.file; |
|---|
| 298 | ListView_SetItemText(hwndLV, id, 1, const_cast<TCHAR*>(msg.c_str())); |
|---|
| 299 | msg = strEx::itos(entry.line); |
|---|
| 300 | ListView_SetItemText(hwndLV, id, 2, const_cast<TCHAR*>(msg.c_str())); |
|---|
| 301 | msg = entry.message; |
|---|
| 302 | ListView_SetItemText(hwndLV, id, 3, const_cast<TCHAR*>(msg.c_str())); |
|---|
| 303 | } |
|---|
| 304 | |
|---|
| 305 | INT_PTR CALLBACK TrayIcon::LogDialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) { |
|---|
| 306 | switch (uMsg) |
|---|
| 307 | { |
|---|
| 308 | case WM_INITDIALOG: |
|---|
| 309 | { |
|---|
| 310 | SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(NSCModuleWrapper::getModule(), MAKEINTRESOURCE(IDI_NSCP))); |
|---|
| 311 | SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(NSCModuleWrapper::getModule(), MAKEINTRESOURCE(IDI_NSCP))); |
|---|
| 312 | gSysTray.setLogWindow(hwndDlg); |
|---|
| 313 | HWND hwndLV = GetDlgItem(hwndDlg, IDC_LOG); |
|---|
| 314 | LVCOLUMN col; |
|---|
| 315 | col.mask = LVCF_TEXT|LVCF_WIDTH; |
|---|
| 316 | col.cx = 10; |
|---|
| 317 | col.pszText = _T("Type"); |
|---|
| 318 | ListView_InsertColumn(hwndLV, 1, &col); |
|---|
| 319 | col.pszText = _T("File"); |
|---|
| 320 | ListView_InsertColumn(hwndLV, 2, &col); |
|---|
| 321 | col.pszText = _T("Line"); |
|---|
| 322 | ListView_InsertColumn(hwndLV, 3, &col); |
|---|
| 323 | col.pszText = _T("Message"); |
|---|
| 324 | ListView_InsertColumn(hwndLV, 4, &col); |
|---|
| 325 | |
|---|
| 326 | SysTray::log_type log = gSysTray.getLog(); |
|---|
| 327 | for (SysTray::log_type::const_iterator cit = log.begin(); cit != log.end(); ++cit) { |
|---|
| 328 | insert_logrecord(hwndLV, *cit); |
|---|
| 329 | } |
|---|
| 330 | |
|---|
| 331 | ListView_SetColumnWidth(hwndLV, 0, LVSCW_AUTOSIZE_USEHEADER); |
|---|
| 332 | ListView_SetColumnWidth(hwndLV, 1, LVSCW_AUTOSIZE_USEHEADER); |
|---|
| 333 | ListView_SetColumnWidth(hwndLV, 2, LVSCW_AUTOSIZE_USEHEADER); |
|---|
| 334 | ListView_SetColumnWidth(hwndLV, 3, LVSCW_AUTOSIZE_USEHEADER); |
|---|
| 335 | } |
|---|
| 336 | return TRUE; |
|---|
| 337 | |
|---|
| 338 | case WM_USER+1: |
|---|
| 339 | { |
|---|
| 340 | HWND hwndLV = GetDlgItem(hwndDlg, IDC_LOG); |
|---|
| 341 | const SysTray::log_entry* record = reinterpret_cast<const SysTray::log_entry*>(wParam); |
|---|
| 342 | insert_logrecord(hwndLV, *record); |
|---|
| 343 | |
|---|
| 344 | } |
|---|
| 345 | return TRUE; |
|---|
| 346 | |
|---|
| 347 | case WM_SIZE: |
|---|
| 348 | if (wParam == SIZE_RESTORED) { |
|---|
| 349 | HWND hwndLV = GetDlgItem(hwndDlg, IDC_LOG); |
|---|
| 350 | ::SetWindowPos(hwndLV, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam), SWP_NOZORDER); |
|---|
| 351 | } |
|---|
| 352 | return TRUE; |
|---|
| 353 | |
|---|
| 354 | case WM_COMMAND: |
|---|
| 355 | case IDOK: |
|---|
| 356 | case IDCANCEL: |
|---|
| 357 | gSysTray.setLogWindow(NULL); |
|---|
| 358 | EndDialog(hwndDlg, wParam); |
|---|
| 359 | return TRUE; |
|---|
| 360 | } |
|---|
| 361 | return FALSE; |
|---|
| 362 | } |
|---|
| 363 | |
|---|
| 364 | |
|---|
| 365 | INT_PTR CALLBACK TrayIcon::DialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) |
|---|
| 366 | { |
|---|
| 367 | switch (uMsg) |
|---|
| 368 | { |
|---|
| 369 | case WM_DESTROY: |
|---|
| 370 | TrayIcon::removeIcon(hwndDlg); |
|---|
| 371 | PostQuitMessage(0); |
|---|
| 372 | return 0; |
|---|
| 373 | |
|---|
| 374 | case WM_INITDIALOG: |
|---|
| 375 | addIcon(hwndDlg); |
|---|
| 376 | break; |
|---|
| 377 | |
|---|
| 378 | case WM_ICON_NOTIFY: |
|---|
| 379 | if (lParam==WM_RBUTTONDOWN) { |
|---|
| 380 | HMENU hMenu = LoadMenu(NSCModuleWrapper::getModule(),MAKEINTRESOURCE(IDR_POPUP)); |
|---|
| 381 | HMENU hSubMenu = GetSubMenu(hMenu, 0); |
|---|
| 382 | const RECT r = {0, 0, 0, 0}; |
|---|
| 383 | POINT pt; |
|---|
| 384 | GetCursorPos(&pt); |
|---|
| 385 | SetForegroundWindow(hwndDlg); |
|---|
| 386 | int cmd = TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, &r); |
|---|
| 387 | DestroyMenu(hMenu); |
|---|
| 388 | switch (cmd) { |
|---|
| 389 | case ID_POPUP_STOPSERVICE: |
|---|
| 390 | NSCModuleHelper::Exit(); |
|---|
| 391 | break; |
|---|
| 392 | case ID_POPUP_INJECTCOMMAND: |
|---|
| 393 | //if (TrayIcon::defaultCommand.empty()) |
|---|
| 394 | // TrayIcon::defaultCommand = NSCModuleHelper::getSettingsString(_T("systray"), _T("defaultCommand"), _T("")); |
|---|
| 395 | CreateDialog(NSCModuleWrapper::getModule(),MAKEINTRESOURCE(IDD_INJECTDIALOG),hwndDlg,InjectDialogProc); |
|---|
| 396 | break; |
|---|
| 397 | case ID_POPUP_SHOWLOG: |
|---|
| 398 | CreateDialog(NSCModuleWrapper::getModule(),MAKEINTRESOURCE(IDD_LOGWINDOW),hwndDlg,LogDialogProc); |
|---|
| 399 | } |
|---|
| 400 | return TRUE; |
|---|
| 401 | } |
|---|
| 402 | break; |
|---|
| 403 | } |
|---|
| 404 | return FALSE; |
|---|
| 405 | } |
|---|
| 406 | void TrayIcon::addIcon(HWND hWnd) { |
|---|
| 407 | assert(NSCModuleWrapper::getModule() != NULL); |
|---|
| 408 | assert(hWnd != NULL); |
|---|
| 409 | |
|---|
| 410 | NOTIFYICONDATA ndata; |
|---|
| 411 | ndata.cbSize=sizeof(NOTIFYICONDATA); |
|---|
| 412 | ndata.hWnd=hWnd; |
|---|
| 413 | ndata.uID=2000; |
|---|
| 414 | ndata.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP; |
|---|
| 415 | ndata.uCallbackMessage=WM_ICON_NOTIFY; |
|---|
| 416 | ndata.hIcon=::LoadIcon(NSCModuleWrapper::getModule(),MAKEINTRESOURCE(IDI_NSCP)); |
|---|
| 417 | std::wstring title = NSCModuleHelper::getApplicationName() + _T(" - ") + NSCModuleHelper::getApplicationVersionString(); |
|---|
| 418 | wcsncpy_s(ndata.szTip, 64, title.c_str(), min(64, title.size())); |
|---|
| 419 | Shell_NotifyIcon(NIM_ADD,&ndata); |
|---|
| 420 | } |
|---|
| 421 | |
|---|
| 422 | void TrayIcon::removeIcon(HWND hWnd) { |
|---|
| 423 | NOTIFYICONDATA ndata; |
|---|
| 424 | ndata.cbSize=sizeof(NOTIFYICONDATA); |
|---|
| 425 | ndata.hWnd=hWnd; |
|---|
| 426 | ndata.uID=2000; |
|---|
| 427 | Shell_NotifyIcon(NIM_DELETE,&ndata); |
|---|
| 428 | } |
|---|