on windows [tk_getOpenFile -multiple 1] returns wrong results,
when one or multiple file name, containing a path, are entered maunally.
The resulting file names get the current path prepended, regardless
wether they contain already a path or not.
Since 8.5.9 the code in GetFileNameW() and OFNHookProcW() do their own buffer/selection handling
which is somehow buggy ;-(
Here are the steps to reproduce the bug with tcl/tk 8.5.11 on windows:
tk_getOpenFile -multiple 1 -initialdir c:/windows
#(enter c:\autoexec.bat)
-> C:/WINDOWS/c:/autoexec.bat
The problem is that OFNHookProcW (and OFNHookProcA) prepend the -initialdir to the result regardless of whether the result is an absolute path or not. The attached patch works for me. I have tested only the OFNHookProcW() diff, please someone take a look at the OFNHookProcA() diff whether it has the correct functions for the non-WCHAR types.
I know there was a way to attach files...but I don't find it right now, so here is the patch (hopefully not mangled)
diff -u tk8.5.13/win/tkWinDialog.c.orig tk8.5.13/win/tkWinDialog.c
--- tk8.5.13/win/tkWinDialog.c.orig 2012-11-06 16:08:56.000000000 +0100
+++ tk8.5.13/win/tkWinDialog.c 2012-11-14 13:59:51.000000000 +0100
@@ -1066,14 +1066,21 @@
}
*tmp = '\0'; /* Second NULL terminator. */
} else {
- buffer[selsize] = '\0'; /* Second NULL terminator. */
-
/*
- * Replace directory terminating NULL with a backslash.
+ * Replace directory terminating NULL with a backslash,
+ * but only if not an absolute path
*/
-
- buffer--;
- *buffer = '\\';
+ Tcl_DString tmpfile;
+ (void) ConvertExternalFilename(TkWinGetUnicodeEncoding(), (char *) buffer, &tmpfile);
+ if (TCL_PATH_ABSOLUTE == Tcl_GetPathType(Tcl_DStringValue(&tmpfile))) {
+ /* re-get the full path to the start of the buffer */
+ buffer = (WCHAR *) ofnData->dynFileBuffer;
+ SendMessageW(hdlg, CDM_GETSPEC, selsize, (LPARAM) buffer);
+ } else {
+ *(buffer-1) = '\\';
+ }
+ buffer[selsize] = '\0'; /* Second NULL terminator. */
+ Tcl_DStringFree(&tmpfile);
}
} else {
/*
@@ -1613,14 +1620,21 @@
}
*tmp = '\0'; /* Second NULL terminator. */
} else {
- buffer[selsize] = '\0'; /* Second NULL terminator. */
-
/*
- * Replace directory terminating NULL with a backslash.
+ * Replace directory terminating NULL with a backslash,
+ * but only if not an absolute path
*/
-
- buffer--;
- *buffer = '\\';
+ Tcl_DString tmpfile;
+ (void) ConvertExternalFilename(NULL, buffer, &tmpfile);
+ if (TCL_PATH_ABSOLUTE == Tcl_GetPathType(Tcl_DStringValue(&tmpfile))) {
+ /* re-get the full path to the start of the buffer */
+ buffer = ofnData->dynFileBuffer;
+ SendMessageW(hdlg, CDM_GETSPEC, selsize, (LPARAM) buffer);
+ } else {
+ *(buffer-1) = '\\';
+ }
+ buffer[selsize] = '\0'; /* Second NULL terminator. */
+ Tcl_DStringFree(&tmpfile);
}
} else {
Diff finished. Wed Nov 14 14:09:16 2012
Fixed on trunk. Still to be backported