mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 7.4.724
Problem: Vim icon does not show in Windows context menu. (issue 249) Solution: Load the icon in GvimExt.
This commit is contained in:
@@ -79,19 +79,24 @@ getGvimName(char *name, int runtime)
|
|||||||
strcpy(name, searchpath((char *)"gvim.bat"));
|
strcpy(name, searchpath((char *)"gvim.bat"));
|
||||||
if (name[0] == 0)
|
if (name[0] == 0)
|
||||||
strcpy(name, "gvim"); // finds gvim.bat or gvim.exe
|
strcpy(name, "gvim"); // finds gvim.bat or gvim.exe
|
||||||
|
|
||||||
// avoid that Vim tries to expand wildcards in the file names
|
|
||||||
strcat(name, " --literal");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
getGvimNameW(wchar_t *nameW)
|
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;
|
char *name;
|
||||||
|
|
||||||
name = (char *)malloc(BUFSIZE);
|
name = (char *)malloc(BUFSIZE);
|
||||||
getGvimName(name, 0);
|
getGvimInvocation(name, 0);
|
||||||
mbstowcs(nameW, name, BUFSIZE);
|
mbstowcs(nameW, name, BUFSIZE);
|
||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
@@ -123,6 +128,26 @@ getRuntimeDir(char *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
|
// GETTEXT: translated messages and menu entries
|
||||||
//
|
//
|
||||||
@@ -404,7 +429,7 @@ STDMETHODIMP CShellExtClassFactory::QueryInterface(REFIID riid,
|
|||||||
{
|
{
|
||||||
*ppv = NULL;
|
*ppv = NULL;
|
||||||
|
|
||||||
// Any interface on this object is the object pointer
|
// any interface on this object is the object pointer
|
||||||
|
|
||||||
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
|
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
|
||||||
{
|
{
|
||||||
@@ -448,7 +473,7 @@ STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
|
|||||||
// QueryInterface with IID_IShellExtInit--this is how shell extensions are
|
// QueryInterface with IID_IShellExtInit--this is how shell extensions are
|
||||||
// initialized.
|
// initialized.
|
||||||
|
|
||||||
LPCSHELLEXT pShellExt = new CShellExt(); //Create the CShellExt object
|
LPCSHELLEXT pShellExt = new CShellExt(); // create the CShellExt object
|
||||||
|
|
||||||
if (NULL == pShellExt)
|
if (NULL == pShellExt)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
@@ -469,6 +494,8 @@ CShellExt::CShellExt()
|
|||||||
m_pDataObj = NULL;
|
m_pDataObj = NULL;
|
||||||
|
|
||||||
inc_cRefThisDLL();
|
inc_cRefThisDLL();
|
||||||
|
|
||||||
|
LoadMenuIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
CShellExt::~CShellExt()
|
CShellExt::~CShellExt()
|
||||||
@@ -477,6 +504,9 @@ CShellExt::~CShellExt()
|
|||||||
m_pDataObj->Release();
|
m_pDataObj->Release();
|
||||||
|
|
||||||
dec_cRefThisDLL();
|
dec_cRefThisDLL();
|
||||||
|
|
||||||
|
if (m_hVimIconBitmap)
|
||||||
|
DeleteObject(m_hVimIconBitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv)
|
STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv)
|
||||||
@@ -597,6 +627,7 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
|
|||||||
|
|
||||||
HKEY keyhandle;
|
HKEY keyhandle;
|
||||||
bool showExisting = true;
|
bool showExisting = true;
|
||||||
|
bool showIcons = true;
|
||||||
|
|
||||||
// Check whether "Edit with existing Vim" entries are disabled.
|
// Check whether "Edit with existing Vim" entries are disabled.
|
||||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0,
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0,
|
||||||
@@ -605,6 +636,9 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
|
|||||||
if (RegQueryValueEx(keyhandle, "DisableEditWithExisting", 0, NULL,
|
if (RegQueryValueEx(keyhandle, "DisableEditWithExisting", 0, NULL,
|
||||||
NULL, NULL) == ERROR_SUCCESS)
|
NULL, NULL) == ERROR_SUCCESS)
|
||||||
showExisting = false;
|
showExisting = false;
|
||||||
|
if (RegQueryValueEx(keyhandle, "DisableContextMenuIcons", 0, NULL,
|
||||||
|
NULL, NULL) == ERROR_SUCCESS)
|
||||||
|
showIcons = false;
|
||||||
RegCloseKey(keyhandle);
|
RegCloseKey(keyhandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,28 +646,33 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
|
|||||||
if (showExisting)
|
if (showExisting)
|
||||||
EnumWindows(EnumWindowsProc, (LPARAM)this);
|
EnumWindows(EnumWindowsProc, (LPARAM)this);
|
||||||
|
|
||||||
|
MENUITEMINFO mii = { sizeof(MENUITEMINFO) };
|
||||||
|
mii.fMask = MIIM_STRING | MIIM_ID;
|
||||||
|
if (showIcons)
|
||||||
|
{
|
||||||
|
mii.fMask |= MIIM_BITMAP;
|
||||||
|
mii.hbmpItem = m_hVimIconBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
if (cbFiles > 1)
|
if (cbFiles > 1)
|
||||||
{
|
{
|
||||||
InsertMenu(hMenu,
|
mii.wID = idCmd++;
|
||||||
indexMenu++,
|
mii.dwTypeData = _("Edit with &multiple Vims");
|
||||||
MF_STRING|MF_BYPOSITION,
|
mii.cch = lstrlen(mii.dwTypeData);
|
||||||
idCmd++,
|
InsertMenuItem(hMenu, indexMenu++, TRUE, &mii);
|
||||||
_("Edit with &multiple Vims"));
|
|
||||||
|
|
||||||
InsertMenu(hMenu,
|
mii.wID = idCmd++;
|
||||||
indexMenu++,
|
mii.dwTypeData = _("Edit with single &Vim");
|
||||||
MF_STRING|MF_BYPOSITION,
|
mii.cch = lstrlen(mii.dwTypeData);
|
||||||
idCmd++,
|
InsertMenuItem(hMenu, indexMenu++, TRUE, &mii);
|
||||||
_("Edit with single &Vim"));
|
|
||||||
|
|
||||||
if (cbFiles <= 4)
|
if (cbFiles <= 4)
|
||||||
{
|
{
|
||||||
// Can edit up to 4 files in diff mode
|
// Can edit up to 4 files in diff mode
|
||||||
InsertMenu(hMenu,
|
mii.wID = idCmd++;
|
||||||
indexMenu++,
|
mii.dwTypeData = _("Diff with Vim");
|
||||||
MF_STRING|MF_BYPOSITION,
|
mii.cch = lstrlen(mii.dwTypeData);
|
||||||
idCmd++,
|
InsertMenuItem(hMenu, indexMenu++, TRUE, &mii);
|
||||||
_("Diff with Vim"));
|
|
||||||
m_edit_existing_off = 3;
|
m_edit_existing_off = 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -642,11 +681,10 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
InsertMenu(hMenu,
|
mii.wID = idCmd++;
|
||||||
indexMenu++,
|
mii.dwTypeData = _("Edit with &Vim");
|
||||||
MF_STRING|MF_BYPOSITION,
|
mii.cch = lstrlen(mii.dwTypeData);
|
||||||
idCmd++,
|
InsertMenuItem(hMenu, indexMenu++, TRUE, &mii);
|
||||||
_("Edit with &Vim"));
|
|
||||||
m_edit_existing_off = 1;
|
m_edit_existing_off = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -672,11 +710,11 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
|
|||||||
temp[BUFSIZE - 1] = '\0';
|
temp[BUFSIZE - 1] = '\0';
|
||||||
strncat(temp, title, BUFSIZE - 1 - strlen(temp));
|
strncat(temp, title, BUFSIZE - 1 - strlen(temp));
|
||||||
temp[BUFSIZE - 1] = '\0';
|
temp[BUFSIZE - 1] = '\0';
|
||||||
InsertMenu(hMenu,
|
|
||||||
indexMenu++,
|
mii.wID = idCmd++;
|
||||||
MF_STRING|MF_BYPOSITION,
|
mii.dwTypeData = temp;
|
||||||
idCmd++,
|
mii.cch = lstrlen(mii.dwTypeData);
|
||||||
temp);
|
InsertMenuItem(hMenu, indexMenu++, TRUE, &mii);
|
||||||
}
|
}
|
||||||
// InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL);
|
// InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL);
|
||||||
|
|
||||||
@@ -813,6 +851,22 @@ BOOL CALLBACK CShellExt::EnumWindowsProc(HWND hWnd, LPARAM lParam)
|
|||||||
return TRUE; // continue enumeration (otherwise this would be false)
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// This symbol is not defined in older versions of the SDK or Visual C++.
|
// This symbol is not defined in older versions of the SDK or Visual C++.
|
||||||
|
|
||||||
@@ -893,7 +947,7 @@ STDMETHODIMP CShellExt::InvokeGvim(HWND hParent,
|
|||||||
m_szFileUserClickedOn,
|
m_szFileUserClickedOn,
|
||||||
sizeof(m_szFileUserClickedOn));
|
sizeof(m_szFileUserClickedOn));
|
||||||
|
|
||||||
getGvimNameW(cmdStrW);
|
getGvimInvocationW(cmdStrW);
|
||||||
wcscat(cmdStrW, L" \"");
|
wcscat(cmdStrW, L" \"");
|
||||||
|
|
||||||
if ((wcslen(cmdStrW) + wcslen(m_szFileUserClickedOn) + 2) < BUFSIZE)
|
if ((wcslen(cmdStrW) + wcslen(m_szFileUserClickedOn) + 2) < BUFSIZE)
|
||||||
@@ -961,7 +1015,7 @@ STDMETHODIMP CShellExt::InvokeSingleGvim(HWND hParent,
|
|||||||
|
|
||||||
cmdlen = BUFSIZE;
|
cmdlen = BUFSIZE;
|
||||||
cmdStrW = (wchar_t *) malloc(cmdlen * sizeof(wchar_t));
|
cmdStrW = (wchar_t *) malloc(cmdlen * sizeof(wchar_t));
|
||||||
getGvimNameW(cmdStrW);
|
getGvimInvocationW(cmdStrW);
|
||||||
|
|
||||||
if (useDiff)
|
if (useDiff)
|
||||||
wcscat(cmdStrW, L" -d");
|
wcscat(cmdStrW, L" -d");
|
||||||
|
@@ -110,10 +110,14 @@ typedef CShellExtClassFactory *LPCSHELLEXTCLASSFACTORY;
|
|||||||
class CShellExt : public IContextMenu,
|
class CShellExt : public IContextMenu,
|
||||||
IShellExtInit
|
IShellExtInit
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
BOOL LoadMenuIcon();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ULONG m_cRef;
|
ULONG m_cRef;
|
||||||
LPDATAOBJECT m_pDataObj;
|
LPDATAOBJECT m_pDataObj;
|
||||||
UINT m_edit_existing_off;
|
UINT m_edit_existing_off;
|
||||||
|
HBITMAP m_hVimIconBitmap;
|
||||||
|
|
||||||
// For some reason, this callback must be static
|
// For some reason, this callback must be static
|
||||||
static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam);
|
static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam);
|
||||||
|
@@ -741,6 +741,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
724,
|
||||||
/**/
|
/**/
|
||||||
723,
|
723,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user