summaryrefslogtreecommitdiff
path: root/uvim/src/GvimExt/gvimext.cpp
diff options
context:
space:
mode:
authorMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-03 22:21:25 +0300
committerMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-04 00:23:03 +0300
commit2eae5db069dc171f74cd863487655f6a88e5384d (patch)
tree2d9d05e09978a2a44acbfbb8d651f240df3ca052 /uvim/src/GvimExt/gvimext.cpp
parent473d922faed49241a5d29d9e37dc4819cd512006 (diff)
downloadProject-Tick-2eae5db069dc171f74cd863487655f6a88e5384d.tar.gz
Project-Tick-2eae5db069dc171f74cd863487655f6a88e5384d.zip
NOISSUE rebrand vim to MNV's not Vim
Signed-off-by: Mehmet Samet Duman <yongdohyun@projecttick.org>
Diffstat (limited to 'uvim/src/GvimExt/gvimext.cpp')
-rw-r--r--uvim/src/GvimExt/gvimext.cpp1065
1 files changed, 0 insertions, 1065 deletions
diff --git a/uvim/src/GvimExt/gvimext.cpp b/uvim/src/GvimExt/gvimext.cpp
deleted file mode 100644
index f98423c15f..0000000000
--- a/uvim/src/GvimExt/gvimext.cpp
+++ /dev/null
@@ -1,1065 +0,0 @@
-/* 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"
-
-static char *searchpath(char *name);
-
-// 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;
-
-/* The buffers size used to be MAX_PATH (260 bytes), but that's not always
- * enough */
-#define BUFSIZE 1100
-
-// The "Edit with Vim" shell extension provides these choices when
-// a new instance of Gvim is selected:
-// - use tabpages
-// - enable diff mode
-// - none of the above
-#define EDIT_WITH_VIM_USE_TABPAGES (2)
-#define EDIT_WITH_VIM_IN_DIFF_MODE (1)
-#define EDIT_WITH_VIM_NO_OPTIONS (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[BUFSIZE]. 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. Try
- // HKEY_CURRENT_USER first, then fall back to HKEY_LOCAL_MACHINE if
- // not found.
- name[0] = 0;
- if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Vim\\Gvim", 0,
- KEY_READ, &keyhandle) == ERROR_SUCCESS)
- {
- hlen = BUFSIZE;
- if (RegQueryValueEx(keyhandle, "path", 0, NULL, (BYTE *)name, &hlen)
- != ERROR_SUCCESS)
- name[0] = 0;
- else
- name[hlen] = 0;
- RegCloseKey(keyhandle);
- }
-
- if ((name[0] == 0) &&
- (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0,
- KEY_READ, &keyhandle) == ERROR_SUCCESS))
- {
- hlen = BUFSIZE;
- 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((char *)"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((char *)"gvim.bat"));
- if (name[0] == 0)
- strcpy(name, "gvim"); // finds gvim.bat or gvim.exe
- }
-}
-
- static void
-getGvimInvocation(char *name, int runtime)
-{
- getGvimName(name, runtime);
- // avoid that Vim tries to expand wildcards in the file names
- strcat(name, " --literal");
-}
-
- static void
-getGvimInvocationW(wchar_t *nameW)
-{
- char *name;
-
- name = (char *)malloc(BUFSIZE);
- getGvimInvocation(name, 0);
- mbstowcs(nameW, name, BUFSIZE);
- free(name);
-}
-
-//
-// Get the Vim runtime directory into buf[BUFSIZE].
-// 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 = (int)strlen(buf) - 1; idx >= 0; idx--)
- if (buf[idx] == '\\' || buf[idx] == '/')
- {
- buf[idx + 1] = 0;
- break;
- }
- }
-}
-
- WCHAR *
-utf8_to_utf16(const char *s)
-{
- int size = MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0);
- WCHAR *buf = (WCHAR *)malloc(size * sizeof(WCHAR));
- MultiByteToWideChar(CP_UTF8, 0, s, -1, buf, size);
- return buf;
-}
-
- HBITMAP
-IconToBitmap(HICON hIcon, HBRUSH hBackground, int width, int height)
-{
- HDC hDC = GetDC(NULL);
- HDC hMemDC = CreateCompatibleDC(hDC);
- HBITMAP hMemBmp = CreateCompatibleBitmap(hDC, width, height);
- HBITMAP hResultBmp = NULL;
- HGDIOBJ hOrgBMP = SelectObject(hMemDC, hMemBmp);
-
- DrawIconEx(hMemDC, 0, 0, hIcon, width, height, 0, hBackground, DI_NORMAL);
-
- hResultBmp = hMemBmp;
- hMemBmp = NULL;
-
- SelectObject(hMemDC, hOrgBMP);
- DeleteDC(hMemDC);
- ReleaseDC(NULL, hDC);
- DestroyIcon(hIcon);
- return hResultBmp;
-}
-
-//
-// GETTEXT: translated messages and menu entries
-//
-#ifndef FEAT_GETTEXT
-# define _(x) x
-# define W_impl(x) _wcsdup(L##x)
-# define W(x) W_impl(x)
-# define set_gettext_codeset() NULL
-# define restore_gettext_codeset(x)
-#else
-# define _(x) (*dyn_libintl_gettext)(x)
-# define W(x) utf8_to_utf16(x)
-# define VIMPACKAGE "vim"
-# ifndef GETTEXT_DLL
-# define GETTEXT_DLL "libintl.dll"
-# define GETTEXT_DLL_ALT "libintl-8.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 char *null_libintl_bind_textdomain_codeset(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;
-static char *(*dyn_libintl_bind_textdomain_codeset)(const char *, const char *)
- = null_libintl_bind_textdomain_codeset;
-
-//
-// 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[] =
- {
- {(char *)"gettext", (FARPROC*)&dyn_libintl_gettext},
- {(char *)"textdomain", (FARPROC*)&dyn_libintl_textdomain},
- {(char *)"bindtextdomain", (FARPROC*)&dyn_libintl_bindtextdomain},
- {(char *)"bind_textdomain_codeset", (FARPROC*)&dyn_libintl_bind_textdomain_codeset},
- {NULL, NULL}
- };
- DWORD len, len2;
- LPWSTR buf = NULL;
- LPWSTR buf2 = NULL;
-
- // No need to initialize twice.
- if (hLibintlDLL)
- return 1;
-
- // Load gettext library from $VIMRUNTIME\GvimExt{64,32} directory.
- // Add the directory to $PATH temporarily.
- len = GetEnvironmentVariableW(L"PATH", NULL, 0);
- len2 = MAX_PATH + 1 + len;
- buf = (LPWSTR)malloc(len * sizeof(WCHAR));
- buf2 = (LPWSTR)malloc(len2 * sizeof(WCHAR));
- if (buf != NULL && buf2 != NULL)
- {
- GetEnvironmentVariableW(L"PATH", buf, len);
-# ifdef _WIN64
- _snwprintf(buf2, len2, L"%S\\GvimExt64;%s", dir, buf);
-# else
- _snwprintf(buf2, len2, L"%S\\GvimExt32;%s", dir, buf);
-# endif
- SetEnvironmentVariableW(L"PATH", buf2);
- hLibintlDLL = LoadLibrary(GETTEXT_DLL);
-# ifdef GETTEXT_DLL_ALT
- if (!hLibintlDLL)
- hLibintlDLL = LoadLibrary(GETTEXT_DLL_ALT);
-# endif
- SetEnvironmentVariableW(L"PATH", buf);
- }
- free(buf);
- free(buf2);
- 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;
- dyn_libintl_bind_textdomain_codeset = null_libintl_bind_textdomain_codeset;
-}
-
- static char *
-null_libintl_gettext(const char *msgid)
-{
- return (char *)msgid;
-}
-
- static char *
-null_libintl_textdomain(const char * /* domainname */)
-{
- return NULL;
-}
-
- static char *
-null_libintl_bindtextdomain(const char * /* domainname */, const char * /* dirname */)
-{
- return NULL;
-}
-
- static char *
-null_libintl_bind_textdomain_codeset(const char * /* domainname */, const char * /* codeset */)
-{
- return NULL;
-}
-
-//
-// Setup for translating strings.
-//
- static void
-dyn_gettext_load(void)
-{
- char szBuff[BUFSIZE];
- DWORD len;
-
- // 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 = (DWORD)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();
-}
-
-//
-// Use UTF-8 for gettext. Returns previous codeset.
-//
- static char *
-set_gettext_codeset(void)
-{
- char *prev = dyn_libintl_bind_textdomain_codeset(VIMPACKAGE, NULL);
- prev = _strdup((prev != NULL) ? prev : "char");
- dyn_libintl_bind_textdomain_codeset(VIMPACKAGE, "utf-8");
-
- return prev;
-}
-
-//
-// Restore previous codeset for gettext.
-//
- static void
-restore_gettext_codeset(char *prev)
-{
- dyn_libintl_bind_textdomain_codeset(VIMPACKAGE, prev);
- free(prev);
-}
-#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();
-
- LoadMenuIcon();
-}
-
-CShellExt::~CShellExt()
-{
- if (m_pDataObj)
- m_pDataObj->Release();
-
- dec_cRefThisDLL();
-
- if (m_hVimIconBitmap)
- DeleteObject(m_hVimIconBitmap);
-}
-
-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 - Specifies 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 = DragQueryFileW((HDROP)medium.hGlobal, (UINT)-1, 0, 0);
-
- // InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL);
-
- // Initialize m_cntOfHWnd to 0
- m_cntOfHWnd = 0;
-
- HKEY keyhandle;
- bool showExisting = true;
- bool showIcons = true;
-
- // Check whether "Edit with existing Vim" entries are disabled.
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0,
- KEY_READ, &keyhandle) == ERROR_SUCCESS)
- {
- if (RegQueryValueEx(keyhandle, "DisableEditWithExisting", 0, NULL,
- NULL, NULL) == ERROR_SUCCESS)
- showExisting = false;
- if (RegQueryValueEx(keyhandle, "DisableContextMenuIcons", 0, NULL,
- NULL, NULL) == ERROR_SUCCESS)
- showIcons = false;
- RegCloseKey(keyhandle);
- }
-
- // Use UTF-8 for gettext.
- char *prev = set_gettext_codeset();
-
- // Retrieve all the vim instances, unless disabled.
- if (showExisting)
- EnumWindows(EnumWindowsProc, (LPARAM)this);
-
- MENUITEMINFOW mii = { sizeof(MENUITEMINFOW) };
- mii.fMask = MIIM_STRING | MIIM_ID;
- if (showIcons)
- {
- mii.fMask |= MIIM_BITMAP;
- mii.hbmpItem = m_hVimIconBitmap;
- }
-
- if (cbFiles > 1)
- {
- mii.wID = idCmd++;
- mii.dwTypeData = W(_("Edit with Vim using &tabpages"));
- mii.cch = wcslen(mii.dwTypeData);
- InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii);
- free(mii.dwTypeData);
-
- mii.wID = idCmd++;
- mii.dwTypeData = W(_("Edit with single &Vim"));
- mii.cch = wcslen(mii.dwTypeData);
- InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii);
- free(mii.dwTypeData);
-
- if (cbFiles <= 4)
- {
- // Can edit up to 4 files in diff mode
- mii.wID = idCmd++;
- mii.dwTypeData = W(_("Diff with Vim"));
- mii.cch = wcslen(mii.dwTypeData);
- InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii);
- free(mii.dwTypeData);
- m_edit_existing_off = 3;
- }
- else
- m_edit_existing_off = 2;
-
- }
- else
- {
- mii.wID = idCmd++;
- mii.dwTypeData = W(_("Edit with &Vim"));
- mii.cch = wcslen(mii.dwTypeData);
- InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii);
- free(mii.dwTypeData);
- m_edit_existing_off = 1;
- }
-
- HMENU hSubMenu = NULL;
- if (m_cntOfHWnd > 1)
- {
- hSubMenu = CreatePopupMenu();
- mii.fMask |= MIIM_SUBMENU;
- mii.wID = idCmd;
- mii.dwTypeData = W(_("Edit with existing Vim"));
- mii.cch = wcslen(mii.dwTypeData);
- mii.hSubMenu = hSubMenu;
- InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii);
- free(mii.dwTypeData);
- mii.fMask = mii.fMask & ~MIIM_SUBMENU;
- mii.hSubMenu = NULL;
- }
- // Now display all the vim instances
- for (int i = 0; i < m_cntOfHWnd; i++)
- {
- WCHAR title[BUFSIZE];
- WCHAR temp[BUFSIZE];
- int index;
- HMENU hmenu;
-
- // Obtain window title, continue if can not
- if (GetWindowTextW(m_hWnd[i], title, BUFSIZE - 1) == 0)
- continue;
- // Truncate the title before the path, keep the file name
- WCHAR *pos = wcschr(title, L'(');
- if (pos != NULL)
- {
- if (pos > title && pos[-1] == L' ')
- --pos;
- *pos = 0;
- }
- // Now concatenate
- if (m_cntOfHWnd > 1)
- temp[0] = L'\0';
- else
- {
- WCHAR *s = W(_("Edit with existing Vim - "));
- wcsncpy(temp, s, BUFSIZE - 1);
- temp[BUFSIZE - 1] = L'\0';
- free(s);
- }
- wcsncat(temp, title, BUFSIZE - 1 - wcslen(temp));
- temp[BUFSIZE - 1] = L'\0';
-
- mii.wID = idCmd++;
- mii.dwTypeData = temp;
- mii.cch = wcslen(mii.dwTypeData);
- if (m_cntOfHWnd > 1)
- {
- hmenu = hSubMenu;
- index = i;
- }
- else
- {
- hmenu = hMenu;
- index = indexMenu++;
- }
- InsertMenuItemW(hmenu, index, TRUE, &mii);
- }
- // InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL);
-
- // Restore previous codeset.
- restore_gettext_codeset(prev);
-
- // 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;
- int gvimExtraOptions;
-
- // 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:
- gvimExtraOptions = EDIT_WITH_VIM_USE_TABPAGES;
- break;
- case 1:
- gvimExtraOptions = EDIT_WITH_VIM_NO_OPTIONS;
- break;
- case 2:
- gvimExtraOptions = EDIT_WITH_VIM_IN_DIFF_MODE;
- break;
- default:
- // If execution reaches this point we likely have an
- // inconsistency between the code that setup the menus
- // and this code that determines what the user
- // selected. This should be detected and fixed during
- // development.
- return E_FAIL;
- }
-
- LPCMINVOKECOMMANDINFOEX lpcmiex = (LPCMINVOKECOMMANDINFOEX)lpcmi;
- LPCWSTR currentDirectory = lpcmi->cbSize == sizeof(CMINVOKECOMMANDINFOEX) ? lpcmiex->lpDirectoryW : NULL;
-
- hr = InvokeSingleGvim(lpcmi->hwnd,
- currentDirectory,
- lpcmi->lpVerb,
- lpcmi->lpParameters,
- lpcmi->nShow,
- gvimExtraOptions);
- }
- }
- 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_PTR /* idCmd */,
- UINT uFlags,
- UINT FAR * /* reserved */,
- LPSTR pszName,
- UINT cchMax)
-{
- // Use UTF-8 for gettext.
- char *prev = set_gettext_codeset();
-
- WCHAR *s = W(_("Edits the selected file(s) with Vim"));
- if (uFlags == GCS_HELPTEXTW && cchMax > wcslen(s))
- wcscpy((WCHAR *)pszName, s);
- free(s);
-
- // Restore previous codeset.
- restore_gettext_codeset(prev);
-
- return NOERROR;
-}
-
-BOOL CALLBACK CShellExt::EnumWindowsProc(HWND hWnd, LPARAM lParam)
-{
- char temp[BUFSIZE];
-
- // 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 FALSE; // stop enumeration
- // 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)
-}
-
-BOOL CShellExt::LoadMenuIcon()
-{
- char vimExeFile[BUFSIZE];
- getGvimName(vimExeFile, 1);
- if (vimExeFile[0] == '\0')
- return FALSE;
- HICON hVimIcon;
- if (ExtractIconEx(vimExeFile, 0, NULL, &hVimIcon, 1) == 0)
- return FALSE;
- m_hVimIconBitmap = IconToBitmap(hVimIcon,
- GetSysColorBrush(COLOR_MENU),
- GetSystemMetrics(SM_CXSMICON),
- GetSystemMetrics(SM_CYSMICON));
- return TRUE;
-}
-
- static char *
-searchpath(char *name)
-{
- static char widename[2 * BUFSIZE];
- static char location[2 * BUFSIZE + 2];
-
- // There appears to be a bug in FindExecutableA() on Windows NT.
- // Use FindExecutableW() instead...
- MultiByteToWideChar(CP_ACP, 0, (LPCSTR)name, -1,
- (LPWSTR)widename, BUFSIZE);
- if (FindExecutableW((LPCWSTR)widename, (LPCWSTR)"",
- (LPWSTR)location) > (HINSTANCE)32)
- {
- WideCharToMultiByte(CP_ACP, 0, (LPWSTR)location, -1,
- (LPSTR)widename, 2 * BUFSIZE, NULL, NULL);
- return widename;
- }
- return (char *)"";
-}
-
-
-STDMETHODIMP CShellExt::InvokeSingleGvim(HWND hParent,
- LPCWSTR workingDir,
- LPCSTR /* pszCmd */,
- LPCSTR /* pszParam */,
- int /* iShowCmd */,
- int gvimExtraOptions)
-{
- wchar_t m_szFileUserClickedOn[BUFSIZE];
- wchar_t *cmdStrW;
- size_t cmdlen;
- size_t len;
- UINT i;
-
- cmdlen = BUFSIZE;
- cmdStrW = (wchar_t *) malloc(cmdlen * sizeof(wchar_t));
- if (cmdStrW == NULL)
- return E_FAIL;
- getGvimInvocationW(cmdStrW);
-
- if (gvimExtraOptions == EDIT_WITH_VIM_IN_DIFF_MODE)
- wcscat(cmdStrW, L" -d");
- else if (gvimExtraOptions == EDIT_WITH_VIM_USE_TABPAGES)
- wcscat(cmdStrW, L" -p");
- for (i = 0; i < cbFiles; i++)
- {
- DragQueryFileW((HDROP)medium.hGlobal,
- i,
- m_szFileUserClickedOn,
- sizeof(m_szFileUserClickedOn));
-
- len = wcslen(cmdStrW) + wcslen(m_szFileUserClickedOn) + 4;
- if (len > cmdlen)
- {
- cmdlen = len + BUFSIZE;
- wchar_t *cmdStrW_new = (wchar_t *)realloc(cmdStrW, cmdlen * sizeof(wchar_t));
- if (cmdStrW_new == NULL)
- {
- free(cmdStrW);
- return E_FAIL;
- }
- cmdStrW = cmdStrW_new;
- }
- wcscat(cmdStrW, L" \"");
- wcscat(cmdStrW, m_szFileUserClickedOn);
- wcscat(cmdStrW, L"\"");
- }
-
- STARTUPINFOW si;
- PROCESS_INFORMATION pi;
-
- ZeroMemory(&si, sizeof(si));
- si.cb = sizeof(si);
-
- // Start the child process.
- if (!CreateProcessW(NULL, // No module name (use command line).
- cmdStrW, // 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.
- workingDir, // Use parent's starting directory.
- &si, // Pointer to STARTUPINFO structure.
- &pi) // Pointer to PROCESS_INFORMATION structure.
- )
- {
- // Use UTF-8 for gettext.
- char *prev = set_gettext_codeset();
-
- WCHAR *msg = W(_("Error creating process: Check if gvim is in your path!"));
- WCHAR *title = W(_("gvimext.dll error"));
-
- MessageBoxW(hParent, msg, title, MB_OK);
-
- free(msg);
- free(title);
-
- // Restore previous codeset.
- restore_gettext_codeset(prev);
- }
- else
- {
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- }
- free(cmdStrW);
-
- return NOERROR;
-}