summaryrefslogtreecommitdiffstats
path: root/src/VisVim
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 02:44:24 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 02:44:24 +0000
commit8baab3c8d7a6f22888bd581cd5c6098fd2e4b5a8 (patch)
tree3537e168b860f2742f6029d70501b5ed7d15d345 /src/VisVim
parentInitial commit. (diff)
downloadvim-upstream.tar.xz
vim-upstream.zip
Adding upstream version 2:8.1.0875.upstream/2%8.1.0875upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/VisVim/Commands.cpp710
-rw-r--r--src/VisVim/Commands.h127
-rw-r--r--src/VisVim/DSAddIn.cpp160
-rw-r--r--src/VisVim/DSAddIn.h53
-rw-r--r--src/VisVim/OleAut.cpp781
-rw-r--r--src/VisVim/OleAut.h73
-rw-r--r--src/VisVim/README_VisVim.txt326
-rw-r--r--src/VisVim/Reg.cpp56
-rw-r--r--src/VisVim/Register.bat1
-rw-r--r--src/VisVim/Res/ToolbarL.bmpbin0 -> 2678 bytes
-rw-r--r--src/VisVim/Res/ToolbarM.bmpbin0 -> 758 bytes
-rw-r--r--src/VisVim/Resource.h30
-rw-r--r--src/VisVim/StdAfx.cpp6
-rw-r--r--src/VisVim/StdAfx.h73
-rw-r--r--src/VisVim/UnRegist.bat1
-rw-r--r--src/VisVim/VisVim.cpp152
-rw-r--r--src/VisVim/VisVim.def11
-rw-r--r--src/VisVim/VisVim.dllbin0 -> 49664 bytes
-rw-r--r--src/VisVim/VisVim.h33
-rw-r--r--src/VisVim/VisVim.mak205
-rw-r--r--src/VisVim/VisVim.odl61
-rw-r--r--src/VisVim/VisVim.rc202
-rw-r--r--src/VisVim/VsReadMe.txt91
23 files changed, 3152 insertions, 0 deletions
diff --git a/src/VisVim/Commands.cpp b/src/VisVim/Commands.cpp
new file mode 100644
index 0000000..569fbb8
--- /dev/null
+++ b/src/VisVim/Commands.cpp
@@ -0,0 +1,710 @@
+#include "stdafx.h"
+#include <comdef.h> // For _bstr_t
+#include "VisVim.h"
+#include "Commands.h"
+#include "OleAut.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+
+#endif
+
+
+// Change directory before opening file?
+#define CD_SOURCE 0 // Cd to source path
+#define CD_SOURCE_PARENT 1 // Cd to parent directory of source path
+#define CD_NONE 2 // No cd
+
+
+static BOOL g_bEnableVim = TRUE; // Vim enabled
+static BOOL g_bDevStudioEditor = FALSE; // Open file in Dev Studio editor simultaneously
+static BOOL g_bNewTabs = FALSE;
+static int g_ChangeDir = CD_NONE; // CD after file open?
+
+static void VimSetEnableState(BOOL bEnableState);
+static BOOL VimOpenFile(BSTR& FileName, long LineNr);
+static DISPID VimGetDispatchId(COleAutomationControl& VimOle, char* Method);
+static void VimErrDiag(COleAutomationControl& VimOle);
+static void VimChangeDir(COleAutomationControl& VimOle, DISPID DispatchId, BSTR& FileName);
+static void DebugMsg(char* Msg, char* Arg = NULL);
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CCommands
+
+CCommands::CCommands()
+{
+ // m_pApplication == NULL; M$ Code generation bug!!!
+ m_pApplication = NULL;
+ m_pApplicationEventsObj = NULL;
+ m_pDebuggerEventsObj = NULL;
+}
+
+CCommands::~CCommands()
+{
+ ASSERT(m_pApplication != NULL);
+ if (m_pApplication)
+ {
+ m_pApplication->Release();
+ m_pApplication = NULL;
+ }
+}
+
+void CCommands::SetApplicationObject(IApplication * pApplication)
+{
+ // This function assumes pApplication has already been AddRef'd
+ // for us, which CDSAddIn did in it's QueryInterface call
+ // just before it called us.
+ m_pApplication = pApplication;
+ if (! m_pApplication)
+ return;
+
+ // Create Application event handlers
+ XApplicationEventsObj::CreateInstance(&m_pApplicationEventsObj);
+ if (! m_pApplicationEventsObj)
+ {
+ ReportInternalError("XApplicationEventsObj::CreateInstance");
+ return;
+ }
+ m_pApplicationEventsObj->AddRef();
+ m_pApplicationEventsObj->Connect(m_pApplication);
+ m_pApplicationEventsObj->m_pCommands = this;
+
+#ifdef NEVER
+ // 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;
+ }
+#endif
+
+ // Get settings from registry HKEY_CURRENT_USER\Software\Vim\VisVim
+ HKEY hAppKey = GetAppKey("Vim");
+ if (hAppKey)
+ {
+ HKEY hSectionKey = GetSectionKey(hAppKey, "VisVim");
+ if (hSectionKey)
+ {
+ g_bEnableVim = GetRegistryInt(hSectionKey, "EnableVim",
+ g_bEnableVim);
+ g_bDevStudioEditor = GetRegistryInt(hSectionKey,
+ "DevStudioEditor", g_bDevStudioEditor);
+ g_bNewTabs = GetRegistryInt(hSectionKey, "NewTabs",
+ g_bNewTabs);
+ g_ChangeDir = GetRegistryInt(hSectionKey, "ChangeDir",
+ g_ChangeDir);
+ RegCloseKey(hSectionKey);
+ }
+ RegCloseKey(hAppKey);
+ }
+}
+
+void CCommands::UnadviseFromEvents()
+{
+ ASSERT(m_pApplicationEventsObj != NULL);
+ if (m_pApplicationEventsObj)
+ {
+ m_pApplicationEventsObj->Disconnect(m_pApplication);
+ m_pApplicationEventsObj->Release();
+ m_pApplicationEventsObj = NULL;
+ }
+
+#ifdef NEVER
+ if (m_pDebuggerEventsObj)
+ {
+ // 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;
+ }
+#endif
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Event handlers
+
+// 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());
+ return S_OK;
+}
+
+HRESULT CCommands::XApplicationEvents::BeforeApplicationShutDown()
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+ return S_OK;
+}
+
+// The open document event handle is the place where the real interface work
+// is done.
+// Vim gets called from here.
+//
+HRESULT CCommands::XApplicationEvents::DocumentOpen(IDispatch * theDocument)
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+
+ if (! g_bEnableVim)
+ // Vim not enabled or empty command line entered
+ return S_OK;
+
+ // First get the current file name and line number
+
+ // Get the document object
+ CComQIPtr < ITextDocument, &IID_ITextDocument > pDoc(theDocument);
+ if (! pDoc)
+ return S_OK;
+
+ BSTR FileName;
+ long LineNr = -1;
+
+ // Get the document name
+ if (FAILED(pDoc->get_FullName(&FileName)))
+ return S_OK;
+
+ LPDISPATCH pDispSel;
+
+ // Get a selection object dispatch pointer
+ if (SUCCEEDED(pDoc->get_Selection(&pDispSel)))
+ {
+ // Get the selection object
+ CComQIPtr < ITextSelection, &IID_ITextSelection > pSel(pDispSel);
+
+ if (pSel)
+ // Get the selection line number
+ pSel->get_CurrentLine(&LineNr);
+
+ pDispSel->Release();
+ }
+
+ // Open the file in Vim and position to the current line
+ if (VimOpenFile(FileName, LineNr))
+ {
+ if (! g_bDevStudioEditor)
+ {
+ // Close the document in developer studio
+ CComVariant vSaveChanges = dsSaveChangesPrompt;
+ DsSaveStatus Saved;
+
+ pDoc->Close(vSaveChanges, &Saved);
+ }
+ }
+
+ // We're done here
+ SysFreeString(FileName);
+ 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());
+
+ if (! g_bEnableVim)
+ // Vim not enabled or empty command line entered
+ return S_OK;
+
+ // First get the current file name and line number
+
+ CComQIPtr < ITextDocument, &IID_ITextDocument > pDoc(theDocument);
+ if (! pDoc)
+ return S_OK;
+
+ BSTR FileName;
+ HRESULT hr;
+
+ hr = pDoc->get_FullName(&FileName);
+ if (FAILED(hr))
+ return S_OK;
+
+ // Open the file in Vim and position to the current line
+ if (VimOpenFile(FileName, 0))
+ {
+ if (! g_bDevStudioEditor)
+ {
+ // Close the document in developer studio
+ CComVariant vSaveChanges = dsSaveChangesPrompt;
+ DsSaveStatus Saved;
+
+ pDoc->Close(vSaveChanges, &Saved);
+ }
+ }
+
+ SysFreeString(FileName);
+ 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;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// VisVim dialog
+
+class CMainDialog : public CDialog
+{
+ public:
+ CMainDialog(CWnd * pParent = NULL); // Standard constructor
+
+ //{{AFX_DATA(CMainDialog)
+ enum { IDD = IDD_ADDINMAIN };
+ int m_ChangeDir;
+ BOOL m_bDevStudioEditor;
+ BOOL m_bNewTabs;
+ //}}AFX_DATA
+
+ //{{AFX_VIRTUAL(CMainDialog)
+ protected:
+ virtual void DoDataExchange(CDataExchange * pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+ protected:
+ //{{AFX_MSG(CMainDialog)
+ afx_msg void OnEnable();
+ afx_msg void OnDisable();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+CMainDialog::CMainDialog(CWnd * pParent /* =NULL */ )
+ : CDialog(CMainDialog::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CMainDialog)
+ m_ChangeDir = -1;
+ m_bDevStudioEditor = FALSE;
+ m_bNewTabs = FALSE;
+ //}}AFX_DATA_INIT
+}
+
+void CMainDialog::DoDataExchange(CDataExchange * pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CMainDialog)
+ DDX_Radio(pDX, IDC_CD_SOURCE_PATH, m_ChangeDir);
+ DDX_Check(pDX, IDC_DEVSTUDIO_EDITOR, m_bDevStudioEditor);
+ DDX_Check(pDX, IDC_NEW_TABS, m_bNewTabs);
+ //}}AFX_DATA_MAP
+}
+
+BEGIN_MESSAGE_MAP(CMainDialog, CDialog)
+ //{{AFX_MSG_MAP(CMainDialog)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CCommands methods
+
+STDMETHODIMP CCommands::VisVimDialog()
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+
+ // 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));
+
+ CMainDialog Dlg;
+
+ Dlg.m_bDevStudioEditor = g_bDevStudioEditor;
+ Dlg.m_bNewTabs = g_bNewTabs;
+ Dlg.m_ChangeDir = g_ChangeDir;
+ if (Dlg.DoModal() == IDOK)
+ {
+ g_bDevStudioEditor = Dlg.m_bDevStudioEditor;
+ g_bNewTabs = Dlg.m_bNewTabs;
+ g_ChangeDir = Dlg.m_ChangeDir;
+
+ // Save settings to registry HKEY_CURRENT_USER\Software\Vim\VisVim
+ HKEY hAppKey = GetAppKey("Vim");
+ if (hAppKey)
+ {
+ HKEY hSectionKey = GetSectionKey(hAppKey, "VisVim");
+ if (hSectionKey)
+ {
+ WriteRegistryInt(hSectionKey, "DevStudioEditor",
+ g_bDevStudioEditor);
+ WriteRegistryInt(hSectionKey, "NewTabs",
+ g_bNewTabs);
+ WriteRegistryInt(hSectionKey, "ChangeDir", g_ChangeDir);
+ RegCloseKey(hSectionKey);
+ }
+ RegCloseKey(hAppKey);
+ }
+ }
+
+ VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));
+ return S_OK;
+}
+
+STDMETHODIMP CCommands::VisVimEnable()
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+ VimSetEnableState(true);
+ return S_OK;
+}
+
+STDMETHODIMP CCommands::VisVimDisable()
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+ VimSetEnableState(false);
+ return S_OK;
+}
+
+STDMETHODIMP CCommands::VisVimToggle()
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+ VimSetEnableState(! g_bEnableVim);
+ return S_OK;
+}
+
+STDMETHODIMP CCommands::VisVimLoad()
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+
+ // 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)
+
+ CComBSTR bStr;
+ // Define dispatch pointers for document and selection objects
+ CComPtr < IDispatch > pDispDoc, pDispSel;
+
+ // Get a document object dispatch pointer
+ VERIFY_OK(m_pApplication->get_ActiveDocument(&pDispDoc));
+ if (! pDispDoc)
+ return S_OK;
+
+ BSTR FileName;
+ long LineNr = -1;
+
+ // Get the document object
+ CComQIPtr < ITextDocument, &IID_ITextDocument > pDoc(pDispDoc);
+
+ if (! pDoc)
+ return S_OK;
+
+ // Get the document name
+ if (FAILED(pDoc->get_FullName(&FileName)))
+ return S_OK;
+
+ // Get a selection object dispatch pointer
+ if (SUCCEEDED(pDoc->get_Selection(&pDispSel)))
+ {
+ // Get the selection object
+ CComQIPtr < ITextSelection, &IID_ITextSelection > pSel(pDispSel);
+
+ if (pSel)
+ // Get the selection line number
+ pSel->get_CurrentLine(&LineNr);
+ }
+
+ // Open the file in Vim
+ VimOpenFile(FileName, LineNr);
+
+ SysFreeString(FileName);
+ return S_OK;
+}
+
+
+//
+// Here we do the actual processing and communication with Vim
+//
+
+// Set the enable state and save to registry
+//
+static void VimSetEnableState(BOOL bEnableState)
+{
+ g_bEnableVim = bEnableState;
+ HKEY hAppKey = GetAppKey("Vim");
+ if (hAppKey)
+ {
+ HKEY hSectionKey = GetSectionKey(hAppKey, "VisVim");
+ if (hSectionKey)
+ WriteRegistryInt(hSectionKey, "EnableVim", g_bEnableVim);
+ RegCloseKey(hAppKey);
+ }
+}
+
+// Open the file 'FileName' in Vim and goto line 'LineNr'
+// 'FileName' is expected to contain an absolute DOS path including the drive
+// letter.
+// 'LineNr' must contain a valid line number or 0, e. g. for a new file
+//
+static BOOL VimOpenFile(BSTR& FileName, long LineNr)
+{
+
+ // OLE automation object for com. with Vim
+ // When the object goes out of scope, it's destructor destroys the OLE
+ // connection;
+ // This is important to avoid blocking the object
+ // (in this memory corruption would be likely when terminating Vim
+ // while still running DevStudio).
+ // So keep this object local!
+ COleAutomationControl VimOle;
+
+ // :cd D:/Src2/VisVim/
+ //
+ // Get a dispatch id for the SendKeys method of Vim;
+ // enables connection to Vim if necessary
+ DISPID DispatchId;
+ DispatchId = VimGetDispatchId(VimOle, "SendKeys");
+ if (! DispatchId)
+ // OLE error, can't obtain dispatch id
+ goto OleError;
+
+ OLECHAR Buf[MAX_OLE_STR];
+ char FileNameTmp[MAX_OLE_STR];
+ char VimCmd[MAX_OLE_STR];
+ char *s, *p;
+
+ // Prepend CTRL-\ CTRL-N to exit insert mode
+ VimCmd[0] = 0x1c;
+ VimCmd[1] = 0x0e;
+ VimCmd[2] = 0;
+
+#ifdef SINGLE_WINDOW
+ // Update the current file in Vim if it has been modified.
+ // Disabled, because it could write the file when you don't want to.
+ sprintf(VimCmd + 2, ":up\n");
+#endif
+ if (! VimOle.Method(DispatchId, "s", TO_OLE_STR_BUF(VimCmd, Buf)))
+ goto OleError;
+
+ // Change Vim working directory to where the file is if desired
+ if (g_ChangeDir != CD_NONE)
+ VimChangeDir(VimOle, DispatchId, FileName);
+
+ // Make Vim open the file.
+ // In the filename convert all \ to /, put a \ before a space.
+ if (g_bNewTabs)
+ {
+ sprintf(VimCmd, ":tab drop ");
+ s = VimCmd + 10;
+ }
+ else
+ {
+ sprintf(VimCmd, ":drop ");
+ s = VimCmd + 6;
+ }
+ sprintf(FileNameTmp, "%S", (char *)FileName);
+ for (p = FileNameTmp; *p != '\0' && s < VimCmd + MAX_OLE_STR - 4; ++p)
+ if (*p == '\\')
+ *s++ = '/';
+ else
+ {
+ if (*p == ' ')
+ *s++ = '\\';
+ *s++ = *p;
+ }
+ *s++ = '\n';
+ *s = '\0';
+
+ if (! VimOle.Method(DispatchId, "s", TO_OLE_STR_BUF(VimCmd, Buf)))
+ goto OleError;
+
+ if (LineNr > 0)
+ {
+ // Goto line
+ sprintf(VimCmd, ":%ld\n", LineNr);
+ if (! VimOle.Method(DispatchId, "s", TO_OLE_STR_BUF(VimCmd, Buf)))
+ goto OleError;
+ }
+
+ // Make Vim come to the foreground
+ if (! VimOle.Method("SetForeground"))
+ VimOle.ErrDiag();
+
+ // We're done
+ return true;
+
+ OleError:
+ // There was an OLE error
+ // Check if it's the "unknown class string" error
+ VimErrDiag(VimOle);
+ return false;
+}
+
+// Return the dispatch id for the Vim method 'Method'
+// Create the Vim OLE object if necessary
+// Returns a valid dispatch id or null on error
+//
+static DISPID VimGetDispatchId(COleAutomationControl& VimOle, char* Method)
+{
+ // Initialize Vim OLE connection if not already done
+ if (! VimOle.IsCreated())
+ {
+ if (! VimOle.CreateObject("Vim.Application"))
+ return NULL;
+ }
+
+ // Get the dispatch id for the SendKeys method.
+ // By doing this, we are checking if Vim is still there...
+ DISPID DispatchId = VimOle.GetDispatchId("SendKeys");
+ if (! DispatchId)
+ {
+ // We can't get a dispatch id.
+ // This means that probably Vim has been terminated.
+ // Don't issue an error message here, instead
+ // destroy the OLE object and try to connect once more
+ //
+ // In fact, this should never happen, because the OLE aut. object
+ // should not be kept long enough to allow the user to terminate Vim
+ // to avoid memory corruption (why the heck is there no system garbage
+ // collection for those damned OLE memory chunks???).
+ VimOle.DeleteObject();
+ if (! VimOle.CreateObject("Vim.Application"))
+ // If this create fails, it's time for an error msg
+ return NULL;
+
+ if (! (DispatchId = VimOle.GetDispatchId("SendKeys")))
+ // There is something wrong...
+ return NULL;
+ }
+
+ return DispatchId;
+}
+
+// Output an error message for an OLE error
+// Check on the classstring error, which probably means Vim wasn't registered.
+//
+static void VimErrDiag(COleAutomationControl& VimOle)
+{
+ SCODE sc = GetScode(VimOle.GetResult());
+ if (sc == CO_E_CLASSSTRING)
+ {
+ char Buf[256];
+ sprintf(Buf, "There is no registered OLE automation server named "
+ "\"Vim.Application\".\n"
+ "Use the OLE-enabled version of Vim with VisVim and "
+ "make sure to register Vim by running \"vim -register\".");
+ MessageBox(NULL, Buf, "OLE Error", MB_OK);
+ }
+ else
+ VimOle.ErrDiag();
+}
+
+// Change directory to the directory the file 'FileName' is in or it's parent
+// directory according to the setting of the global 'g_ChangeDir':
+// 'FileName' is expected to contain an absolute DOS path including the drive
+// letter.
+// CD_NONE
+// CD_SOURCE_PATH
+// CD_SOURCE_PARENT
+//
+static void VimChangeDir(COleAutomationControl& VimOle, DISPID DispatchId, BSTR& FileName)
+{
+ // Do a :cd first
+
+ // Get the path name of the file ("dir/")
+ CString StrFileName = FileName;
+ char Drive[_MAX_DRIVE];
+ char Dir[_MAX_DIR];
+ char DirUnix[_MAX_DIR * 2];
+ char *s, *t;
+
+ _splitpath(StrFileName, Drive, Dir, NULL, NULL);
+
+ // Convert to Unix path name format, escape spaces.
+ t = DirUnix;
+ for (s = Dir; *s; ++s)
+ if (*s == '\\')
+ *t++ = '/';
+ else
+ {
+ if (*s == ' ')
+ *t++ = '\\';
+ *t++ = *s;
+ }
+ *t = '\0';
+
+
+ // Construct the cd command; append /.. if cd to parent
+ // directory and not in root directory
+ OLECHAR Buf[MAX_OLE_STR];
+ char VimCmd[MAX_OLE_STR];
+
+ sprintf(VimCmd, ":cd %s%s%s\n", Drive, DirUnix,
+ g_ChangeDir == CD_SOURCE_PARENT && DirUnix[1] ? ".." : "");
+ VimOle.Method(DispatchId, "s", TO_OLE_STR_BUF(VimCmd, Buf));
+}
+
+#ifdef _DEBUG
+// Print out a debug message
+//
+static void DebugMsg(char* Msg, char* Arg)
+{
+ char Buf[400];
+ sprintf(Buf, Msg, Arg);
+ AfxMessageBox(Buf);
+}
+#endif
diff --git a/src/VisVim/Commands.h b/src/VisVim/Commands.h
new file mode 100644
index 0000000..e47c81a
--- /dev/null
+++ b/src/VisVim/Commands.h
@@ -0,0 +1,127 @@
+// Commands.h : header file
+//
+
+#if !defined(AFX_COMMANDS_H__AC726717_2977_11D1_B2F3_006008040780__INCLUDED_)
+#define AFX_COMMANDS_H__AC726717_2977_11D1_B2F3_006008040780__INCLUDED_
+
+#include "vsvtypes.h"
+
+class CCommands :
+ public CComDualImpl < ICommands,
+ &IID_ICommands,
+ &LIBID_VisVim >,
+ public CComObjectRoot,
+ public CComCoClass < CCommands,
+ &CLSID_Commands >
+{
+ protected:
+ IApplication * m_pApplication;
+
+ public:
+ CCommands ();
+ ~CCommands ();
+ void SetApplicationObject (IApplication * m_pApplication);
+ IApplication *GetApplicationObject ()
+ {
+ return m_pApplication;
+ }
+ void UnadviseFromEvents ();
+
+ BEGIN_COM_MAP (CCommands)
+ COM_INTERFACE_ENTRY (IDispatch)
+ COM_INTERFACE_ENTRY (ICommands)
+ END_COM_MAP ()
+ DECLARE_NOT_AGGREGATABLE (CCommands)
+
+ protected:
+ // This class template is used as the base class for the Application
+ // event handler object and the Debugger event handler object,
+ // which are declared below.
+ template < class IEvents,
+ const IID * piidEvents,
+ const GUID * plibid,
+ class XEvents,
+ const CLSID * pClsidEvents >
+ class XEventHandler :
+ public CComDualImpl < IEvents,
+ piidEvents,
+ plibid >,
+ public CComObjectRoot,
+ public CComCoClass < XEvents,
+ pClsidEvents >
+ {
+ public:
+ BEGIN_COM_MAP (XEvents)
+ COM_INTERFACE_ENTRY (IDispatch)
+ COM_INTERFACE_ENTRY_IID (*piidEvents, IEvents)
+ END_COM_MAP ()
+ DECLARE_NOT_AGGREGATABLE (XEvents)
+ void Connect (IUnknown * pUnk)
+ {
+ VERIFY (SUCCEEDED (AtlAdvise (pUnk, this, *piidEvents,
+ &m_dwAdvise)));
+ }
+ void Disconnect (IUnknown * pUnk)
+ {
+ AtlUnadvise (pUnk, *piidEvents, m_dwAdvise);
+ }
+
+ CCommands *m_pCommands;
+
+ protected:
+ DWORD m_dwAdvise;
+ };
+
+ // This object handles events fired by the Application object
+ class XApplicationEvents : public XEventHandler < IApplicationEvents,
+ &IID_IApplicationEvents,
+ &LIBID_VisVim,
+ XApplicationEvents,
+ &CLSID_ApplicationEvents >
+ {
+ public:
+ // IApplicationEvents methods
+ STDMETHOD (BeforeBuildStart) (THIS);
+ STDMETHOD (BuildFinish) (THIS_ long nNumErrors, long nNumWarnings);
+ STDMETHOD (BeforeApplicationShutDown) (THIS);
+ STDMETHOD (DocumentOpen) (THIS_ IDispatch * theDocument);
+ STDMETHOD (BeforeDocumentClose) (THIS_ IDispatch * theDocument);
+ STDMETHOD (DocumentSave) (THIS_ IDispatch * theDocument);
+ STDMETHOD (NewDocument) (THIS_ IDispatch * theDocument);
+ STDMETHOD (WindowActivate) (THIS_ IDispatch * theWindow);
+ STDMETHOD (WindowDeactivate) (THIS_ IDispatch * theWindow);
+ STDMETHOD (WorkspaceOpen) (THIS);
+ STDMETHOD (WorkspaceClose) (THIS);
+ STDMETHOD (NewWorkspace) (THIS);
+ };
+ typedef CComObject < XApplicationEvents > XApplicationEventsObj;
+ XApplicationEventsObj *m_pApplicationEventsObj;
+
+ // This object handles events fired by the Application object
+ class XDebuggerEvents : public XEventHandler < IDebuggerEvents,
+ &IID_IDebuggerEvents,
+ &LIBID_VisVim,
+ XDebuggerEvents,
+ &CLSID_DebuggerEvents >
+ {
+ public:
+ // IDebuggerEvents method
+ STDMETHOD (BreakpointHit) (THIS_ IDispatch * pBreakpoint);
+ };
+ typedef CComObject < XDebuggerEvents > XDebuggerEventsObj;
+ XDebuggerEventsObj *m_pDebuggerEventsObj;
+
+ public:
+ // ICommands methods
+ STDMETHOD (VisVimDialog) (THIS);
+ STDMETHOD (VisVimEnable) (THIS);
+ STDMETHOD (VisVimDisable) (THIS);
+ STDMETHOD (VisVimToggle) (THIS);
+ STDMETHOD (VisVimLoad) (THIS);
+};
+
+typedef CComObject < CCommands > CCommandsObj;
+
+//{{AFX_INSERT_LOCATION}}
+
+#endif // !defined(AFX_COMMANDS_H__AC726717_2977_11D1_B2F3_006008040780__INCLUDED)
diff --git a/src/VisVim/DSAddIn.cpp b/src/VisVim/DSAddIn.cpp
new file mode 100644
index 0000000..b16361b
--- /dev/null
+++ b/src/VisVim/DSAddIn.cpp
@@ -0,0 +1,160 @@
+#include "stdafx.h"
+#include "VisVim.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 ());
+ *OnConnection = VARIANT_FALSE;
+
+ // Store info passed to us
+ IApplication *pApplication = NULL;
+ HRESULT hr;
+
+ hr = pApp->QueryInterface (IID_IApplication, (void **) &pApplication);
+ if (FAILED (hr))
+ {
+ ReportLastError (hr);
+ return E_UNEXPECTED;
+ }
+ if (pApplication == NULL)
+ {
+ ReportInternalError ("IApplication::QueryInterface");
+ return E_UNEXPECTED;
+ }
+
+ m_dwCookie = dwCookie;
+
+ // Create command dispatch, send info back to DevStudio
+ CCommandsObj::CreateInstance (&m_pCommands);
+ if (! m_pCommands)
+ {
+ ReportInternalError ("CCommandsObj::CreateInstance");
+ return E_UNEXPECTED;
+ }
+ m_pCommands->AddRef ();
+
+ // The QueryInterface above AddRef'd the Application object. It will
+ // be Release'd in CCommand's destructor.
+ m_pCommands->SetApplicationObject (pApplication);
+
+ hr = pApplication->SetAddInInfo ((long) AfxGetInstanceHandle (),
+ (LPDISPATCH) m_pCommands, IDR_TOOLBAR_MEDIUM, IDR_TOOLBAR_LARGE,
+ m_dwCookie);
+ if (FAILED (hr))
+ {
+ ReportLastError (hr);
+ return E_UNEXPECTED;
+ }
+
+ // Inform DevStudio of the commands we implement
+ if (! AddCommand (pApplication, "VisVimDialog", "VisVimDialogCmd",
+ IDS_CMD_DIALOG, 0, bFirstTime))
+ return E_UNEXPECTED;
+ if (! AddCommand (pApplication, "VisVimEnable", "VisVimEnableCmd",
+ IDS_CMD_ENABLE, 1, bFirstTime))
+ return E_UNEXPECTED;
+ if (! AddCommand (pApplication, "VisVimDisable", "VisVimDisableCmd",
+ IDS_CMD_DISABLE, 2, bFirstTime))
+ return E_UNEXPECTED;
+ if (! AddCommand (pApplication, "VisVimToggle", "VisVimToggleCmd",
+ IDS_CMD_TOGGLE, 3, bFirstTime))
+ return E_UNEXPECTED;
+ if (! AddCommand (pApplication, "VisVimLoad", "VisVimLoadCmd",
+ IDS_CMD_LOAD, 4, bFirstTime))
+ return E_UNEXPECTED;
+
+ *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->UnadviseFromEvents ();
+ m_pCommands->Release ();
+ m_pCommands = NULL;
+
+ return S_OK;
+}
+
+// Add a command to DevStudio
+// Creates a toolbar button for the command also.
+// 'MethodName' is the name of the method specified in the .odl file
+// 'StrResId' the resource id of the descriptive string
+// 'GlyphIndex' the image index into the command buttons bitmap
+// Return true on success
+//
+bool CDSAddIn::AddCommand (IApplication* pApp, char* MethodName, char* CmdName,
+ UINT StrResId, UINT GlyphIndex, VARIANT_BOOL bFirstTime)
+{
+ CString CmdString;
+ CString CmdText;
+
+ CmdText.LoadString (StrResId);
+ CmdString = CmdName;
+ CmdString += CmdText;
+
+ CComBSTR bszCmdString (CmdString);
+ CComBSTR bszMethod (MethodName);
+ CComBSTR bszCmdName (CmdName);
+
+ // (see stdafx.h for the definition of VERIFY_OK)
+
+ VARIANT_BOOL bRet;
+ VERIFY_OK (pApp->AddCommand (bszCmdString, bszMethod, GlyphIndex,
+ m_dwCookie, &bRet));
+ if (bRet == VARIANT_FALSE)
+ {
+ // AddCommand failed because a command with this name already exists.
+ ReportInternalError ("IApplication::AddCommand");
+ return FALSE;
+ }
+
+ // 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 (pApp->AddCommandBarButton (dsGlyph, bszCmdName, m_dwCookie));
+
+ return TRUE;
+}
+
+void ReportLastError (HRESULT Err)
+{
+ char *Buf = NULL;
+ char Msg[512];
+
+ FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL, Err,
+ MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
+ Buf, 400, NULL);
+ sprintf (Msg, "Unexpected error (Error code: %lx)\n%s", Err, Buf);
+
+ ::MessageBox (NULL, Msg, "VisVim", MB_OK | MB_ICONSTOP);
+ if (Buf)
+ LocalFree (Buf);
+}
+
+void ReportInternalError (char* Fct)
+{
+ char Msg[512];
+
+ sprintf (Msg, "Unexpected error\n%s failed", Fct);
+ ::MessageBox (NULL, Msg, "VisVim", MB_OK | MB_ICONSTOP);
+}
+
diff --git a/src/VisVim/DSAddIn.h b/src/VisVim/DSAddIn.h
new file mode 100644
index 0000000..7282872
--- /dev/null
+++ b/src/VisVim/DSAddIn.h
@@ -0,0 +1,53 @@
+// DSAddIn.h : header file
+//
+
+#if !defined(AFX_DSADDIN_H__AC726715_2977_11D1_B2F3_006008040780__INCLUDED_)
+#define AFX_DSADDIN_H__AC726715_2977_11D1_B2F3_006008040780__INCLUDED_
+
+#include "commands.h"
+
+// {4F9E01C0-406B-11d2-8006-00001C405077}
+DEFINE_GUID (CLSID_DSAddIn,
+ 0x4f9e01c0, 0x406b, 0x11d2, 0x80, 0x6, 0x0, 0x0, 0x1c, 0x40, 0x50, 0x77);
+
+/////////////////////////////////////////////////////////////////////////////
+// CDSAddIn
+
+class CDSAddIn :
+ public IDSAddIn,
+ public CComObjectRoot,
+ public CComCoClass < CDSAddIn,
+ &CLSID_DSAddIn >
+{
+ public:
+ DECLARE_REGISTRY (CDSAddIn, "VisVim.DSAddIn.1",
+ "VisVim Developer Studio Add-in", IDS_VISVIM_LONGNAME,
+ THREADFLAGS_BOTH)
+
+ CDSAddIn ()
+ {
+ }
+
+ BEGIN_COM_MAP (CDSAddIn)
+ COM_INTERFACE_ENTRY (IDSAddIn)
+ END_COM_MAP ()
+ DECLARE_NOT_AGGREGATABLE (CDSAddIn)
+
+ // IDSAddIns
+ public:
+ STDMETHOD (OnConnection) (THIS_ IApplication * pApp, VARIANT_BOOL bFirstTime,
+ long dwCookie, VARIANT_BOOL * OnConnection);
+ STDMETHOD (OnDisconnection) (THIS_ VARIANT_BOOL bLastTime);
+
+ protected:
+ bool AddCommand (IApplication* pApp, char* MethodName, char* CmdName,
+ UINT StrResId, UINT GlyphIndex, VARIANT_BOOL bFirstTime);
+
+ protected:
+ CCommandsObj * m_pCommands;
+ DWORD m_dwCookie;
+};
+
+//{{AFX_INSERT_LOCATION}}
+
+#endif // !defined(AFX_DSADDIN_H__AC726715_2977_11D1_B2F3_006008040780__INCLUDED)
diff --git a/src/VisVim/OleAut.cpp b/src/VisVim/OleAut.cpp
new file mode 100644
index 0000000..6902df9
--- /dev/null
+++ b/src/VisVim/OleAut.cpp
@@ -0,0 +1,781 @@
+//
+// Class for creating OLE automation controllers.
+//
+// CreateObject() creates an automation object
+// Invoke() will call a property or method of the automation object.
+// GetProperty() returns a property
+// SetProperty() changes a property
+// Method() invokes a method
+//
+// For example, the following VB code will control Microsoft Word:
+//
+// Private Sub Form_Load()
+// Dim wb As Object
+// Set wb = CreateObject("Word.Basic")
+// wb.AppShow
+// wb.FileNewDefault
+// wb.Insert "This is a test"
+// wb.FileSaveAs "c:\sample.doc)"
+// End Sub
+//
+// A C++ automation controller that does the same can be written as follows:
+// the helper functions:
+//
+// Void FormLoad ()
+// {
+// COleAutomationControl Aut;
+// Aut.CreateObject("Word.Basic");
+// Aut.Method ("AppShow");
+// Aut.Method ("FileNewDefault");
+// Aut.Method ("Insert", "s", (LPOLESTR) OLESTR ("This is a test"));
+// Aut.Method ("FileSaveAs", "s", OLESTR ("c:\\sample.doc"));
+// }
+//
+//
+
+#include "stdafx.h"
+#include <stdarg.h>
+#include "oleaut.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+static bool CountArgsInFormat (LPCTSTR Format, UINT* nArgs);
+static LPCTSTR GetNextVarType (LPCTSTR Format, VARTYPE* pVarType);
+
+
+COleAutomationControl::COleAutomationControl ()
+{
+ m_pDispatch = NULL;
+ m_hResult = NOERROR;
+ m_nErrArg = 0;
+ VariantInit (&m_VariantResult);
+}
+
+COleAutomationControl::~COleAutomationControl ()
+{
+ DeleteObject ();
+}
+
+void COleAutomationControl::DeleteObject ()
+{
+ if (m_pDispatch)
+ {
+ m_pDispatch->Release ();
+ m_pDispatch = NULL;
+ }
+}
+
+// Creates an instance of the Automation object and
+// obtains it's IDispatch interface.
+//
+// Parameters:
+// ProgId ProgID of Automation object
+//
+bool COleAutomationControl::CreateObject (char* ProgId)
+{
+ CLSID ClsId; // CLSID of automation object
+ LPUNKNOWN pUnknown = NULL; // IUnknown of automation object
+
+ // Retrieve CLSID from the progID that the user specified
+ LPOLESTR OleProgId = TO_OLE_STR (ProgId);
+ m_hResult = CLSIDFromProgID (OleProgId, &ClsId);
+ if (FAILED (m_hResult))
+ goto error;
+
+ // Create an instance of the automation object and ask for the
+ // IDispatch interface
+ m_hResult = CoCreateInstance (ClsId, NULL, CLSCTX_SERVER,
+ IID_IUnknown, (void**) &pUnknown);
+ if (FAILED (m_hResult))
+ goto error;
+
+ m_hResult = pUnknown->QueryInterface (IID_IDispatch, (void**) &m_pDispatch);
+ if (FAILED (m_hResult))
+ goto error;
+
+ pUnknown->Release ();
+ return true;
+
+error:
+ if (pUnknown)
+ pUnknown->Release ();
+ if (m_pDispatch)
+ m_pDispatch->Release ();
+ return false;
+}
+
+// Return the dispatch id of a named service
+// This id can be used in subsequent calls to GetProperty (), SetProperty () and
+// Method (). This is the preferred method when performance is important.
+//
+DISPID COleAutomationControl::GetDispatchId (char* Name)
+{
+ DISPID DispatchId;
+
+ ASSERT (m_pDispatch);
+
+ // Get DISPID of property/method
+ LPOLESTR OleName = TO_OLE_STR (Name);
+ m_hResult = m_pDispatch->GetIDsOfNames (IID_NULL, &OleName, 1,
+ LOCALE_USER_DEFAULT, &DispatchId);
+ if (FAILED (m_hResult))
+ return NULL;
+ return DispatchId;
+}
+
+// The following functions use these parameters:
+//
+// Parameters:
+//
+// Name Name of property or method.
+//
+// Format Format string that describes the variable list of parameters that
+// follows. The format string can contain the following characters.
+// & = mark the following format character as VT_BYREF
+// B = VT_BOOL
+// i = VT_I2
+// I = VT_I4
+// r = VT_R2
+// R = VT_R4
+// c = VT_CY
+// s = VT_BSTR (string pointer can be passed,
+// BSTR will be allocated by this function).
+// e = VT_ERROR
+// d = VT_DATE
+// v = VT_VARIANT. Use this to pass data types that are not described
+// in the format string. (For example SafeArrays).
+// D = VT_DISPATCH
+// U = VT_UNKNOWN
+//
+// ... Arguments of the property or method.
+// Arguments are described by Format.
+//
+
+bool COleAutomationControl::GetProperty (char* Name)
+{
+ return Invoke (DISPATCH_PROPERTYGET, Name, NULL, NULL);
+}
+
+bool COleAutomationControl::GetProperty (DISPID DispatchId)
+{
+ return Invoke (DISPATCH_PROPERTYGET, DispatchId, NULL, NULL);
+}
+
+bool COleAutomationControl::PutProperty (char* Name, LPCTSTR Format, ...)
+{
+ va_list ArgList;
+
+ va_start (ArgList, Format);
+ bool bRet = Invoke (DISPATCH_PROPERTYPUT, Name, Format, ArgList);
+ va_end (ArgList);
+ return bRet;
+}
+
+bool COleAutomationControl::PutProperty (DISPID DispatchId, LPCTSTR Format, ...)
+{
+ va_list ArgList;
+
+ va_start (ArgList, Format);
+ bool bRet = Invoke (DISPATCH_PROPERTYPUT, DispatchId, Format, ArgList);
+ va_end (ArgList);
+ return bRet;
+}
+
+bool COleAutomationControl::Method (char* Name, LPCTSTR Format, ...)
+{
+ va_list ArgList;
+
+ va_start (ArgList, Format);
+ bool bRet = Invoke (DISPATCH_METHOD, Name, Format, ArgList);
+ va_end (ArgList);
+ return bRet;
+}
+
+bool COleAutomationControl::Method (DISPID DispatchId, LPCTSTR Format, ...)
+{
+ va_list ArgList;
+
+ va_start (ArgList, Format);
+ bool bRet = Invoke (DISPATCH_METHOD, DispatchId, Format, ArgList);
+ va_end (ArgList);
+ return bRet;
+}
+
+bool COleAutomationControl::Invoke (WORD Flags, char* Name,
+ LPCTSTR Format, va_list ArgList)
+{
+ DISPID DispatchId = GetDispatchId (Name);
+ if (! DispatchId)
+ return false;
+ return Invoke (Flags, DispatchId, Format, ArgList);
+}
+
+bool COleAutomationControl::Invoke (WORD Flags, DISPID DispatchId,
+ LPCTSTR Format, va_list ArgList)
+{
+ UINT ArgCount = 0;
+ VARIANTARG* ArgVector = NULL;
+
+ ASSERT (m_pDispatch);
+
+ DISPPARAMS DispatchParams;
+ memset (&DispatchParams, 0, sizeof (DispatchParams));
+
+ // Determine number of arguments
+ if (Format)
+ CountArgsInFormat (Format, &ArgCount);
+
+ // Property puts have a named argument that represents the value that
+ // the property is being assigned.
+ DISPID DispIdNamed = DISPID_PROPERTYPUT;
+ if (Flags & DISPATCH_PROPERTYPUT)
+ {
+ if (ArgCount == 0)
+ {
+ m_hResult = ResultFromScode (E_INVALIDARG);
+ return false;
+ }
+ DispatchParams.cNamedArgs = 1;
+ DispatchParams.rgdispidNamedArgs = &DispIdNamed;
+ }
+
+ if (ArgCount)
+ {
+ // Allocate memory for all VARIANTARG parameters
+ ArgVector = (VARIANTARG*) CoTaskMemAlloc (
+ ArgCount * sizeof (VARIANTARG));
+ if (! ArgVector)
+ {
+ m_hResult = ResultFromScode (E_OUTOFMEMORY);
+ return false;
+ }
+ memset (ArgVector, 0, sizeof (VARIANTARG) * ArgCount);
+
+ // Get ready to walk vararg list
+ LPCTSTR s = Format;
+
+ VARIANTARG *p = ArgVector + ArgCount - 1; // Params go in opposite order
+
+ for (;;)
+ {
+ VariantInit (p);
+ if (! (s = GetNextVarType (s, &p->vt)))
+ break;
+
+ if (p < ArgVector)
+ {
+ m_hResult = ResultFromScode (E_INVALIDARG);
+ goto Cleanup;
+ }
+ switch (p->vt)
+ {
+ case VT_I2:
+ V_I2 (p) = va_arg (ArgList, short);
+ break;
+ case VT_I4:
+ V_I4 (p) = va_arg (ArgList, long);
+ break;
+ case VT_R4:
+ V_R4 (p) = va_arg (ArgList, float);
+ break;
+ case VT_DATE:
+ case VT_R8:
+ V_R8 (p) = va_arg (ArgList, double);
+ break;
+ case VT_CY:
+ V_CY (p) = va_arg (ArgList, CY);
+ break;
+ case VT_BSTR:
+ V_BSTR (p) = SysAllocString (va_arg (ArgList,
+ OLECHAR*));
+ if (! p->bstrVal)
+ {
+ m_hResult = ResultFromScode (E_OUTOFMEMORY);
+ p->vt = VT_EMPTY;
+ goto Cleanup;
+ }
+ break;
+ case VT_DISPATCH:
+ V_DISPATCH (p) = va_arg (ArgList, LPDISPATCH);
+ break;
+ case VT_ERROR:
+ V_ERROR (p) = va_arg (ArgList, SCODE);
+ break;
+ case VT_BOOL:
+ V_BOOL (p) = va_arg (ArgList, BOOL) ? -1 : 0;
+ break;
+ case VT_VARIANT:
+ *p = va_arg (ArgList, VARIANTARG);
+ break;
+ case VT_UNKNOWN:
+ V_UNKNOWN (p) = va_arg (ArgList, LPUNKNOWN);
+ break;
+
+ case VT_I2 | VT_BYREF:
+ V_I2REF (p) = va_arg (ArgList, short*);
+ break;
+ case VT_I4 | VT_BYREF:
+ V_I4REF (p) = va_arg (ArgList, long*);
+ break;
+ case VT_R4 | VT_BYREF:
+ V_R4REF (p) = va_arg (ArgList, float*);
+ break;
+ case VT_R8 | VT_BYREF:
+ V_R8REF (p) = va_arg (ArgList, double*);
+ break;
+ case VT_DATE | VT_BYREF:
+ V_DATEREF (p) = va_arg (ArgList, DATE*);
+ break;
+ case VT_CY | VT_BYREF:
+ V_CYREF (p) = va_arg (ArgList, CY*);
+ break;
+ case VT_BSTR | VT_BYREF:
+ V_BSTRREF (p) = va_arg (ArgList, BSTR*);
+ break;
+ case VT_DISPATCH | VT_BYREF:
+ V_DISPATCHREF (p) = va_arg (ArgList, LPDISPATCH*);
+ break;
+ case VT_ERROR | VT_BYREF:
+ V_ERRORREF (p) = va_arg (ArgList, SCODE*);
+ break;
+ case VT_BOOL | VT_BYREF:
+ {
+ BOOL* pBool = va_arg (ArgList, BOOL*);
+
+ *pBool = 0;
+ V_BOOLREF (p) = (VARIANT_BOOL*) pBool;
+ }
+ break;
+ case VT_VARIANT | VT_BYREF:
+ V_VARIANTREF (p) = va_arg (ArgList, VARIANTARG*);
+ break;
+ case VT_UNKNOWN | VT_BYREF:
+ V_UNKNOWNREF (p) = va_arg (ArgList, LPUNKNOWN*);
+ break;
+
+ default:
+ {
+ m_hResult = ResultFromScode (E_INVALIDARG);
+ goto Cleanup;
+ }
+ break;
+ }
+
+ --p; // Get ready to fill next argument
+ }
+ }
+
+ DispatchParams.cArgs = ArgCount;
+ DispatchParams.rgvarg = ArgVector;
+
+ // Initialize return variant, in case caller forgot. Caller can pass
+ // NULL if return value is not expected.
+ VariantInit (&m_VariantResult);
+
+ // Make the call
+ m_hResult = m_pDispatch->Invoke (DispatchId, IID_NULL, LOCALE_USER_DEFAULT,
+ Flags, &DispatchParams, &m_VariantResult,
+ &m_ExceptionInfo, &m_nErrArg);
+
+ Cleanup:
+ // Cleanup any arguments that need cleanup
+ if (ArgCount)
+ {
+ VARIANTARG* p = ArgVector;
+
+ while (ArgCount--)
+ {
+ switch (p->vt)
+ {
+ case VT_BSTR:
+ VariantClear (p);
+ break;
+ }
+ ++p;
+ }
+ CoTaskMemFree (ArgVector);
+ }
+
+ return FAILED (m_hResult) ? false : true;
+}
+
+#define CASE_SCODE(sc) \
+ case sc: \
+ lstrcpy((char*)ErrName, (char*)#sc); \
+ break;
+
+void COleAutomationControl::ErrDiag ()
+{
+ char ErrName[200];
+
+ SCODE sc = GetScode (m_hResult);
+ switch (sc)
+ {
+ // SCODE's defined in SCODE.H
+ CASE_SCODE (S_OK)
+ CASE_SCODE (S_FALSE)
+ CASE_SCODE (E_UNEXPECTED)
+ CASE_SCODE (E_OUTOFMEMORY)
+ CASE_SCODE (E_INVALIDARG)
+ CASE_SCODE (E_NOINTERFACE)
+ CASE_SCODE (E_POINTER)
+ CASE_SCODE (E_HANDLE)
+ CASE_SCODE (E_ABORT)
+ CASE_SCODE (E_FAIL)
+ CASE_SCODE (E_ACCESSDENIED)
+
+ // SCODE's defined in OLE2.H
+ CASE_SCODE (OLE_E_OLEVERB)
+ CASE_SCODE (OLE_E_ADVF)
+ CASE_SCODE (OLE_E_ENUM_NOMORE)
+ CASE_SCODE (OLE_E_ADVISENOTSUPPORTED)
+ CASE_SCODE (OLE_E_NOCONNECTION)
+ CASE_SCODE (OLE_E_NOTRUNNING)
+ CASE_SCODE (OLE_E_NOCACHE)
+ CASE_SCODE (OLE_E_BLANK)
+ CASE_SCODE (OLE_E_CLASSDIFF)
+ CASE_SCODE (OLE_E_CANT_GETMONIKER)
+ CASE_SCODE (OLE_E_CANT_BINDTOSOURCE)
+ CASE_SCODE (OLE_E_STATIC)
+ CASE_SCODE (OLE_E_PROMPTSAVECANCELLED)
+ CASE_SCODE (OLE_E_INVALIDRECT)
+ CASE_SCODE (OLE_E_WRONGCOMPOBJ)
+ CASE_SCODE (OLE_E_INVALIDHWND)
+ CASE_SCODE (OLE_E_NOT_INPLACEACTIVE)
+ CASE_SCODE (OLE_E_CANTCONVERT)
+ CASE_SCODE (OLE_E_NOSTORAGE)
+
+ CASE_SCODE (DV_E_FORMATETC)
+ CASE_SCODE (DV_E_DVTARGETDEVICE)
+ CASE_SCODE (DV_E_STGMEDIUM)
+ CASE_SCODE (DV_E_STATDATA)
+ CASE_SCODE (DV_E_LINDEX)
+ CASE_SCODE (DV_E_TYMED)
+ CASE_SCODE (DV_E_CLIPFORMAT)
+ CASE_SCODE (DV_E_DVASPECT)
+ CASE_SCODE (DV_E_DVTARGETDEVICE_SIZE)
+ CASE_SCODE (DV_E_NOIVIEWOBJECT)
+
+ CASE_SCODE (OLE_S_USEREG)
+ CASE_SCODE (OLE_S_STATIC)
+ CASE_SCODE (OLE_S_MAC_CLIPFORMAT)
+
+ CASE_SCODE (CONVERT10_E_OLESTREAM_GET)
+ CASE_SCODE (CONVERT10_E_OLESTREAM_PUT)
+ CASE_SCODE (CONVERT10_E_OLESTREAM_FMT)
+ CASE_SCODE (CONVERT10_E_OLESTREAM_BITMAP_TO_DIB)
+ CASE_SCODE (CONVERT10_E_STG_FMT)
+ CASE_SCODE (CONVERT10_E_STG_NO_STD_STREAM)
+ CASE_SCODE (CONVERT10_E_STG_DIB_TO_BITMAP)
+ CASE_SCODE (CONVERT10_S_NO_PRESENTATION)
+
+ CASE_SCODE (CLIPBRD_E_CANT_OPEN)
+ CASE_SCODE (CLIPBRD_E_CANT_EMPTY)
+ CASE_SCODE (CLIPBRD_E_CANT_SET)
+ CASE_SCODE (CLIPBRD_E_BAD_DATA)
+ CASE_SCODE (CLIPBRD_E_CANT_CLOSE)
+
+ CASE_SCODE (DRAGDROP_E_NOTREGISTERED)
+ CASE_SCODE (DRAGDROP_E_ALREADYREGISTERED)
+ CASE_SCODE (DRAGDROP_E_INVALIDHWND)
+ CASE_SCODE (DRAGDROP_S_DROP)
+ CASE_SCODE (DRAGDROP_S_CANCEL)
+ CASE_SCODE (DRAGDROP_S_USEDEFAULTCURSORS)
+
+ CASE_SCODE (OLEOBJ_E_NOVERBS)
+ CASE_SCODE (OLEOBJ_E_INVALIDVERB)
+ CASE_SCODE (OLEOBJ_S_INVALIDVERB)
+ CASE_SCODE (OLEOBJ_S_CANNOT_DOVERB_NOW)
+ CASE_SCODE (OLEOBJ_S_INVALIDHWND)
+ CASE_SCODE (INPLACE_E_NOTUNDOABLE)
+ CASE_SCODE (INPLACE_E_NOTOOLSPACE)
+ CASE_SCODE (INPLACE_S_TRUNCATED)
+
+ // SCODE's defined in COMPOBJ.H
+ CASE_SCODE (CO_E_NOTINITIALIZED)
+ CASE_SCODE (CO_E_ALREADYINITIALIZED)
+ CASE_SCODE (CO_E_CANTDETERMINECLASS)
+ CASE_SCODE (CO_E_CLASSSTRING)
+ CASE_SCODE (CO_E_IIDSTRING)
+ CASE_SCODE (CO_E_APPNOTFOUND)
+ CASE_SCODE (CO_E_APPSINGLEUSE)
+ CASE_SCODE (CO_E_ERRORINAPP)
+ CASE_SCODE (CO_E_DLLNOTFOUND)
+ CASE_SCODE (CO_E_ERRORINDLL)
+ CASE_SCODE (CO_E_WRONGOSFORAPP)
+ CASE_SCODE (CO_E_OBJNOTREG)
+ CASE_SCODE (CO_E_OBJISREG)
+ CASE_SCODE (CO_E_OBJNOTCONNECTED)
+ CASE_SCODE (CO_E_APPDIDNTREG)
+ CASE_SCODE (CLASS_E_NOAGGREGATION)
+ CASE_SCODE (CLASS_E_CLASSNOTAVAILABLE)
+ CASE_SCODE (REGDB_E_READREGDB)
+ CASE_SCODE (REGDB_E_WRITEREGDB)
+ CASE_SCODE (REGDB_E_KEYMISSING)
+ CASE_SCODE (REGDB_E_INVALIDVALUE)
+ CASE_SCODE (REGDB_E_CLASSNOTREG)
+ CASE_SCODE (REGDB_E_IIDNOTREG)
+ CASE_SCODE (RPC_E_CALL_REJECTED)
+ CASE_SCODE (RPC_E_CALL_CANCELED)
+ CASE_SCODE (RPC_E_CANTPOST_INSENDCALL)
+ CASE_SCODE (RPC_E_CANTCALLOUT_INASYNCCALL)
+ CASE_SCODE (RPC_E_CANTCALLOUT_INEXTERNALCALL)
+ CASE_SCODE (RPC_E_CONNECTION_TERMINATED)
+ CASE_SCODE (RPC_E_SERVER_DIED)
+ CASE_SCODE (RPC_E_CLIENT_DIED)
+ CASE_SCODE (RPC_E_INVALID_DATAPACKET)
+ CASE_SCODE (RPC_E_CANTTRANSMIT_CALL)
+ CASE_SCODE (RPC_E_CLIENT_CANTMARSHAL_DATA)
+ CASE_SCODE (RPC_E_CLIENT_CANTUNMARSHAL_DATA)
+ CASE_SCODE (RPC_E_SERVER_CANTMARSHAL_DATA)
+ CASE_SCODE (RPC_E_SERVER_CANTUNMARSHAL_DATA)
+ CASE_SCODE (RPC_E_INVALID_DATA)
+ CASE_SCODE (RPC_E_INVALID_PARAMETER)
+ CASE_SCODE (RPC_E_CANTCALLOUT_AGAIN)
+ CASE_SCODE (RPC_E_UNEXPECTED)
+
+ // SCODE's defined in DVOBJ.H
+ CASE_SCODE (DATA_S_SAMEFORMATETC)
+ CASE_SCODE (VIEW_E_DRAW)
+ CASE_SCODE (VIEW_S_ALREADY_FROZEN)
+ CASE_SCODE (CACHE_E_NOCACHE_UPDATED)
+ CASE_SCODE (CACHE_S_FORMATETC_NOTSUPPORTED)
+ CASE_SCODE (CACHE_S_SAMECACHE)
+ CASE_SCODE (CACHE_S_SOMECACHES_NOTUPDATED)
+
+ // SCODE's defined in STORAGE.H
+ CASE_SCODE (STG_E_INVALIDFUNCTION)
+ CASE_SCODE (STG_E_FILENOTFOUND)
+ CASE_SCODE (STG_E_PATHNOTFOUND)
+ CASE_SCODE (STG_E_TOOMANYOPENFILES)
+ CASE_SCODE (STG_E_ACCESSDENIED)
+ CASE_SCODE (STG_E_INVALIDHANDLE)
+ CASE_SCODE (STG_E_INSUFFICIENTMEMORY)
+ CASE_SCODE (STG_E_INVALIDPOINTER)
+ CASE_SCODE (STG_E_NOMOREFILES)
+ CASE_SCODE (STG_E_DISKISWRITEPROTECTED)
+ CASE_SCODE (STG_E_SEEKERROR)
+ CASE_SCODE (STG_E_WRITEFAULT)
+ CASE_SCODE (STG_E_READFAULT)
+ CASE_SCODE (STG_E_SHAREVIOLATION)
+ CASE_SCODE (STG_E_LOCKVIOLATION)
+ CASE_SCODE (STG_E_FILEALREADYEXISTS)
+ CASE_SCODE (STG_E_INVALIDPARAMETER)
+ CASE_SCODE (STG_E_MEDIUMFULL)
+ CASE_SCODE (STG_E_ABNORMALAPIEXIT)
+ CASE_SCODE (STG_E_INVALIDHEADER)
+ CASE_SCODE (STG_E_INVALIDNAME)
+ CASE_SCODE (STG_E_UNKNOWN)
+ CASE_SCODE (STG_E_UNIMPLEMENTEDFUNCTION)
+ CASE_SCODE (STG_E_INVALIDFLAG)
+ CASE_SCODE (STG_E_INUSE)
+ CASE_SCODE (STG_E_NOTCURRENT)
+ CASE_SCODE (STG_E_REVERTED)
+ CASE_SCODE (STG_E_CANTSAVE)
+ CASE_SCODE (STG_E_OLDFORMAT)
+ CASE_SCODE (STG_E_OLDDLL)
+ CASE_SCODE (STG_E_SHAREREQUIRED)
+ CASE_SCODE (STG_E_NOTFILEBASEDSTORAGE)
+ CASE_SCODE (STG_E_EXTANTMARSHALLINGS)
+ CASE_SCODE (STG_S_CONVERTED)
+
+ // SCODE's defined in STORAGE.H
+ CASE_SCODE (MK_E_CONNECTMANUALLY)
+ CASE_SCODE (MK_E_EXCEEDEDDEADLINE)
+ CASE_SCODE (MK_E_NEEDGENERIC)
+ CASE_SCODE (MK_E_UNAVAILABLE)
+ CASE_SCODE (MK_E_SYNTAX)
+ CASE_SCODE (MK_E_NOOBJECT)
+ CASE_SCODE (MK_E_INVALIDEXTENSION)
+ CASE_SCODE (MK_E_INTERMEDIATEINTERFACENOTSUPPORTED)
+ CASE_SCODE (MK_E_NOTBINDABLE)
+ CASE_SCODE (MK_E_NOTBOUND)
+ CASE_SCODE (MK_E_CANTOPENFILE)
+ CASE_SCODE (MK_E_MUSTBOTHERUSER)
+ CASE_SCODE (MK_E_NOINVERSE)
+ CASE_SCODE (MK_E_NOSTORAGE)
+ CASE_SCODE (MK_E_NOPREFIX)
+ CASE_SCODE (MK_S_REDUCED_TO_SELF)
+ CASE_SCODE (MK_S_ME)
+ CASE_SCODE (MK_S_HIM)
+ CASE_SCODE (MK_S_US)
+ CASE_SCODE (MK_S_MONIKERALREADYREGISTERED)
+
+ // SCODE's defined in DISPATCH.H
+ CASE_SCODE (DISP_E_UNKNOWNINTERFACE)
+ CASE_SCODE (DISP_E_MEMBERNOTFOUND)
+ CASE_SCODE (DISP_E_PARAMNOTFOUND)
+ CASE_SCODE (DISP_E_TYPEMISMATCH)
+ CASE_SCODE (DISP_E_UNKNOWNNAME)
+ CASE_SCODE (DISP_E_NONAMEDARGS)
+ CASE_SCODE (DISP_E_BADVARTYPE)
+ CASE_SCODE (DISP_E_EXCEPTION)
+ CASE_SCODE (DISP_E_OVERFLOW)
+ CASE_SCODE (DISP_E_BADINDEX)
+ CASE_SCODE (DISP_E_UNKNOWNLCID)
+ CASE_SCODE (DISP_E_ARRAYISLOCKED)
+ CASE_SCODE (DISP_E_BADPARAMCOUNT)
+ CASE_SCODE (DISP_E_PARAMNOTOPTIONAL)
+ CASE_SCODE (DISP_E_BADCALLEE)
+ CASE_SCODE (DISP_E_NOTACOLLECTION)
+
+ CASE_SCODE (TYPE_E_BUFFERTOOSMALL)
+ CASE_SCODE (TYPE_E_INVDATAREAD)
+ CASE_SCODE (TYPE_E_UNSUPFORMAT)
+ CASE_SCODE (TYPE_E_REGISTRYACCESS)
+ CASE_SCODE (TYPE_E_LIBNOTREGISTERED)
+ CASE_SCODE (TYPE_E_UNDEFINEDTYPE)
+ CASE_SCODE (TYPE_E_QUALIFIEDNAMEDISALLOWED)
+ CASE_SCODE (TYPE_E_INVALIDSTATE)
+ CASE_SCODE (TYPE_E_WRONGTYPEKIND)
+ CASE_SCODE (TYPE_E_ELEMENTNOTFOUND)
+ CASE_SCODE (TYPE_E_AMBIGUOUSNAME)
+ CASE_SCODE (TYPE_E_NAMECONFLICT)
+ CASE_SCODE (TYPE_E_UNKNOWNLCID)
+ CASE_SCODE (TYPE_E_DLLFUNCTIONNOTFOUND)
+ CASE_SCODE (TYPE_E_BADMODULEKIND)
+ CASE_SCODE (TYPE_E_SIZETOOBIG)
+ CASE_SCODE (TYPE_E_DUPLICATEID)
+ CASE_SCODE (TYPE_E_TYPEMISMATCH)
+ CASE_SCODE (TYPE_E_OUTOFBOUNDS)
+ CASE_SCODE (TYPE_E_IOERROR)
+ CASE_SCODE (TYPE_E_CANTCREATETMPFILE)
+ CASE_SCODE (TYPE_E_CANTLOADLIBRARY)
+ CASE_SCODE (TYPE_E_INCONSISTENTPROPFUNCS)
+ CASE_SCODE (TYPE_E_CIRCULARTYPE)
+
+ default:
+ lstrcpy (ErrName, "UNKNOWN SCODE");
+ }
+
+ char Buf[256];
+ sprintf (Buf, "An OLE error occurred:\r\nCode = %s\r\nResult = %lx.",
+ (char*) ErrName, m_hResult);
+ MessageBox (NULL, Buf, "OLE Error", MB_OK);
+}
+
+
+static bool CountArgsInFormat (LPCTSTR Format, UINT* pArgCount)
+{
+ *pArgCount = 0;
+
+ if (! Format)
+ return true;
+
+ while (*Format)
+ {
+ if (*Format == '&')
+ Format++;
+
+ switch (*Format)
+ {
+ case 'b':
+ case 'i':
+ case 'I':
+ case 'r':
+ case 'R':
+ case 'c':
+ case 's':
+ case 'e':
+ case 'd':
+ case 'v':
+ case 'D':
+ case 'U':
+ ++ (*pArgCount);
+ Format++;
+ break;
+ case '\0':
+ default:
+ return false;
+ }
+ }
+ return true;
+}
+
+static LPCTSTR GetNextVarType (LPCTSTR Format, VARTYPE* pVarType)
+{
+ *pVarType = 0;
+ if (*Format == '&')
+ {
+ *pVarType = VT_BYREF;
+ Format++;
+ if (!*Format)
+ return NULL;
+ }
+ switch (*Format)
+ {
+ case 'b':
+ *pVarType |= VT_BOOL;
+ break;
+ case 'i':
+ *pVarType |= VT_I2;
+ break;
+ case 'I':
+ *pVarType |= VT_I4;
+ break;
+ case 'r':
+ *pVarType |= VT_R4;
+ break;
+ case 'R':
+ *pVarType |= VT_R8;
+ break;
+ case 'c':
+ *pVarType |= VT_CY;
+ break;
+ case 's':
+ *pVarType |= VT_BSTR;
+ break;
+ case 'e':
+ *pVarType |= VT_ERROR;
+ break;
+ case 'd':
+ *pVarType |= VT_DATE;
+ break;
+ case 'v':
+ *pVarType |= VT_VARIANT;
+ break;
+ case 'U':
+ *pVarType |= VT_UNKNOWN;
+ break;
+ case 'D':
+ *pVarType |= VT_DISPATCH;
+ break;
+ case '\0':
+ return NULL; // End of Format string
+ default:
+ return NULL;
+ }
+ return ++Format;
+}
+
+#ifndef UNICODE
+char* ConvertToAnsi (OLECHAR* sUnicode)
+{
+ static char BufAscii[MAX_OLE_STR];
+ return ConvertToAnsiBuf (sUnicode, BufAscii);
+}
+
+char* ConvertToAnsiBuf (OLECHAR* sUnicode, char* BufAscii)
+{
+ WideCharToMultiByte (CP_ACP, 0, sUnicode, -1, BufAscii, MAX_OLE_STR, NULL, NULL);
+ return BufAscii;
+}
+
+OLECHAR* ConvertToUnicode (char* sAscii)
+{
+ static OLECHAR BufUnicode[MAX_OLE_STR];
+ return ConvertToUnicodeBuf (sAscii, BufUnicode);
+}
+
+OLECHAR* ConvertToUnicodeBuf (char* sAscii, OLECHAR* BufUnicode)
+{
+ MultiByteToWideChar (CP_ACP, 0, sAscii, -1, BufUnicode, MAX_OLE_STR);
+ return BufUnicode;
+}
+#endif
+
diff --git a/src/VisVim/OleAut.h b/src/VisVim/OleAut.h
new file mode 100644
index 0000000..37de807
--- /dev/null
+++ b/src/VisVim/OleAut.h
@@ -0,0 +1,73 @@
+#ifndef __OLEAUT_H__
+#define __OLEAUT_H__
+
+class COleAutomationControl : public CObject
+{
+ public:
+ COleAutomationControl ();
+ ~COleAutomationControl ();
+ bool CreateObject (char* ProgId);
+ DISPID GetDispatchId (char* Name);
+ bool GetProperty (char* Name);
+ bool GetProperty (DISPID DispatchId);
+ bool PutProperty (char* Name, LPCTSTR Format, ...);
+ bool PutProperty (DISPID DispatchId, LPCTSTR Format, ...);
+ bool Method (char* Name, LPCTSTR Format = NULL, ...);
+ bool Method (DISPID DispatchId, LPCTSTR Format = NULL, ...);
+ void DeleteObject ();
+ void ErrDiag ();
+ bool IsCreated ()
+ {
+ return m_pDispatch ? true : false;
+ }
+ bool IsAlive ();
+ HRESULT GetResult ()
+ {
+ return m_hResult;
+ }
+ UINT GetErrArgNr ()
+ {
+ return m_nErrArg;
+ }
+ EXCEPINFO* GetExceptionInfo ()
+ {
+ return &m_ExceptionInfo;
+ }
+ LPVARIANT GetResultVariant ()
+ {
+ return &m_VariantResult;
+ }
+
+ protected:
+ bool Invoke (WORD Flags, char* Name, LPCTSTR Format, va_list ArgList);
+ bool Invoke (WORD Flags, DISPID DispatchId, LPCTSTR Format, va_list ArgList);
+
+ protected:
+ IDispatch* m_pDispatch;
+ HRESULT m_hResult;
+ UINT m_nErrArg;
+ EXCEPINFO m_ExceptionInfo;
+ VARIANTARG m_VariantResult;
+};
+
+#ifdef UNICODE
+ #define FROM_OLE_STRING(str) str
+ #define FROM_OLE_STRING_BUF(str,buf) str
+ #define TO_OLE_STR(str) str
+ #define TO_OLE_STR_BUF(str,buf) str
+ #define MAX_OLE_STR 1
+#else
+ #define FROM_OLE_STR(str) ConvertToAnsi(str)
+ #define FROM_OLE_STR_BUF(str,buf) ConvertToAnsiBuf(str,buf)
+ char* ConvertToAnsi (OLECHAR* sUnicode);
+ char* ConvertToAnsiBuf (OLECHAR* sUnicode, char* Buf);
+ #define TO_OLE_STR(str) ConvertToUnicode(str)
+ #define TO_OLE_STR_BUF(str,buf) ConvertToUnicodeBuf(str,buf)
+ OLECHAR* ConvertToUnicode (char* sAscii);
+ OLECHAR* ConvertToUnicodeBuf (char* sAscii, OLECHAR* Buf);
+ // Maximum length of string that can be converted between Ansi & Unicode
+ #define MAX_OLE_STR 500
+#endif
+
+
+#endif // __OLEAUT_H__
diff --git a/src/VisVim/README_VisVim.txt b/src/VisVim/README_VisVim.txt
new file mode 100644
index 0000000..25b0fbd
--- /dev/null
+++ b/src/VisVim/README_VisVim.txt
@@ -0,0 +1,326 @@
+===============================
+Visual Studio - Vim Integration
+===============================
+
+Copyright (C) 1997 Heiko Erhardt
+
+VisVim is a Visual Studio Add-In that allows Vim to be integrated
+as the default text editor. It will be used instead of the Visual
+Studio built-in editor when you double-click on a file or press F4
+after compiling (it will go to the proper line in the Vim buffer).
+The file can be loaded exclusively by Vim or additionally to the
+builtin Visual Studio editor (this option can be set in the VisVim
+configuration dialog inside Visual Studio).
+Vim does not replace the Visual Studio editor, it still runs in its
+own window.
+
+VisVim is based upon VisEmacs by Christopher Payne
+(Copyright (C) Christopher Payne 1997).
+
+Author: Heiko Erhardt <heiko.erhardt@gmx.net>
+Based upon: VisEmacs by Christopher Payne <payneca@sagian.com>
+Version: 1.0
+Created: 23 Oct 1997
+Date: 23 Oct 1997
+
+VisVim was originally GNU GPL licensed, as stated below. On March 21 2012
+Heiko Erhardt declared this work to be relicensed under the Vim license, as
+stated in ../../runtime/doc/uganda.txt (or ":help uganda" in Vim).
+
+VisVim is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+VisVim 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 General Public License for more details.
+
+
+Requirements
+------------
+
+VisVim works with the *OLE-enabled* version of Vim version 5.0 and higher
+only!!! You must download the extra archive containing the OLE-enabled
+executable from your Vim download site. When building your own Vim
+executable, use the if_ole_vc.mak makefile (Vim 5.1 and higher).
+VisVim needs DevStudio 5.0 or higher. It does not work with DevStudio 4.2.
+
+
+Installation
+------------
+
+1) Close running instances of DevStudio.
+
+2) Copy VisVim.dll into a convenient directory like \vim,
+ \vim\lib, or \vim\addin
+
+3) Register the DLL using regsvr32.exe ... (Skip this on Windows 95/98)
+ Example:
+ > cd \vim\addin
+ > regsvr32 VisVim.dll
+ On NT, you should do this from an administrator account.
+ Before installing a new version of VisVim you should unregister
+ the old one using
+ > regsvr32 -unregister VisVim.dll
+ The batch files register.bat and unregister.bat can do that for you.
+
+3a) If you didn't do this yet: Register the OLE gvim:
+ > gvim -register
+
+4) Start Visual Studio and go to:
+ Tools
+ Customize...
+ Add-Ins and Macro Files
+
+5) Click on Browse, and point Visual Studio to your VisVim.dll file.
+
+6) Click the checkbox to indicate that you want to use the Add-In, and
+ Close the Customize dialog box.
+
+7) You should notice the VisVim Toolbar with the Vim Icon.
+ Click the first item of the toolbar to get to the options dialog.
+
+
+Compiling VisVim
+----------------
+
+Two Options:
+
+1) Load the VisVim.mak file as a Workspace in Visual Studio and compile
+
+2) Use the MSVC command line compiler:
+ vcvars32
+ nmake -f VisVim.mak
+
+
+Using VisVim
+------------
+
+The VisVim DLL exposes several functions to the user. These functions are
+accessible using the toolbar or by assigning hotkeys to them (see below).
+The following functions are visible on the toolbar (from left to right):
+
+1. VisVim settings dialog
+ The settings you adjust here will be saved in the registry and
+ will be reloaded on program startup.
+
+2. Enable Vim
+ Enables Vim as Visual Studio editor. Control will be switched to Vim when:
+ - Clicking a file in the file view
+ - Clicking a compiler error message line
+ - Using the 'File-Open' Dialog
+ - Showing the current source line when encountering a debugger breakpoint.
+ - Using File-New
+
+3. Disable Vim
+ The internal Visual Studio editor will be used to edit files.
+
+4. Toggle enable state
+ Toggles the enable state of VisVim. Use this function if you want to have
+ one button only to activate/deactivate Vim.
+
+5. Load current file in Vim
+ Loads the file shown in the internal editor into Vim. Use this function if
+ you want the internal editor to stay active and just edit one file in Vim.
+ This command works always whether Vim is enabled as default editor or not.
+
+You cannot use DevStudio's debugger commands from inside Vim, so you should
+disable Vim before running the debugger.
+
+You can customize the Vim toolbar itself or add the Vim buttons to other
+toolbars.
+To have fast access to the VisVim options dialog I suggest to create keyboard
+shortcuts:
+
+1) Choose
+ Tools
+ Customize...
+ Keyboard
+2) Choose Category:AddIns and Commands:VisVim.
+3) Choose 'Main' as editor, enter each hotkey and press the Assign button.
+ I suggest:
+ VisVimDialogCmd Alt+Shift+V
+ VisVimEnableCmd Alt+Shift+E
+ VisVimDisableCmd Alt+Shift+D
+ VisVimToggleCmd Alt+Shift+T
+ VisVimLoadCmd Alt+Shift+G
+4) Close the dialog
+
+Now a typical debugging example:
+
+Using "Alt+Shift+d" you turn off Vim before starting the debugger.
+After hitting the breakpoint you single step through your application
+using the internal source code editor and examine variables.
+When you stumble across the line with the null pointer
+assignment, just press "Alt+Shift+g", and correct the error in Vim.
+Save the file, press Alt+Tab to return to DevStudio and press F7 to compile.
+That's it.
+
+
+Troubleshooting
+---------------
+
+1. When opening a file in DevStudio the file is opened in the DevStudio
+ editor and immediately vanishes. No Vim shows up.
+ Cause: Probably you don't have the OLE-enabled Vim or you didn't
+ register it.
+ Explanation: VisVim is notified by DevStudio if an 'open document' event
+ occurs. It then closes the document in the internal editor
+ and tries to start Vim. If Vim isn't properly OLE-registered,
+ this won't work.
+ Workaround: Download and install the OLE-enable version of Vim and
+ execute "gvim -register".
+
+2. Sometimes when clicking on a file, the file won't be opened by Vim but
+ instead the Visual Studio editor comes up.
+ Cause: The file was already loaded by the DevStudio editor.
+ Explanation: VisVim works by hooks exposed by Visual Studio.
+ Most of the functionality works from the OpenDocument hook.
+ If a document is already loaded in the Visual Studio editor,
+ no 'open document' event will be generated when clicking the
+ file in the file list.
+ Workaround: Close the document in Visual Studio first.
+
+3. I can't get VisVim to work. Either the Vim toolbar does not appear at all
+ or weird crashes happen.
+ Cause: The Visual Studio installation is messed up.
+ Explanation: I can't give you one. Ask M$.
+ Workaround: Reinstall DevStudio (I know this is brute, but in some cases
+ it helped). There was one case where the service pack 1 had
+ to be installed, too.
+
+4. If an instance of Vim is already running, VisVim will use that instance
+ and not start a new one.
+ Cause: This is proper OLE behaviour
+ Explanation: Some call it a bug, some a feature. That's just the way OLE
+ works.
+
+5. When being in insert mode in Vim and selecting a file in Visual Studio,
+ the Vim command :e ... is inserted as text instead of being executed.
+ Cause: You probably know...
+ Explanation: The Vim OLE automation interface interprets the VisVim
+ commands as if they were typed in by the user.
+ So if you're in insert mode Vim considers it to be text.
+ I decided against sending an ESC before the command because
+ it may cause a beep or at least a screen flash when noeb is
+ set.
+ Workaround: Get used to press ESC before switching to DevStudio.
+
+6. I'm tired of VisVim but I can't get rid of it. I can't delete it in
+ Tools-Customize-Add-Ins.
+ Cause: You can't delete an item you once added to the add-ins
+ list box.
+ Explanation: M$ just didn't put a 'delete' button in the dialog box.
+ Unfortunately there is no DEL key accellerator as well...
+ Workaround: You can't kill it, but you can knock it out:
+ 1. Uncheck the check box in front of 'Vim Developer Studio
+ Add-in'.
+ 2. Close Visual Studio.
+ 3. Delete VisVim.dll or move it somewhere it can't be found.
+ 4. Run Visual Studio.
+ 5. Tools -> Customize ->Add-ins and Macro-Files.
+ 6. A message appears:
+ ".../VisVim.dll" "This add-in no longer exists. It will
+ no longer be displayed."
+ That's it!
+
+
+Change history
+--------------
+
+1.0a to 1.0
+-----------
+
+- All settings in the VisVim dialog are remembered between DevStudio sessions
+ by keeping them in the registry (HKEY_CURRENT_USER\Software\Vim\VisVim).
+- Added an option to do a :cd before opening the file (having a file opened
+ by clicking it but finding out to be still in C:\Windows\system when trying to
+ open another file by ":e" can be annoying). Change directory can be
+ done to the source file's directory or it's parent directory.
+- Added some explanations to the error message for the CO_E_CLASSSTRING error
+ ("Use OLE Vim and make sure to register...").
+
+1.0 to 1.1a
+-----------
+
+- The VisVim toolbar button now shows the new Vim icon instead of the old one.
+- Made some changes to the documentation, added the troubleshooting chapter
+ and ToDo list.
+- File-New-* now invokes Vim instead of the builtin editor if enabled.
+
+1.1 to 1.1b
+-----------
+
+- Extended the VisVim toolbar to have multiple buttons instead of one.
+- Moved the enable/disable commands from the settings dialog to the toolbar.
+- Added the toggle enable/disable command
+- Added the 'load current file' command.
+
+1.1b to 1.2
+-----------
+
+No new features, just some fine tuning:
+
+- Changed the GUID of the VisVim OLE interface to avoid conflicts with a
+ version of VisEmacs or VisVile on the same computer (Guy Gascoigne)
+- Fixed a bug caused by a bug in the Developer Studio add-in code generator
+ (Clark Morgan)
+- Fixed a memory leak (Clark Morgan)
+- Added an option in the VisVim dialog to prepend ESC before the first command
+ that is sent to Vim. This will avoid inserting the command as text when Vim
+ is still in insert mode.
+- An :update command is sent to Vim before any other command to update the
+ current file if it is modified, or else the following :cd or :e command will fail.
+
+1.2 to 1.3a
+-----------
+
+- Fixed a bug caused by a missing EnableModeless() function call in VimLoad().
+ This seems to reduce VisVim crashing DevStudio on some systems (it
+ occasionally still seems to happen, but it's more stable now).
+ (Vince Negri)
+- Added support for the new CTRL-\ CTRL-N command of Vim 5.4a.
+ This prevents Vim from beeping when a VisVim command is executed and Vim is
+ not in insert mode.
+
+
+ToDo List
+---------
+
+P1 is highest priority, P10 lowest
+
+P9 Switching to DevStudio using ALT-TAB may get annoying. Would be nice to
+ have the option to map ActivateApplication("Visual Studio") in Vim.
+ Vim DLLs would solve that problem.
+
+P8 Execute :tag command in Vim for word under cursor in DevStudio
+
+P7 Controlling the Visual Studio Debugger from inside Vim
+ See message above. Also a 'Debug' highlight group and a
+ command to highlight a certain line would be necessary.
+
+P6 Provide an option to open the current file in VisVim in
+ Visual Studio editor
+ Same as above message. A kind of two way OLE automation would have to be
+ established between VisVim and Vim. Also a 'Debug' highlight group and a
+ command to highlight a certain line would be necessary.
+
+
+Known Problems
+--------------
+
+- Occasional memory corruptions in DevStudio may appear on some systems.
+ Reinstalling DevStudio helped in some cases.
+ The cause of these crashes is unclear; there is no way to debug this.
+ Recompiling VisVim with DevStudio SP3 didn't help.
+ I assume it's a problem deep inside the DevStudio add-in OLE interfaces.
+ This will hopefully be fixed with DevStudio 6.
+
+
+Have fun!
+
+Heiko Erhardt
+heiko.erhardt@gmx.net
+
diff --git a/src/VisVim/Reg.cpp b/src/VisVim/Reg.cpp
new file mode 100644
index 0000000..b4378e5
--- /dev/null
+++ b/src/VisVim/Reg.cpp
@@ -0,0 +1,56 @@
+#include "stdafx.h"
+
+// Returns key for HKEY_CURRENT_USER\"Software"\Company\AppName
+// creating it if it doesn't exist
+// responsibility of the caller to call RegCloseKey() on the returned HKEY
+//
+HKEY GetAppKey (char* AppName)
+{
+ HKEY hAppKey = NULL;
+ HKEY hSoftKey = NULL;
+ if (RegOpenKeyEx (HKEY_CURRENT_USER, "Software", 0, KEY_WRITE | KEY_READ,
+ &hSoftKey) == ERROR_SUCCESS)
+ {
+ DWORD Dummy;
+ RegCreateKeyEx (hSoftKey, AppName, 0, REG_NONE,
+ REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_READ, NULL,
+ &hAppKey, &Dummy);
+ }
+ if (hSoftKey)
+ RegCloseKey (hSoftKey);
+
+ return hAppKey;
+}
+
+// Returns key for
+// HKEY_CURRENT_USER\"Software"\RegistryKey\AppName\Section
+// creating it if it doesn't exist.
+// responsibility of the caller to call RegCloseKey () on the returned HKEY
+//
+HKEY GetSectionKey (HKEY hAppKey, LPCTSTR Section)
+{
+ HKEY hSectionKey = NULL;
+ DWORD Dummy;
+ RegCreateKeyEx (hAppKey, Section, 0, REG_NONE,
+ REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL,
+ &hSectionKey, &Dummy);
+ return hSectionKey;
+}
+
+int GetRegistryInt (HKEY hSectionKey, LPCTSTR Entry, int Default)
+{
+ DWORD Value;
+ DWORD Type;
+ DWORD Count = sizeof (DWORD);
+ if (RegQueryValueEx (hSectionKey, (LPTSTR) Entry, NULL, &Type,
+ (LPBYTE) &Value, &Count) == ERROR_SUCCESS)
+ return Value;
+ return Default;
+}
+
+bool WriteRegistryInt (HKEY hSectionKey, char* Entry, int nValue)
+{
+ return RegSetValueEx (hSectionKey, Entry, NULL, REG_DWORD,
+ (LPBYTE) &nValue, sizeof (nValue)) == ERROR_SUCCESS;
+}
+
diff --git a/src/VisVim/Register.bat b/src/VisVim/Register.bat
new file mode 100644
index 0000000..baef50b
--- /dev/null
+++ b/src/VisVim/Register.bat
@@ -0,0 +1 @@
+regsvr32.exe visvim.dll
diff --git a/src/VisVim/Res/ToolbarL.bmp b/src/VisVim/Res/ToolbarL.bmp
new file mode 100644
index 0000000..e11c66f
--- /dev/null
+++ b/src/VisVim/Res/ToolbarL.bmp
Binary files differ
diff --git a/src/VisVim/Res/ToolbarM.bmp b/src/VisVim/Res/ToolbarM.bmp
new file mode 100644
index 0000000..22e15f4
--- /dev/null
+++ b/src/VisVim/Res/ToolbarM.bmp
Binary files differ
diff --git a/src/VisVim/Resource.h b/src/VisVim/Resource.h
new file mode 100644
index 0000000..1070091
--- /dev/null
+++ b/src/VisVim/Resource.h
@@ -0,0 +1,30 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by VisVim.rc
+//
+#define IDS_VISVIM_LONGNAME 1
+#define IDS_VISVIM_DESCRIPTION 2
+#define IDS_CMD_DIALOG 3
+#define IDS_CMD_ENABLE 4
+#define IDS_CMD_DISABLE 5
+#define IDS_CMD_TOGGLE 6
+#define IDS_CMD_LOAD 7
+#define IDR_TOOLBAR_MEDIUM 128
+#define IDR_TOOLBAR_LARGE 129
+#define IDD_ADDINMAIN 130
+#define IDC_DEVSTUDIO_EDITOR 1000
+#define IDC_CD_SOURCE_PATH 1001
+#define IDC_CD_SOURCE_PARENT 1002
+#define IDC_CD_NONE 1003
+#define IDC_NEW_TABS 1004
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 131
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1004
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/VisVim/StdAfx.cpp b/src/VisVim/StdAfx.cpp
new file mode 100644
index 0000000..f4f6eb5
--- /dev/null
+++ b/src/VisVim/StdAfx.cpp
@@ -0,0 +1,6 @@
+// Stdafx.cpp : source file that includes just the standard includes
+// VisEmacs.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+#include "atlimpl.cpp"
diff --git a/src/VisVim/StdAfx.h b/src/VisVim/StdAfx.h
new file mode 100644
index 0000000..10bfdc0
--- /dev/null
+++ b/src/VisVim/StdAfx.h
@@ -0,0 +1,73 @@
+// Stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__AC72670E_2977_11D1_B2F3_006008040780__INCLUDED_)
+#define AFX_STDAFX_H__AC72670E_2977_11D1_B2F3_006008040780__INCLUDED_
+
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxdisp.h>
+
+#include <atlbase.h>
+//You may derive a class from CComModule and use it if you want to override
+//something, but do not change the name of _Module
+extern CComModule _Module;
+
+#include <atlcom.h>
+
+// Developer Studio Object Model
+#include <ObjModel\addauto.h>
+#include <ObjModel\appdefs.h>
+#include <ObjModel\appauto.h>
+#include <ObjModel\blddefs.h>
+#include <ObjModel\bldauto.h>
+#include <ObjModel\textdefs.h>
+#include <ObjModel\textauto.h>
+#include <ObjModel\dbgdefs.h>
+#include <ObjModel\dbgauto.h>
+
+/////////////////////////////////////////////////////////////////////////////
+// Debugging support
+
+// Use VERIFY_OK around all calls to the Developer Studio objects which
+// you expect to return S_OK.
+// In DEBUG builds of your add-in, VERIFY_OK displays an ASSERT dialog box
+// if the expression returns an HRESULT other than S_OK. If the HRESULT
+// is a success code, the ASSERT box will display that HRESULT. If it
+// is a failure code, the ASSERT box will display that HRESULT plus the
+// error description string provided by the object which raised the error.
+// In RETAIL builds of your add-in, VERIFY_OK just evaluates the expression
+// and ignores the returned HRESULT.
+
+#ifdef _DEBUG
+
+void GetLastErrorDescription (CComBSTR & bstr); // Defined in VisVim.cpp
+#define VERIFY_OK(f) \
+ { \
+ HRESULT hr = (f); \
+ if (hr != S_OK) \
+ { \
+ if (FAILED(hr)) \
+ { \
+ CComBSTR bstr; \
+ GetLastErrorDescription(bstr); \
+ _RPTF2(_CRT_ASSERT, "Object call returned %lx\n\n%S", hr, (BSTR) bstr); \
+ } \
+ else \
+ _RPTF1(_CRT_ASSERT, "Object call returned %lx", hr); \
+ } \
+ }
+
+#else //_DEBUG
+
+#define VERIFY_OK(f) (f);
+
+#endif //_DEBUG
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__AC72670E_2977_11D1_B2F3_006008040780__INCLUDED)
diff --git a/src/VisVim/UnRegist.bat b/src/VisVim/UnRegist.bat
new file mode 100644
index 0000000..9ea105d
--- /dev/null
+++ b/src/VisVim/UnRegist.bat
@@ -0,0 +1 @@
+regsvr32.exe -unregister visvim.dll
diff --git a/src/VisVim/VisVim.cpp b/src/VisVim/VisVim.cpp
new file mode 100644
index 0000000..222925a
--- /dev/null
+++ b/src/VisVim/VisVim.cpp
@@ -0,0 +1,152 @@
+// VisVim.cpp : Defines the initialization routines for the DLL.
+//
+
+#include "stdafx.h"
+#include <initguid.h>
+#include "VisVim.h"
+#include "DSAddIn.h"
+#include "Commands.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+
+#endif
+
+CComModule _Module;
+
+BEGIN_OBJECT_MAP (ObjectMap)
+OBJECT_ENTRY (CLSID_DSAddIn, CDSAddIn)
+END_OBJECT_MAP ()
+
+class CVisVimApp : public CWinApp
+{
+ public:
+ CVisVimApp ();
+
+ //{{AFX_VIRTUAL(CVisVimApp)
+ public:
+ virtual BOOL InitInstance ();
+ virtual int ExitInstance ();
+ //}}AFX_VIRTUAL
+
+ //{{AFX_MSG(CVisVimApp)
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP ()
+};
+
+BEGIN_MESSAGE_MAP (CVisVimApp, CWinApp)
+//{{AFX_MSG_MAP(CVisVimApp)
+//}}AFX_MSG_MAP
+END_MESSAGE_MAP ()
+
+// The one and only CVisVimApp object
+CVisVimApp theApp;
+
+CVisVimApp::CVisVimApp ()
+{
+}
+
+BOOL CVisVimApp::InitInstance ()
+{
+ _Module.Init (ObjectMap, m_hInstance);
+ return CWinApp::InitInstance ();
+}
+
+int CVisVimApp::ExitInstance ()
+{
+ _Module.Term ();
+ return CWinApp::ExitInstance ();
+}
+
+// Special entry points required for inproc servers
+//
+
+STDAPI DllGetClassObject (REFCLSID rclsid, REFIID riid, LPVOID * ppv)
+{
+ AFX_MANAGE_STATE (AfxGetStaticModuleState ());
+ return _Module.GetClassObject (rclsid, riid, ppv);
+}
+
+STDAPI DllCanUnloadNow (void)
+{
+ AFX_MANAGE_STATE (AfxGetStaticModuleState ());
+ return (AfxDllCanUnloadNow () == S_OK && _Module.GetLockCount () == 0)
+ ? S_OK : S_FALSE;
+}
+
+// By exporting DllRegisterServer, you can use regsvr32.exe
+//
+STDAPI DllRegisterServer (void)
+{
+ AFX_MANAGE_STATE (AfxGetStaticModuleState ());
+ HRESULT hRes;
+
+ // Registers object, typelib and all interfaces in typelib
+ hRes = _Module.RegisterServer (TRUE);
+ if (FAILED (hRes))
+ // Hack: When this fails we might be a normal user, while the
+ // admin already registered the module. Returning S_OK then
+ // makes it work. When the module was never registered it
+ // will soon fail in another way.
+ // old code: return hRes;
+ return S_OK;
+
+ _ATL_OBJMAP_ENTRY *pEntry = _Module.m_pObjMap;
+ CRegKey key;
+ LONG lRes = key.Open (HKEY_CLASSES_ROOT, _T ("CLSID"));
+
+ if (lRes == ERROR_SUCCESS)
+ {
+ USES_CONVERSION;
+ LPOLESTR lpOleStr;
+
+ StringFromCLSID (*pEntry->pclsid, &lpOleStr);
+ LPTSTR lpsz = OLE2T (lpOleStr);
+
+ lRes = key.Open (key, lpsz);
+ if (lRes == ERROR_SUCCESS)
+ {
+ CString strDescription;
+
+ strDescription.LoadString (IDS_VISVIM_DESCRIPTION);
+ key.SetKeyValue (_T ("Description"), strDescription);
+ }
+ CoTaskMemFree (lpOleStr);
+ }
+
+ if (lRes != ERROR_SUCCESS)
+ hRes = HRESULT_FROM_WIN32 (lRes);
+
+ return hRes;
+
+}
+
+// DllUnregisterServer - Removes entries from the system registry
+//
+STDAPI DllUnregisterServer (void)
+{
+ AFX_MANAGE_STATE (AfxGetStaticModuleState ());
+
+ HRESULT hRes = S_OK;
+ _Module.UnregisterServer ();
+ return hRes;
+}
+
+
+// Debugging support
+
+// GetLastErrorDescription is used in the implementation of the VERIFY_OK
+// macro, defined in stdafx.h.
+
+#ifdef _DEBUG
+
+void GetLastErrorDescription (CComBSTR & bstr)
+{
+ CComPtr < IErrorInfo > pErrorInfo;
+ if (GetErrorInfo (0, &pErrorInfo) == S_OK)
+ pErrorInfo->GetDescription (&bstr);
+}
+
+#endif //_DEBUG
diff --git a/src/VisVim/VisVim.def b/src/VisVim/VisVim.def
new file mode 100644
index 0000000..023d478
--- /dev/null
+++ b/src/VisVim/VisVim.def
@@ -0,0 +1,11 @@
+; VisVim.def : Declares the module parameters for the DLL.
+
+LIBRARY "VISVIM"
+DESCRIPTION 'VISVIM Windows Dynamic Link Library'
+
+EXPORTS
+ ; Explicit exports can go here
+ DllCanUnloadNow PRIVATE
+ DllGetClassObject PRIVATE
+ DllRegisterServer PRIVATE
+ DllUnregisterServer PRIVATE
diff --git a/src/VisVim/VisVim.dll b/src/VisVim/VisVim.dll
new file mode 100644
index 0000000..017b417
--- /dev/null
+++ b/src/VisVim/VisVim.dll
Binary files differ
diff --git a/src/VisVim/VisVim.h b/src/VisVim/VisVim.h
new file mode 100644
index 0000000..7759778
--- /dev/null
+++ b/src/VisVim/VisVim.h
@@ -0,0 +1,33 @@
+// VisVIM.h : main header file for the VisVim DLL
+//
+
+#if !defined(AFX_VISVIM_H__AC72670B_2977_11D1_B2F3_006008040780__INCLUDED_)
+#define AFX_VISVIM_H__AC72670B_2977_11D1_B2F3_006008040780__INCLUDED_
+
+#ifndef __AFXWIN_H__
+#error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h" // Main symbols
+
+#include <ObjModel\addguid.h>
+#include <ObjModel\appguid.h>
+#include <ObjModel\bldguid.h>
+#include <ObjModel\textguid.h>
+#include <ObjModel\dbgguid.h>
+
+//
+// Prototypes
+//
+
+HKEY GetAppKey (char* AppName);
+HKEY GetSectionKey (HKEY hAppKey, LPCTSTR Section);
+int GetRegistryInt (HKEY hSectionKey, LPCTSTR Entry, int Default);
+bool WriteRegistryInt (HKEY hSectionKey, char* Entry, int nValue);
+void ReportLastError (HRESULT Err);
+void ReportInternalError (char* Fct);
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_VISVIM_H__AC72670B_2977_11D1_B2F3_006008040780__INCLUDED)
diff --git a/src/VisVim/VisVim.mak b/src/VisVim/VisVim.mak
new file mode 100644
index 0000000..30a9cf4
--- /dev/null
+++ b/src/VisVim/VisVim.mak
@@ -0,0 +1,205 @@
+# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00
+# ** DO NOT EDIT **
+#
+# When Who What
+# 1999-08-01 Anon Original VisVim.dsp
+# 2001-08-08 W.Briscoe Back-ported to a condensed VC4 Makefile
+# Reduced inter-dependency of Release and Debug builds.
+#
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+!IF "$(CFG)" == ""
+CFG=VisVim - Win32 Release
+!MESSAGE No configuration specified. Defaulting to VisVim - Win32 Release.
+!ENDIF
+
+!IF "$(CFG)" != "VisVim - Win32 Release" && "$(CFG)" != "VisVim - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE on this makefile
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "VisVim.mak" CFG="VisVim - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "VisVim - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "VisVim - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+DEL_TREE = rmdir /s /q
+!ELSE
+NULL=nul
+DEL_TREE = deltree /y
+!ENDIF
+# Begin Project
+# PROP Target_Last_Scanned "VisVim - Win32 Release"
+# PROP Use_MFC 2
+CPP=cl.exe
+RSC=rc.exe
+LINK32=link.exe
+
+!IF "$(CFG)" == "VisVim - Win32 Release"
+
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\Release"
+# PROP Intermediate_Dir ".\Release"
+# PROP Target_Dir ""
+OUTDIR=.\Release
+INTDIR=.\Release
+CPP_OBJS=.\Release/
+
+# ADD CPP /MD /O2 /D "NDEBUG" /I.\Release
+CPP_PROJ= /MD /O2 /D "NDEBUG" /I.\Release
+# ADD RSC /d "NDEBUG
+RSC_PROJ= /d "NDEBUG"
+# ADD LINK32 /pdb:none
+LINK32_FLAGS=/pdb:none
+
+!ELSEIF "$(CFG)" == "VisVim - Win32 Debug"
+
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".\Debug"
+# PROP Intermediate_Dir ".\Debug"
+# PROP Target_Dir ""
+OUTDIR=.\Debug
+INTDIR=.\Debug
+CPP_OBJS=.\Debug/
+
+# ADD CPP /MDd /Gm /Zi /Od /D "_DEBUG" /I.\Debug
+CPP_PROJ= /MDd /Gm /Zi /Od /D "_DEBUG" /I.\Debug /Fd"$(INTDIR)/"
+MTL_PROJ= /D "_DEBUG"
+# ADD RSC /d "_DEBUG
+RSC_PROJ= /d "_DEBUG"
+# ADD LINK32 /debug /pdbtype:sept /pdb:".\Debug/VisVim.pdb"
+LINK32_FLAGS=/debug /pdbtype:sept /pdb:"$(OUTDIR)/VisVim.pdb"
+
+!ENDIF
+
+# ADD CPP /nologo /W3 /GX /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /D "_USRDLL" /c
+CPP_PROJ=$(CPP_PROJ) /nologo /W3 /GX /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /D "_USRDLL" /c /Fo"$(INTDIR)/"
+# ADD RSC /l 0x409 /d "_AFXDLL"
+RSC_PROJ=$(RSC_PROJ) /l 0x409 /d "_AFXDLL" /fo"$(INTDIR)/VisVim.res"
+# ADD LINK32 /nologo /subsystem:windows /dll /machine:I386 /incremental:no
+LINK32_FLAGS=$(LINK32_FLAGS) /nologo /subsystem:windows /dll /machine:I386\
+ /incremental:no /def:".\VisVim.def"\
+ /out:"$(OUTDIR)/VisVim.dll" /implib:"$(OUTDIR)/VisVim.lib"
+
+ALL : "$(OUTDIR)\VisVim.dll"
+
+CLEAN :
+ -@if exist "$(INTDIR)/$(NULL)" $(DEL_TREE) "$(INTDIR)"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+LINK32_OBJS= \
+ "$(INTDIR)/VisVim.res" \
+ "$(INTDIR)/VisVim.obj" \
+ "$(INTDIR)/StdAfx.obj" \
+ "$(INTDIR)/Reg.obj" \
+ "$(INTDIR)/DSAddIn.obj" \
+ "$(INTDIR)/OleAut.obj" \
+ "$(INTDIR)/Commands.obj"
+
+"$(OUTDIR)\VisVim.dll" : "$(OUTDIR)" ".\VisVim.def" $(LINK32_OBJS)
+ $(LINK32) $(LINK32_FLAGS) $(LINK32_OBJS)
+
+{.}.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+{.}.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+# Begin Target
+
+# Name "VisVim - Win32 Release"
+# Name "VisVim - Win32 Debug"
+
+# Begin Source File
+
+SOURCE=.\VisVim.cpp
+
+"$(INTDIR)\VisVim.obj" : $(SOURCE) "$(INTDIR)"
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\VisVim.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\VisVim.odl
+
+!IF "$(CFG)" == "VisVim - Win32 Release"
+
+# PROP Ignore_Default_Tool 1
+# Begin Custom Build
+
+"$(INTDIR)\VisVim.tlb" : $(SOURCE) "$(INTDIR)"
+ midl /nologo /mktyplib203 /win32 /tlb VisVim.tlb /h VSVTypes.h .\VisVim.odl /out .\Release /D "NDEBUG"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "VisVim - Win32 Debug"
+
+# PROP Ignore_Default_Tool 1
+# Begin Custom Build
+
+"$(INTDIR)\VisVim.tlb" : $(SOURCE) "$(INTDIR)"
+ midl /nologo /mktyplib203 /win32 /tlb VisVim.tlb /h VSVTypes.h .\VisVim.odl /out .\Debug /D "_DEBUG"
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+
+"$(INTDIR)\StdAfx.obj" : $(SOURCE) "$(INTDIR)"
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\VisVim.rc
+
+"$(INTDIR)\VisVim.res" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\VisVim.tlb"
+ $(RSC) $(RSC_PROJ) /i "$(INTDIR)" $(SOURCE)
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Reg.cpp
+
+"$(INTDIR)\Reg.obj" : $(SOURCE) "$(INTDIR)"
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\DSAddIn.cpp
+
+"$(INTDIR)\DSAddIn.obj" : $(SOURCE) "$(INTDIR)"
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\OleAut.cpp
+
+"$(INTDIR)\OleAut.obj" : $(SOURCE) "$(INTDIR)"
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Commands.cpp
+
+"$(INTDIR)\Commands.obj" : $(SOURCE) "$(INTDIR)"
+
+# End Source File
+# End Target
+# End Project
diff --git a/src/VisVim/VisVim.odl b/src/VisVim/VisVim.odl
new file mode 100644
index 0000000..0491b8f
--- /dev/null
+++ b/src/VisVim/VisVim.odl
@@ -0,0 +1,61 @@
+// VisVim.odl : type library source for VisVim.dll
+
+// This file will be processed by the Make Type Library (mktyplib) tool to
+// produce the type library (VisVim.tlb).
+
+[ uuid(AC726707-2977-11D1-B2F3-006008040780), version(1.0),
+ helpstring ("VisVim Developer Studio Add-in") ]
+library VisVim
+{
+ importlib("stdole32.tlb");
+ importlib("devshl.dll");
+ importlib("ide\devdbg.pkg");
+
+
+ // Dual interface for CCommands
+ //
+ // All commands that your add-in adds to DevStudio
+ // must appear in this interface. You may use the
+ // ClassView to add methods to this interface, which
+ // will cause stub implementations of those methods to
+ // appear in your CCommands class.
+
+ [ uuid(AC726703-2977-11D1-B2F3-006008040780),
+ oleautomation,
+ dual
+ ]
+
+ interface ICommands : IDispatch
+ {
+ // methods
+ [id(1)]
+ HRESULT VisVimDialog();
+ HRESULT VisVimEnable();
+ HRESULT VisVimDisable();
+ HRESULT VisVimToggle();
+ HRESULT VisVimLoad();
+ };
+
+ // Class information for CCommands
+
+ [ uuid(AC726704-2977-11D1-B2F3-006008040780) ]
+ coclass Commands
+ {
+ [default] interface ICommands;
+ };
+
+ [ hidden, uuid(AC726705-2977-11D1-B2F3-006008040780) ]
+ coclass ApplicationEvents
+ {
+ [default] interface IApplicationEvents;
+ }
+
+ [ hidden, uuid(AC726706-2977-11D1-B2F3-006008040780) ]
+ coclass DebuggerEvents
+ {
+ [default] interface IDebuggerEvents;
+ }
+
+ //{{AFX_APPEND_ODL}}
+ //}}AFX_APPEND_ODL}}
+};
diff --git a/src/VisVim/VisVim.rc b/src/VisVim/VisVim.rc
new file mode 100644
index 0000000..cf74b29
--- /dev/null
+++ b/src/VisVim/VisVim.rc
@@ -0,0 +1,202 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Englisch (USA) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "#ifdef _WIN32\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#endif\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#endif\r\n"
+ "1 TYPELIB ""VisVim.tlb""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDR_TOOLBAR_MEDIUM BITMAP MOVEABLE PURE "res\\ToolbarM.bmp"
+IDR_TOOLBAR_LARGE BITMAP MOVEABLE PURE "res\\ToolbarL.bmp"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,1,0,1
+ PRODUCTVERSION 1,1,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "\0"
+ VALUE "FileDescription", "VisVim DLL\0"
+ VALUE "FileVersion", "1, 1, 0, 1\0"
+ VALUE "InternalName", "VisVim\0"
+ VALUE "LegalCopyright", "Copyright (C) 1998\0"
+ VALUE "OriginalFilename", "VisVim.DLL\0"
+ VALUE "ProductName", "VisVim Dynamic Link Library\0"
+ VALUE "ProductVersion", "1, 1, 0, 1\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ADDINMAIN DIALOG DISCARDABLE 0, 0, 178, 124
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Vim Add-In 1.4"
+FONT 8, "MS Sans Serif"
+BEGIN
+ CONTROL "&Open file in DevStudio editor simultaneously",
+ IDC_DEVSTUDIO_EDITOR,"Button",BS_AUTOCHECKBOX | WS_GROUP |
+ WS_TABSTOP,7,7,153,10
+ CONTROL "Open files in new tabs",
+ IDC_NEW_TABS,"Button",BS_AUTOCHECKBOX | WS_GROUP |
+ WS_TABSTOP,7,21,153,10
+ GROUPBOX "Current directory",IDC_STATIC,7,35,164,58,WS_GROUP
+ CONTROL "Set to &source file path",IDC_CD_SOURCE_PATH,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,17,49,85,10
+ CONTROL "Set to &parent directory of source file path",
+ IDC_CD_SOURCE_PARENT,"Button",BS_AUTORADIOBUTTON,17,63,
+ 143,10
+ CONTROL "Do &not change",IDC_CD_NONE,"Button",BS_AUTORADIOBUTTON,
+ 17,78,63,10
+ DEFPUSHBUTTON "&Ok",IDOK,7,102,74,14,WS_GROUP
+ PUSHBUTTON "&Cancel",IDCANCEL,97,102,74,14,WS_GROUP
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_ADDINMAIN, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 171
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 117
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_VISVIM_LONGNAME "Vim Developer Studio Add-In"
+ IDS_VISVIM_DESCRIPTION "Allows integration of Vim as the text editor in Developer Studio."
+ IDS_CMD_DIALOG "\nVim Add-In Dialog\nDisplays the options dialog box of the Vim Add-In\nVim Add-In Dialog"
+ IDS_CMD_ENABLE "\nEnable Vim Add-In\nEnables Vim as Visual Studio editor\nEnable Vim Add-In"
+ IDS_CMD_DISABLE "\nDisable Vim Add-In\nDisables Vim as Visual Studio editor\nDisable Vim Add-In"
+ IDS_CMD_TOGGLE "\nToggle Vim Add-In State\nToggles the enable state of the Vim Add-In\nToggle Vim Add-In State"
+ IDS_CMD_LOAD "\nVim Add-In Load Document\nLoads the current document in Vim\nVim Add-In Load Document"
+END
+
+#endif // Englisch (USA) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#endif
+#include "afxres.rc" // Standard components
+#endif
+1 TYPELIB "VisVim.tlb"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/src/VisVim/VsReadMe.txt b/src/VisVim/VsReadMe.txt
new file mode 100644
index 0000000..f480c6b
--- /dev/null
+++ b/src/VisVim/VsReadMe.txt
@@ -0,0 +1,91 @@
+========================================================================
+ DEVELOPER STUDIO ADD-IN : VisVim
+========================================================================
+
+
+The Add-in Wizard has created this VisVim DLL for you. This DLL not only
+demonstrates the basics of creating a Developer Studio add-in, but it is also
+a starting point for writing your own add-in.
+
+An add-in mainly does two things.
+ (1) It adds commands to Developer Studio, which can then be tied
+ to keystrokes or toolbar buttons by the user or programmatically
+ by the add-in.
+ (2) It responds to events fired by Developer Studio.
+In both cases, the add-in code has access to the full Developer Studio
+Automation Object Model, and may manipulate those objects to affect the
+behavior of Developer Studio.
+
+This file contains a summary of what you will find in each of the files that
+make up your VisVim DLL.
+
+
+VisVim.h
+ This is the main header file for the DLL. It declares the
+ CVisVimApp class.
+
+VisVim.cpp
+ This is the main DLL source file. It contains the class CVisVimApp.
+ It also contains the OLE entry points required of inproc servers.
+
+VisVim.odl
+ This file contains the Object Description Language source code for the
+ type library of your DLL.
+
+VisVim.rc
+ This is a listing of all of the Microsoft Windows resources that the
+ program uses. It includes the sample toolbar bitmap that is stored
+ in the RES subdirectory. This file can be directly edited in Microsoft
+ Developer Studio.
+
+res\VisVim.rc2
+ This file contains resources that are not edited by Microsoft
+ Developer Studio. You should place all resources not
+ editable by the resource editor in this file.
+
+VisVim.def
+ This file contains information about the DLL that must be
+ provided to run with Microsoft Windows. It defines parameters
+ such as the name and description of the DLL. It also exports
+ functions from the DLL.
+
+VisVim.clw
+ This file contains information used by ClassWizard to edit existing
+ classes or add new classes. ClassWizard also uses this file to store
+ information needed to create and edit message maps and dialog data
+ maps and to create prototype member functions.
+
+/////////////////////////////////////////////////////////////////////////////
+Add-in-specific files:
+
+DSAddIn.cpp, DSAddIn.h
+ These files contain the CDSAddIn class, which implements the
+ IDSAddIn interface. This interface contains handlers
+ for connecting and disconnecting the add-in.
+
+Commands.cpp, Commands.h
+ These files contain the CCommands class, which implements your
+ command dispatch interface. This interface contains one method
+ for each command you add to Developer Studio.
+ These files also contain stub implementations of handlers for all events
+ fired by the Developer Studio Application object.
+
+OleAut.cpp
+ These files contain a general OLE automation class used to communicate
+ with vim.
+
+Reg.cpp
+ These files contain functions to access the registry.
+
+
+/////////////////////////////////////////////////////////////////////////////
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+ These files are used to build a precompiled header (PCH) file
+ named VisVim.pch and a precompiled types file named StdAfx.obj.
+
+Resource.h
+ This is the standard header file, which defines new resource IDs.
+ Microsoft Developer Studio reads and updates this file.
+