|
// Commands.cpp : implementation file
//
#include "stdafx.h"
#include "AutoBuild.h"
#include "Commands.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;
}
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());
//=====================================================================
IDispatch* pDispatch;
m_pCommands->GetApplicationObject()->get_ActiveProject(&pDispatch);
if (!pDispatch)
{
m_pCommands->GetApplicationObject()->PrintToOutputWindow(CComBSTR(_T("Build Number Unchanged")));
return S_OK; // or some error message
}
CComQIPtr<IGenericProject, &IID_IGenericProject> pProject(pDispatch);
CComBSTR bsName;
pProject->get_FullName(&bsName);
CString sName = bsName;
pDispatch->Release();
//======================================================================
m_pCommands->GetApplicationObject()->PrintToOutputWindow(bsName);
// check whether the application file has a incrementbuild flag set.
int iLastSlash = sName.ReverseFind('\\');
if(iLastSlash == -1)
{
m_pCommands->GetApplicationObject()->PrintToOutputWindow(CComBSTR(_T("Build Number Unchanged")));
return S_OK; // or some error message
}
CString sPath = sName.Left(iLastSlash+1);
CString sApp = sName.Left(sName.GetLength()-4).Mid(iLastSlash+1);
// now that we got the project name, compute the name of the rc file.
CString sFileRC = sPath + sApp + ".rc";
// also compute the path of our header file.
CString sFileAutoBld = sPath + "AutoBuild.h";
// check whether the rc file is read-only.
CStdioFile cFile;
CFileStatus cStatus;
cFile.GetStatus(sFileRC, cStatus);
if(cStatus.m_attribute & CFile::Attribute::readOnly)
{
m_pCommands->GetApplicationObject()->PrintToOutputWindow(CComBSTR(_T("Build Number Unchanged")));
return S_OK; // or some error message
}
// check whether the autobuild file can be opened in read-write mode.
cFile.GetStatus(sFileAutoBld, cStatus);
if(cStatus.m_attribute & CFile::Attribute::readOnly)
{
m_pCommands->GetApplicationObject()->PrintToOutputWindow(CComBSTR(_T("Build Number Unchanged")));
return S_OK; // or some error message
}
// open the autobld file and see whether the user wants to increment the build.
CFileException cFileException;
if(!cFile.Open(sFileAutoBld, CFile::modeReadWrite, &cFileException))
{
// file does not exist, so create it.
cFile.Open(sFileAutoBld, CFile::modeCreate|CFile::modeWrite, &cFileException);
cFile.WriteString("#ifndef __AUTOBUILD_H__\n");
cFile.WriteString("#define __AUTOBUILD_H__\n");
cFile.WriteString("//change the FALSE to TRUE for autoincrement of build number\n");
cFile.WriteString("#define INCREMENT_BUILD_NUM FALSE\n");
cFile.WriteString("#define BUILD_NUM 0\n");
cFile.WriteString("#endif //__AUTOBUILD_H__\n");
cFile.Close();
m_pCommands->GetApplicationObject()->PrintToOutputWindow(CComBSTR(_T("Build Number Unchanged")));
return S_OK; // or some error message
}
else
cFile.Close();
BOOL bIncrement = FALSE;
CString sLine;
cFile.Open(sFileAutoBld, CFile::modeRead, &cFileException);
CString ksIncrementBuild = "#define INCREMENT_BUILD_NUM";
while(cFile.ReadString(sLine))
{
if( sLine.Find(ksIncrementBuild) != -1 &&
(sLine.Find("TRUE")+1 || sLine.Find("1")+1))
{
bIncrement = TRUE;
break;
}
}
cFile.Close();
if(!bIncrement)
{
m_pCommands->GetApplicationObject()->PrintToOutputWindow(CComBSTR(_T("Build Number Unchanged")));
return S_OK; // or some error message
}
cFile.Open(sFileAutoBld, CFile::modeReadWrite, &cFileException);
// check whether the first line contains
// #define INCREMENTBUILD TRUE
CString sLines;
CString ksBuildNum = "#define BUILD_NUM";
int iBuildNum = 0;
CString sBuildNum;
while(cFile.ReadString(sLine))
{
if(int i = sLine.Find(ksBuildNum)+1)
{
sBuildNum = sLine.Mid(i + strlen(ksBuildNum));
sBuildNum.TrimLeft();
iBuildNum=atol(sBuildNum);
// increment the BuildNum;
sBuildNum.Format("%d",++iBuildNum);
sLine = ksBuildNum+ " " + sBuildNum;
}
sLines += sLine + "\n";
}
cFile.SeekToBegin();
cFile.WriteString(sLines);
sLines="";
cFile.Close();
m_pCommands->GetApplicationObject()->PrintToOutputWindow(
CComBSTR(_T("Incrementing Build Number To: " + sBuildNum)));
// now that we have incremented the autobuild.h file,
// update the rc file.
cFile.Open(sFileRC, CFile::modeReadWrite, &cFileException);
// p.s. already confirmed that we can open this file.
/* Go throuth the rc file and replace the build version info.
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
...
VALUE "FileVersion", "1, 0, 0, 1\0"
...
VALUE "ProductVersion", "1, 0, 0, 1\0"
...
END
*/
CString ksVERSION_INFO = "VS_VERSION_INFO";
CString ksFILEVERSION = "FILEVERSION";
CString ksPRODUCTVERSION = "PRODUCTVERSION";
CString ksFileVersion = "VALUE \"FileVersion\",";
CString ksProductVersion = "VALUE \"ProductVersion\",";
BOOL bInBlock = FALSE;
int iFound=0;
while(cFile.ReadString(sLine))
{
if(!bInBlock && sLine.Find(ksVERSION_INFO) != -1)
bInBlock = TRUE;
if(bInBlock)
{
if( ((iFound = sLine.Find(ksFILEVERSION)) != -1) ||
((iFound = sLine.Find(ksPRODUCTVERSION)) != -1))
{
int i = sLine.ReverseFind(',');
sLine = sLine.Left(++i) + sBuildNum;
}
if( ((iFound = sLine.Find(ksFileVersion)) != -1) ||
((iFound = sLine.Find(ksProductVersion)) != -1))
{
CString sVersion = sLine.Mid(iFound);
int i = sVersion.ReverseFind(',')+2;
int j = sVersion.ReverseFind('\\');
sLine = sLine.Left(iFound) + sVersion.Left(i) + sBuildNum + sVersion.Mid(j);
}
}
sLines += sLine + "\n";
}
cFile.SeekToBegin();
cFile.WriteString(sLines);
cFile.Close();
return S_OK;
}
HRESULT CCommands::XApplicationEvents::BuildFinish(long nNumErrors, long nNumWarnings)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
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::AutoBuildCommandMethod()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: Replace this with the actual code to execute this command
// Use m_pApplication to access the Developer Studio Application object,
// and VERIFY_OK to see error strings in DEBUG builds of your add-in
// (see stdafx.h)
VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));
// ::MessageBox(NULL, "AutoBuild Command invoked.", "AutoBuild", MB_OK | MB_ICONINFORMATION);
VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));
return S_OK;
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.