comparison src/GvimExt/gvimext.cpp @ 32491:32c9b7396a75 v9.0.1577

patch 9.0.1577: MS-Windows: context menu translations may be wrong Commit: https://github.com/vim/vim/commit/1271572a35ae215fa023d97db9896c5745591024 Author: K.Takata <kentkt@csc.jp> Date: Thu May 25 16:43:27 2023 +0100 patch 9.0.1577: MS-Windows: context menu translations may be wrong Problem: MS-Windows: context menu translations may be wrong. Solution: Set the encoding before using gettext(). (Ken Takata, closes #12441, closes #12431)
author Bram Moolenaar <Bram@vim.org>
date Thu, 25 May 2023 17:45:05 +0200
parents 64dac9ff015e
children 448aef880252
comparison
equal deleted inserted replaced
32490:4f54d3384e48 32491:32c9b7396a75
128 break; 128 break;
129 } 129 }
130 } 130 }
131 } 131 }
132 132
133 HBITMAP IconToBitmap(HICON hIcon, HBRUSH hBackground, int width, int height) 133 WCHAR *
134 { 134 utf8_to_utf16(const char *s)
135 HDC hDC = GetDC(NULL); 135 {
136 HDC hMemDC = CreateCompatibleDC(hDC); 136 int size = MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0);
137 HBITMAP hMemBmp = CreateCompatibleBitmap(hDC, width, height); 137 WCHAR *buf = (WCHAR *)malloc(size * sizeof(WCHAR));
138 HBITMAP hResultBmp = NULL; 138 MultiByteToWideChar(CP_UTF8, 0, s, -1, buf, size);
139 HGDIOBJ hOrgBMP = SelectObject(hMemDC, hMemBmp); 139 return buf;
140 140 }
141 DrawIconEx(hMemDC, 0, 0, hIcon, width, height, 0, hBackground, DI_NORMAL); 141
142 142 HBITMAP
143 hResultBmp = hMemBmp; 143 IconToBitmap(HICON hIcon, HBRUSH hBackground, int width, int height)
144 hMemBmp = NULL; 144 {
145 145 HDC hDC = GetDC(NULL);
146 SelectObject(hMemDC, hOrgBMP); 146 HDC hMemDC = CreateCompatibleDC(hDC);
147 DeleteDC(hMemDC); 147 HBITMAP hMemBmp = CreateCompatibleBitmap(hDC, width, height);
148 ReleaseDC(NULL, hDC); 148 HBITMAP hResultBmp = NULL;
149 DestroyIcon(hIcon); 149 HGDIOBJ hOrgBMP = SelectObject(hMemDC, hMemBmp);
150 return hResultBmp; 150
151 DrawIconEx(hMemDC, 0, 0, hIcon, width, height, 0, hBackground, DI_NORMAL);
152
153 hResultBmp = hMemBmp;
154 hMemBmp = NULL;
155
156 SelectObject(hMemDC, hOrgBMP);
157 DeleteDC(hMemDC);
158 ReleaseDC(NULL, hDC);
159 DestroyIcon(hIcon);
160 return hResultBmp;
151 } 161 }
152 162
153 // 163 //
154 // GETTEXT: translated messages and menu entries 164 // GETTEXT: translated messages and menu entries
155 // 165 //
156 #ifndef FEAT_GETTEXT 166 #ifndef FEAT_GETTEXT
157 # define _(x) x 167 # define _(x) x
168 # define W_impl(x) _wcsdup(L##x)
169 # define W(x) W_impl(x)
170 # define set_gettext_codeset() NULL
171 # define restore_gettext_codeset(x)
158 #else 172 #else
159 # define _(x) (*dyn_libintl_gettext)(x) 173 # define _(x) (*dyn_libintl_gettext)(x)
174 # define W(x) utf8_to_utf16(x)
160 # define VIMPACKAGE "vim" 175 # define VIMPACKAGE "vim"
161 # ifndef GETTEXT_DLL 176 # ifndef GETTEXT_DLL
162 # define GETTEXT_DLL "libintl.dll" 177 # define GETTEXT_DLL "libintl.dll"
163 # define GETTEXT_DLL_ALT "libintl-8.dll" 178 # define GETTEXT_DLL_ALT "libintl-8.dll"
164 # endif 179 # endif
165 180
166 // Dummy functions 181 // Dummy functions
167 static char *null_libintl_gettext(const char *); 182 static char *null_libintl_gettext(const char *);
168 static char *null_libintl_textdomain(const char *); 183 static char *null_libintl_textdomain(const char *);
169 static char *null_libintl_bindtextdomain(const char *, const char *); 184 static char *null_libintl_bindtextdomain(const char *, const char *);
185 static char *null_libintl_bind_textdomain_codeset(const char *, const char *);
170 static int dyn_libintl_init(char *dir); 186 static int dyn_libintl_init(char *dir);
171 static void dyn_libintl_end(void); 187 static void dyn_libintl_end(void);
172 188
173 static HINSTANCE hLibintlDLL = 0; 189 static HINSTANCE hLibintlDLL = 0;
174 static char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext; 190 static char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext;
175 static char *(*dyn_libintl_textdomain)(const char *) = null_libintl_textdomain; 191 static char *(*dyn_libintl_textdomain)(const char *) = null_libintl_textdomain;
176 static char *(*dyn_libintl_bindtextdomain)(const char *, const char *) 192 static char *(*dyn_libintl_bindtextdomain)(const char *, const char *)
177 = null_libintl_bindtextdomain; 193 = null_libintl_bindtextdomain;
194 static char *(*dyn_libintl_bind_textdomain_codeset)(const char *, const char *)
195 = null_libintl_bind_textdomain_codeset;
178 196
179 // 197 //
180 // Attempt to load libintl.dll. If it doesn't work, use dummy functions. 198 // Attempt to load libintl.dll. If it doesn't work, use dummy functions.
181 // "dir" is the directory where the libintl.dll might be. 199 // "dir" is the directory where the libintl.dll might be.
182 // Return 1 for success, 0 for failure. 200 // Return 1 for success, 0 for failure.
192 } libintl_entry[] = 210 } libintl_entry[] =
193 { 211 {
194 {(char *)"gettext", (FARPROC*)&dyn_libintl_gettext}, 212 {(char *)"gettext", (FARPROC*)&dyn_libintl_gettext},
195 {(char *)"textdomain", (FARPROC*)&dyn_libintl_textdomain}, 213 {(char *)"textdomain", (FARPROC*)&dyn_libintl_textdomain},
196 {(char *)"bindtextdomain", (FARPROC*)&dyn_libintl_bindtextdomain}, 214 {(char *)"bindtextdomain", (FARPROC*)&dyn_libintl_bindtextdomain},
215 {(char *)"bind_textdomain_codeset", (FARPROC*)&dyn_libintl_bind_textdomain_codeset},
197 {NULL, NULL} 216 {NULL, NULL}
198 }; 217 };
199 DWORD len, len2; 218 DWORD len, len2;
200 LPWSTR buf = NULL; 219 LPWSTR buf = NULL;
201 LPWSTR buf2 = NULL; 220 LPWSTR buf2 = NULL;
252 FreeLibrary(hLibintlDLL); 271 FreeLibrary(hLibintlDLL);
253 hLibintlDLL = NULL; 272 hLibintlDLL = NULL;
254 dyn_libintl_gettext = null_libintl_gettext; 273 dyn_libintl_gettext = null_libintl_gettext;
255 dyn_libintl_textdomain = null_libintl_textdomain; 274 dyn_libintl_textdomain = null_libintl_textdomain;
256 dyn_libintl_bindtextdomain = null_libintl_bindtextdomain; 275 dyn_libintl_bindtextdomain = null_libintl_bindtextdomain;
276 dyn_libintl_bind_textdomain_codeset = null_libintl_bind_textdomain_codeset;
257 } 277 }
258 278
259 static char * 279 static char *
260 null_libintl_gettext(const char *msgid) 280 null_libintl_gettext(const char *msgid)
261 { 281 {
262 return (char *)msgid; 282 return (char *)msgid;
263 } 283 }
264 284
265 static char * 285 static char *
286 null_libintl_textdomain(const char * /* domainname */)
287 {
288 return NULL;
289 }
290
291 static char *
266 null_libintl_bindtextdomain(const char * /* domainname */, const char * /* dirname */) 292 null_libintl_bindtextdomain(const char * /* domainname */, const char * /* dirname */)
267 { 293 {
268 return NULL; 294 return NULL;
269 } 295 }
270 296
271 static char * 297 static char *
272 null_libintl_textdomain(const char* /* domainname */) 298 null_libintl_bind_textdomain_codeset(const char * /* domainname */, const char * /* codeset */)
273 { 299 {
274 return NULL; 300 return NULL;
275 } 301 }
276 302
277 // 303 //
301 327
302 static void 328 static void
303 dyn_gettext_free(void) 329 dyn_gettext_free(void)
304 { 330 {
305 dyn_libintl_end(); 331 dyn_libintl_end();
332 }
333
334 //
335 // Use UTF-8 for gettext. Returns previous codeset.
336 //
337 static char *
338 set_gettext_codeset(void)
339 {
340 char *prev = dyn_libintl_bind_textdomain_codeset(VIMPACKAGE, NULL);
341 prev = _strdup((prev != NULL) ? prev : "char");
342 dyn_libintl_bind_textdomain_codeset(VIMPACKAGE, "utf-8");
343
344 return prev;
345 }
346
347 //
348 // Restore previous codeset for gettext.
349 //
350 static void
351 restore_gettext_codeset(char *prev)
352 {
353 dyn_libintl_bind_textdomain_codeset(VIMPACKAGE, prev);
354 free(prev);
306 } 355 }
307 #endif // FEAT_GETTEXT 356 #endif // FEAT_GETTEXT
308 357
309 // 358 //
310 // Global variables 359 // Global variables
581 { 630 {
582 UINT idCmd = idCmdFirst; 631 UINT idCmd = idCmdFirst;
583 632
584 hres = m_pDataObj->GetData(&fmte, &medium); 633 hres = m_pDataObj->GetData(&fmte, &medium);
585 if (medium.hGlobal) 634 if (medium.hGlobal)
586 cbFiles = DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, 0, 0); 635 cbFiles = DragQueryFileW((HDROP)medium.hGlobal, (UINT)-1, 0, 0);
587 636
588 // InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL); 637 // InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL);
589 638
590 // Initialize m_cntOfHWnd to 0 639 // Initialize m_cntOfHWnd to 0
591 m_cntOfHWnd = 0; 640 m_cntOfHWnd = 0;
605 NULL, NULL) == ERROR_SUCCESS) 654 NULL, NULL) == ERROR_SUCCESS)
606 showIcons = false; 655 showIcons = false;
607 RegCloseKey(keyhandle); 656 RegCloseKey(keyhandle);
608 } 657 }
609 658
659 // Use UTF-8 for gettext.
660 char *prev = set_gettext_codeset();
661
610 // Retrieve all the vim instances, unless disabled. 662 // Retrieve all the vim instances, unless disabled.
611 if (showExisting) 663 if (showExisting)
612 EnumWindows(EnumWindowsProc, (LPARAM)this); 664 EnumWindows(EnumWindowsProc, (LPARAM)this);
613 665
614 MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; 666 MENUITEMINFOW mii = { sizeof(MENUITEMINFOW) };
615 mii.fMask = MIIM_STRING | MIIM_ID; 667 mii.fMask = MIIM_STRING | MIIM_ID;
616 if (showIcons) 668 if (showIcons)
617 { 669 {
618 mii.fMask |= MIIM_BITMAP; 670 mii.fMask |= MIIM_BITMAP;
619 mii.hbmpItem = m_hVimIconBitmap; 671 mii.hbmpItem = m_hVimIconBitmap;
620 } 672 }
621 673
622 if (cbFiles > 1) 674 if (cbFiles > 1)
623 { 675 {
624 mii.wID = idCmd++; 676 mii.wID = idCmd++;
625 mii.dwTypeData = _("Edit with Vim using &tabpages"); 677 mii.dwTypeData = W(_("Edit with Vim using &tabpages"));
626 mii.cch = lstrlen(mii.dwTypeData); 678 mii.cch = wcslen(mii.dwTypeData);
627 InsertMenuItem(hMenu, indexMenu++, TRUE, &mii); 679 InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii);
680 free(mii.dwTypeData);
628 681
629 mii.wID = idCmd++; 682 mii.wID = idCmd++;
630 mii.dwTypeData = _("Edit with single &Vim"); 683 mii.dwTypeData = W(_("Edit with single &Vim"));
631 mii.cch = lstrlen(mii.dwTypeData); 684 mii.cch = wcslen(mii.dwTypeData);
632 InsertMenuItem(hMenu, indexMenu++, TRUE, &mii); 685 InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii);
686 free(mii.dwTypeData);
633 687
634 if (cbFiles <= 4) 688 if (cbFiles <= 4)
635 { 689 {
636 // Can edit up to 4 files in diff mode 690 // Can edit up to 4 files in diff mode
637 mii.wID = idCmd++; 691 mii.wID = idCmd++;
638 mii.dwTypeData = _("Diff with Vim"); 692 mii.dwTypeData = W(_("Diff with Vim"));
639 mii.cch = lstrlen(mii.dwTypeData); 693 mii.cch = wcslen(mii.dwTypeData);
640 InsertMenuItem(hMenu, indexMenu++, TRUE, &mii); 694 InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii);
695 free(mii.dwTypeData);
641 m_edit_existing_off = 3; 696 m_edit_existing_off = 3;
642 } 697 }
643 else 698 else
644 m_edit_existing_off = 2; 699 m_edit_existing_off = 2;
645 700
646 } 701 }
647 else 702 else
648 { 703 {
649 mii.wID = idCmd++; 704 mii.wID = idCmd++;
650 mii.dwTypeData = _("Edit with &Vim"); 705 mii.dwTypeData = W(_("Edit with &Vim"));
651 mii.cch = lstrlen(mii.dwTypeData); 706 mii.cch = wcslen(mii.dwTypeData);
652 InsertMenuItem(hMenu, indexMenu++, TRUE, &mii); 707 InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii);
708 free(mii.dwTypeData);
653 m_edit_existing_off = 1; 709 m_edit_existing_off = 1;
654 } 710 }
655 711
656 HMENU hSubMenu = NULL; 712 HMENU hSubMenu = NULL;
657 if (m_cntOfHWnd > 1) 713 if (m_cntOfHWnd > 1)
658 { 714 {
659 hSubMenu = CreatePopupMenu(); 715 hSubMenu = CreatePopupMenu();
660 mii.fMask |= MIIM_SUBMENU; 716 mii.fMask |= MIIM_SUBMENU;
661 mii.wID = idCmd; 717 mii.wID = idCmd;
662 mii.dwTypeData = _("Edit with existing Vim"); 718 mii.dwTypeData = W(_("Edit with existing Vim"));
663 mii.cch = lstrlen(mii.dwTypeData); 719 mii.cch = wcslen(mii.dwTypeData);
664 mii.hSubMenu = hSubMenu; 720 mii.hSubMenu = hSubMenu;
665 InsertMenuItem(hMenu, indexMenu++, TRUE, &mii); 721 InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii);
722 free(mii.dwTypeData);
666 mii.fMask = mii.fMask & ~MIIM_SUBMENU; 723 mii.fMask = mii.fMask & ~MIIM_SUBMENU;
667 mii.hSubMenu = NULL; 724 mii.hSubMenu = NULL;
668 } 725 }
669 // Now display all the vim instances 726 // Now display all the vim instances
670 for (int i = 0; i < m_cntOfHWnd; i++) 727 for (int i = 0; i < m_cntOfHWnd; i++)
671 { 728 {
672 char title[BUFSIZE]; 729 WCHAR title[BUFSIZE];
673 char temp[BUFSIZE]; 730 WCHAR temp[BUFSIZE];
674 int index; 731 int index;
675 HMENU hmenu; 732 HMENU hmenu;
676 733
677 // Obtain window title, continue if can not 734 // Obtain window title, continue if can not
678 if (GetWindowText(m_hWnd[i], title, BUFSIZE - 1) == 0) 735 if (GetWindowTextW(m_hWnd[i], title, BUFSIZE - 1) == 0)
679 continue; 736 continue;
680 // Truncate the title before the path, keep the file name 737 // Truncate the title before the path, keep the file name
681 char *pos = strchr(title, '('); 738 WCHAR *pos = wcschr(title, L'(');
682 if (pos != NULL) 739 if (pos != NULL)
683 { 740 {
684 if (pos > title && pos[-1] == ' ') 741 if (pos > title && pos[-1] == L' ')
685 --pos; 742 --pos;
686 *pos = 0; 743 *pos = 0;
687 } 744 }
688 // Now concatenate 745 // Now concatenate
689 if (m_cntOfHWnd > 1) 746 if (m_cntOfHWnd > 1)
690 temp[0] = '\0'; 747 temp[0] = L'\0';
691 else 748 else
692 { 749 {
693 strncpy(temp, _("Edit with existing Vim - "), BUFSIZE - 1); 750 WCHAR *s = W(_("Edit with existing Vim - "));
694 temp[BUFSIZE - 1] = '\0'; 751 wcsncpy(temp, s, BUFSIZE - 1);
752 temp[BUFSIZE - 1] = L'\0';
753 free(s);
695 } 754 }
696 strncat(temp, title, BUFSIZE - 1 - strlen(temp)); 755 wcsncat(temp, title, BUFSIZE - 1 - wcslen(temp));
697 temp[BUFSIZE - 1] = '\0'; 756 temp[BUFSIZE - 1] = L'\0';
698 757
699 mii.wID = idCmd++; 758 mii.wID = idCmd++;
700 mii.dwTypeData = temp; 759 mii.dwTypeData = temp;
701 mii.cch = lstrlen(mii.dwTypeData); 760 mii.cch = wcslen(mii.dwTypeData);
702 if (m_cntOfHWnd > 1) 761 if (m_cntOfHWnd > 1)
703 { 762 {
704 hmenu = hSubMenu; 763 hmenu = hSubMenu;
705 index = i; 764 index = i;
706 } 765 }
707 else 766 else
708 { 767 {
709 hmenu = hMenu; 768 hmenu = hMenu;
710 index = indexMenu++; 769 index = indexMenu++;
711 } 770 }
712 InsertMenuItem(hmenu, index, TRUE, &mii); 771 InsertMenuItemW(hmenu, index, TRUE, &mii);
713 } 772 }
714 // InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL); 773 // InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL);
774
775 // Restore previous codeset.
776 restore_gettext_codeset(prev);
715 777
716 // Must return number of menu items we added. 778 // Must return number of menu items we added.
717 return ResultFromShort(idCmd-idCmdFirst); 779 return ResultFromShort(idCmd-idCmdFirst);
718 } 780 }
719 781
817 UINT uFlags, 879 UINT uFlags,
818 UINT FAR * /* reserved */, 880 UINT FAR * /* reserved */,
819 LPSTR pszName, 881 LPSTR pszName,
820 UINT cchMax) 882 UINT cchMax)
821 { 883 {
822 if (uFlags == GCS_HELPTEXT && cchMax > 35) 884 // Use UTF-8 for gettext.
823 lstrcpy(pszName, _("Edits the selected file(s) with Vim")); 885 char *prev = set_gettext_codeset();
886
887 WCHAR *s = W(_("Edits the selected file(s) with Vim"));
888 if (uFlags == GCS_HELPTEXTW && cchMax > wcslen(s))
889 wcscpy((WCHAR *)pszName, s);
890 free(s);
891
892 // Restore previous codeset.
893 restore_gettext_codeset(prev);
824 894
825 return NOERROR; 895 return NOERROR;
826 } 896 }
827 897
828 BOOL CALLBACK CShellExt::EnumWindowsProc(HWND hWnd, LPARAM lParam) 898 BOOL CALLBACK CShellExt::EnumWindowsProc(HWND hWnd, LPARAM lParam)
829 { 899 {
830 char temp[BUFSIZE]; 900 char temp[BUFSIZE];
831 901
832 // First do a bunch of check 902 // First do a bunch of check
833 // No invisible window 903 // No invisible window
834 if (!IsWindowVisible(hWnd)) return TRUE; 904 if (!IsWindowVisible(hWnd))
905 return TRUE;
835 // No child window ??? 906 // No child window ???
836 // if (GetParent(hWnd)) return TRUE; 907 // if (GetParent(hWnd)) return TRUE;
837 // Class name should be Vim, if failed to get class name, return 908 // Class name should be Vim, if failed to get class name, return
838 if (GetClassName(hWnd, temp, sizeof(temp)) == 0) 909 if (GetClassName(hWnd, temp, sizeof(temp)) == 0)
839 return TRUE; 910 return TRUE;
840 // Compare class name to that of vim, if not, return 911 // Compare class name to that of vim, if not, return
841 if (_strnicmp(temp, "vim", sizeof("vim")) != 0) 912 if (_strnicmp(temp, "vim", sizeof("vim")) != 0)
842 return TRUE; 913 return TRUE;
843 // First check if the number of vim instance exceeds MAX_HWND 914 // First check if the number of vim instance exceeds MAX_HWND
844 CShellExt *cs = (CShellExt*) lParam; 915 CShellExt *cs = (CShellExt*) lParam;
845 if (cs->m_cntOfHWnd >= MAX_HWND) return TRUE; 916 if (cs->m_cntOfHWnd >= MAX_HWND)
917 return FALSE; // stop enumeration
846 // Now we get the vim window, put it into some kind of array 918 // Now we get the vim window, put it into some kind of array
847 cs->m_hWnd[cs->m_cntOfHWnd] = hWnd; 919 cs->m_hWnd[cs->m_cntOfHWnd] = hWnd;
848 cs->m_cntOfHWnd ++; 920 cs->m_cntOfHWnd ++;
849 921
850 return TRUE; // continue enumeration (otherwise this would be false) 922 return TRUE; // continue enumeration (otherwise this would be false)
851 } 923 }
852 924
853 BOOL CShellExt::LoadMenuIcon() 925 BOOL CShellExt::LoadMenuIcon()
854 { 926 {
855 char vimExeFile[BUFSIZE]; 927 char vimExeFile[BUFSIZE];
856 getGvimName(vimExeFile, 1); 928 getGvimName(vimExeFile, 1);
857 if (vimExeFile[0] == '\0') 929 if (vimExeFile[0] == '\0')
858 return FALSE; 930 return FALSE;
859 HICON hVimIcon; 931 HICON hVimIcon;
860 if (ExtractIconEx(vimExeFile, 0, NULL, &hVimIcon, 1) == 0) 932 if (ExtractIconEx(vimExeFile, 0, NULL, &hVimIcon, 1) == 0)
861 return FALSE; 933 return FALSE;
862 m_hVimIconBitmap = IconToBitmap(hVimIcon, 934 m_hVimIconBitmap = IconToBitmap(hVimIcon,
863 GetSysColorBrush(COLOR_MENU), 935 GetSysColorBrush(COLOR_MENU),
864 GetSystemMetrics(SM_CXSMICON), 936 GetSystemMetrics(SM_CXSMICON),
865 GetSystemMetrics(SM_CYSMICON)); 937 GetSystemMetrics(SM_CYSMICON));
866 return TRUE; 938 return TRUE;
867 } 939 }
868 940
869 static char * 941 static char *
870 searchpath(char *name) 942 searchpath(char *name)
871 { 943 {
946 NULL, // Process handle not inheritable. 1018 NULL, // Process handle not inheritable.
947 NULL, // Thread handle not inheritable. 1019 NULL, // Thread handle not inheritable.
948 FALSE, // Set handle inheritance to FALSE. 1020 FALSE, // Set handle inheritance to FALSE.
949 0, // No creation flags. 1021 0, // No creation flags.
950 NULL, // Use parent's environment block. 1022 NULL, // Use parent's environment block.
951 workingDir, // Use parent's starting directory. 1023 workingDir, // Use parent's starting directory.
952 &si, // Pointer to STARTUPINFO structure. 1024 &si, // Pointer to STARTUPINFO structure.
953 &pi) // Pointer to PROCESS_INFORMATION structure. 1025 &pi) // Pointer to PROCESS_INFORMATION structure.
954 ) 1026 )
955 { 1027 {
956 MessageBox( 1028 // Use UTF-8 for gettext.
957 hParent, 1029 char *prev = set_gettext_codeset();
958 _("Error creating process: Check if gvim is in your path!"), 1030
959 _("gvimext.dll error"), 1031 WCHAR *msg = W(_("Error creating process: Check if gvim is in your path!"));
960 MB_OK); 1032 WCHAR *title = W(_("gvimext.dll error"));
1033
1034 MessageBoxW(hParent, msg, title, MB_OK);
1035
1036 free(msg);
1037 free(title);
1038
1039 // Restore previous codeset.
1040 restore_gettext_codeset(prev);
961 } 1041 }
962 else 1042 else
963 { 1043 {
964 CloseHandle(pi.hProcess); 1044 CloseHandle(pi.hProcess);
965 CloseHandle(pi.hThread); 1045 CloseHandle(pi.hThread);