// PerforceClientServiceDlg.cpp : implementation file // #include "stdafx.h" #include "PerforceClientService.h" #include "PerforceClientServiceDlg.h" #include "DirectoryWatcher.h" #include "DirectoryList.h" #include "Excludes.h" #include "MyClientUser.h" #include <stdarg.h> #include <vector> #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif namespace CPerforceClientServiceDlgNamespace { typedef std::vector<DirectoryWatcher *> DirectoryWatchers; CEdit * ms_log; CRITICAL_SECTION ms_criticalSection; DirectoryWatchers ms_directoryWatchers; NOTIFYICONDATA ms_nidIconData; } using namespace CPerforceClientServiceDlgNamespace; ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPerforceClientServiceDlg dialog CPerforceClientServiceDlg::CPerforceClientServiceDlg(CWnd* pParent /*=NULL*/) : CDialog(CPerforceClientServiceDlg::IDD, pParent) { //{{AFX_DATA_INIT(CPerforceClientServiceDlg) //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CPerforceClientServiceDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CPerforceClientServiceDlg) DDX_Control(pDX, IDC_LOG, m_log); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CPerforceClientServiceDlg, CDialog) //{{AFX_MSG_MAP(CPerforceClientServiceDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_DESTROY() ON_BN_CLICKED(IDC_BUTTON2, OnDirectories) ON_BN_CLICKED(IDC_EXCLUDES, OnExcludes) ON_MESSAGE(WM_TRAY_ICON_NOTIFY_MESSAGE,OnTrayNotify) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPerforceClientServiceDlg message handlers BOOL CPerforceClientServiceDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here InitializeCriticalSection(&ms_criticalSection); ms_log = &m_log; // set up the systray icon memset(&ms_nidIconData, 0, sizeof(ms_nidIconData)); ms_nidIconData.cbSize = sizeof(NOTIFYICONDATA); ms_nidIconData.hWnd = this->m_hWnd; ms_nidIconData.uID = 1; ms_nidIconData.uCallbackMessage = WM_TRAY_ICON_NOTIFY_MESSAGE; ms_nidIconData.hIcon = m_hIcon; ms_nidIconData.szTip[0] = 0; ms_nidIconData.uFlags = NIF_MESSAGE | NIF_ICON; Shell_NotifyIcon(NIM_ADD, &ms_nidIconData); DirectoryList::install(); MyClientUser myClientUser; return TRUE; // return TRUE unless you set the focus to a control } void CPerforceClientServiceDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else if (nID == SC_MINIMIZE) { ShowWindow(SW_HIDE); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CPerforceClientServiceDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CPerforceClientServiceDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CPerforceClientServiceDlg::OnDestroy() { while (!ms_directoryWatchers.empty()) { delete ms_directoryWatchers.back(); ms_directoryWatchers.pop_back(); } EnterCriticalSection(&ms_criticalSection); ms_log = NULL; LeaveCriticalSection(&ms_criticalSection); DeleteCriticalSection(&ms_criticalSection); if (ms_nidIconData.hWnd && ms_nidIconData.uID > 0) Shell_NotifyIcon(NIM_DELETE, &ms_nidIconData); CDialog::OnDestroy(); } LRESULT CPerforceClientServiceDlg::OnTrayNotify(WPARAM wParam, LPARAM lParam) { if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN || lParam == WM_CONTEXTMENU) ShowWindow(SW_SHOW); return 0; } void CPerforceClientServiceDlg::Log(char const * format, ...) { EnterCriticalSection(&ms_criticalSection); va_list va; va_start(va, format); char buffer[2048]; _vsnprintf_s(buffer, sizeof(buffer)-1, _TRUNCATE, format, va); buffer[sizeof(buffer)-1] = '\0'; va_end(va); CString append(buffer); append.Replace("\n", "\r\n"); if (ms_log) ms_log->ReplaceSel(append); LeaveCriticalSection(&ms_criticalSection); } void CPerforceClientServiceDlg::OnOK() { } void CPerforceClientServiceDlg::OnDirectories() { DirectoryList directoryList; directoryList.DoModal(); } void CPerforceClientServiceDlg::OnExcludes() { Excludes excludes; excludes.DoModal(); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#3 | 7201 | Jeff Grills | Upgrade to VS2005 and the 2008.2 p4api | ||
#2 | 4963 | Jeff Grills |
Major clean up and code reorganization. Add new dialog to control the directories that are watched. Persist the watched directories in the windows registry. Restore the watched directories when the application is run again. Handle login correctly. Change the way error messages are examined to make them significantly more robust. Issue an "info" command at startup to make sure we can communicate with the server and get logged in. Change the icon to the standard P4 icon. Allow the dialog to be minimized to the systray. Clicking on the systray icon will show the dialog again. |
||
#1 | 4896 | Jeff Grills |
First drop of the PerforceClientService. This version is only barely functional, supporting adds, edits, and deletes. It does not handle multiple operations on the same file gracefully. |