Mercurial > vim
comparison src/os_mswin.c @ 16196:973070a30381 v8.1.1103
patch 8.1.1103: MS-Windows: old API calls are no longer needed
commit https://github.com/vim/vim/commit/0eb035c974c47e65d32439b48e5a056b370ad429
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Apr 2 22:15:55 2019 +0200
patch 8.1.1103: MS-Windows: old API calls are no longer needed
Problem: MS-Windows: old API calls are no longer needed.
Solution: Always use the wide functions. (Ken Takata, closes https://github.com/vim/vim/issues/4199)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 02 Apr 2019 22:30:04 +0200 |
parents | cd5c83115ec6 |
children | b3bc3ba07bef |
comparison
equal
deleted
inserted
replaced
16195:4d55a37f8b1b | 16196:973070a30381 |
---|---|
103 typedef int LPWSTR; | 103 typedef int LPWSTR; |
104 typedef int LRESULT; | 104 typedef int LRESULT; |
105 typedef int MOUSE_EVENT_RECORD; | 105 typedef int MOUSE_EVENT_RECORD; |
106 typedef int NEWTEXTMETRICW; | 106 typedef int NEWTEXTMETRICW; |
107 typedef int PACL; | 107 typedef int PACL; |
108 typedef int PRINTDLG; | 108 typedef int PRINTDLGW; |
109 typedef int PSECURITY_DESCRIPTOR; | 109 typedef int PSECURITY_DESCRIPTOR; |
110 typedef int PSID; | 110 typedef int PSID; |
111 typedef int SECURITY_INFORMATION; | 111 typedef int SECURITY_INFORMATION; |
112 typedef int SHORT; | 112 typedef int SHORT; |
113 typedef int SMALL_RECT; | 113 typedef int SMALL_RECT; |
280 # ifdef FEAT_GUI_MSWIN | 280 # ifdef FEAT_GUI_MSWIN |
281 gui_mch_settitle(title, icon); | 281 gui_mch_settitle(title, icon); |
282 # else | 282 # else |
283 if (title != NULL) | 283 if (title != NULL) |
284 { | 284 { |
285 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | 285 WCHAR *wp = enc_to_utf16(title, NULL); |
286 { | 286 |
287 /* Convert the title from 'encoding' to the active codepage. */ | 287 if (wp == NULL) |
288 WCHAR *wp = enc_to_utf16(title, NULL); | 288 return; |
289 | 289 |
290 if (wp != NULL) | 290 SetConsoleTitleW(wp); |
291 { | 291 vim_free(wp); |
292 SetConsoleTitleW(wp); | 292 return; |
293 vim_free(wp); | |
294 return; | |
295 } | |
296 } | |
297 SetConsoleTitle((LPCSTR)title); | |
298 } | 293 } |
299 # endif | 294 # endif |
300 } | 295 } |
301 | 296 |
302 | 297 |
357 if (*fname == NUL) /* Borland behaves badly here - make it consistent */ | 352 if (*fname == NUL) /* Borland behaves badly here - make it consistent */ |
358 nResult = mch_dirname(buf, len); | 353 nResult = mch_dirname(buf, len); |
359 else | 354 else |
360 #endif | 355 #endif |
361 { | 356 { |
362 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | 357 WCHAR *wname; |
358 WCHAR wbuf[MAX_PATH]; | |
359 char_u *cname = NULL; | |
360 | |
361 wname = enc_to_utf16(fname, NULL); | |
362 if (wname != NULL && _wfullpath(wbuf, wname, MAX_PATH) != NULL) | |
363 { | 363 { |
364 WCHAR *wname; | 364 cname = utf16_to_enc((short_u *)wbuf, NULL); |
365 WCHAR wbuf[MAX_PATH]; | 365 if (cname != NULL) |
366 char_u *cname = NULL; | |
367 | |
368 /* Use the wide function: | |
369 * - convert the fname from 'encoding' to UCS2. | |
370 * - invoke _wfullpath() | |
371 * - convert the result from UCS2 to 'encoding'. | |
372 */ | |
373 wname = enc_to_utf16(fname, NULL); | |
374 if (wname != NULL && _wfullpath(wbuf, wname, MAX_PATH) != NULL) | |
375 { | 366 { |
376 cname = utf16_to_enc((short_u *)wbuf, NULL); | 367 vim_strncpy(buf, cname, len - 1); |
377 if (cname != NULL) | 368 nResult = OK; |
378 { | |
379 vim_strncpy(buf, cname, len - 1); | |
380 nResult = OK; | |
381 } | |
382 } | 369 } |
383 vim_free(wname); | |
384 vim_free(cname); | |
385 } | 370 } |
386 if (nResult == FAIL) /* fall back to non-wide function */ | 371 vim_free(wname); |
387 { | 372 vim_free(cname); |
388 if (_fullpath((char *)buf, (const char *)fname, len - 1) == NULL) | |
389 { | |
390 /* failed, use relative path name */ | |
391 vim_strncpy(buf, fname, len - 1); | |
392 } | |
393 else | |
394 nResult = OK; | |
395 } | |
396 } | 373 } |
397 | 374 |
398 #ifdef USE_FNAME_CASE | 375 #ifdef USE_FNAME_CASE |
399 fname_case(buf, len); | 376 fname_case(buf, len); |
400 #else | 377 #else |
476 #if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__) | 453 #if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__) |
477 # define OPEN_OH_ARGTYPE intptr_t | 454 # define OPEN_OH_ARGTYPE intptr_t |
478 #else | 455 #else |
479 # define OPEN_OH_ARGTYPE long | 456 # define OPEN_OH_ARGTYPE long |
480 #endif | 457 #endif |
481 | |
482 static int | |
483 stat_symlink_aware(const char *name, stat_T *stp) | |
484 { | |
485 #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__) | |
486 /* Work around for VC12 or earlier (and MinGW). stat() can't handle | |
487 * symlinks properly. | |
488 * VC9 or earlier: stat() doesn't support a symlink at all. It retrieves | |
489 * status of a symlink itself. | |
490 * VC10: stat() supports a symlink to a normal file, but it doesn't support | |
491 * a symlink to a directory (always returns an error). | |
492 * VC11 and VC12: stat() doesn't return an error for a symlink to a | |
493 * directory, but it doesn't set S_IFDIR flag. | |
494 * MinGW: Same as VC9. */ | |
495 WIN32_FIND_DATA findData; | |
496 HANDLE hFind, h; | |
497 DWORD attr = 0; | |
498 BOOL is_symlink = FALSE; | |
499 | |
500 hFind = FindFirstFile(name, &findData); | |
501 if (hFind != INVALID_HANDLE_VALUE) | |
502 { | |
503 attr = findData.dwFileAttributes; | |
504 if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) | |
505 && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) | |
506 is_symlink = TRUE; | |
507 FindClose(hFind); | |
508 } | |
509 if (is_symlink) | |
510 { | |
511 h = CreateFile(name, FILE_READ_ATTRIBUTES, | |
512 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, | |
513 OPEN_EXISTING, | |
514 (attr & FILE_ATTRIBUTE_DIRECTORY) | |
515 ? FILE_FLAG_BACKUP_SEMANTICS : 0, | |
516 NULL); | |
517 if (h != INVALID_HANDLE_VALUE) | |
518 { | |
519 int fd, n; | |
520 | |
521 fd = _open_osfhandle((OPEN_OH_ARGTYPE)h, _O_RDONLY); | |
522 n = _fstat(fd, (struct _stat *)stp); | |
523 if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY)) | |
524 stp->st_mode = (stp->st_mode & ~S_IFREG) | S_IFDIR; | |
525 _close(fd); | |
526 return n; | |
527 } | |
528 } | |
529 #endif | |
530 return stat(name, stp); | |
531 } | |
532 | 458 |
533 static int | 459 static int |
534 wstat_symlink_aware(const WCHAR *name, stat_T *stp) | 460 wstat_symlink_aware(const WCHAR *name, stat_T *stp) |
535 { | 461 { |
536 #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__) | 462 #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__) |
591 /* WinNT and later can use _MAX_PATH wide characters for a pathname, which | 517 /* WinNT and later can use _MAX_PATH wide characters for a pathname, which |
592 * means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is | 518 * means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is |
593 * UTF-8. */ | 519 * UTF-8. */ |
594 char_u buf[_MAX_PATH * 3 + 1]; | 520 char_u buf[_MAX_PATH * 3 + 1]; |
595 char_u *p; | 521 char_u *p; |
522 WCHAR *wp; | |
523 int n; | |
596 | 524 |
597 vim_strncpy((char_u *)buf, (char_u *)name, sizeof(buf) - 1); | 525 vim_strncpy((char_u *)buf, (char_u *)name, sizeof(buf) - 1); |
598 p = buf + STRLEN(buf); | 526 p = buf + STRLEN(buf); |
599 if (p > buf) | 527 if (p > buf) |
600 MB_PTR_BACK(buf, p); | 528 MB_PTR_BACK(buf, p); |
612 p = vim_strpbrk(p + 1, (char_u *)"\\/"); | 540 p = vim_strpbrk(p + 1, (char_u *)"\\/"); |
613 if (p == NULL) | 541 if (p == NULL) |
614 STRCAT(buf, "\\"); | 542 STRCAT(buf, "\\"); |
615 } | 543 } |
616 } | 544 } |
617 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | 545 |
618 { | 546 wp = enc_to_utf16(buf, NULL); |
619 WCHAR *wp = enc_to_utf16(buf, NULL); | 547 if (wp == NULL) |
620 int n; | 548 return -1; |
621 | 549 |
622 if (wp != NULL) | 550 n = wstat_symlink_aware(wp, stp); |
623 { | 551 vim_free(wp); |
624 n = wstat_symlink_aware(wp, stp); | 552 return n; |
625 vim_free(wp); | |
626 return n; | |
627 } | |
628 } | |
629 return stat_symlink_aware((char *)buf, stp); | |
630 } | 553 } |
631 | 554 |
632 #if defined(FEAT_GUI_MSWIN) || defined(PROTO) | 555 #if defined(FEAT_GUI_MSWIN) || defined(PROTO) |
633 void | 556 void |
634 mch_settmode(int tmode UNUSED) | 557 mch_settmode(int tmode UNUSED) |
756 * Returning 0 implies success; -1 implies failure. | 679 * Returning 0 implies success; -1 implies failure. |
757 */ | 680 */ |
758 int | 681 int |
759 mch_chdir(char *path) | 682 mch_chdir(char *path) |
760 { | 683 { |
684 WCHAR *p; | |
685 int n; | |
686 | |
761 if (path[0] == NUL) /* just checking... */ | 687 if (path[0] == NUL) /* just checking... */ |
762 return -1; | 688 return -1; |
763 | 689 |
764 if (p_verbose >= 5) | 690 if (p_verbose >= 5) |
765 { | 691 { |
777 } | 703 } |
778 | 704 |
779 if (*path == NUL) /* drive name only */ | 705 if (*path == NUL) /* drive name only */ |
780 return 0; | 706 return 0; |
781 | 707 |
782 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | 708 p = enc_to_utf16((char_u *)path, NULL); |
783 { | 709 if (p == NULL) |
784 WCHAR *p = enc_to_utf16((char_u *)path, NULL); | 710 return -1; |
785 int n; | 711 |
786 | 712 n = _wchdir(p); |
787 if (p != NULL) | 713 vim_free(p); |
788 { | 714 return n; |
789 n = _wchdir(p); | |
790 vim_free(p); | |
791 return n; | |
792 } | |
793 } | |
794 | |
795 return chdir(path); /* let the normal chdir() do the rest */ | |
796 } | 715 } |
797 | 716 |
798 | 717 |
799 #ifdef FEAT_GUI_MSWIN | 718 #ifdef FEAT_GUI_MSWIN |
800 /* | 719 /* |
1095 /*================================================================= | 1014 /*================================================================= |
1096 * Win32 printer stuff | 1015 * Win32 printer stuff |
1097 */ | 1016 */ |
1098 | 1017 |
1099 static HFONT prt_font_handles[2][2][2]; | 1018 static HFONT prt_font_handles[2][2][2]; |
1100 static PRINTDLG prt_dlg; | 1019 static PRINTDLGW prt_dlg; |
1101 static const int boldface[2] = {FW_REGULAR, FW_BOLD}; | 1020 static const int boldface[2] = {FW_REGULAR, FW_BOLD}; |
1102 static TEXTMETRIC prt_tm; | 1021 static TEXTMETRIC prt_tm; |
1103 static int prt_line_height; | 1022 static int prt_line_height; |
1104 static int prt_number_width; | 1023 static int prt_number_width; |
1105 static int prt_left_margin; | 1024 static int prt_left_margin; |
1117 #define IDC_PROGRESS 403 | 1036 #define IDC_PROGRESS 403 |
1118 | 1037 |
1119 static BOOL | 1038 static BOOL |
1120 vimSetDlgItemText(HWND hDlg, int nIDDlgItem, char_u *s) | 1039 vimSetDlgItemText(HWND hDlg, int nIDDlgItem, char_u *s) |
1121 { | 1040 { |
1122 WCHAR *wp = NULL; | 1041 WCHAR *wp; |
1123 BOOL ret; | 1042 BOOL ret; |
1124 | 1043 |
1125 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | 1044 wp = enc_to_utf16(s, NULL); |
1126 wp = enc_to_utf16(s, NULL); | 1045 if (wp == NULL) |
1127 if (wp != NULL) | 1046 return FALSE; |
1128 { | 1047 |
1129 ret = SetDlgItemTextW(hDlg, nIDDlgItem, wp); | 1048 ret = SetDlgItemTextW(hDlg, nIDDlgItem, wp); |
1130 vim_free(wp); | 1049 vim_free(wp); |
1131 return ret; | 1050 return ret; |
1132 } | |
1133 return SetDlgItemText(hDlg, nIDDlgItem, (LPCSTR)s); | |
1134 } | 1051 } |
1135 | 1052 |
1136 /* | 1053 /* |
1137 * Convert BGR to RGB for Windows GDI calls | 1054 * Convert BGR to RGB for Windows GDI calls |
1138 */ | 1055 */ |
1246 LPARAM lParam // message parameter | 1163 LPARAM lParam // message parameter |
1247 ) | 1164 ) |
1248 { | 1165 { |
1249 HWND hwndOwner; | 1166 HWND hwndOwner; |
1250 RECT rc, rcDlg, rcOwner; | 1167 RECT rc, rcDlg, rcOwner; |
1251 PRINTDLG *pPD; | 1168 PRINTDLGW *pPD; |
1252 | 1169 |
1253 if (uiMsg == WM_INITDIALOG) | 1170 if (uiMsg == WM_INITDIALOG) |
1254 { | 1171 { |
1255 // Get the owner window and dialog box rectangles. | 1172 // Get the owner window and dialog box rectangles. |
1256 if ((hwndOwner = GetParent(hDlg)) == NULL) | 1173 if ((hwndOwner = GetParent(hDlg)) == NULL) |
1278 rcOwner.top + (rc.bottom / 2), | 1195 rcOwner.top + (rc.bottom / 2), |
1279 0, 0, // ignores size arguments | 1196 0, 0, // ignores size arguments |
1280 SWP_NOSIZE); | 1197 SWP_NOSIZE); |
1281 | 1198 |
1282 /* tackle the printdlg copiesctrl problem */ | 1199 /* tackle the printdlg copiesctrl problem */ |
1283 pPD = (PRINTDLG *)lParam; | 1200 pPD = (PRINTDLGW *)lParam; |
1284 pPD->nCopies = (WORD)pPD->lCustData; | 1201 pPD->nCopies = (WORD)pPD->lCustData; |
1285 SetDlgItemInt( hDlg, edt3, pPD->nCopies, FALSE ); | 1202 SetDlgItemInt( hDlg, edt3, pPD->nCopies, FALSE ); |
1286 /* Bring the window to top */ | 1203 /* Bring the window to top */ |
1287 BringWindowToTop(GetParent(hDlg)); | 1204 BringWindowToTop(GetParent(hDlg)); |
1288 SetForegroundWindow(hDlg); | 1205 SetForegroundWindow(hDlg); |
1421 LOGFONTW fLogFont; | 1338 LOGFONTW fLogFont; |
1422 int pifItalic; | 1339 int pifItalic; |
1423 int pifBold; | 1340 int pifBold; |
1424 int pifUnderline; | 1341 int pifUnderline; |
1425 | 1342 |
1426 DEVMODE *mem; | 1343 DEVMODEW *mem; |
1427 DEVNAMES *devname; | 1344 DEVNAMES *devname; |
1428 int i; | 1345 int i; |
1429 | 1346 |
1430 bUserAbort = &(psettings->user_abort); | 1347 bUserAbort = &(psettings->user_abort); |
1431 vim_memset(&prt_dlg, 0, sizeof(PRINTDLG)); | 1348 vim_memset(&prt_dlg, 0, sizeof(PRINTDLGW)); |
1432 prt_dlg.lStructSize = sizeof(PRINTDLG); | 1349 prt_dlg.lStructSize = sizeof(PRINTDLGW); |
1433 #ifndef FEAT_GUI | 1350 #ifndef FEAT_GUI |
1434 GetConsoleHwnd(); /* get value of s_hwnd */ | 1351 GetConsoleHwnd(); /* get value of s_hwnd */ |
1435 #endif | 1352 #endif |
1436 prt_dlg.hwndOwner = s_hwnd; | 1353 prt_dlg.hwndOwner = s_hwnd; |
1437 prt_dlg.Flags = PD_NOPAGENUMS | PD_NOSELECTION | PD_RETURNDC; | 1354 prt_dlg.Flags = PD_NOPAGENUMS | PD_NOSELECTION | PD_RETURNDC; |
1468 if (*p_pdev != NUL) | 1385 if (*p_pdev != NUL) |
1469 prt_dlg.hDC = CreateDC(NULL, (LPCSTR)p_pdev, NULL, NULL); | 1386 prt_dlg.hDC = CreateDC(NULL, (LPCSTR)p_pdev, NULL, NULL); |
1470 else | 1387 else |
1471 { | 1388 { |
1472 prt_dlg.Flags |= PD_RETURNDEFAULT; | 1389 prt_dlg.Flags |= PD_RETURNDEFAULT; |
1473 if (PrintDlg(&prt_dlg) == 0) | 1390 if (PrintDlgW(&prt_dlg) == 0) |
1474 goto init_fail_dlg; | 1391 goto init_fail_dlg; |
1475 } | 1392 } |
1476 } | 1393 } |
1477 else if (PrintDlg(&prt_dlg) == 0) | 1394 else if (PrintDlgW(&prt_dlg) == 0) |
1478 goto init_fail_dlg; | 1395 goto init_fail_dlg; |
1479 else | 1396 else |
1480 { | 1397 { |
1481 /* | 1398 /* |
1482 * keep the previous driver context | 1399 * keep the previous driver context |
1508 /* | 1425 /* |
1509 * On some windows systems the nCopies parameter is not | 1426 * On some windows systems the nCopies parameter is not |
1510 * passed back correctly. It must be retrieved from the | 1427 * passed back correctly. It must be retrieved from the |
1511 * hDevMode struct. | 1428 * hDevMode struct. |
1512 */ | 1429 */ |
1513 mem = (DEVMODE *)GlobalLock(prt_dlg.hDevMode); | 1430 mem = (DEVMODEW *)GlobalLock(prt_dlg.hDevMode); |
1514 if (mem != NULL) | 1431 if (mem != NULL) |
1515 { | 1432 { |
1516 if (mem->dmCopies != 1) | 1433 if (mem->dmCopies != 1) |
1517 stored_nCopies = mem->dmCopies; | 1434 stored_nCopies = mem->dmCopies; |
1518 if ((mem->dmFields & DM_DUPLEX) && (mem->dmDuplex & ~DMDUP_SIMPLEX)) | 1435 if ((mem->dmFields & DM_DUPLEX) && (mem->dmDuplex & ~DMDUP_SIMPLEX)) |
1523 GlobalUnlock(prt_dlg.hDevMode); | 1440 GlobalUnlock(prt_dlg.hDevMode); |
1524 | 1441 |
1525 devname = (DEVNAMES *)GlobalLock(prt_dlg.hDevNames); | 1442 devname = (DEVNAMES *)GlobalLock(prt_dlg.hDevNames); |
1526 if (devname != 0) | 1443 if (devname != 0) |
1527 { | 1444 { |
1528 char_u *printer_name = (char_u *)devname + devname->wDeviceOffset; | 1445 WCHAR *wprinter_name = (WCHAR *)devname + devname->wDeviceOffset; |
1529 char_u *port_name = (char_u *)devname +devname->wOutputOffset; | 1446 WCHAR *wport_name = (WCHAR *)devname + devname->wOutputOffset; |
1530 char_u *text = (char_u *)_("to %s on %s"); | 1447 char_u *text = (char_u *)_("to %s on %s"); |
1531 char_u *printer_name_orig = printer_name; | 1448 char_u *printer_name = utf16_to_enc(wprinter_name, NULL); |
1532 char_u *port_name_orig = port_name; | 1449 char_u *port_name = utf16_to_enc(wport_name, NULL); |
1533 | 1450 |
1534 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | 1451 if (printer_name != NULL && port_name != NULL) |
1535 { | 1452 prt_name = alloc((unsigned)(STRLEN(printer_name) |
1536 char_u *to_free = NULL; | 1453 + STRLEN(port_name) + STRLEN(text))); |
1537 int maxlen; | |
1538 | |
1539 acp_to_enc(printer_name, (int)STRLEN(printer_name), &to_free, | |
1540 &maxlen); | |
1541 if (to_free != NULL) | |
1542 printer_name = to_free; | |
1543 acp_to_enc(port_name, (int)STRLEN(port_name), &to_free, &maxlen); | |
1544 if (to_free != NULL) | |
1545 port_name = to_free; | |
1546 } | |
1547 prt_name = alloc((unsigned)(STRLEN(printer_name) + STRLEN(port_name) | |
1548 + STRLEN(text))); | |
1549 if (prt_name != NULL) | 1454 if (prt_name != NULL) |
1550 wsprintf((char *)prt_name, (const char *)text, | 1455 wsprintf((char *)prt_name, (const char *)text, |
1551 printer_name, port_name); | 1456 printer_name, port_name); |
1552 if (printer_name != printer_name_orig) | 1457 vim_free(printer_name); |
1553 vim_free(printer_name); | 1458 vim_free(port_name); |
1554 if (port_name != port_name_orig) | |
1555 vim_free(port_name); | |
1556 } | 1459 } |
1557 GlobalUnlock(prt_dlg.hDevNames); | 1460 GlobalUnlock(prt_dlg.hDevNames); |
1558 | 1461 |
1559 /* | 1462 /* |
1560 * Initialise the font according to 'printfont' | 1463 * Initialise the font according to 'printfont' |
1637 | 1540 |
1638 | 1541 |
1639 int | 1542 int |
1640 mch_print_begin(prt_settings_T *psettings) | 1543 mch_print_begin(prt_settings_T *psettings) |
1641 { | 1544 { |
1642 int ret; | 1545 int ret = 0; |
1643 char szBuffer[300]; | 1546 char szBuffer[300]; |
1644 WCHAR *wp = NULL; | 1547 WCHAR *wp; |
1645 | 1548 |
1646 hDlgPrint = CreateDialog(GetModuleHandle(NULL), TEXT("PrintDlgBox"), | 1549 hDlgPrint = CreateDialog(GetModuleHandle(NULL), TEXT("PrintDlgBox"), |
1647 prt_dlg.hwndOwner, PrintDlgProc); | 1550 prt_dlg.hwndOwner, PrintDlgProc); |
1648 SetAbortProc(prt_dlg.hDC, AbortProc); | 1551 SetAbortProc(prt_dlg.hDC, AbortProc); |
1649 wsprintf(szBuffer, _("Printing '%s'"), gettail(psettings->jobname)); | 1552 wsprintf(szBuffer, _("Printing '%s'"), gettail(psettings->jobname)); |
1650 vimSetDlgItemText(hDlgPrint, IDC_PRINTTEXT1, (char_u *)szBuffer); | 1553 vimSetDlgItemText(hDlgPrint, IDC_PRINTTEXT1, (char_u *)szBuffer); |
1651 | 1554 |
1652 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | 1555 wp = enc_to_utf16(psettings->jobname, NULL); |
1653 wp = enc_to_utf16(psettings->jobname, NULL); | |
1654 if (wp != NULL) | 1556 if (wp != NULL) |
1655 { | 1557 { |
1656 DOCINFOW di; | 1558 DOCINFOW di; |
1657 | 1559 |
1658 vim_memset(&di, 0, sizeof(di)); | 1560 vim_memset(&di, 0, sizeof(di)); |
1659 di.cbSize = sizeof(di); | 1561 di.cbSize = sizeof(di); |
1660 di.lpszDocName = wp; | 1562 di.lpszDocName = wp; |
1661 ret = StartDocW(prt_dlg.hDC, &di); | 1563 ret = StartDocW(prt_dlg.hDC, &di); |
1662 vim_free(wp); | 1564 vim_free(wp); |
1663 } | |
1664 else | |
1665 { | |
1666 DOCINFO di; | |
1667 | |
1668 vim_memset(&di, 0, sizeof(di)); | |
1669 di.cbSize = sizeof(di); | |
1670 di.lpszDocName = (LPCSTR)psettings->jobname; | |
1671 ret = StartDoc(prt_dlg.hDC, &di); | |
1672 } | 1565 } |
1673 | 1566 |
1674 #ifdef FEAT_GUI | 1567 #ifdef FEAT_GUI |
1675 /* Give focus back to main window (when using MDI). */ | 1568 /* Give focus back to main window (when using MDI). */ |
1676 SetFocus(s_hwnd); | 1569 SetFocus(s_hwnd); |
1723 | 1616 |
1724 int | 1617 int |
1725 mch_print_text_out(char_u *p, int len) | 1618 mch_print_text_out(char_u *p, int len) |
1726 { | 1619 { |
1727 SIZE sz; | 1620 SIZE sz; |
1728 WCHAR *wp = NULL; | 1621 WCHAR *wp; |
1729 int wlen = len; | 1622 int wlen = len; |
1730 | 1623 int ret = FALSE; |
1731 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | 1624 |
1732 wp = enc_to_utf16(p, &wlen); | 1625 wp = enc_to_utf16(p, &wlen); |
1733 if (wp != NULL) | 1626 if (wp == NULL) |
1734 { | 1627 return FALSE; |
1735 int ret = FALSE; | 1628 |
1736 | 1629 TextOutW(prt_dlg.hDC, prt_pos_x + prt_left_margin, |
1737 TextOutW(prt_dlg.hDC, prt_pos_x + prt_left_margin, | 1630 prt_pos_y + prt_top_margin, wp, wlen); |
1738 prt_pos_y + prt_top_margin, wp, wlen); | 1631 GetTextExtentPoint32W(prt_dlg.hDC, wp, wlen, &sz); |
1739 GetTextExtentPoint32W(prt_dlg.hDC, wp, wlen, &sz); | 1632 vim_free(wp); |
1740 vim_free(wp); | |
1741 prt_pos_x += (sz.cx - prt_tm.tmOverhang); | |
1742 /* This is wrong when printing spaces for a TAB. */ | |
1743 if (p[len] != NUL) | |
1744 { | |
1745 wlen = MB_PTR2LEN(p + len); | |
1746 wp = enc_to_utf16(p + len, &wlen); | |
1747 if (wp != NULL) | |
1748 { | |
1749 GetTextExtentPoint32W(prt_dlg.hDC, wp, 1, &sz); | |
1750 ret = (prt_pos_x + prt_left_margin + sz.cx > prt_right_margin); | |
1751 vim_free(wp); | |
1752 } | |
1753 } | |
1754 return ret; | |
1755 } | |
1756 TextOut(prt_dlg.hDC, prt_pos_x + prt_left_margin, | |
1757 prt_pos_y + prt_top_margin, | |
1758 (LPCSTR)p, len); | |
1759 #ifndef FEAT_PROPORTIONAL_FONTS | |
1760 prt_pos_x += len * prt_tm.tmAveCharWidth; | |
1761 return (prt_pos_x + prt_left_margin + prt_tm.tmAveCharWidth | |
1762 + prt_tm.tmOverhang > prt_right_margin); | |
1763 #else | |
1764 GetTextExtentPoint32(prt_dlg.hDC, (LPCSTR)p, len, &sz); | |
1765 prt_pos_x += (sz.cx - prt_tm.tmOverhang); | 1633 prt_pos_x += (sz.cx - prt_tm.tmOverhang); |
1766 /* This is wrong when printing spaces for a TAB. */ | 1634 /* This is wrong when printing spaces for a TAB. */ |
1767 if (p[len] == NUL) | 1635 if (p[len] != NUL) |
1768 return FALSE; | 1636 { |
1769 GetTextExtentPoint32(prt_dlg.hDC, p + len, 1, &sz); | 1637 wlen = MB_PTR2LEN(p + len); |
1770 return (prt_pos_x + prt_left_margin + sz.cx > prt_right_margin); | 1638 wp = enc_to_utf16(p + len, &wlen); |
1771 #endif | 1639 if (wp != NULL) |
1640 { | |
1641 GetTextExtentPoint32W(prt_dlg.hDC, wp, 1, &sz); | |
1642 ret = (prt_pos_x + prt_left_margin + sz.cx > prt_right_margin); | |
1643 vim_free(wp); | |
1644 } | |
1645 } | |
1646 return ret; | |
1772 } | 1647 } |
1773 | 1648 |
1774 void | 1649 void |
1775 mch_print_set_font(int iBold, int iItalic, int iUnderline) | 1650 mch_print_set_font(int iBold, int iItalic, int iUnderline) |
1776 { | 1651 { |
1861 char_u * | 1736 char_u * |
1862 resolve_reparse_point(char_u *fname) | 1737 resolve_reparse_point(char_u *fname) |
1863 { | 1738 { |
1864 HANDLE h = INVALID_HANDLE_VALUE; | 1739 HANDLE h = INVALID_HANDLE_VALUE; |
1865 DWORD size; | 1740 DWORD size; |
1741 WCHAR *p; | |
1866 char_u *rfname = NULL; | 1742 char_u *rfname = NULL; |
1867 FILE_NAME_INFO_ *nameinfo = NULL; | 1743 FILE_NAME_INFO_ *nameinfo = NULL; |
1868 WCHAR buff[MAX_PATH], *volnames = NULL; | 1744 WCHAR buff[MAX_PATH], *volnames = NULL; |
1869 HANDLE hv; | 1745 HANDLE hv; |
1870 DWORD snfile, snfind; | 1746 DWORD snfile, snfind; |
1885 if (pGetFileInformationByHandleEx == NULL || | 1761 if (pGetFileInformationByHandleEx == NULL || |
1886 pGetVolumeInformationByHandleW == NULL) | 1762 pGetVolumeInformationByHandleW == NULL) |
1887 return NULL; | 1763 return NULL; |
1888 } | 1764 } |
1889 | 1765 |
1890 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | 1766 p = enc_to_utf16(fname, NULL); |
1891 { | 1767 if (p == NULL) |
1892 WCHAR *p; | 1768 goto fail; |
1893 | 1769 |
1894 p = enc_to_utf16(fname, NULL); | 1770 if ((GetFileAttributesW(p) & FILE_ATTRIBUTE_REPARSE_POINT) == 0) |
1895 if (p == NULL) | 1771 { |
1896 goto fail; | |
1897 | |
1898 if ((GetFileAttributesW(p) & FILE_ATTRIBUTE_REPARSE_POINT) == 0) | |
1899 { | |
1900 vim_free(p); | |
1901 goto fail; | |
1902 } | |
1903 | |
1904 h = CreateFileW(p, 0, 0, NULL, OPEN_EXISTING, | |
1905 FILE_FLAG_BACKUP_SEMANTICS, NULL); | |
1906 vim_free(p); | 1772 vim_free(p); |
1907 } | 1773 goto fail; |
1908 else | 1774 } |
1909 { | 1775 |
1910 if ((GetFileAttributes((char*) fname) & | 1776 h = CreateFileW(p, 0, 0, NULL, OPEN_EXISTING, |
1911 FILE_ATTRIBUTE_REPARSE_POINT) == 0) | 1777 FILE_FLAG_BACKUP_SEMANTICS, NULL); |
1912 goto fail; | 1778 vim_free(p); |
1913 | |
1914 h = CreateFile((char*) fname, 0, 0, NULL, OPEN_EXISTING, | |
1915 FILE_FLAG_BACKUP_SEMANTICS, NULL); | |
1916 } | |
1917 | 1779 |
1918 if (h == INVALID_HANDLE_VALUE) | 1780 if (h == INVALID_HANDLE_VALUE) |
1919 goto fail; | 1781 goto fail; |
1920 | 1782 |
1921 size = sizeof(FILE_NAME_INFO_) + sizeof(WCHAR) * (MAX_PATH - 1); | 1783 size = sizeof(FILE_NAME_INFO_) + sizeof(WCHAR) * (MAX_PATH - 1); |
1986 { | 1848 { |
1987 HRESULT hr; | 1849 HRESULT hr; |
1988 IShellLink *psl = NULL; | 1850 IShellLink *psl = NULL; |
1989 IPersistFile *ppf = NULL; | 1851 IPersistFile *ppf = NULL; |
1990 OLECHAR wsz[MAX_PATH]; | 1852 OLECHAR wsz[MAX_PATH]; |
1991 WIN32_FIND_DATA ffd; // we get those free of charge | |
1992 CHAR buf[MAX_PATH]; // could have simply reused 'wsz'... | |
1993 char_u *rfname = NULL; | 1853 char_u *rfname = NULL; |
1994 int len; | 1854 int len; |
1995 IShellLinkW *pslw = NULL; | 1855 IShellLinkW *pslw = NULL; |
1996 WIN32_FIND_DATAW ffdw; // we get those free of charge | 1856 WIN32_FIND_DATAW ffdw; // we get those free of charge |
1997 | 1857 |
2003 if (len <= 4 || STRNICMP(fname + len - 4, ".lnk", 4) != 0) | 1863 if (len <= 4 || STRNICMP(fname + len - 4, ".lnk", 4) != 0) |
2004 return rfname; | 1864 return rfname; |
2005 | 1865 |
2006 CoInitialize(NULL); | 1866 CoInitialize(NULL); |
2007 | 1867 |
2008 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | |
2009 { | |
2010 // create a link manager object and request its interface | |
2011 hr = CoCreateInstance( | |
2012 &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, | |
2013 &IID_IShellLinkW, (void**)&pslw); | |
2014 if (hr == S_OK) | |
2015 { | |
2016 WCHAR *p = enc_to_utf16(fname, NULL); | |
2017 | |
2018 if (p != NULL) | |
2019 { | |
2020 // Get a pointer to the IPersistFile interface. | |
2021 hr = pslw->lpVtbl->QueryInterface( | |
2022 pslw, &IID_IPersistFile, (void**)&ppf); | |
2023 if (hr != S_OK) | |
2024 goto shortcut_errorw; | |
2025 | |
2026 // "load" the name and resolve the link | |
2027 hr = ppf->lpVtbl->Load(ppf, p, STGM_READ); | |
2028 if (hr != S_OK) | |
2029 goto shortcut_errorw; | |
2030 # if 0 // This makes Vim wait a long time if the target does not exist. | |
2031 hr = pslw->lpVtbl->Resolve(pslw, NULL, SLR_NO_UI); | |
2032 if (hr != S_OK) | |
2033 goto shortcut_errorw; | |
2034 # endif | |
2035 | |
2036 // Get the path to the link target. | |
2037 ZeroMemory(wsz, MAX_PATH * sizeof(WCHAR)); | |
2038 hr = pslw->lpVtbl->GetPath(pslw, wsz, MAX_PATH, &ffdw, 0); | |
2039 if (hr == S_OK && wsz[0] != NUL) | |
2040 rfname = utf16_to_enc(wsz, NULL); | |
2041 | |
2042 shortcut_errorw: | |
2043 vim_free(p); | |
2044 goto shortcut_end; | |
2045 } | |
2046 } | |
2047 goto shortcut_end; | |
2048 } | |
2049 // create a link manager object and request its interface | 1868 // create a link manager object and request its interface |
2050 hr = CoCreateInstance( | 1869 hr = CoCreateInstance( |
2051 &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, | 1870 &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, |
2052 &IID_IShellLink, (void**)&psl); | 1871 &IID_IShellLinkW, (void**)&pslw); |
2053 if (hr != S_OK) | 1872 if (hr == S_OK) |
2054 goto shortcut_end; | 1873 { |
2055 | 1874 WCHAR *p = enc_to_utf16(fname, NULL); |
2056 // Get a pointer to the IPersistFile interface. | 1875 |
2057 hr = psl->lpVtbl->QueryInterface( | 1876 if (p != NULL) |
2058 psl, &IID_IPersistFile, (void**)&ppf); | 1877 { |
2059 if (hr != S_OK) | 1878 // Get a pointer to the IPersistFile interface. |
2060 goto shortcut_end; | 1879 hr = pslw->lpVtbl->QueryInterface( |
2061 | 1880 pslw, &IID_IPersistFile, (void**)&ppf); |
2062 // full path string must be in Unicode. | 1881 if (hr != S_OK) |
2063 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)fname, -1, wsz, MAX_PATH); | 1882 goto shortcut_errorw; |
2064 | 1883 |
2065 // "load" the name and resolve the link | 1884 // "load" the name and resolve the link |
2066 hr = ppf->lpVtbl->Load(ppf, wsz, STGM_READ); | 1885 hr = ppf->lpVtbl->Load(ppf, p, STGM_READ); |
2067 if (hr != S_OK) | 1886 if (hr != S_OK) |
2068 goto shortcut_end; | 1887 goto shortcut_errorw; |
2069 # if 0 // This makes Vim wait a long time if the target doesn't exist. | 1888 # if 0 // This makes Vim wait a long time if the target does not exist. |
2070 hr = psl->lpVtbl->Resolve(psl, NULL, SLR_NO_UI); | 1889 hr = pslw->lpVtbl->Resolve(pslw, NULL, SLR_NO_UI); |
2071 if (hr != S_OK) | 1890 if (hr != S_OK) |
2072 goto shortcut_end; | 1891 goto shortcut_errorw; |
2073 # endif | 1892 # endif |
2074 | 1893 |
2075 // Get the path to the link target. | 1894 // Get the path to the link target. |
2076 ZeroMemory(buf, MAX_PATH); | 1895 ZeroMemory(wsz, MAX_PATH * sizeof(WCHAR)); |
2077 hr = psl->lpVtbl->GetPath(psl, buf, MAX_PATH, &ffd, 0); | 1896 hr = pslw->lpVtbl->GetPath(pslw, wsz, MAX_PATH, &ffdw, 0); |
2078 if (hr == S_OK && buf[0] != NUL) | 1897 if (hr == S_OK && wsz[0] != NUL) |
2079 rfname = vim_strsave((char_u *)buf); | 1898 rfname = utf16_to_enc(wsz, NULL); |
2080 | 1899 |
2081 shortcut_end: | 1900 shortcut_errorw: |
1901 vim_free(p); | |
1902 } | |
1903 } | |
1904 | |
2082 // Release all interface pointers (both belong to the same object) | 1905 // Release all interface pointers (both belong to the same object) |
2083 if (ppf != NULL) | 1906 if (ppf != NULL) |
2084 ppf->lpVtbl->Release(ppf); | 1907 ppf->lpVtbl->Release(ppf); |
2085 if (psl != NULL) | 1908 if (psl != NULL) |
2086 psl->lpVtbl->Release(psl); | 1909 psl->lpVtbl->Release(psl); |