0
0
mirror of https://github.com/vim/vim.git synced 2025-09-30 04:44:14 -04:00

updated for version 7.0002

This commit is contained in:
Bram Moolenaar
2004-06-24 15:53:16 +00:00
parent 69a7cb473c
commit f4b8e57ffd
39 changed files with 3963 additions and 2144 deletions

20
src/GvimExt/GvimExt.reg Normal file
View File

@@ -0,0 +1,20 @@
REGEDIT4
[HKEY_CLASSES_ROOT\CLSID\{51EEE242-AD87-11d3-9C1E-0090278BBD99}]
@="Vim Shell Extension"
[HKEY_CLASSES_ROOT\CLSID\{51EEE242-AD87-11d3-9C1E-0090278BBD99}\InProcServer32]
@="gvimext.dll"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\gvim]
@="{51EEE242-AD87-11d3-9C1E-0090278BBD99}"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved]
"{51EEE242-AD87-11d3-9C1E-0090278BBD99}"="Vim Shell Extension"
[HKEY_LOCAL_MACHINE\Software\Vim\Gvim]
"path"="gvim.exe"
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\Vim 7.0aa]
"DisplayName"="Vim 7.0aa: Edit with Vim popup menu entry"
"UninstallString"="uninstal.exe"

43
src/GvimExt/Make_bc5.mak Normal file
View File

@@ -0,0 +1,43 @@
### USEDLL no for statically linked version of run-time, yes for DLL runtime
### BOR path to root of Borland C install (c:\bc5)
### (requires cc3250.dll be available in %PATH%)
!if ("$(USEDLL)"=="")
USEDLL = no
!endif
### BOR: root of the BC installation
!if ("$(BOR)"=="")
BOR = c:\bc5
!endif
CC = $(BOR)\bin\Bcc32
BRC = $(BOR)\bin\brc32
LINK = $(BOR)\BIN\ILink32
INCLUDE = $(BOR)\include;.
LIB = $(BOR)\lib
!if ("$(USEDLL)"=="yes")
RT_DEF = -D_RTLDLL
RT_LIB = cw32i.lib
!else
RT_DEF =
RT_LIB = cw32.lib
!endif
all : gvimext.dll
gvimext.obj : gvimext.cpp gvimext.h
$(CC) -tWD -I$(INCLUDE) -c -DFEAT_GETTEXT $(RT_DEF) -w- gvimext.cpp
gvimext.res : gvimext.rc
$(BRC) -r gvimext.rc
gvimext.dll : gvimext.obj gvimext.res
$(LINK) -L$(LIB) -aa gvimext.obj, gvimext.dll, , c0d32.obj $(RT_LIB) import32.lib, gvimext.def, gvimext.res
clean :
-@del gvimext.obj
-@del gvimext.res
-@del gvimext.dll

63
src/GvimExt/Make_ming.mak Normal file
View File

@@ -0,0 +1,63 @@
# Project: gvimext
# Generates gvimext.dll with gcc.
# Can be used for Cygwin and MingW (MingW ignores -mno-cygwin)
#
# Originally, the DLL base address was fixed: -Wl,--image-base=0x1C000000
# Now it is allocated dymanically by the linker by evaluating all DLLs
# already loaded in memory. The binary image contains as well information
# for automatic pseudo-rebasing, if needed by the system. ALV 2004-02-29
# If cross-compiling set this to yes, else set it to no
CROSS = no
#CROSS = yes
# For the old MinGW 2.95 (the one you get e.g. with debian woody)
# set the following variable to yes and check if the executables are
# really named that way.
# If you have a newer MinGW or you are using cygwin set it to no and
# check also the executables
MINGWOLD = no
ifeq ($(CROSS),yes)
ifeq ($(MINGWOLD),yes)
CXX = i586-mingw32msvc-g++
CXXFLAGS := -O2 -mno-cygwin -fvtable-thunks
WINDRES = i586-mingw32msvc-windres
else
CXX = i386-mingw32msvc-g++
CXXFLAGS := -O2 -mno-cygwin
WINDRES = i386-mingw32msvc-windres
endif
else
CXX := g++.exe
WINDRES := windres.exe
CXXFLAGS := -O2 -mno-cygwin
endif
LIBS := -luuid
RES := gvimext.res
DEFFILE = gvimext_ming.def
OBJ := gvimext.o
DLL := gvimext.dll
.PHONY: all all-before all-after clean clean-custom
all: all-before $(DLL) all-after
$(DLL): $(OBJ) $(RES) $(DEFFILE)
$(CXX) -shared $(CXXFLAGS) -s -o $@ \
-Wl,--enable-auto-image-base \
-Wl,--enable-auto-import \
-Wl,--whole-archive \
$^ \
-Wl,--no-whole-archive \
$(LIBS)
gvimext.o: gvimext.cpp
$(CXX) $(CXXFLAGS) -DFEAT_GETTEXT -c $? -o $@
$(RES): gvimext_ming.rc
$(WINDRES) --input-format=rc --output-format=coff -DMING $? -o $@
clean: clean-custom
$(RM) $(OBJ) $(RES) $(DLL)

35
src/GvimExt/Makefile Normal file
View File

@@ -0,0 +1,35 @@
# Makefile for GvimExt, using MSVC
# Options:
# DEBUG=yes Build debug version (for VC7 and maybe later)
#
TARGETOS=BOTH
APPVER=4.0
!if "$(DEBUG)" != "yes"
NODEBUG = 1
!endif
!include <win32.mak>
all: gvimext.dll
gvimext.dll: gvimext.obj \
gvimext.res
$(implib) /NOLOGO -machine:$(CPU) -def:gvimext.def $** -out:gvimext.lib
$(link) $(dlllflags) -base:0x1C000000 -out:$*.dll $** $(olelibsdll) shell32.lib gvimext.lib comctl32.lib gvimext.exp
gvimext.obj: gvimext.h
.cpp.obj:
$(cc) $(cflags) -DFEAT_GETTEXT $(cvarsdll) $*.cpp
gvimext.res: gvimext.rc
$(rc) $(rcflags) $(rcvars) gvimext.rc
clean:
- if exist gvimext.dll del gvimext.dll
- if exist gvimext.lib del gvimext.lib
- if exist gvimext.exp del gvimext.exp
- if exist gvimext.obj del gvimext.obj
- if exist gvimext.res del gvimext.res

94
src/GvimExt/README.txt Normal file
View File

@@ -0,0 +1,94 @@
README.txt for the gvimext DLL.
Written by Tianmiao Hu. Edited by Bram Moolenaar.
INSTALLATION
To install the "Edit with Vim" popup menu entry, it is recommended to use the
"install.exe" program. It will ask you a few questions and install the needed
registry entries.
In special situations you might want to make changes by hand. Check these
items:
- The gvimext.dll, gvim.exe and uninstal.exe either need to be in the search
path, or you have to set the full path in the registry entries. You could
move the gvimext.dll to the "windows\system" or "windows\system32"
directory, where the other DLL files are.
- You can find the names of the used registry entries in the file
"GvimExt.reg". You can edit this file to add the paths. To install the
registry entries, right-click the gvimext.reg file and choose the "merge"
menu option.
- The registry key [HKEY_LOCAL_MACHINE\Software\Vim\Gvim] is used by the
gvimext.dll. The value "path" specifies the location of "gvim.exe". If
gvim.exe is in the search path, the path can be omitted. The value "lang"
can be used to set the language, for example "de" for German. If "lang" is
omitted, the language set for Windows will be used.
It is the preferred method to keep gvim.exe with the runtime files, so that
Vim will find them (also the translated menu items are there).
UNINSTALLATION
To uninstall the "Edit with Vim" popup menu entry, it is recommended to use
the "uninstal.exe" program.
In special situations you might want to uninstall by hand:
- Open the registry by running regedit.exe.
- Delete all the keys listed in GvimExt.reg, except this one:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved]
For this key, only delete one value:
"{51EEE242-AD87-11d3-9C1E-0090278BBD99}"="Vim Shell Extension"
- Delete the gvimext.dll, if you want. You might need to reboot the machine
in order to remove this file. A quick way is to log off and re-login.
Another method is by using the uninst.bat script:
uninst gvimext.inf
This batch file will remove all the registry keys from the system. Then you
can remove the gvimext.dll file.
Note: In order for this batch file to work, you must have two system files:
rundll32.exe and setupapi.dll. I believe you will have rundll32.exe in your
system. I know windows nt 4.0 with the service pack 4 has setupapi.dll. My
windows 95 has setupapi.dll. I find that the internet explorer 4.0 comes with
the setupapi.dll in file Ie4_5.cab.
If you do encounter problems running this script, then probably you need to
modify the uninst.bat to suit to your system. Basically, you must find out
where are the locations for your rundll32.exe and setupapi.dll files. In
windows nt, both files are under c:\winnt\system32 directory. In my windows 95
system, I got setupapi.dll at c:\windows\system and rundll32.exe at
c:\windows. So you might want to try something like:
rundll32.exe c:\windows\system\setupapi.dll,InstallHinfSection DefaultUninstall 128 %1
where %1 can be substitued by gvimext.inf
THE SOURCE CODE
I have provided the source code here in hope that gvim users around world can
further enhance this little dll. I believe the only thing you need to change
is gvimext.cpp file. The important two functions you need to look at are
QueryContextMenu and InvokeCommand. You can modify right-click menus in the
QueryContextMenu function and invoke gvim in the InvokeCommand function. Note
the selected files can be accessed from the DragQueryFile function. I am not
familiar with the invoking options for gvim. I believe there are some
improvements that can be made on that side.
I use MS Visual C++ 6.0's nmake to make the gvimext.dll. I don't have a
chance to try earlier versions of MSVC. The files that are required for build
are:
gvimext.cpp
gvimext.h
gvimext.def
gvimext.rc
resource.h
Makefile
To compile the DLL from the command line:
vcvars32
nmake -f Makefile
If you did something interesting to this dll, please let me know
@ tianmiao@acm.org.
Happy vimming!!!

979
src/GvimExt/gvimext.cpp Normal file
View File

@@ -0,0 +1,979 @@
/* vi:set ts=8 sts=4 sw=4:
*
* VIM - Vi IMproved gvimext by Tianmiao Hu
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
*/
/*
* gvimext is a DLL which is used for the "Edit with Vim" context menu
* extension. It implements a MS defined interface with the Shell.
*
* If you have any questions or any suggestions concerning gvimext, please
* contact Tianmiao Hu: tianmiao@acm.org.
*/
#include "gvimext.h"
#ifdef __BORLANDC__
# include <dir.h>
# ifndef _strnicmp
# define _strnicmp(a, b, c) strnicmp((a), (b), (c))
# endif
#else
static char *searchpath(char *name);
#endif
// Always get an error while putting the following stuff to the
// gvimext.h file as class protected variables, give up and
// declare them as global stuff
FORMATETC fmte = {CF_HDROP,
(DVTARGETDEVICE FAR *)NULL,
DVASPECT_CONTENT,
-1,
TYMED_HGLOBAL
};
STGMEDIUM medium;
HRESULT hres = 0;
UINT cbFiles = 0;
//
// Get the name of the Gvim executable to use, with the path.
// When "runtime" is non-zero, we were called to find the runtime directory.
// Returns the path in name[MAX_PATH]. It's empty when it fails.
//
static void
getGvimName(char *name, int runtime)
{
HKEY keyhandle;
DWORD hlen;
// Get the location of gvim from the registry.
name[0] = 0;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0,
KEY_READ, &keyhandle) == ERROR_SUCCESS)
{
hlen = MAX_PATH;
if (RegQueryValueEx(keyhandle, "path", 0, NULL, (BYTE *)name, &hlen)
!= ERROR_SUCCESS)
name[0] = 0;
else
name[hlen] = 0;
RegCloseKey(keyhandle);
}
// Registry didn't work, use the search path.
if (name[0] == 0)
strcpy(name, searchpath("gvim.exe"));
if (!runtime)
{
// Only when looking for the executable, not the runtime dir, we can
// search for the batch file or a name without a path.
if (name[0] == 0)
strcpy(name, searchpath("gvim.bat"));
if (name[0] == 0)
strcpy(name, "gvim"); // finds gvim.bat or gvim.exe
// avoid that Vim tries to expand wildcards in the file names
strcat(name, " --literal");
}
}
//
// Get the Vim runtime directory into buf[MAX_PATH].
// The result is empty when it failed.
// When it works, the path ends in a slash or backslash.
//
static void
getRuntimeDir(char *buf)
{
int idx;
getGvimName(buf, 1);
if (buf[0] != 0)
{
// When no path found, use the search path to expand it.
if (strchr(buf, '/') == NULL && strchr(buf, '\\') == NULL)
strcpy(buf, searchpath(buf));
// remove "gvim.exe" from the end
for (idx = strlen(buf) - 1; idx >= 0; idx--)
if (buf[idx] == '\\' || buf[idx] == '/')
{
buf[idx + 1] = 0;
break;
}
}
}
//
// GETTEXT: translated messages and menu entries
//
#ifndef FEAT_GETTEXT
# define _(x) x
#else
# define _(x) (*dyn_libintl_gettext)(x)
# define VIMPACKAGE "vim"
# ifndef GETTEXT_DLL
# define GETTEXT_DLL "libintl.dll"
# endif
// Dummy functions
static char *null_libintl_gettext(const char *);
static char *null_libintl_textdomain(const char *);
static char *null_libintl_bindtextdomain(const char *, const char *);
static int dyn_libintl_init(char *dir);
static void dyn_libintl_end(void);
static HINSTANCE hLibintlDLL = 0;
static char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext;
static char *(*dyn_libintl_textdomain)(const char *) = null_libintl_textdomain;
static char *(*dyn_libintl_bindtextdomain)(const char *, const char *)
= null_libintl_bindtextdomain;
//
// Attempt to load libintl.dll. If it doesn't work, use dummy functions.
// "dir" is the directory where the libintl.dll might be.
// Return 1 for success, 0 for failure.
//
static int
dyn_libintl_init(char *dir)
{
int i;
static struct
{
char *name;
FARPROC *ptr;
} libintl_entry[] =
{
{"gettext", (FARPROC*)&dyn_libintl_gettext},
{"textdomain", (FARPROC*)&dyn_libintl_textdomain},
{"bindtextdomain", (FARPROC*)&dyn_libintl_bindtextdomain},
{NULL, NULL}
};
// No need to initialize twice.
if (hLibintlDLL)
return 1;
// Load gettext library, first try the Vim runtime directory, then search
// the path.
strcat(dir, GETTEXT_DLL);
hLibintlDLL = LoadLibrary(dir);
if (!hLibintlDLL)
{
hLibintlDLL = LoadLibrary(GETTEXT_DLL);
if (!hLibintlDLL)
return 0;
}
// Get the addresses of the functions we need.
for (i = 0; libintl_entry[i].name != NULL
&& libintl_entry[i].ptr != NULL; ++i)
{
if ((*libintl_entry[i].ptr = GetProcAddress(hLibintlDLL,
libintl_entry[i].name)) == NULL)
{
dyn_libintl_end();
return 0;
}
}
return 1;
}
static void
dyn_libintl_end(void)
{
if (hLibintlDLL)
FreeLibrary(hLibintlDLL);
hLibintlDLL = NULL;
dyn_libintl_gettext = null_libintl_gettext;
dyn_libintl_textdomain = null_libintl_textdomain;
dyn_libintl_bindtextdomain = null_libintl_bindtextdomain;
}
static char *
null_libintl_gettext(const char *msgid)
{
return (char *)msgid;
}
static char *
null_libintl_bindtextdomain(const char *domainname, const char *dirname)
{
return NULL;
}
static char *
null_libintl_textdomain(const char* domainname)
{
return NULL;
}
//
// Setup for translating strings.
//
static void
dyn_gettext_load(void)
{
char szBuff[MAX_PATH];
char szLang[MAX_PATH];
DWORD len;
HKEY keyhandle;
int gotlang = 0;
strcpy(szLang, "LANG=");
// First try getting the language from the registry, this can be
// used to overrule the system language.
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0,
KEY_READ, &keyhandle) == ERROR_SUCCESS)
{
len = MAX_PATH;
if (RegQueryValueEx(keyhandle, "lang", 0, NULL, (BYTE*)szBuff, &len)
== ERROR_SUCCESS)
{
szBuff[len] = 0;
strcat(szLang, szBuff);
gotlang = 1;
}
RegCloseKey(keyhandle);
}
if (!gotlang && getenv("LANG") == NULL)
{
// Get the language from the system.
// Could use LOCALE_SISO639LANGNAME, but it's not in Win95.
// LOCALE_SABBREVLANGNAME gives us three letters, like "enu", we use
// only the first two.
len = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVLANGNAME,
(LPTSTR)szBuff, MAX_PATH);
if (len >= 2 && _strnicmp(szBuff, "en", 2) != 0)
{
// There are a few exceptions (probably more)
if (_strnicmp(szBuff, "cht", 3) == 0
|| _strnicmp(szBuff, "zht", 3) == 0)
strcpy(szBuff, "zh_TW");
else if (_strnicmp(szBuff, "chs", 3) == 0
|| _strnicmp(szBuff, "zhc", 3) == 0)
strcpy(szBuff, "zh_CN");
else if (_strnicmp(szBuff, "jp", 2) == 0)
strcpy(szBuff, "ja");
else
szBuff[2] = 0; // truncate to two-letter code
strcat(szLang, szBuff);
gotlang = 1;
}
}
if (gotlang)
putenv(szLang);
// Try to locate the runtime files. The path is used to find libintl.dll
// and the vim.mo files.
getRuntimeDir(szBuff);
if (szBuff[0] != 0)
{
len = strlen(szBuff);
if (dyn_libintl_init(szBuff))
{
strcpy(szBuff + len, "lang");
(*dyn_libintl_bindtextdomain)(VIMPACKAGE, szBuff);
(*dyn_libintl_textdomain)(VIMPACKAGE);
}
}
}
static void
dyn_gettext_free(void)
{
dyn_libintl_end();
}
#endif // FEAT_GETTEXT
//
// Global variables
//
UINT g_cRefThisDll = 0; // Reference count of this DLL.
HINSTANCE g_hmodThisDll = NULL; // Handle to this DLL itself.
//---------------------------------------------------------------------------
// DllMain
//---------------------------------------------------------------------------
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
// Extension DLL one-time initialization
g_hmodThisDll = hInstance;
break;
case DLL_PROCESS_DETACH:
break;
}
return 1; // ok
}
static void
inc_cRefThisDLL()
{
#ifdef FEAT_GETTEXT
if (g_cRefThisDll == 0)
dyn_gettext_load();
#endif
InterlockedIncrement((LPLONG)&g_cRefThisDll);
}
static void
dec_cRefThisDLL()
{
#ifdef FEAT_GETTEXT
if (InterlockedDecrement((LPLONG)&g_cRefThisDll) == 0)
dyn_gettext_free();
#else
InterlockedDecrement((LPLONG)&g_cRefThisDll);
#endif
}
//---------------------------------------------------------------------------
// DllCanUnloadNow
//---------------------------------------------------------------------------
STDAPI DllCanUnloadNow(void)
{
return (g_cRefThisDll == 0 ? S_OK : S_FALSE);
}
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut)
{
*ppvOut = NULL;
if (IsEqualIID(rclsid, CLSID_ShellExtension))
{
CShellExtClassFactory *pcf = new CShellExtClassFactory;
return pcf->QueryInterface(riid, ppvOut);
}
return CLASS_E_CLASSNOTAVAILABLE;
}
CShellExtClassFactory::CShellExtClassFactory()
{
m_cRef = 0L;
inc_cRefThisDLL();
}
CShellExtClassFactory::~CShellExtClassFactory()
{
dec_cRefThisDLL();
}
STDMETHODIMP CShellExtClassFactory::QueryInterface(REFIID riid,
LPVOID FAR *ppv)
{
*ppv = NULL;
// Any interface on this object is the object pointer
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
{
*ppv = (LPCLASSFACTORY)this;
AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CShellExtClassFactory::AddRef()
{
return InterlockedIncrement((LPLONG)&m_cRef);
}
STDMETHODIMP_(ULONG) CShellExtClassFactory::Release()
{
if (InterlockedDecrement((LPLONG)&m_cRef))
return m_cRef;
delete this;
return 0L;
}
STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
REFIID riid,
LPVOID *ppvObj)
{
*ppvObj = NULL;
// Shell extensions typically don't support aggregation (inheritance)
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
// Create the main shell extension object. The shell will then call
// QueryInterface with IID_IShellExtInit--this is how shell extensions are
// initialized.
LPCSHELLEXT pShellExt = new CShellExt(); //Create the CShellExt object
if (NULL == pShellExt)
return E_OUTOFMEMORY;
return pShellExt->QueryInterface(riid, ppvObj);
}
STDMETHODIMP CShellExtClassFactory::LockServer(BOOL fLock)
{
return NOERROR;
}
// *********************** CShellExt *************************
CShellExt::CShellExt()
{
m_cRef = 0L;
m_pDataObj = NULL;
inc_cRefThisDLL();
}
CShellExt::~CShellExt()
{
if (m_pDataObj)
m_pDataObj->Release();
dec_cRefThisDLL();
}
STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, IID_IShellExtInit) || IsEqualIID(riid, IID_IUnknown))
{
*ppv = (LPSHELLEXTINIT)this;
}
else if (IsEqualIID(riid, IID_IContextMenu))
{
*ppv = (LPCONTEXTMENU)this;
}
if (*ppv)
{
AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CShellExt::AddRef()
{
return InterlockedIncrement((LPLONG)&m_cRef);
}
STDMETHODIMP_(ULONG) CShellExt::Release()
{
if (InterlockedDecrement((LPLONG)&m_cRef))
return m_cRef;
delete this;
return 0L;
}
//
// FUNCTION: CShellExt::Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY)
//
// PURPOSE: Called by the shell when initializing a context menu or property
// sheet extension.
//
// PARAMETERS:
// pIDFolder - Specifies the parent folder
// pDataObj - Spefifies the set of items selected in that folder.
// hRegKey - Specifies the type of the focused item in the selection.
//
// RETURN VALUE:
//
// NOERROR in all cases.
//
// COMMENTS: Note that at the time this function is called, we don't know
// (or care) what type of shell extension is being initialized.
// It could be a context menu or a property sheet.
//
STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
LPDATAOBJECT pDataObj,
HKEY hRegKey)
{
// Initialize can be called more than once
if (m_pDataObj)
m_pDataObj->Release();
// duplicate the object pointer and registry handle
if (pDataObj)
{
m_pDataObj = pDataObj;
pDataObj->AddRef();
}
return NOERROR;
}
//
// FUNCTION: CShellExt::QueryContextMenu(HMENU, UINT, UINT, UINT, UINT)
//
// PURPOSE: Called by the shell just before the context menu is displayed.
// This is where you add your specific menu items.
//
// PARAMETERS:
// hMenu - Handle to the context menu
// indexMenu - Index of where to begin inserting menu items
// idCmdFirst - Lowest value for new menu ID's
// idCmtLast - Highest value for new menu ID's
// uFlags - Specifies the context of the menu event
//
// RETURN VALUE:
//
//
// COMMENTS:
//
STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags)
{
UINT idCmd = idCmdFirst;
hres = m_pDataObj->GetData(&fmte, &medium);
if (medium.hGlobal)
cbFiles = DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, 0, 0);
// InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL);
// Initialize m_cntOfHWnd to 0
m_cntOfHWnd = 0;
// Retieve all the vim instances
EnumWindows(EnumWindowsProc, (LPARAM)this);
if (cbFiles > 1)
{
InsertMenu(hMenu,
indexMenu++,
MF_STRING|MF_BYPOSITION,
idCmd++,
_("Edit with &multiple Vims"));
InsertMenu(hMenu,
indexMenu++,
MF_STRING|MF_BYPOSITION,
idCmd++,
_("Edit with single &Vim"));
if (cbFiles <= 4)
{
// Can edit up to 4 files in diff mode
InsertMenu(hMenu,
indexMenu++,
MF_STRING|MF_BYPOSITION,
idCmd++,
_("&Diff with Vim"));
m_edit_existing_off = 3;
}
else
m_edit_existing_off = 2;
}
else
{
InsertMenu(hMenu,
indexMenu++,
MF_STRING|MF_BYPOSITION,
idCmd++,
_("Edit with &Vim"));
m_edit_existing_off = 1;
}
// Now display all the vim instances
for (int i = 0; i < m_cntOfHWnd; i++)
{
char title[MAX_PATH];
char temp[MAX_PATH];
// Obtain window title, continue if can not
if (GetWindowText(m_hWnd[i], title, MAX_PATH - 1) == 0)
continue;
// Truncate the title before the path, keep the file name
char *pos = strchr(title, '(');
if (pos != NULL)
{
if (pos > title && pos[-1] == ' ')
--pos;
*pos = 0;
}
// Now concatenate
strncpy(temp, _("Edit with existing Vim - &"), MAX_PATH - 1);
strncat(temp, title, MAX_PATH - 1);
InsertMenu(hMenu,
indexMenu++,
MF_STRING|MF_BYPOSITION,
idCmd++,
temp);
}
// InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL);
// Must return number of menu items we added.
return ResultFromShort(idCmd-idCmdFirst);
}
//
// FUNCTION: CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO)
//
// PURPOSE: Called by the shell after the user has selected on of the
// menu items that was added in QueryContextMenu().
//
// PARAMETERS:
// lpcmi - Pointer to an CMINVOKECOMMANDINFO structure
//
// RETURN VALUE:
//
//
// COMMENTS:
//
STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
{
HRESULT hr = E_INVALIDARG;
// If HIWORD(lpcmi->lpVerb) then we have been called programmatically
// and lpVerb is a command that should be invoked. Otherwise, the shell
// has called us, and LOWORD(lpcmi->lpVerb) is the menu ID the user has
// selected. Actually, it's (menu ID - idCmdFirst) from QueryContextMenu().
if (!HIWORD(lpcmi->lpVerb))
{
UINT idCmd = LOWORD(lpcmi->lpVerb);
if (idCmd >= m_edit_existing_off)
{
// Existing with vim instance
hr = PushToWindow(lpcmi->hwnd,
lpcmi->lpDirectory,
lpcmi->lpVerb,
lpcmi->lpParameters,
lpcmi->nShow,
idCmd - m_edit_existing_off);
}
else
{
switch (idCmd)
{
case 0:
hr = InvokeGvim(lpcmi->hwnd,
lpcmi->lpDirectory,
lpcmi->lpVerb,
lpcmi->lpParameters,
lpcmi->nShow);
break;
case 1:
hr = InvokeSingleGvim(lpcmi->hwnd,
lpcmi->lpDirectory,
lpcmi->lpVerb,
lpcmi->lpParameters,
lpcmi->nShow,
0);
break;
case 2:
hr = InvokeSingleGvim(lpcmi->hwnd,
lpcmi->lpDirectory,
lpcmi->lpVerb,
lpcmi->lpParameters,
lpcmi->nShow,
1);
break;
}
}
}
return hr;
}
STDMETHODIMP CShellExt::PushToWindow(HWND hParent,
LPCSTR pszWorkingDir,
LPCSTR pszCmd,
LPCSTR pszParam,
int iShowCmd,
int idHWnd)
{
HWND hWnd = m_hWnd[idHWnd];
// Show and bring vim instance to foreground
if (IsIconic(hWnd) != 0)
ShowWindow(hWnd, SW_RESTORE);
else
ShowWindow(hWnd, SW_SHOW);
SetForegroundWindow(hWnd);
// Post the selected files to the vim instance
PostMessage(hWnd, WM_DROPFILES, (WPARAM)medium.hGlobal, 0);
return NOERROR;
}
STDMETHODIMP CShellExt::GetCommandString(UINT idCmd,
UINT uFlags,
UINT FAR *reserved,
LPSTR pszName,
UINT cchMax)
{
if (uFlags == GCS_HELPTEXT && cchMax > 35)
lstrcpy(pszName, _("Edits the selected file(s) with Vim"));
return NOERROR;
}
BOOL CALLBACK CShellExt::EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
char temp[MAX_PATH];
// First do a bunch of check
// No invisible window
if (!IsWindowVisible(hWnd)) return TRUE;
// No child window ???
// if (GetParent(hWnd)) return TRUE;
// Class name should be Vim, if failed to get class name, return
if (GetClassName(hWnd, temp, sizeof(temp)) == 0)
return TRUE;
// Compare class name to that of vim, if not, return
if (_strnicmp(temp, "vim", sizeof("vim")) != 0)
return TRUE;
// First check if the number of vim instance exceeds MAX_HWND
CShellExt *cs = (CShellExt*) lParam;
if (cs->m_cntOfHWnd >= MAX_HWND) return TRUE;
// Now we get the vim window, put it into some kind of array
cs->m_hWnd[cs->m_cntOfHWnd] = hWnd;
cs->m_cntOfHWnd ++;
return TRUE; // continue enumeration (otherwise this would be false)
}
#ifdef WIN32
// This symbol is not defined in older versions of the SDK or Visual C++.
#ifndef VER_PLATFORM_WIN32_WINDOWS
# define VER_PLATFORM_WIN32_WINDOWS 1
#endif
static DWORD g_PlatformId;
//
// Set g_PlatformId to VER_PLATFORM_WIN32_NT (NT) or
// VER_PLATFORM_WIN32_WINDOWS (Win95).
//
static void
PlatformId(void)
{
static int done = FALSE;
if (!done)
{
OSVERSIONINFO ovi;
ovi.dwOSVersionInfoSize = sizeof(ovi);
GetVersionEx(&ovi);
g_PlatformId = ovi.dwPlatformId;
done = TRUE;
}
}
# ifndef __BORLANDC__
static char *
searchpath(char *name)
{
static char widename[2 * MAX_PATH];
static char location[2 * MAX_PATH + 2];
// There appears to be a bug in FindExecutableA() on Windows NT.
// Use FindExecutableW() instead...
PlatformId();
if (g_PlatformId == VER_PLATFORM_WIN32_NT)
{
MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)name, -1,
(LPWSTR)widename, MAX_PATH);
if (FindExecutableW((LPCWSTR)widename, (LPCWSTR)"",
(LPWSTR)location) > (HINSTANCE)32)
{
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)location, -1,
(LPSTR)widename, 2 * MAX_PATH, NULL, NULL);
return widename;
}
}
else
{
if (FindExecutableA((LPCTSTR)name, (LPCTSTR)"",
(LPTSTR)location) > (HINSTANCE)32)
return location;
}
return "";
}
# endif
#endif
STDMETHODIMP CShellExt::InvokeGvim(HWND hParent,
LPCSTR pszWorkingDir,
LPCSTR pszCmd,
LPCSTR pszParam,
int iShowCmd)
{
char m_szFileUserClickedOn[MAX_PATH];
char cmdStr[MAX_PATH];
UINT i;
for (i = 0; i < cbFiles; i++)
{
DragQueryFile((HDROP)medium.hGlobal,
i,
m_szFileUserClickedOn,
sizeof(m_szFileUserClickedOn));
getGvimName(cmdStr, 0);
strcat(cmdStr, " \"");
if ((strlen(cmdStr) + strlen(m_szFileUserClickedOn) + 2) < MAX_PATH)
{
strcat(cmdStr, m_szFileUserClickedOn);
strcat(cmdStr, "\"");
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
// Start the child process.
if (!CreateProcess(NULL, // No module name (use command line).
cmdStr, // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi) // Pointer to PROCESS_INFORMATION structure.
)
{
MessageBox(
hParent,
_("Error creating process: Check if gvim is in your path!"),
_("gvimext.dll error"),
MB_OK);
}
else
{
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
}
else
{
MessageBox(
hParent,
_("Path length too long!"),
_("gvimext.dll error"),
MB_OK);
}
}
return NOERROR;
}
STDMETHODIMP CShellExt::InvokeSingleGvim(HWND hParent,
LPCSTR pszWorkingDir,
LPCSTR pszCmd,
LPCSTR pszParam,
int iShowCmd,
int useDiff)
{
char m_szFileUserClickedOn[MAX_PATH];
char *cmdStr;
size_t cmdlen;
size_t len;
UINT i;
cmdlen = MAX_PATH;
cmdStr = (char *)malloc(cmdlen);
getGvimName(cmdStr, 0);
if (useDiff)
strcat(cmdStr, " -d");
for (i = 0; i < cbFiles; i++)
{
DragQueryFile((HDROP)medium.hGlobal,
i,
m_szFileUserClickedOn,
sizeof(m_szFileUserClickedOn));
len = strlen(cmdStr) + strlen(m_szFileUserClickedOn) + 4;
if (len > cmdlen)
{
cmdlen = len + MAX_PATH;
cmdStr = (char *)realloc(cmdStr, cmdlen);
}
strcat(cmdStr, " \"");
strcat(cmdStr, m_szFileUserClickedOn);
strcat(cmdStr, "\"");
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
// Start the child process.
if (!CreateProcess(NULL, // No module name (use command line).
cmdStr, // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi) // Pointer to PROCESS_INFORMATION structure.
)
{
MessageBox(
hParent,
_("Error creating process: Check if gvim is in your path!"),
_("gvimext.dll error"),
MB_OK);
}
else
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
free(cmdStr);
return NOERROR;
}

8
src/GvimExt/gvimext.def Normal file
View File

@@ -0,0 +1,8 @@
;gvimdef.def : Declares the module parameters for the DLL.
LIBRARY gvimext
DESCRIPTION 'Vim Shell Extension'
EXPORTS
DllCanUnloadNow private
DllGetClassObject private

164
src/GvimExt/gvimext.h Normal file
View File

@@ -0,0 +1,164 @@
/* vi:set ts=8 sts=4 sw=4:
*
* VIM - Vi IMproved gvimext by Tianmiao Hu
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
*/
/*
* If you have any questions or any suggestions concerning gvimext, please
* contact Tianmiao Hu: tianmiao@acm.org.
*/
#if !defined(AFX_STDAFX_H__3389658B_AD83_11D3_9C1E_0090278BBD99__INCLUDED_)
#define AFX_STDAFX_H__3389658B_AD83_11D3_9C1E_0090278BBD99__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Insert your headers here
// #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
//--------------------------------------------------------------
// common user interface routines
//
//
//--------------------------------------------------------------
#ifndef STRICT
#define STRICT
#endif
#define INC_OLE2 // WIN32, get ole2 from windows.h
#include <windows.h>
#include <windowsx.h>
#include <shlobj.h>
#define ResultFromShort(i) ResultFromScode(MAKE_SCODE(SEVERITY_SUCCESS, 0, (USHORT)(i)))
// Initialize GUIDs (should be done only and at-least once per DLL/EXE)
//
#pragma data_seg(".text")
#define INITGUID
#include <initguid.h>
#include <shlguid.h>
//
// The class ID of this Shell extension class.
//
// class id: {51EEE242-AD87-11d3-9C1E-0090278BBD99}
//
//
// NOTE!!! If you use this shell extension as a starting point,
// you MUST change the GUID below. Simply run UUIDGEN.EXE
// to generate a new GUID.
//
// {51EEE242-AD87-11d3-9C1E-0090278BBD99}
// static const GUID <<name>> =
// { 0x51eee242, 0xad87, 0x11d3, { 0x9c, 0x1e, 0x0, 0x90, 0x27, 0x8b, 0xbd, 0x99 } };
//
//
// {51EEE242-AD87-11d3-9C1E-0090278BBD99}
// IMPLEMENT_OLECREATE(<<class>>, <<external_name>>,
// 0x51eee242, 0xad87, 0x11d3, 0x9c, 0x1e, 0x0, 0x90, 0x27, 0x8b, 0xbd, 0x99);
//
// {51EEE242-AD87-11d3-9C1E-0090278BBD99} -- this is the registry format
DEFINE_GUID(CLSID_ShellExtension, 0x51eee242, 0xad87, 0x11d3, 0x9c, 0x1e, 0x0, 0x90, 0x27, 0x8b, 0xbd, 0x99);
// this class factory object creates context menu handlers for windows 32 shell
class CShellExtClassFactory : public IClassFactory
{
protected:
ULONG m_cRef;
public:
CShellExtClassFactory();
~CShellExtClassFactory();
//IUnknown members
STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
//IClassFactory members
STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR *);
STDMETHODIMP LockServer(BOOL);
};
typedef CShellExtClassFactory *LPCSHELLEXTCLASSFACTORY;
#define MAX_HWND 100
// this is the actual OLE Shell context menu handler
class CShellExt : public IContextMenu,
IShellExtInit
{
protected:
ULONG m_cRef;
LPDATAOBJECT m_pDataObj;
UINT m_edit_existing_off;
// For some reason, this callback must be static
static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam);
STDMETHODIMP PushToWindow(HWND hParent,
LPCSTR pszWorkingDir,
LPCSTR pszCmd,
LPCSTR pszParam,
int iShowCmd,
int idHWnd);
STDMETHODIMP InvokeGvim(HWND hParent,
LPCSTR pszWorkingDir,
LPCSTR pszCmd,
LPCSTR pszParam,
int iShowCmd);
STDMETHODIMP InvokeSingleGvim(HWND hParent,
LPCSTR pszWorkingDir,
LPCSTR pszCmd,
LPCSTR pszParam,
int iShowCmd,
int useDiff);
public:
int m_cntOfHWnd;
HWND m_hWnd[MAX_HWND];
CShellExt();
~CShellExt();
//IUnknown members
STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
//IShell members
STDMETHODIMP QueryContextMenu(HMENU hMenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags);
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
STDMETHODIMP GetCommandString(UINT idCmd,
UINT uFlags,
UINT FAR *reserved,
LPSTR pszName,
UINT cchMax);
//IShellExtInit methods
STDMETHODIMP Initialize(LPCITEMIDLIST pIDFolder,
LPDATAOBJECT pDataObj,
HKEY hKeyID);
};
typedef CShellExt *LPCSHELLEXT;
#pragma data_seg()
#endif

22
src/GvimExt/gvimext.inf Normal file
View File

@@ -0,0 +1,22 @@
[Version]
Signature="$Windows NT$""
Provider="Tianmiao"
[Manufacture]
[DefaultInstall]
AddReg=ThisDll.Add.Reg
[DefaultUninstall]
DelReg=ThisDLL.Add.Reg
[ThisDll.Add.Reg]
HKCR,CLSID\{51EEE242-AD87-11d3-9C1E-0090278BBD99}
HKCR,CLSID\{51EEE242-AD87-11d3-9C1E-0090278BBD99}\InProcServer32
HKCR,*\shellex\ContextMenuHandlers\gvim
HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved",{51EEE242-AD87-11d3-9C1E-0090278BBD99}
HKLM,Software\Vim\Gvim
HKLM,"Software\Microsoft\Windows\CurrentVersion\Uninstall\Vim 6.0"
[Strings]
ThisDll="gvimext.dll"

111
src/GvimExt/gvimext.rc Normal file
View File

@@ -0,0 +1,111 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#ifndef __BORLANDC__
# include "afxres.h"
#endif
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x3L
#else
FILEFLAGS 0x2L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "Developed using COM architecture!\0"
VALUE "CompanyName", "Tianmiao Hu's Developer Studio\0"
VALUE "FileDescription", "A small project for the context menu of gvim!\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "gvim right-click menu extension\0"
VALUE "LegalCopyright", "Copyright <20> 1999 Tianmiao Hu\0"
VALUE "LegalTrademarks", "Tianmiao Hu's Gvim Context Menu Extension\0"
VALUE "OriginalFilename", "gvimext.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "Tianmiao Hu's gvimext context menu extension\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
#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
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,10 @@
;gvimdef_ming.def : Declares the module parameters for the DLL.
;The mingw environment doesn't know anything about private declarations
;Hence this is the same file as gvimext.def with private removed
LIBRARY gvimext
DESCRIPTION 'Vim Shell Extension build with MinGW'
EXPORTS
DllCanUnloadNow = DllCanUnloadNow@0
DllGetClassObject = DllGetClassObject@12

View File

@@ -0,0 +1,45 @@
#include <windows.h>
#define xstr(x) str(x)
#define str(x) #x
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x3L
#else
FILEFLAGS 0x2L
#endif
FILEOS 0x4L
FILETYPE VFT_DLL
FILESUBTYPE 0x0L
{
BLOCK "StringFileInfo"
{
BLOCK "040904b0"
{
VALUE "Comments", "Developed using COM architecture!\0"
VALUE "CompanyName", "Tianmiao Hu's Developer Studio\0"
VALUE "FileDescription", "A small project for the context menu of gvim!\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "gvim right-click menu extension\0"
VALUE "LegalCopyright", "Copyright <20> 1999 Tianmiao Hu\0"
VALUE "LegalTrademarks", "Tianmiao Hu's Gvim Context Menu Extension\0"
VALUE "OriginalFilename", "gvimext.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "Tianmiao Hu's gvimext context menu extension\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
#if defined(__GNUC__)
VALUE "SpecialBuild", "Build With " "MingW " xstr(__GNUC__) "." xstr(__GNUC_MINOR__) "." xstr(__GNUC_PATCHLEVEL__) " on " __DATE__ " " __TIME__ "\0"
#else
VALUE "SpecialBuild", "Unknown compiler\0"
#endif
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x409, 1200
}
}

15
src/GvimExt/resource.h Normal file
View File

@@ -0,0 +1,15 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by gvimext.rc
//
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

1
src/GvimExt/uninst.bat Normal file
View File

@@ -0,0 +1 @@
rundll32.exe setupapi,InstallHinfSection DefaultUninstall 128 %1