@@ -79,19 +79,24 @@ getGvimName(char *name, int runtime)
7979 strcpy (name, searchpath ((char *)" gvim.bat" ));
8080 if (name[0 ] == 0 )
8181 strcpy (name, " gvim" ); // finds gvim.bat or gvim.exe
82-
83- // avoid that Vim tries to expand wildcards in the file names
84- strcat (name, " --literal" );
8582 }
8683}
8784
8885 static void
89- getGvimNameW (wchar_t *nameW)
86+ getGvimInvocation (char *name, int runtime)
87+ {
88+ getGvimName (name, runtime);
89+ // avoid that Vim tries to expand wildcards in the file names
90+ strcat (name, " --literal" );
91+ }
92+
93+ static void
94+ getGvimInvocationW (wchar_t *nameW)
9095{
9196 char *name;
9297
9398 name = (char *)malloc (BUFSIZE );
94- getGvimName (name, 0 );
99+ getGvimInvocation (name, 0 );
95100 mbstowcs (nameW, name, BUFSIZE );
96101 free (name);
97102}
@@ -123,6 +128,26 @@ getRuntimeDir(char *buf)
123128 }
124129}
125130
131+ HBITMAP IconToBitmap (HICON hIcon, HBRUSH hBackground, int width, int height)
132+ {
133+ HDC hDC = GetDC (NULL );
134+ HDC hMemDC = CreateCompatibleDC (hDC);
135+ HBITMAP hMemBmp = CreateCompatibleBitmap (hDC, width, height);
136+ HBITMAP hResultBmp = NULL ;
137+ HGDIOBJ hOrgBMP = SelectObject (hMemDC, hMemBmp);
138+
139+ DrawIconEx (hMemDC, 0 , 0 , hIcon, width, height, 0 , hBackground, DI_NORMAL );
140+
141+ hResultBmp = hMemBmp;
142+ hMemBmp = NULL ;
143+
144+ SelectObject (hMemDC, hOrgBMP);
145+ DeleteDC (hMemDC);
146+ ReleaseDC (NULL , hDC);
147+ DestroyIcon (hIcon);
148+ return hResultBmp;
149+ }
150+
126151//
127152// GETTEXT: translated messages and menu entries
128153//
@@ -404,7 +429,7 @@ STDMETHODIMP CShellExtClassFactory::QueryInterface(REFIID riid,
404429{
405430 *ppv = NULL ;
406431
407- // Any interface on this object is the object pointer
432+ // any interface on this object is the object pointer
408433
409434 if (IsEqualIID (riid, IID_IUnknown) || IsEqualIID (riid, IID_IClassFactory))
410435 {
@@ -448,7 +473,7 @@ STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
448473 // QueryInterface with IID_IShellExtInit--this is how shell extensions are
449474 // initialized.
450475
451- LPCSHELLEXT pShellExt = new CShellExt (); // Create the CShellExt object
476+ LPCSHELLEXT pShellExt = new CShellExt (); // create the CShellExt object
452477
453478 if (NULL == pShellExt)
454479 return E_OUTOFMEMORY ;
@@ -469,6 +494,8 @@ CShellExt::CShellExt()
469494 m_pDataObj = NULL ;
470495
471496 inc_cRefThisDLL ();
497+
498+ LoadMenuIcon ();
472499}
473500
474501CShellExt::~CShellExt ()
@@ -477,6 +504,9 @@ CShellExt::~CShellExt()
477504 m_pDataObj->Release ();
478505
479506 dec_cRefThisDLL ();
507+
508+ if (m_hVimIconBitmap)
509+ DeleteObject (m_hVimIconBitmap);
480510}
481511
482512STDMETHODIMP CShellExt::QueryInterface (REFIID riid, LPVOID FAR *ppv)
@@ -597,6 +627,7 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
597627
598628 HKEY keyhandle;
599629 bool showExisting = true ;
630+ bool showIcons = true ;
600631
601632 // Check whether "Edit with existing Vim" entries are disabled.
602633 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE , " Software\\ Vim\\ Gvim" , 0 ,
@@ -605,35 +636,43 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
605636 if (RegQueryValueEx (keyhandle, " DisableEditWithExisting" , 0 , NULL ,
606637 NULL , NULL ) == ERROR_SUCCESS )
607638 showExisting = false ;
639+ if (RegQueryValueEx (keyhandle, " DisableContextMenuIcons" , 0 , NULL ,
640+ NULL , NULL ) == ERROR_SUCCESS )
641+ showIcons = false ;
608642 RegCloseKey (keyhandle);
609643 }
610644
611645 // Retrieve all the vim instances, unless disabled.
612646 if (showExisting)
613647 EnumWindows (EnumWindowsProc, (LPARAM )this );
614648
649+ MENUITEMINFO mii = { sizeof (MENUITEMINFO ) };
650+ mii.fMask = MIIM_STRING | MIIM_ID ;
651+ if (showIcons)
652+ {
653+ mii.fMask |= MIIM_BITMAP ;
654+ mii.hbmpItem = m_hVimIconBitmap;
655+ }
656+
615657 if (cbFiles > 1 )
616658 {
617- InsertMenu (hMenu,
618- indexMenu++,
619- MF_STRING |MF_BYPOSITION ,
620- idCmd++,
621- _ (" Edit with &multiple Vims" ));
622-
623- InsertMenu (hMenu,
624- indexMenu++,
625- MF_STRING |MF_BYPOSITION ,
626- idCmd++,
627- _ (" Edit with single &Vim" ));
659+ mii.wID = idCmd++;
660+ mii.dwTypeData = _ (" Edit with &multiple Vims" );
661+ mii.cch = lstrlen (mii.dwTypeData );
662+ InsertMenuItem (hMenu, indexMenu++, TRUE , &mii);
663+
664+ mii.wID = idCmd++;
665+ mii.dwTypeData = _ (" Edit with single &Vim" );
666+ mii.cch = lstrlen (mii.dwTypeData );
667+ InsertMenuItem (hMenu, indexMenu++, TRUE , &mii);
628668
629669 if (cbFiles <= 4 )
630670 {
631671 // Can edit up to 4 files in diff mode
632- InsertMenu (hMenu,
633- indexMenu++,
634- MF_STRING |MF_BYPOSITION ,
635- idCmd++,
636- _ (" Diff with Vim" ));
672+ mii.wID = idCmd++;
673+ mii.dwTypeData = _ (" Diff with Vim" );
674+ mii.cch = lstrlen (mii.dwTypeData );
675+ InsertMenuItem (hMenu, indexMenu++, TRUE , &mii);
637676 m_edit_existing_off = 3 ;
638677 }
639678 else
@@ -642,11 +681,10 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
642681 }
643682 else
644683 {
645- InsertMenu (hMenu,
646- indexMenu++,
647- MF_STRING |MF_BYPOSITION ,
648- idCmd++,
649- _ (" Edit with &Vim" ));
684+ mii.wID = idCmd++;
685+ mii.dwTypeData = _ (" Edit with &Vim" );
686+ mii.cch = lstrlen (mii.dwTypeData );
687+ InsertMenuItem (hMenu, indexMenu++, TRUE , &mii);
650688 m_edit_existing_off = 1 ;
651689 }
652690
@@ -672,11 +710,11 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
672710 temp[BUFSIZE - 1 ] = ' \0 ' ;
673711 strncat (temp, title, BUFSIZE - 1 - strlen (temp));
674712 temp[BUFSIZE - 1 ] = ' \0 ' ;
675- InsertMenu (hMenu,
676- indexMenu++,
677- MF_STRING | MF_BYPOSITION ,
678- idCmd++,
679- temp );
713+
714+ mii. wID = idCmd++;
715+ mii. dwTypeData = temp;
716+ mii. cch = lstrlen (mii. dwTypeData );
717+ InsertMenuItem (hMenu, indexMenu++, TRUE , &mii );
680718 }
681719 // InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL);
682720
@@ -813,6 +851,22 @@ BOOL CALLBACK CShellExt::EnumWindowsProc(HWND hWnd, LPARAM lParam)
813851 return TRUE ; // continue enumeration (otherwise this would be false)
814852}
815853
854+ BOOL CShellExt::LoadMenuIcon ()
855+ {
856+ char vimExeFile[BUFSIZE ];
857+ getGvimName (vimExeFile, 1 );
858+ if (vimExeFile[0 ] == ' \0 ' )
859+ return FALSE ;
860+ HICON hVimIcon;
861+ if (ExtractIconEx (vimExeFile, 0 , NULL , &hVimIcon, 1 ) == 0 )
862+ return FALSE ;
863+ m_hVimIconBitmap = IconToBitmap (hVimIcon,
864+ GetSysColorBrush (COLOR_MENU ),
865+ GetSystemMetrics (SM_CXSMICON ),
866+ GetSystemMetrics (SM_CYSMICON ));
867+ return TRUE ;
868+ }
869+
816870#ifdef WIN32
817871// This symbol is not defined in older versions of the SDK or Visual C++.
818872
@@ -893,7 +947,7 @@ STDMETHODIMP CShellExt::InvokeGvim(HWND hParent,
893947 m_szFileUserClickedOn,
894948 sizeof (m_szFileUserClickedOn));
895949
896- getGvimNameW (cmdStrW);
950+ getGvimInvocationW (cmdStrW);
897951 wcscat (cmdStrW, L" \" " );
898952
899953 if ((wcslen (cmdStrW) + wcslen (m_szFileUserClickedOn) + 2 ) < BUFSIZE )
@@ -961,7 +1015,7 @@ STDMETHODIMP CShellExt::InvokeSingleGvim(HWND hParent,
9611015
9621016 cmdlen = BUFSIZE ;
9631017 cmdStrW = (wchar_t *) malloc (cmdlen * sizeof (wchar_t ));
964- getGvimNameW (cmdStrW);
1018+ getGvimInvocationW (cmdStrW);
9651019
9661020 if (useDiff)
9671021 wcscat (cmdStrW, L" -d" );
0 commit comments