Karsten Hopp 127033
To: vim_dev@googlegroups.com
Karsten Hopp 127033
Subject: Patch 7.4.724
Karsten Hopp 127033
Fcc: outbox
Karsten Hopp 127033
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 127033
Mime-Version: 1.0
Karsten Hopp 127033
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 127033
Content-Transfer-Encoding: 8bit
Karsten Hopp 127033
------------
Karsten Hopp 127033
Karsten Hopp 127033
Patch 7.4.724
Karsten Hopp 127033
Problem:    Vim icon does not show in Windows context menu. (issue 249)
Karsten Hopp 127033
Solution:   Load the icon in GvimExt.
Karsten Hopp 127033
Files:      src/GvimExt/gvimext.cpp, src/GvimExt/gvimext.h
Karsten Hopp 127033
Karsten Hopp 127033
Karsten Hopp 127033
*** ../vim-7.4.723/src/GvimExt/gvimext.cpp	2013-05-06 04:06:04.000000000 +0200
Karsten Hopp 127033
--- src/GvimExt/gvimext.cpp	2015-05-04 18:20:37.345326768 +0200
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 79,97 ****
Karsten Hopp 127033
  	    strcpy(name, searchpath((char *)"gvim.bat"));
Karsten Hopp 127033
  	if (name[0] == 0)
Karsten Hopp 127033
  	    strcpy(name, "gvim");	// finds gvim.bat or gvim.exe
Karsten Hopp 127033
- 
Karsten Hopp 127033
- 	// avoid that Vim tries to expand wildcards in the file names
Karsten Hopp 127033
- 	strcat(name, " --literal");
Karsten Hopp 127033
      }
Karsten Hopp 127033
  }
Karsten Hopp 127033
  
Karsten Hopp 127033
      static void
Karsten Hopp 127033
! getGvimNameW(wchar_t *nameW)
Karsten Hopp 127033
  {
Karsten Hopp 127033
      char *name;
Karsten Hopp 127033
  
Karsten Hopp 127033
      name = (char *)malloc(BUFSIZE);
Karsten Hopp 127033
!     getGvimName(name, 0);
Karsten Hopp 127033
      mbstowcs(nameW, name, BUFSIZE);
Karsten Hopp 127033
      free(name);
Karsten Hopp 127033
  }
Karsten Hopp 127033
--- 79,102 ----
Karsten Hopp 127033
  	    strcpy(name, searchpath((char *)"gvim.bat"));
Karsten Hopp 127033
  	if (name[0] == 0)
Karsten Hopp 127033
  	    strcpy(name, "gvim");	// finds gvim.bat or gvim.exe
Karsten Hopp 127033
      }
Karsten Hopp 127033
  }
Karsten Hopp 127033
  
Karsten Hopp 127033
      static void
Karsten Hopp 127033
! getGvimInvocation(char *name, int runtime)
Karsten Hopp 127033
! {
Karsten Hopp 127033
!     getGvimName(name, runtime);
Karsten Hopp 127033
!     // avoid that Vim tries to expand wildcards in the file names
Karsten Hopp 127033
!     strcat(name, " --literal");
Karsten Hopp 127033
! }
Karsten Hopp 127033
! 
Karsten Hopp 127033
!     static void
Karsten Hopp 127033
! getGvimInvocationW(wchar_t *nameW)
Karsten Hopp 127033
  {
Karsten Hopp 127033
      char *name;
Karsten Hopp 127033
  
Karsten Hopp 127033
      name = (char *)malloc(BUFSIZE);
Karsten Hopp 127033
!     getGvimInvocation(name, 0);
Karsten Hopp 127033
      mbstowcs(nameW, name, BUFSIZE);
Karsten Hopp 127033
      free(name);
Karsten Hopp 127033
  }
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 123,128 ****
Karsten Hopp 127033
--- 128,153 ----
Karsten Hopp 127033
      }
Karsten Hopp 127033
  }
Karsten Hopp 127033
  
Karsten Hopp 127033
+ HBITMAP IconToBitmap(HICON hIcon, HBRUSH hBackground, int width, int height)
Karsten Hopp 127033
+ {
Karsten Hopp 127033
+ 	HDC hDC = GetDC(NULL);
Karsten Hopp 127033
+ 	HDC hMemDC = CreateCompatibleDC(hDC);
Karsten Hopp 127033
+ 	HBITMAP hMemBmp = CreateCompatibleBitmap(hDC, width, height);
Karsten Hopp 127033
+ 	HBITMAP hResultBmp = NULL;
Karsten Hopp 127033
+ 	HGDIOBJ hOrgBMP = SelectObject(hMemDC, hMemBmp);
Karsten Hopp 127033
+ 
Karsten Hopp 127033
+ 	DrawIconEx(hMemDC, 0, 0, hIcon, width, height, 0, hBackground, DI_NORMAL);
Karsten Hopp 127033
+ 
Karsten Hopp 127033
+ 	hResultBmp = hMemBmp;
Karsten Hopp 127033
+ 	hMemBmp = NULL;
Karsten Hopp 127033
+ 
Karsten Hopp 127033
+ 	SelectObject(hMemDC, hOrgBMP);
Karsten Hopp 127033
+ 	DeleteDC(hMemDC);
Karsten Hopp 127033
+ 	ReleaseDC(NULL, hDC);
Karsten Hopp 127033
+ 	DestroyIcon(hIcon);
Karsten Hopp 127033
+ 	return hResultBmp;
Karsten Hopp 127033
+ }
Karsten Hopp 127033
+ 
Karsten Hopp 127033
  //
Karsten Hopp 127033
  // GETTEXT: translated messages and menu entries
Karsten Hopp 127033
  //
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 404,410 ****
Karsten Hopp 127033
  {
Karsten Hopp 127033
      *ppv = NULL;
Karsten Hopp 127033
  
Karsten Hopp 127033
!     // Any interface on this object is the object pointer
Karsten Hopp 127033
  
Karsten Hopp 127033
      if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
Karsten Hopp 127033
      {
Karsten Hopp 127033
--- 429,435 ----
Karsten Hopp 127033
  {
Karsten Hopp 127033
      *ppv = NULL;
Karsten Hopp 127033
  
Karsten Hopp 127033
!     // any interface on this object is the object pointer
Karsten Hopp 127033
  
Karsten Hopp 127033
      if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
Karsten Hopp 127033
      {
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 448,454 ****
Karsten Hopp 127033
      // QueryInterface with IID_IShellExtInit--this is how shell extensions are
Karsten Hopp 127033
      // initialized.
Karsten Hopp 127033
  
Karsten Hopp 127033
!     LPCSHELLEXT pShellExt = new CShellExt();  //Create the CShellExt object
Karsten Hopp 127033
  
Karsten Hopp 127033
      if (NULL == pShellExt)
Karsten Hopp 127033
  	return E_OUTOFMEMORY;
Karsten Hopp 127033
--- 473,479 ----
Karsten Hopp 127033
      // QueryInterface with IID_IShellExtInit--this is how shell extensions are
Karsten Hopp 127033
      // initialized.
Karsten Hopp 127033
  
Karsten Hopp 127033
!     LPCSHELLEXT pShellExt = new CShellExt();  // create the CShellExt object
Karsten Hopp 127033
  
Karsten Hopp 127033
      if (NULL == pShellExt)
Karsten Hopp 127033
  	return E_OUTOFMEMORY;
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 469,474 ****
Karsten Hopp 127033
--- 494,501 ----
Karsten Hopp 127033
      m_pDataObj = NULL;
Karsten Hopp 127033
  
Karsten Hopp 127033
      inc_cRefThisDLL();
Karsten Hopp 127033
+ 
Karsten Hopp 127033
+     LoadMenuIcon();
Karsten Hopp 127033
  }
Karsten Hopp 127033
  
Karsten Hopp 127033
  CShellExt::~CShellExt()
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 477,482 ****
Karsten Hopp 127033
--- 504,512 ----
Karsten Hopp 127033
  	m_pDataObj->Release();
Karsten Hopp 127033
  
Karsten Hopp 127033
      dec_cRefThisDLL();
Karsten Hopp 127033
+ 
Karsten Hopp 127033
+     if (m_hVimIconBitmap)
Karsten Hopp 127033
+ 	DeleteObject(m_hVimIconBitmap);
Karsten Hopp 127033
  }
Karsten Hopp 127033
  
Karsten Hopp 127033
  STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv)
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 597,602 ****
Karsten Hopp 127033
--- 627,633 ----
Karsten Hopp 127033
  
Karsten Hopp 127033
      HKEY keyhandle;
Karsten Hopp 127033
      bool showExisting = true;
Karsten Hopp 127033
+     bool showIcons = true;
Karsten Hopp 127033
  
Karsten Hopp 127033
      // Check whether "Edit with existing Vim" entries are disabled.
Karsten Hopp 127033
      if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0,
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 605,610 ****
Karsten Hopp 127033
--- 636,644 ----
Karsten Hopp 127033
  	if (RegQueryValueEx(keyhandle, "DisableEditWithExisting", 0, NULL,
Karsten Hopp 127033
  						 NULL, NULL) == ERROR_SUCCESS)
Karsten Hopp 127033
  	    showExisting = false;
Karsten Hopp 127033
+ 	if (RegQueryValueEx(keyhandle, "DisableContextMenuIcons", 0, NULL,
Karsten Hopp 127033
+ 						 NULL, NULL) == ERROR_SUCCESS)
Karsten Hopp 127033
+ 	    showIcons = false;
Karsten Hopp 127033
  	RegCloseKey(keyhandle);
Karsten Hopp 127033
      }
Karsten Hopp 127033
  
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 612,639 ****
Karsten Hopp 127033
      if (showExisting)
Karsten Hopp 127033
  	EnumWindows(EnumWindowsProc, (LPARAM)this);
Karsten Hopp 127033
  
Karsten Hopp 127033
      if (cbFiles > 1)
Karsten Hopp 127033
      {
Karsten Hopp 127033
! 	InsertMenu(hMenu,
Karsten Hopp 127033
! 		indexMenu++,
Karsten Hopp 127033
! 		MF_STRING|MF_BYPOSITION,
Karsten Hopp 127033
! 		idCmd++,
Karsten Hopp 127033
! 		_("Edit with &multiple Vims"));
Karsten Hopp 127033
! 
Karsten Hopp 127033
! 	InsertMenu(hMenu,
Karsten Hopp 127033
! 		indexMenu++,
Karsten Hopp 127033
! 		MF_STRING|MF_BYPOSITION,
Karsten Hopp 127033
! 		idCmd++,
Karsten Hopp 127033
! 		_("Edit with single &Vim"));
Karsten Hopp 127033
  
Karsten Hopp 127033
  	if (cbFiles <= 4)
Karsten Hopp 127033
  	{
Karsten Hopp 127033
  	    // Can edit up to 4 files in diff mode
Karsten Hopp 127033
! 	    InsertMenu(hMenu,
Karsten Hopp 127033
! 		    indexMenu++,
Karsten Hopp 127033
! 		    MF_STRING|MF_BYPOSITION,
Karsten Hopp 127033
! 		    idCmd++,
Karsten Hopp 127033
! 		    _("Diff with Vim"));
Karsten Hopp 127033
  	    m_edit_existing_off = 3;
Karsten Hopp 127033
  	}
Karsten Hopp 127033
  	else
Karsten Hopp 127033
--- 646,678 ----
Karsten Hopp 127033
      if (showExisting)
Karsten Hopp 127033
  	EnumWindows(EnumWindowsProc, (LPARAM)this);
Karsten Hopp 127033
  
Karsten Hopp 127033
+     MENUITEMINFO mii = { sizeof(MENUITEMINFO) };
Karsten Hopp 127033
+     mii.fMask = MIIM_STRING | MIIM_ID;
Karsten Hopp 127033
+     if (showIcons)
Karsten Hopp 127033
+     {
Karsten Hopp 127033
+ 	mii.fMask |= MIIM_BITMAP;
Karsten Hopp 127033
+ 	mii.hbmpItem = m_hVimIconBitmap;
Karsten Hopp 127033
+     }
Karsten Hopp 127033
+ 
Karsten Hopp 127033
      if (cbFiles > 1)
Karsten Hopp 127033
      {
Karsten Hopp 127033
! 	mii.wID = idCmd++;
Karsten Hopp 127033
! 	mii.dwTypeData = _("Edit with &multiple Vims");
Karsten Hopp 127033
! 	mii.cch = lstrlen(mii.dwTypeData);
Karsten Hopp 127033
! 	InsertMenuItem(hMenu, indexMenu++, TRUE, &mii;;
Karsten Hopp 127033
! 
Karsten Hopp 127033
! 	mii.wID = idCmd++;
Karsten Hopp 127033
! 	mii.dwTypeData = _("Edit with single &Vim");
Karsten Hopp 127033
! 	mii.cch = lstrlen(mii.dwTypeData);
Karsten Hopp 127033
! 	InsertMenuItem(hMenu, indexMenu++, TRUE, &mii;;
Karsten Hopp 127033
  
Karsten Hopp 127033
  	if (cbFiles <= 4)
Karsten Hopp 127033
  	{
Karsten Hopp 127033
  	    // Can edit up to 4 files in diff mode
Karsten Hopp 127033
! 	    mii.wID = idCmd++;
Karsten Hopp 127033
! 	    mii.dwTypeData = _("Diff with Vim");
Karsten Hopp 127033
! 	    mii.cch = lstrlen(mii.dwTypeData);
Karsten Hopp 127033
! 	    InsertMenuItem(hMenu, indexMenu++, TRUE, &mii;;
Karsten Hopp 127033
  	    m_edit_existing_off = 3;
Karsten Hopp 127033
  	}
Karsten Hopp 127033
  	else
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 642,652 ****
Karsten Hopp 127033
      }
Karsten Hopp 127033
      else
Karsten Hopp 127033
      {
Karsten Hopp 127033
! 	InsertMenu(hMenu,
Karsten Hopp 127033
! 		indexMenu++,
Karsten Hopp 127033
! 		MF_STRING|MF_BYPOSITION,
Karsten Hopp 127033
! 		idCmd++,
Karsten Hopp 127033
! 		_("Edit with &Vim"));
Karsten Hopp 127033
  	m_edit_existing_off = 1;
Karsten Hopp 127033
      }
Karsten Hopp 127033
  
Karsten Hopp 127033
--- 681,690 ----
Karsten Hopp 127033
      }
Karsten Hopp 127033
      else
Karsten Hopp 127033
      {
Karsten Hopp 127033
! 	mii.wID = idCmd++;
Karsten Hopp 127033
! 	mii.dwTypeData = _("Edit with &Vim");
Karsten Hopp 127033
! 	mii.cch = lstrlen(mii.dwTypeData);
Karsten Hopp 127033
! 	InsertMenuItem(hMenu, indexMenu++, TRUE, &mii;;
Karsten Hopp 127033
  	m_edit_existing_off = 1;
Karsten Hopp 127033
      }
Karsten Hopp 127033
  
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 672,682 ****
Karsten Hopp 127033
  	temp[BUFSIZE - 1] = '\0';
Karsten Hopp 127033
  	strncat(temp, title, BUFSIZE - 1 - strlen(temp));
Karsten Hopp 127033
  	temp[BUFSIZE - 1] = '\0';
Karsten Hopp 127033
! 	InsertMenu(hMenu,
Karsten Hopp 127033
! 		indexMenu++,
Karsten Hopp 127033
! 		MF_STRING|MF_BYPOSITION,
Karsten Hopp 127033
! 		idCmd++,
Karsten Hopp 127033
! 		temp);
Karsten Hopp 127033
      }
Karsten Hopp 127033
      // InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL);
Karsten Hopp 127033
  
Karsten Hopp 127033
--- 710,720 ----
Karsten Hopp 127033
  	temp[BUFSIZE - 1] = '\0';
Karsten Hopp 127033
  	strncat(temp, title, BUFSIZE - 1 - strlen(temp));
Karsten Hopp 127033
  	temp[BUFSIZE - 1] = '\0';
Karsten Hopp 127033
! 
Karsten Hopp 127033
! 	mii.wID = idCmd++;
Karsten Hopp 127033
! 	mii.dwTypeData = temp;
Karsten Hopp 127033
! 	mii.cch = lstrlen(mii.dwTypeData);
Karsten Hopp 127033
! 	InsertMenuItem(hMenu, indexMenu++, TRUE, &mii;;
Karsten Hopp 127033
      }
Karsten Hopp 127033
      // InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL);
Karsten Hopp 127033
  
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 813,818 ****
Karsten Hopp 127033
--- 851,872 ----
Karsten Hopp 127033
      return TRUE; // continue enumeration (otherwise this would be false)
Karsten Hopp 127033
  }
Karsten Hopp 127033
  
Karsten Hopp 127033
+ BOOL CShellExt::LoadMenuIcon()
Karsten Hopp 127033
+ {
Karsten Hopp 127033
+ 	char vimExeFile[BUFSIZE];
Karsten Hopp 127033
+ 	getGvimName(vimExeFile, 1);
Karsten Hopp 127033
+ 	if (vimExeFile[0] == '\0')
Karsten Hopp 127033
+ 		return FALSE;
Karsten Hopp 127033
+ 	HICON hVimIcon;
Karsten Hopp 127033
+ 	if (ExtractIconEx(vimExeFile, 0, NULL, &hVimIcon, 1) == 0)
Karsten Hopp 127033
+ 		return FALSE;
Karsten Hopp 127033
+ 	m_hVimIconBitmap = IconToBitmap(hVimIcon,
Karsten Hopp 127033
+ 		GetSysColorBrush(COLOR_MENU),
Karsten Hopp 127033
+ 		GetSystemMetrics(SM_CXSMICON),
Karsten Hopp 127033
+ 		GetSystemMetrics(SM_CYSMICON));
Karsten Hopp 127033
+ 	return TRUE;
Karsten Hopp 127033
+ }
Karsten Hopp 127033
+ 
Karsten Hopp 127033
  #ifdef WIN32
Karsten Hopp 127033
  // This symbol is not defined in older versions of the SDK or Visual C++.
Karsten Hopp 127033
  
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 893,899 ****
Karsten Hopp 127033
  		m_szFileUserClickedOn,
Karsten Hopp 127033
  		sizeof(m_szFileUserClickedOn));
Karsten Hopp 127033
  
Karsten Hopp 127033
! 	getGvimNameW(cmdStrW);
Karsten Hopp 127033
  	wcscat(cmdStrW, L" \"");
Karsten Hopp 127033
  
Karsten Hopp 127033
  	if ((wcslen(cmdStrW) + wcslen(m_szFileUserClickedOn) + 2) < BUFSIZE)
Karsten Hopp 127033
--- 947,953 ----
Karsten Hopp 127033
  		m_szFileUserClickedOn,
Karsten Hopp 127033
  		sizeof(m_szFileUserClickedOn));
Karsten Hopp 127033
  
Karsten Hopp 127033
! 	getGvimInvocationW(cmdStrW);
Karsten Hopp 127033
  	wcscat(cmdStrW, L" \"");
Karsten Hopp 127033
  
Karsten Hopp 127033
  	if ((wcslen(cmdStrW) + wcslen(m_szFileUserClickedOn) + 2) < BUFSIZE)
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 961,967 ****
Karsten Hopp 127033
  
Karsten Hopp 127033
      cmdlen = BUFSIZE;
Karsten Hopp 127033
      cmdStrW  = (wchar_t *) malloc(cmdlen * sizeof(wchar_t));
Karsten Hopp 127033
!     getGvimNameW(cmdStrW);
Karsten Hopp 127033
  
Karsten Hopp 127033
      if (useDiff)
Karsten Hopp 127033
  	wcscat(cmdStrW, L" -d");
Karsten Hopp 127033
--- 1015,1021 ----
Karsten Hopp 127033
  
Karsten Hopp 127033
      cmdlen = BUFSIZE;
Karsten Hopp 127033
      cmdStrW  = (wchar_t *) malloc(cmdlen * sizeof(wchar_t));
Karsten Hopp 127033
!     getGvimInvocationW(cmdStrW);
Karsten Hopp 127033
  
Karsten Hopp 127033
      if (useDiff)
Karsten Hopp 127033
  	wcscat(cmdStrW, L" -d");
Karsten Hopp 127033
*** ../vim-7.4.723/src/GvimExt/gvimext.h	2010-05-26 21:39:23.000000000 +0200
Karsten Hopp 127033
--- src/GvimExt/gvimext.h	2015-05-04 18:24:28.898738746 +0200
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 110,119 ****
Karsten Hopp 127033
--- 110,123 ----
Karsten Hopp 127033
  class CShellExt : public IContextMenu,
Karsten Hopp 127033
  			 IShellExtInit
Karsten Hopp 127033
  {
Karsten Hopp 127033
+ private:
Karsten Hopp 127033
+     BOOL LoadMenuIcon();
Karsten Hopp 127033
+ 
Karsten Hopp 127033
  protected:
Karsten Hopp 127033
      ULONG	 m_cRef;
Karsten Hopp 127033
      LPDATAOBJECT m_pDataObj;
Karsten Hopp 127033
      UINT	 m_edit_existing_off;
Karsten Hopp 127033
+     HBITMAP	 m_hVimIconBitmap;
Karsten Hopp 127033
  
Karsten Hopp 127033
      // For some reason, this callback must be static
Karsten Hopp 127033
      static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam);
Karsten Hopp 127033
*** ../vim-7.4.723/src/version.c	2015-05-04 17:50:25.613605986 +0200
Karsten Hopp 127033
--- src/version.c	2015-05-04 18:25:12.494251378 +0200
Karsten Hopp 127033
***************
Karsten Hopp 127033
*** 743,744 ****
Karsten Hopp 127033
--- 743,746 ----
Karsten Hopp 127033
  {   /* Add new patch number below this line */
Karsten Hopp 127033
+ /**/
Karsten Hopp 127033
+     724,
Karsten Hopp 127033
  /**/
Karsten Hopp 127033
Karsten Hopp 127033
-- 
Karsten Hopp 127033
How To Keep A Healthy Level Of Insanity:
Karsten Hopp 127033
3. Every time someone asks you to do something, ask if they want fries
Karsten Hopp 127033
   with that.
Karsten Hopp 127033
Karsten Hopp 127033
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 127033
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 127033
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 127033
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///