0
0
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:
Bram Moolenaar
2015-05-04 18:27:36 +02:00
parent 4032cfdf17
commit 7bc25aed33
3 changed files with 94 additions and 34 deletions

View File

@@ -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");

View File

@@ -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);

View File

@@ -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,
/**/ /**/