Mercurial > vim
comparison src/GvimExt/gvimext.cpp @ 6805:81cb471657e0 v7.4.724
patch 7.4.724
Problem: Vim icon does not show in Windows context menu. (issue 249)
Solution: Load the icon in GvimExt.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Mon, 04 May 2015 18:27:36 +0200 |
parents | 04736b4030ec |
children | 1e48ffa2d697 |
comparison
equal
deleted
inserted
replaced
6804:0d87f7311e5b | 6805:81cb471657e0 |
---|---|
77 // search for the batch file or a name without a path. | 77 // search for the batch file or a name without a path. |
78 if (name[0] == 0) | 78 if (name[0] == 0) |
79 strcpy(name, searchpath((char *)"gvim.bat")); | 79 strcpy(name, searchpath((char *)"gvim.bat")); |
80 if (name[0] == 0) | 80 if (name[0] == 0) |
81 strcpy(name, "gvim"); // finds gvim.bat or gvim.exe | 81 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"); | |
85 } | 82 } |
86 } | 83 } |
87 | 84 |
88 static void | 85 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) | |
90 { | 95 { |
91 char *name; | 96 char *name; |
92 | 97 |
93 name = (char *)malloc(BUFSIZE); | 98 name = (char *)malloc(BUFSIZE); |
94 getGvimName(name, 0); | 99 getGvimInvocation(name, 0); |
95 mbstowcs(nameW, name, BUFSIZE); | 100 mbstowcs(nameW, name, BUFSIZE); |
96 free(name); | 101 free(name); |
97 } | 102 } |
98 | 103 |
99 // | 104 // |
119 { | 124 { |
120 buf[idx + 1] = 0; | 125 buf[idx + 1] = 0; |
121 break; | 126 break; |
122 } | 127 } |
123 } | 128 } |
129 } | |
130 | |
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; | |
124 } | 149 } |
125 | 150 |
126 // | 151 // |
127 // GETTEXT: translated messages and menu entries | 152 // GETTEXT: translated messages and menu entries |
128 // | 153 // |
402 STDMETHODIMP CShellExtClassFactory::QueryInterface(REFIID riid, | 427 STDMETHODIMP CShellExtClassFactory::QueryInterface(REFIID riid, |
403 LPVOID FAR *ppv) | 428 LPVOID FAR *ppv) |
404 { | 429 { |
405 *ppv = NULL; | 430 *ppv = NULL; |
406 | 431 |
407 // Any interface on this object is the object pointer | 432 // any interface on this object is the object pointer |
408 | 433 |
409 if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory)) | 434 if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory)) |
410 { | 435 { |
411 *ppv = (LPCLASSFACTORY)this; | 436 *ppv = (LPCLASSFACTORY)this; |
412 | 437 |
446 | 471 |
447 // Create the main shell extension object. The shell will then call | 472 // Create the main shell extension object. The shell will then call |
448 // QueryInterface with IID_IShellExtInit--this is how shell extensions are | 473 // QueryInterface with IID_IShellExtInit--this is how shell extensions are |
449 // initialized. | 474 // initialized. |
450 | 475 |
451 LPCSHELLEXT pShellExt = new CShellExt(); //Create the CShellExt object | 476 LPCSHELLEXT pShellExt = new CShellExt(); // create the CShellExt object |
452 | 477 |
453 if (NULL == pShellExt) | 478 if (NULL == pShellExt) |
454 return E_OUTOFMEMORY; | 479 return E_OUTOFMEMORY; |
455 | 480 |
456 return pShellExt->QueryInterface(riid, ppvObj); | 481 return pShellExt->QueryInterface(riid, ppvObj); |
467 { | 492 { |
468 m_cRef = 0L; | 493 m_cRef = 0L; |
469 m_pDataObj = NULL; | 494 m_pDataObj = NULL; |
470 | 495 |
471 inc_cRefThisDLL(); | 496 inc_cRefThisDLL(); |
497 | |
498 LoadMenuIcon(); | |
472 } | 499 } |
473 | 500 |
474 CShellExt::~CShellExt() | 501 CShellExt::~CShellExt() |
475 { | 502 { |
476 if (m_pDataObj) | 503 if (m_pDataObj) |
477 m_pDataObj->Release(); | 504 m_pDataObj->Release(); |
478 | 505 |
479 dec_cRefThisDLL(); | 506 dec_cRefThisDLL(); |
507 | |
508 if (m_hVimIconBitmap) | |
509 DeleteObject(m_hVimIconBitmap); | |
480 } | 510 } |
481 | 511 |
482 STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv) | 512 STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv) |
483 { | 513 { |
484 *ppv = NULL; | 514 *ppv = NULL; |
595 // Initialize m_cntOfHWnd to 0 | 625 // Initialize m_cntOfHWnd to 0 |
596 m_cntOfHWnd = 0; | 626 m_cntOfHWnd = 0; |
597 | 627 |
598 HKEY keyhandle; | 628 HKEY keyhandle; |
599 bool showExisting = true; | 629 bool showExisting = true; |
630 bool showIcons = true; | |
600 | 631 |
601 // Check whether "Edit with existing Vim" entries are disabled. | 632 // Check whether "Edit with existing Vim" entries are disabled. |
602 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0, | 633 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0, |
603 KEY_READ, &keyhandle) == ERROR_SUCCESS) | 634 KEY_READ, &keyhandle) == ERROR_SUCCESS) |
604 { | 635 { |
605 if (RegQueryValueEx(keyhandle, "DisableEditWithExisting", 0, NULL, | 636 if (RegQueryValueEx(keyhandle, "DisableEditWithExisting", 0, NULL, |
606 NULL, NULL) == ERROR_SUCCESS) | 637 NULL, NULL) == ERROR_SUCCESS) |
607 showExisting = false; | 638 showExisting = false; |
639 if (RegQueryValueEx(keyhandle, "DisableContextMenuIcons", 0, NULL, | |
640 NULL, NULL) == ERROR_SUCCESS) | |
641 showIcons = false; | |
608 RegCloseKey(keyhandle); | 642 RegCloseKey(keyhandle); |
609 } | 643 } |
610 | 644 |
611 // Retrieve all the vim instances, unless disabled. | 645 // Retrieve all the vim instances, unless disabled. |
612 if (showExisting) | 646 if (showExisting) |
613 EnumWindows(EnumWindowsProc, (LPARAM)this); | 647 EnumWindows(EnumWindowsProc, (LPARAM)this); |
614 | 648 |
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 | |
615 if (cbFiles > 1) | 657 if (cbFiles > 1) |
616 { | 658 { |
617 InsertMenu(hMenu, | 659 mii.wID = idCmd++; |
618 indexMenu++, | 660 mii.dwTypeData = _("Edit with &multiple Vims"); |
619 MF_STRING|MF_BYPOSITION, | 661 mii.cch = lstrlen(mii.dwTypeData); |
620 idCmd++, | 662 InsertMenuItem(hMenu, indexMenu++, TRUE, &mii); |
621 _("Edit with &multiple Vims")); | 663 |
622 | 664 mii.wID = idCmd++; |
623 InsertMenu(hMenu, | 665 mii.dwTypeData = _("Edit with single &Vim"); |
624 indexMenu++, | 666 mii.cch = lstrlen(mii.dwTypeData); |
625 MF_STRING|MF_BYPOSITION, | 667 InsertMenuItem(hMenu, indexMenu++, TRUE, &mii); |
626 idCmd++, | |
627 _("Edit with single &Vim")); | |
628 | 668 |
629 if (cbFiles <= 4) | 669 if (cbFiles <= 4) |
630 { | 670 { |
631 // Can edit up to 4 files in diff mode | 671 // Can edit up to 4 files in diff mode |
632 InsertMenu(hMenu, | 672 mii.wID = idCmd++; |
633 indexMenu++, | 673 mii.dwTypeData = _("Diff with Vim"); |
634 MF_STRING|MF_BYPOSITION, | 674 mii.cch = lstrlen(mii.dwTypeData); |
635 idCmd++, | 675 InsertMenuItem(hMenu, indexMenu++, TRUE, &mii); |
636 _("Diff with Vim")); | |
637 m_edit_existing_off = 3; | 676 m_edit_existing_off = 3; |
638 } | 677 } |
639 else | 678 else |
640 m_edit_existing_off = 2; | 679 m_edit_existing_off = 2; |
641 | 680 |
642 } | 681 } |
643 else | 682 else |
644 { | 683 { |
645 InsertMenu(hMenu, | 684 mii.wID = idCmd++; |
646 indexMenu++, | 685 mii.dwTypeData = _("Edit with &Vim"); |
647 MF_STRING|MF_BYPOSITION, | 686 mii.cch = lstrlen(mii.dwTypeData); |
648 idCmd++, | 687 InsertMenuItem(hMenu, indexMenu++, TRUE, &mii); |
649 _("Edit with &Vim")); | |
650 m_edit_existing_off = 1; | 688 m_edit_existing_off = 1; |
651 } | 689 } |
652 | 690 |
653 // Now display all the vim instances | 691 // Now display all the vim instances |
654 for (int i = 0; i < m_cntOfHWnd; i++) | 692 for (int i = 0; i < m_cntOfHWnd; i++) |
670 // Now concatenate | 708 // Now concatenate |
671 strncpy(temp, _("Edit with existing Vim - "), BUFSIZE - 1); | 709 strncpy(temp, _("Edit with existing Vim - "), BUFSIZE - 1); |
672 temp[BUFSIZE - 1] = '\0'; | 710 temp[BUFSIZE - 1] = '\0'; |
673 strncat(temp, title, BUFSIZE - 1 - strlen(temp)); | 711 strncat(temp, title, BUFSIZE - 1 - strlen(temp)); |
674 temp[BUFSIZE - 1] = '\0'; | 712 temp[BUFSIZE - 1] = '\0'; |
675 InsertMenu(hMenu, | 713 |
676 indexMenu++, | 714 mii.wID = idCmd++; |
677 MF_STRING|MF_BYPOSITION, | 715 mii.dwTypeData = temp; |
678 idCmd++, | 716 mii.cch = lstrlen(mii.dwTypeData); |
679 temp); | 717 InsertMenuItem(hMenu, indexMenu++, TRUE, &mii); |
680 } | 718 } |
681 // InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL); | 719 // InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL); |
682 | 720 |
683 // Must return number of menu items we added. | 721 // Must return number of menu items we added. |
684 return ResultFromShort(idCmd-idCmdFirst); | 722 return ResultFromShort(idCmd-idCmdFirst); |
811 cs->m_cntOfHWnd ++; | 849 cs->m_cntOfHWnd ++; |
812 | 850 |
813 return TRUE; // continue enumeration (otherwise this would be false) | 851 return TRUE; // continue enumeration (otherwise this would be false) |
814 } | 852 } |
815 | 853 |
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 | |
816 #ifdef WIN32 | 870 #ifdef WIN32 |
817 // This symbol is not defined in older versions of the SDK or Visual C++. | 871 // This symbol is not defined in older versions of the SDK or Visual C++. |
818 | 872 |
819 #ifndef VER_PLATFORM_WIN32_WINDOWS | 873 #ifndef VER_PLATFORM_WIN32_WINDOWS |
820 # define VER_PLATFORM_WIN32_WINDOWS 1 | 874 # define VER_PLATFORM_WIN32_WINDOWS 1 |
891 DragQueryFileW((HDROP)medium.hGlobal, | 945 DragQueryFileW((HDROP)medium.hGlobal, |
892 i, | 946 i, |
893 m_szFileUserClickedOn, | 947 m_szFileUserClickedOn, |
894 sizeof(m_szFileUserClickedOn)); | 948 sizeof(m_szFileUserClickedOn)); |
895 | 949 |
896 getGvimNameW(cmdStrW); | 950 getGvimInvocationW(cmdStrW); |
897 wcscat(cmdStrW, L" \""); | 951 wcscat(cmdStrW, L" \""); |
898 | 952 |
899 if ((wcslen(cmdStrW) + wcslen(m_szFileUserClickedOn) + 2) < BUFSIZE) | 953 if ((wcslen(cmdStrW) + wcslen(m_szFileUserClickedOn) + 2) < BUFSIZE) |
900 { | 954 { |
901 wcscat(cmdStrW, m_szFileUserClickedOn); | 955 wcscat(cmdStrW, m_szFileUserClickedOn); |
959 size_t len; | 1013 size_t len; |
960 UINT i; | 1014 UINT i; |
961 | 1015 |
962 cmdlen = BUFSIZE; | 1016 cmdlen = BUFSIZE; |
963 cmdStrW = (wchar_t *) malloc(cmdlen * sizeof(wchar_t)); | 1017 cmdStrW = (wchar_t *) malloc(cmdlen * sizeof(wchar_t)); |
964 getGvimNameW(cmdStrW); | 1018 getGvimInvocationW(cmdStrW); |
965 | 1019 |
966 if (useDiff) | 1020 if (useDiff) |
967 wcscat(cmdStrW, L" -d"); | 1021 wcscat(cmdStrW, L" -d"); |
968 for (i = 0; i < cbFiles; i++) | 1022 for (i = 0; i < cbFiles; i++) |
969 { | 1023 { |