Sub CloseExceptActive ()
'DESCRIPTION: Closes all editor windows except the current one.
'Windows.Item(1) is always the currently active window. So to close all
' the windows except the active one, keep looping until there is no
' longer a Windows.Item(2).
do while Windows.Count > 1
Windows.Item(2).Close(dsSaveChangesPrompt)
Loop
End Sub
Sub CommentOut ()
'DESCRIPTION: Comments out a selected block of text.
Dim win
set win = ActiveWindow
if win.type <> "Text" Then
MsgBox "This macro can only be run when a text editor window is active."
else
TypeOfFile = FileType(ActiveDocument)
If TypeOfFile > 0 And TypeOfFile < 5 Then 'C & Java use the same
'style of comments.
ActiveDocument.Selection = "/*" + ActiveDocument.Selection + "*/"
ElseIf TypeOfFile = 5 Then
ActiveDocument.Selection = "<! " + ActiveDocument.Selection + " >"
ElseIf TypeOfFile = 6 Or TypeOfFile = 7 Then
'There is no group comment like there is in the other file types,
'so we need to iterate through each line, and prepend a ' to the line.
'Also, because VBS/DEF does not have a 'end the comment at this
'particular column' delimiter, entire lines of code must be
'commented out, not sections.
If TypeOfFile = 6 Then
CommentType = " ' "
Else
CommentType = " ; "
End If
StartLine = ActiveDocument.Selection.TopLine
EndLine = ActiveDocument.Selection.BottomLine
If EndLine < StartLine Then
Temp = StartLine
StartLine = EndLine
EndLine = Temp
End If
If EndLine = StartLine Then
ActiveDocument.Selection = CommentType + ActiveDocument.Selection
Else
For i = StartLine To EndLine
ActiveDocument.Selection.GoToLine i
ActiveDocument.Selection.SelectLine
ActiveDocument.Selection = CommentType + _
ActiveDocument.Selection
Next
End If
Else
MsgBox("Unable to comment out the highlighted text" + vbLf + _
"because the file type was unrecognized." + vbLf + _
"If the file has not yet been saved, " + vbLf + _
"please save it and try again.")
End If
End If
End Sub
'Allows the user to make sure the current header file is included only once.
' There are two ways to do this, using the #pragma once directive or
' surrounding the entire file in a #ifndef/#endif structure. The first way
' is much cleaner, but it is Visual C++ specific, and therefore not portable. If
' you plan on compiling your code with other compilers, use the
' #ifndef/#endif method, otherwise, the #pragma once option is preferable.
Sub OneTimeInclude ()
'DESCRIPTION: Adds code to the current header file so it is included only once
' per c/cpp file.
ext = ActiveDocument.Name
If ext = "" Then
If MsgBox("The file you are working with does not have a file extension." +_
vbLF + "Are you sure this is a C/C++ header file?", 4) = vbCancel Then
Exit Sub
End If
ext = "nofilenamegiven.h"
End If
DocName = UCase(ext)
pos = Instr(ext, ".")
Do While pos <> 1
ext = Mid(ext, pos, (Len(ext) - pos + 1))
pos = Instr(ext, ".")
Loop
ext = LCase(ext)
pos = Instr(DocName, ".")
If ext = ".h" Or ext = ".hpp" Then
'Warn user that this will not work with a compiler other than Visual C++.
If MsgBox("This macro uses the Visual C++ dependant #pragma once" + _
vbLf + "Is the source to be portable across compilers?", 4) _
= 6 Then
ActiveDocument.Selection.StartOfDocument (False)
Examp = "__" + Left(DocName, pos - 1) + "_" + _
UCase(Right(ext, len(ext) - 1)) + "__"
ControlVarName = InputBox("What should the control variable be?" _
+ vbLf + vbLf + "Example: #ifdef " + _
Examp, "One time header include protection", Examp)
If ValidId (ControlVarName) = True Then
ActiveDocument.Selection = "#ifndef " + ControlVarName + _
vbLf + "#define " + ControlVarName + vbLf
ActiveDocument.Selection.EndOfDocument(False)
ActiveDocument.Selection = vbLf + "#endif //" + _
ControlVarName
Else
MsgBox(ControlVarName + " is not a valid c identifier." + _
vbLf + "please re-run the macro with a valid C identifier")
End If
Else
ActiveDocument.Selection.StartOfDocument(False)
ActiveDocument.Selection = "#pragma once" + vbLf + vbLf
End If
Else
MsgBox("This macro can only be run on .h or .hpp files")
End If
End Sub
Figure 10 Wizard-generated Add-in Classes
|
Class Name |
Description |
|
CCommands |
Implements one or more commands that are made available to Developer Studio by exposing an IDispatch-derived interface named ICommands. |
|
CDSAddIn |
Implements the IDSAddIn custom interface declared in header files provided with Developer Studio. This interface exposes two methods that Developer Studio uses to communicate with the add-in: OnConnection and OnDisconnection. |
|
CProjectNameApp |
This CWinApp-derived class provides initialization and registration code for the add-in. |
Figure 11 CDSAddIn
// AddInMod.cpp : implementation file
//
#include "stdafx.h"
#include "Replace.h"
#include "DSAddIn.h"
#include "Commands.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// This is called when the user first loads the add-in, and on start-up
// of each subsequent Developer Studio session
STDMETHODIMP CDSAddIn::OnConnection(IApplication* pApp, VARIANT_BOOL bFirstTime,
long dwCookie, VARIANT_BOOL* OnConnection)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// Store info passed to us
IApplication* pApplication = NULL;
if (FAILED(pApp->QueryInterface(IID_IApplication, (void**) &pApplication))
|| pApplication == NULL)
{
*OnConnection = VARIANT_FALSE;
return S_OK;
}
m_dwCookie = dwCookie;
// Create command dispatch, send info back to DevStudio
CCommandsObj::CreateInstance(&m_pCommands);
m_pCommands->AddRef();
// The QueryInterface above AddRef'd the Application object. It will
// be Release'd in CCommand's destructor.
m_pCommands->SetApplicationObject(pApplication);
// (see stdafx.h for the definition of VERIFY_OK)
VERIFY_OK(pApplication->SetAddInInfo((long) AfxGetInstanceHandle(),
(LPDISPATCH) m_pCommands, IDR_TOOLBAR_MEDIUM,
IDR_TOOLBAR_LARGE, m_dwCookie));
// Inform DevStudio of the commands we implement
// TODO: Replace the AddCommand call below with a series of calls,
// one for each command your add-in will add.
// The command name should not be localized to other languages. The
// tooltip, command description, and other strings related to this
// command are stored in the string table (IDS_CMD_STRING) and should
// be localized.
LPCTSTR szCommand = _T("ReplaceCommand");
VARIANT_BOOL bRet;
CString strCmdString;
strCmdString.LoadString(IDS_CMD_STRING);
strCmdString = szCommand + strCmdString;
CComBSTR bszCmdString(strCmdString);
CComBSTR bszMethod(_T("ReplaceCommandMethod"));
CComBSTR bszCmdName(szCommand);
VERIFY_OK(pApplication->AddCommand(bszCmdString, bszMethod, 0, m_dwCookie,
&bRet));
if (bRet == VARIANT_FALSE)
{
// AddCommand failed because a command with this name already
// exists. You may try adding your command under a different name.
// Or, you can fail to load as we will do here.
*OnConnection = VARIANT_FALSE;
return S_OK;
}
// Add toolbar buttons only if this is the first time the add-in
// is being loaded. Toolbar buttons are automatically remembered
// by Developer Studio from session to session, so we should only
// add the toolbar buttons once.
if (bFirstTime == VARIANT_TRUE)
{
VERIFY_OK(pApplication->AddCommandBarButton(dsGlyph, bszCmdName,
m_dwCookie));
}
*OnConnection = VARIANT_TRUE;
return S_OK;
}
// This is called on shut-down, and also when the user unloads the add-in
STDMETHODIMP CDSAddIn::OnDisconnection(VARIANT_BOOL bLastTime)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_pCommands->Release();
m_pCommands = NULL;
// TODO: Perform any cleanup work here
return S_OK;
}
Figure 12 Ccommands
// Commands.cpp : implementation file
#include "stdafx.h"
#include "Replace.h"
#include "Commands.h"
#include "ReplaceDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCommands
CCommands::CCommands()
{
m_pApplication == 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;
}
/////////////////////////////////////////////////////////////////////////////
// CCommands methods
STDMETHODIMP CCommands::ReplaceCommandMethod()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));
CReplaceDlg dlg(m_pApplication);
dlg.DoModal();
VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));
return S_OK;
}
Figure 15 BreakpointHit Event Handler
HRESULT CCommands::XDebuggerEvents::BreakpointHit(IDispatch* pBP)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CComQIPtr<IBreakpoint, &IID_IBreakpoint> pBreakpoint = pBP;
// We only care about line# breakpoints. We can tell whether this
// is a line# breakpoint by seeing whether its Location property
// begins with a period (e.g., ".253")
CComBSTR bstrLocation;
pBreakpoint->get_Location(&bstrLocation);
if (bstrLocation.Length() == 0 || *(BSTR)bstrLocation != '.')
return S_OK;
// Is it enabled as a tracepoint?
CComBSTR bstrFile;
pBreakpoint->get_File(&bstrFile);
CString strFullInfo = (BSTR) bstrFile;
strFullInfo += (BSTR) bstrLocation;
BOOL* pEnable = NULL;
m_pCommands->m_mapEnable.Lookup(strFullInfo, (void*&)pEnable);
if (pEnable == NULL || *pEnable == FALSE)
return S_OK;
// Yes, it's a tracepoint. Let's output the expressions.
CStringArray* pExprArray = NULL;
m_pCommands->m_mapExpr.Lookup(strFullInfo, (void*&)pExprArray);
ASSERT(pExprArray);
IDebugger* pDebugger = m_pCommands->GetDebuggerObject();
IApplication* pApplication = m_pCommands->GetApplicationObject();
for (int nLoop = 0; nLoop < pExprArray->GetSize(); nLoop++)
{
CComBSTR bstrValue(_T("<Expression could not be evaluated>"));
pDebugger->Evaluate(CComBSTR(pExprArray->GetAt(nLoop)),
&bstrValue);
CComBSTR bstrOut(pExprArray->GetAt(nLoop));
bstrOut += CComBSTR(_T(" = "));
bstrOut += bstrValue;
pApplication->PrintToOutputWindow(bstrOut);
}
pDebugger->Go();
return S_OK;
}
Figure 17 A Developer Studio Project File
// Partial sample DSP file
!IF "$(CFG)" == "Signature - Win32 Release"
# PROP BASE Use_MFC 2
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 2
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /D "_USRDLL" /Yu"stdafx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 /nologo /subsystem:windows /dll /machine:I386 /out:"Release\Signature.ocx"
# Begin Custom Build - Registering ActiveX Control...
OutDir=.\Release
TargetPath=.\Release\Signature.ocx
InputPath=.\Release\Signature.ocx
SOURCE=$(InputPath)
"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
regsvr32 /s /c "$(TargetPath)"
echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg"
# End Custom Build
Figure 18 CustomizeProject
void CWebDCAppWiz::CustomizeProject(IBuildProject* pProject)
{
IConfigurations* pConfigs = NULL;
pProject->get_Configurations(&pConfigs);
ASSERT(pConfigs);
CComPtr<IUnknown> pUnk;
CComQIPtr<IEnumVARIANT, &IID_IEnumVARIANT> pNewEnum;
if (SUCCEEDED(pConfigs->get__NewEnum(&pUnk)) && pUnk != NULL)
{
pNewEnum = pUnk;
VARIANT varConfig;
CComQIPtr<IConfiguration, &IID_IConfiguration> pConfig;
while (pNewEnum->Next(1, &varConfig, NULL) == S_OK)
{
ASSERT (varConfig.vt == VT_DISPATCH);
pConfig = varConfig.pdispVal;
VariantClear(&varConfig);
// Add Control registration custom build step
VARIANT reserved;
CComBSTR bstrCommand(
"regsvr32 /s /c \"$(TargetPath)\"\n"
"echo regsvr32 exec. time > \"$(OutDir)\\regsvr32.trg\"");
CComBSTR bstrOutput("$(OutDir)\\regsvr32.trg");
CComBSTR bstrDescription("Registering ActiveX Control...");
pConfig->AddCustomBuildStep(bstrCommand, bstrOutput,
bstrDescription, reserved);
// Remove old output name (DLL)
CComBSTR bstrTool = "link.exe";
CComBSTR bstrOption = "/out:";
pConfig->RemoveToolSettings(bstrTool, bstrOption, reserved);
// Change output name to OCX
USES_CONVERSION;
CComBSTR bstrName;
pConfig->get_Name(&bstrName);
BOOL bDebug = (BOOL) _tcsstr(OLE2T(bstrName), _T("Debug"));
bstrOption = bDebug ? "/out:Debug\\" : "/out:Release\\";
bstrOption += m_Dictionary[_T("safe_root")].AllocSysString();
bstrOption += ".ocx";
pConfig->AddToolSettings(bstrTool, bstrOption, reserved);
}
}
}