diff options
Diffstat (limited to 'src/VisVim')
-rw-r--r-- | src/VisVim/Commands.cpp | 710 | ||||
-rw-r--r-- | src/VisVim/Commands.h | 127 | ||||
-rw-r--r-- | src/VisVim/DSAddIn.cpp | 160 | ||||
-rw-r--r-- | src/VisVim/DSAddIn.h | 53 | ||||
-rw-r--r-- | src/VisVim/OleAut.cpp | 781 | ||||
-rw-r--r-- | src/VisVim/OleAut.h | 73 | ||||
-rw-r--r-- | src/VisVim/README_VisVim.txt | 326 | ||||
-rw-r--r-- | src/VisVim/Reg.cpp | 56 | ||||
-rw-r--r-- | src/VisVim/Register.bat | 1 | ||||
-rw-r--r-- | src/VisVim/Res/ToolbarL.bmp | bin | 0 -> 2678 bytes | |||
-rw-r--r-- | src/VisVim/Res/ToolbarM.bmp | bin | 0 -> 758 bytes | |||
-rw-r--r-- | src/VisVim/Resource.h | 30 | ||||
-rw-r--r-- | src/VisVim/StdAfx.cpp | 6 | ||||
-rw-r--r-- | src/VisVim/StdAfx.h | 73 | ||||
-rw-r--r-- | src/VisVim/UnRegist.bat | 1 | ||||
-rw-r--r-- | src/VisVim/VisVim.cpp | 152 | ||||
-rw-r--r-- | src/VisVim/VisVim.def | 11 | ||||
-rw-r--r-- | src/VisVim/VisVim.dll | bin | 0 -> 49664 bytes | |||
-rw-r--r-- | src/VisVim/VisVim.h | 33 | ||||
-rw-r--r-- | src/VisVim/VisVim.mak | 205 | ||||
-rw-r--r-- | src/VisVim/VisVim.odl | 61 | ||||
-rw-r--r-- | src/VisVim/VisVim.rc | 202 | ||||
-rw-r--r-- | src/VisVim/VsReadMe.txt | 91 |
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 Binary files differnew file mode 100644 index 0000000..e11c66f --- /dev/null +++ b/src/VisVim/Res/ToolbarL.bmp diff --git a/src/VisVim/Res/ToolbarM.bmp b/src/VisVim/Res/ToolbarM.bmp Binary files differnew file mode 100644 index 0000000..22e15f4 --- /dev/null +++ b/src/VisVim/Res/ToolbarM.bmp 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 Binary files differnew file mode 100644 index 0000000..017b417 --- /dev/null +++ b/src/VisVim/VisVim.dll 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 ¬ 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. + |