home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
msdn_vcb
/
samples
/
vc98
/
addins
/
autobld
/
commands.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-02
|
15KB
|
478 lines
// Commands.cpp : implementation file
//
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
#include "stdafx.h"
#include "AutoBld.h"
#include "Commands.h"
#include "config.h"
#include <mapi.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCommands
CCommands::CCommands()
{
m_pApplication = NULL;
m_pApplicationEventsObj = NULL;
m_pDebuggerEventsObj = NULL;
//Because AutoBuild has an event for capturing the buildfinish event, we
// need to set some flags to make sure only want to send mail when the
// AutoBuild command is invoked, not when you walk up and say "compile"
m_bAutoBuilding = TRUE;
// if there is a build in progress lets not try to start a second build
m_bBuildInProgres = FALSE;
m_bTesting = TRUE;
//Here we retrieve all our information for the build from the registry
m_bSendMail = (BOOL)(AfxGetApp()->GetProfileInt
(_T("Configure"), _T("SendMail"), 0));
m_strSendTo = AfxGetApp()->GetProfileString
(_T("Configure"), _T("SendTo"), _T(""));
m_strStatusLine = AfxGetApp()->GetProfileString
(_T("Configure"), _T("StatusText"), _T(""));
m_bMailOnEach = (BOOL)(AfxGetApp()->GetProfileInt
(_T("Configure"), _T("MailOnEach"), 1));
m_bIncBuildResults = (BOOL)(AfxGetApp()->GetProfileInt
(_T("Configure"), _T("IncludeBuildResults"), 1));
m_bSendFile = (BOOL)(AfxGetApp()->GetProfileInt
(_T("Configure"), _T("SendFile"), 0));
m_strFileToSend = AfxGetApp()->GetProfileString
(_T("Configure"), _T("FileToSend"));
m_bCloseWhenDone = (BOOL)(AfxGetApp()->GetProfileInt
(_T("Configure"), _T("CloseWhenDone"), 0));
//If the user wishes to send mail when all building is complete, a
// running count of the number of Warnings/Errors is needed
m_nTotalErrors = 0;
m_nTotalWarnings = 0;
}
CCommands::~CCommands()
{
ASSERT (m_pApplication != NULL);
m_pApplication->Release();
}
void CCommands::SetApplicationObject(IApplication* pApplication)
{
// This function assumes pApplication has already been AddRef'd
// for us, which CDSAddIn did in its QueryInterface call
// just before it called us.
m_pApplication = pApplication;
// Create Application event handlers
XApplicationEventsObj::CreateInstance(&m_pApplicationEventsObj);
m_pApplicationEventsObj->AddRef();
m_pApplicationEventsObj->Connect(m_pApplication);
m_pApplicationEventsObj->m_pCommands = this;
// Create Debugger event handler
CComPtr<IDispatch> pDebugger;
if (SUCCEEDED(m_pApplication->get_Debugger(&pDebugger))
&& pDebugger != NULL)
{
XDebuggerEventsObj::CreateInstance(&m_pDebuggerEventsObj);
m_pDebuggerEventsObj->AddRef();
m_pDebuggerEventsObj->Connect(pDebugger);
m_pDebuggerEventsObj->m_pCommands = this;
}
}
void CCommands::UnadviseFromEvents()
{
ASSERT (m_pApplicationEventsObj != NULL);
m_pApplicationEventsObj->Disconnect(m_pApplication);
m_pApplicationEventsObj->Release();
m_pApplicationEventsObj = NULL;
if (m_pDebuggerEventsObj != NULL)
{
// Since we were able to connect to the Debugger events, we
// should be able to access the Debugger object again to
// unadvise from its events (thus the VERIFY_OK below--see stdafx.h).
CComPtr<IDispatch> pDebugger;
VERIFY_OK(m_pApplication->get_Debugger(&pDebugger));
ASSERT (pDebugger != NULL);
m_pDebuggerEventsObj->Disconnect(pDebugger);
m_pDebuggerEventsObj->Release();
m_pDebuggerEventsObj = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////
// Event handlers
// TODO: Fill out the implementation for those events you wish handle
// Use m_pCommands->GetApplicationObject() to access the Developer
// Studio Application object
// Application events
HRESULT CCommands::XApplicationEvents::BeforeBuildStart()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return S_OK;
}
HRESULT CCommands::XApplicationEvents::BuildFinish(long nNumErrors, long nNumWarnings)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_pCommands->m_bBuildInProgres = FALSE;
if (m_pCommands->m_bAutoBuilding == TRUE) //See comment in the constructor
{
//here we create a mail message, and send it off...
if ((m_pCommands->m_bSendMail == TRUE) &&
(m_pCommands->m_bMailOnEach == TRUE))
{
HINSTANCE hInstMail = ::LoadLibrary("MAPI32.DLL");
if (hInstMail != NULL)
{
ULONG (PASCAL *lpfnSendMail)(ULONG, ULONG, MapiMessage*,
FLAGS, ULONG);
(FARPROC&)lpfnSendMail = GetProcAddress(hInstMail,
"MAPISendMail");
if (lpfnSendMail != NULL)
{
MapiMessage message;
memset((void*)&message, 0, sizeof(message));
message.lpszSubject = const_cast<LPTSTR>
((LPCSTR)m_pCommands->m_strStatusLine);
CString strErrWarnCStr;
if (m_pCommands->m_bIncBuildResults == TRUE)
{
CString strErrWarnText;
strErrWarnText.Format(IDS_ERRWARNTEXT, nNumErrors,
nNumWarnings);
strErrWarnCStr = CString(message.lpszSubject) +
strErrWarnText;
message.lpszSubject = const_cast<LPTSTR>
((LPCSTR)strErrWarnCStr);
}
CString strToMail;
if (m_pCommands->m_bSendFile == FALSE)
{
strToMail.Format(IDS_DEFAULTMAILBODY,
m_pCommands->m_strBuildingConfigurationName);
}
else
{
CString strResult;
CStdioFile fileTextToMail;
try
{
fileTextToMail.Open(m_pCommands->m_strFileToSend,
CFile::modeRead | CFile::typeText);
DWORD dwFileSize = fileTextToMail.GetLength();
dwFileSize = fileTextToMail.Read(
strResult.GetBuffer(dwFileSize), dwFileSize);
strResult.ReleaseBuffer(dwFileSize);
CString strLocal;
strLocal.Format(strResult,
m_pCommands->m_strBuildingConfigurationName,
nNumErrors, nNumWarnings);
strToMail = strLocal;
}
catch (...) //If some problem occurrs when working
// with the file, just send the default
// message body
{
if (m_pCommands->m_bTesting == TRUE)
AfxMessageBox(IDS_WARNSENDDEF);
strToMail.Format(IDS_DEFAULTMAILBODY,
m_pCommands->m_strBuildingConfigurationName);
}
}
message.lpszNoteText = const_cast<LPTSTR>((LPCSTR)strToMail);
message.nRecipCount = 1;
message.lpRecips = new MapiRecipDesc;
memset(message.lpRecips, 0, sizeof(MapiRecipDesc));
message.lpRecips->ulRecipClass = MAPI_TO;
CString strTemp2 = CString("SMTP:") + m_pCommands->m_strSendTo;
message.lpRecips->lpszName = const_cast<LPTSTR>
((LPCSTR)m_pCommands->m_strSendTo);
message.lpRecips->lpszAddress = const_cast<LPTSTR>
((LPCSTR)strTemp2);
int error = lpfnSendMail(0, (ULONG)0, &message, 0, 0);
//error is not handled, because you really don't want to
// pop up a message box. Putting up a message box would
// suspend other pending builds until somebody would
// manually click the OK button. You may wish to place
// some sort of logging here, so that the error would be
// dumped to a file.
// The reason you might get an error is because your email
// may require a password. You can log into your email account first,
// or create an account that doesn't require a password.
if (error != SUCCESS_SUCCESS)
{
if (m_pCommands->m_bTesting == TRUE)
{
AfxMessageBox(IDS_MAPIERROR);
}
else
{
// log some other kind of error in a log file
}
}
delete message.lpRecips;
}
::FreeLibrary(hInstMail);
}
}
}
m_pCommands->m_nTotalErrors += nNumErrors;
m_pCommands->m_nTotalWarnings += nNumWarnings;
return S_OK;
}
HRESULT CCommands::XApplicationEvents::BeforeApplicationShutDown()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return S_OK;
}
HRESULT CCommands::XApplicationEvents::DocumentOpen(IDispatch* theDocument)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return S_OK;
}
HRESULT CCommands::XApplicationEvents::BeforeDocumentClose(IDispatch* theDocument)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return S_OK;
}
HRESULT CCommands::XApplicationEvents::DocumentSave(IDispatch* theDocument)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return S_OK;
}
HRESULT CCommands::XApplicationEvents::NewDocument(IDispatch* theDocument)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return S_OK;
}
HRESULT CCommands::XApplicationEvents::WindowActivate(IDispatch* theWindow)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return S_OK;
}
HRESULT CCommands::XApplicationEvents::WindowDeactivate(IDispatch* theWindow)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return S_OK;
}
HRESULT CCommands::XApplicationEvents::WorkspaceOpen()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return S_OK;
}
HRESULT CCommands::XApplicationEvents::WorkspaceClose()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return S_OK;
}
HRESULT CCommands::XApplicationEvents::NewWorkspace()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return S_OK;
}
// Debugger event
HRESULT CCommands::XDebuggerEvents::BreakpointHit(IDispatch* pBreakpoint)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
// CCommands methods
STDMETHODIMP CCommands::AutoBuildTest()
{
// don't allow more than one test to go.
if (m_bBuildInProgres)
return S_OK;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_pApplication->EnableModeless(VARIANT_FALSE);
m_nTotalErrors = 0;
m_nTotalWarnings = 0;
m_bAutoBuilding = TRUE; //See comment in the constructor
m_bBuildInProgres = TRUE; //See comment in the constructor
long lCount;
int nNumWorkspaces = AfxGetApp()->GetProfileInt(_T("Configure"),
_T("NumWorkspaces"), 0);
for (int nWorkspaceNumber = 1 ; nWorkspaceNumber <= nNumWorkspaces ;
nWorkspaceNumber++)
{
char RegKey[50];
wsprintf(RegKey, "Workspace%d", nWorkspaceNumber-1);
CComBSTR bszWorkspacePathName = AfxGetApp()->GetProfileString(
_T("Configure"), RegKey, "");
CComPtr<IDispatch> pDispDocuments;
VERIFY_OK(m_pApplication->get_Documents(&pDispDocuments));
CComVariant OleVariant; //By default, the type is VT_EMPTY
CComQIPtr<IDocuments, &IID_IDocuments> pDocuments(pDispDocuments);
CComPtr<IDispatch> pWorkspace; //Never gets used except in:
VERIFY_OK(pDocuments->Open(bszWorkspacePathName, OleVariant,
OleVariant, &pWorkspace));
//First, get a pointer to the dispatch for the Projects collection
CComPtr<IDispatch> pDispProjects;
// clean out the output files from and old build.
VERIFY_OK(m_pApplication->get_Projects(&pDispProjects));
CComQIPtr<IProjects, &IID_IProjects> pProjects(pDispProjects);
//Get the number of projects in the collection
VERIFY_OK(pProjects->get_Count(&lCount));
for (long i = 1 ; i < lCount+1 ; i++)
{
long lNumConfigs;
CComVariant Vari = i;
//Get the next project
CComPtr<IGenericProject> pGenProject;
VERIFY_OK(pProjects->Item(Vari, &pGenProject));
CComQIPtr<IBuildProject, &IID_IBuildProject> pProject(pGenProject);
//Each project has a configuration (Win32 Release, Win32 Debug,
// etc.), get the collection of these configurations
CComPtr<IConfigurations> pConfigs;
VERIFY_OK(pProject->get_Configurations(&pConfigs));
VERIFY_OK(pConfigs->get_Count(&lNumConfigs));
for (long j = 1 ; j < lNumConfigs+1 ; j++)
{
CComVariant Varj = j;
//Get each individual configuration
CComPtr<IConfiguration> pConfig;
VERIFY_OK(pConfigs->Item(Varj, &pConfig));
CComVariant VarDisp = pConfig;
CComBSTR bszStr;
VERIFY_OK(pConfig->get_Name(&bszStr));
if (m_bMailOnEach == TRUE)
m_strBuildingConfigurationName = bszStr;
else
m_strBuildingConfigurationName += CString(", ") +
CString(bszStr);
//Build this particular
// configuration, in this project,
// in this Workspace...
VERIFY_OK(m_pApplication->Build(VarDisp));
}
}
}
if (m_bMailOnEach == FALSE)
{
//We only wish to send mail when everything is built.
// to do this, we just say "from now on we are sending Mail on each
// configuration build"
m_bMailOnEach = TRUE;
// then manually call the BuildFinish event, as if a configuration is
// done, but this "Configuration" is the entire project
ASSERT(m_pApplicationEventsObj != NULL);
m_pApplicationEventsObj->BuildFinish(m_nTotalErrors, m_nTotalWarnings);
//Reset MailOnEach
m_bMailOnEach = FALSE;
}
m_bAutoBuilding = FALSE; //See comment in the constructor
m_pApplication->EnableModeless(VARIANT_TRUE);
if (m_bTesting == FALSE)
{
if (m_bCloseWhenDone == TRUE)
VERIFY_OK(m_pApplication->Quit());
}
else
{
if (m_bCloseWhenDone == TRUE)
AfxMessageBox(IDS_WARNEXIT);
}
return S_OK;
}
STDMETHODIMP CCommands::AutoBuild()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_bTesting = FALSE;
AutoBuildTest();
m_bTesting = TRUE;
return S_OK;
}
STDMETHODIMP CCommands::AutoBuildConfigure()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_pApplication->EnableModeless(VARIANT_FALSE);
CConfigure AutoBuildConfigDlg;
// stuff all the pre read data values in the dialog before
// showing it
AutoBuildConfigDlg.m_bSendMail = m_bSendMail;
AutoBuildConfigDlg.m_bCloseWhenDone = m_bCloseWhenDone;
AutoBuildConfigDlg.m_bMailOnEach = m_bMailOnEach;
AutoBuildConfigDlg.m_bIncBuildResults = m_bIncBuildResults;
AutoBuildConfigDlg.m_bSendFile = m_bSendFile;
AutoBuildConfigDlg.m_strFileToSend = m_strFileToSend;
AutoBuildConfigDlg.m_strStatusLine = m_strStatusLine;
AutoBuildConfigDlg.m_strSendTo = m_strSendTo;
AutoBuildConfigDlg.DoModal();
// get the data values back.
m_bSendMail = AutoBuildConfigDlg.m_bSendMail;
m_bCloseWhenDone = AutoBuildConfigDlg.m_bCloseWhenDone;
m_bMailOnEach = AutoBuildConfigDlg.m_bMailOnEach;
m_bIncBuildResults = AutoBuildConfigDlg.m_bIncBuildResults;
m_bSendFile = AutoBuildConfigDlg.m_bSendFile;
m_strFileToSend = AutoBuildConfigDlg.m_strFileToSend;
m_strStatusLine = AutoBuildConfigDlg.m_strStatusLine;
m_strSendTo = AutoBuildConfigDlg.m_strSendTo;
m_pApplication->EnableModeless(VARIANT_TRUE);
return S_OK;
}