// This file is part of BOINC. // http://boinc.berkeley.edu // Copyright (C) 2008 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // BOINC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see . // #include "boinc_win.h" #include "diagnostics.h" #include "win_util.h" #include "boinc_tray.h" #include "tray_win.h" #include "idlemon.h" HMODULE g_hModule = NULL; static CBOINCTray* gspBOINCTray = NULL; INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { CBOINCTray BOINCTray; return BOINCTray.Run( hInstance, hPrevInstance, lpCmdLine, nCmdShow ); } CBOINCTray::CBOINCTray() { gspBOINCTray = this; m_hDataManagementThread = NULL; m_bIdleTrackerInitialized = FALSE; } // Starts main execution of BOINC Tray. // INT CBOINCTray::Run( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR /* lpCmdLine */ , int /* nCmdShow */ ) { // Initialize the BOINC Diagnostics Framework int flags = #ifdef _DEBUG BOINC_DIAG_MEMORYLEAKCHECKENABLED | #endif BOINC_DIAG_DUMPCALLSTACKENABLED | BOINC_DIAG_HEAPCHECKENABLED | BOINC_DIAG_TRACETOSTDOUT | BOINC_DIAG_REDIRECTSTDERR | BOINC_DIAG_REDIRECTSTDOUT; chdir_to_data_dir(); diagnostics_init(flags, "stdouttray", "stderrtray"); // Create application window class if (!hPrevInstance) { // Register an appropriate window class for the primary window WNDCLASS cls; cls.hCursor = NULL; cls.hIcon = NULL; cls.lpszMenuName = NULL; cls.lpszClassName = _T("BOINCTrayWndClass"); cls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); cls.hInstance = hInstance; cls.style = CS_OWNDC|CS_VREDRAW|CS_HREDRAW; cls.lpfnWndProc = TrayProcStub; cls.cbWndExtra = 0; cls.cbClsExtra = 0; RegisterClass(&cls); } // Create the window MSG msg; HWND hWnd; hWnd = CreateWindow( _T("BOINCTrayWndClass"), _T("BOINC System Tray Applet"), WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); // Process the message pump while( GetMessage( &msg, NULL, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } // Cleanup and shutdown the BOINC idle tracking system. detach_idle_monitor(); return msg.wParam; } // Create the thread that is used to talk to the daemon. // BOOL CBOINCTray::CreateDataManagementThread() { DWORD dwThreadID = 0; m_hDataManagementThread = CreateThread( NULL, // default security attributes 0, // use default stack size DataManagementProcStub, // thread function NULL, // argument to thread function 0, // use default creation flags &dwThreadID ); // returns the thread identifier if (m_hDataManagementThread == NULL) { return FALSE; } return TRUE; } // Terminate the thread that is used to talk to the daemon. // BOOL CBOINCTray::DestroyDataManagementThread() { if (!TerminateThread(m_hDataManagementThread, 0)) { return FALSE; } return TRUE; } // Update the time since last input activity every 5 seconds or so. // DWORD WINAPI CBOINCTray::DataManagementProc() { while (true) { // On Vista systems, only elevated processes can create shared memory // area's across various user sessions. In this case we need to wait // for BOINC to create the shared memory area and then boinctray can // successfully attach to it. What a PITA. if (!m_bIdleTrackerInitialized) { m_bIdleTrackerInitialized = attach_idle_monitor(); } get_idle_tick_count(); Sleep(5000); } } // This function forwards to DataManagementProc, which has access to the // "this" pointer. // DWORD WINAPI CBOINCTray::DataManagementProcStub(LPVOID) { return gspBOINCTray->DataManagementProc(); } // Handle window messages for main screensaver windows. // LRESULT CBOINCTray::TrayProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch (uMsg) { case WM_CREATE: CreateDataManagementThread(); return 0; break; case WM_CLOSE: DestroyDataManagementThread(); return 0; break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } // This function forwards all window messages to SaverProc, which has // access to the "this" pointer. // LRESULT CALLBACK CBOINCTray::TrayProcStub( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { return gspBOINCTray->TrayProc(hWnd, uMsg, wParam, lParam); }