summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorashok <ashok@noemail.net>2014-09-20 03:17:35 (GMT)
committerashok <ashok@noemail.net>2014-09-20 03:17:35 (GMT)
commit985114eeed0e47d8992dd698a5a75acca8892ebb (patch)
tree5300191a4fb2810253818d828d6e04278ea75fbf
parent26b324e7754e591944b84639d25e9b5b7b3335b4 (diff)
downloadtk-985114eeed0e47d8992dd698a5a75acca8892ebb.zip
tk-985114eeed0e47d8992dd698a5a75acca8892ebb.tar.gz
tk-985114eeed0e47d8992dd698a5a75acca8892ebb.tar.bz2
Convert native paths returned from file dialogs to Tcl canonical paths.
FossilOrigin-Name: 3f096107b42276eadd4f901e57b642a7c99bf72f
-rw-r--r--tests/winDialog.test56
-rw-r--r--win/tkWinDialog.c14
-rw-r--r--win/tkWinTest.c70
3 files changed, 119 insertions, 21 deletions
diff --git a/tests/winDialog.test b/tests/winDialog.test
index 8aa9ac3..357349e 100644
--- a/tests/winDialog.test
+++ b/tests/winDialog.test
@@ -22,11 +22,30 @@ testConstraint english [expr {
&& (([testwinlocale] & 0xff) == 9)
}]
-proc start {arg} {
+proc start {widgetcommand args} {
set ::tk_dialog 0
set ::iter_after 0
- after 1 $arg
+ # On newer versions of Windows, we need to find the dialog window
+ # based on the title
+ if {[llength $args]} {
+ set ::dialogtitle [lindex $args 0]
+ set ::dialogclass "#32770"
+ if {$::dialogtitle eq ""} {
+ switch $widgetcommand {
+ tk_getOpenFile {
+ set ::dialogtitle Open
+ }
+ tk_getSaveFile {
+ set ::dialogtitle "Save As"
+ }
+ tk_chooseDirectory {
+ set ::dialogtitle "Select Folder"
+ }
+ }
+ }
+ }
+ after 1 $widgetcommand
}
proc then {cmd} {
@@ -34,19 +53,32 @@ proc then {cmd} {
set ::dialogresult {}
set ::testfont {}
- afterbody
+ after 100 afterbody
vwait ::dialogresult
return $::dialogresult
}
proc afterbody {} {
- if {$::tk_dialog == 0} {
- if {[incr ::iter_after] > 30} {
- set ::dialogresult ">30 iterations waiting on tk_dialog"
+ # On Vista and later, using the new file dialogs we have to find
+ # the window using its title as tk_dialog will not be set at the C level
+ if {$::dialogtitle ne "" && [string match 6.* $::tcl_platform(osVersion)]} {
+ if {[catch {testfindwindow "" $::dialogclass} ::tk_dialog]} {
+ if {[incr ::iter_after] > 10} {
+ set ::dialogresult ">30 iterations waiting on tk_dialog"
+ return
+ }
+ after 150 {afterbody}
+ return
+ }
+ } else {
+ if {$::tk_dialog == 0} {
+ if {[incr ::iter_after] > 30} {
+ set ::dialogresult ">30 iterations waiting on tk_dialog"
+ return
+ }
+ after 150 {afterbody}
return
}
- after 150 {afterbody}
- return
}
uplevel #0 {set dialogresult [eval $command]}
}
@@ -205,7 +237,7 @@ test winDialog-5.2 {GetFileName: one argument} -constraints {
test winDialog-5.3 {GetFileName: many arguments} -constraints {
nt testwinevent
} -body {
- start {tk_getOpenFile -initialdir c:/ -parent . -title test -initialfile foo}
+ start {tk_getOpenFile -initialdir c:/ -parent . -title test -initialfile foo} test
then {
Click cancel
}
@@ -218,7 +250,7 @@ test winDialog-5.4 {GetFileName: Tcl_GetIndexFromObj() != TCL_OK} -constraints {
test winDialog-5.5 {GetFileName: Tcl_GetIndexFromObj() == TCL_OK} -constraints {
nt testwinevent
} -body {
- start {tk_getOpenFile -title bar}
+ start {tk_getOpenFile -title bar} bar
then {
Click cancel
}
@@ -235,10 +267,10 @@ test winDialog-5.7 {GetFileName: extension begins with .} -constraints {
# string++;
# }
- start {set x [tk_getSaveFile -defaultextension .foo -title Save]}
+ start {set x [tk_getSaveFile -defaultextension .foo -title Save]} Save
set msg {}
then {
- if {[catch {SetText 0x47C bar} msg]} {
+ if {[catch {SetText 0x3e9 bar} msg]} {
Click cancel
} else {
Click ok
diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c
index 3130cf2..67f0df4 100644
--- a/win/tkWinDialog.c
+++ b/win/tkWinDialog.c
@@ -1387,8 +1387,13 @@ static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr,
hr = itemIf->lpVtbl->GetDisplayName(itemIf,
SIGDN_FILESYSPATH, &wstr);
if (SUCCEEDED(hr)) {
- Tcl_ListObjAppendElement(interp, multiObj,
- Tcl_NewUnicodeObj(wstr, -1));
+ Tcl_DString fnds;
+ ConvertExternalFilename(wstr, &fnds);
+ CoTaskMemFree(wstr);
+ Tcl_ListObjAppendElement(
+ interp, multiObj,
+ Tcl_NewStringObj(Tcl_DStringValue(&fnds),
+ Tcl_DStringLength(&fnds)));
}
itemIf->lpVtbl->Release(itemIf);
if (FAILED(hr))
@@ -1408,7 +1413,10 @@ static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr,
hr = resultIf->lpVtbl->GetDisplayName(resultIf, SIGDN_FILESYSPATH,
&wstr);
if (SUCCEEDED(hr)) {
- resultObj = Tcl_NewUnicodeObj(wstr, -1);
+ Tcl_DString fnds;
+ ConvertExternalFilename(wstr, &fnds);
+ resultObj = Tcl_NewStringObj(Tcl_DStringValue(&fnds),
+ Tcl_DStringLength(&fnds));
CoTaskMemFree(wstr);
}
resultIf->lpVtbl->Release(resultIf);
diff --git a/win/tkWinTest.c b/win/tkWinTest.c
index 9fa956c..2c38d71 100644
--- a/win/tkWinTest.c
+++ b/win/tkWinTest.c
@@ -79,6 +79,42 @@ TkplatformtestInit(
return TCL_OK;
}
+struct TestFindControlState {
+ int id;
+ HWND control;
+};
+
+/* Callback for window enumeration - used for TestFindControl */
+BOOL CALLBACK TestFindControlCallback(
+ HWND hwnd,
+ LPARAM lParam
+)
+{
+ struct TestFindControlState *fcsPtr = (struct TestFindControlState *)lParam;
+ fcsPtr->control = GetDlgItem(hwnd, fcsPtr->id);
+ /* If we have found the control, return FALSE to stop the enumeration */
+ return fcsPtr->control == NULL ? TRUE : FALSE;
+}
+
+/*
+ * Finds the descendent control window with the specified ID and returns
+ * its HWND.
+ */
+HWND TestFindControl(HWND root, int id)
+{
+ struct TestFindControlState fcs;
+
+ fcs.control = GetDlgItem(root, id);
+ if (fcs.control == NULL) {
+ /* Control is not a direct child. Look in descendents */
+ fcs.id = id;
+ fcs.control = NULL;
+ EnumChildWindows(root, TestFindControlCallback, (LPARAM) &fcs);
+ }
+ return fcs.control;
+}
+
+
/*
*----------------------------------------------------------------------
*
@@ -244,11 +280,13 @@ TestwineventObjCmd(
{
HWND hwnd = 0;
HWND child = 0;
+ HWND control;
int id;
char *rest;
UINT message;
WPARAM wParam;
LPARAM lParam;
+ LRESULT result;
static const TkStateMap messageMap[] = {
{WM_LBUTTONDOWN, "WM_LBUTTONDOWN"},
{WM_LBUTTONUP, "WM_LBUTTONUP"},
@@ -302,6 +340,7 @@ TestwineventObjCmd(
return TCL_ERROR;
}
}
+
message = TkFindStateNum(NULL, NULL, messageMap, Tcl_GetString(objv[3]));
wParam = 0;
lParam = 0;
@@ -318,7 +357,19 @@ TestwineventObjCmd(
Tcl_DString ds;
char buf[256];
+#if 0
GetDlgItemTextA(hwnd, id, buf, 256);
+#else
+ control = TestFindControl(hwnd, id);
+ if (control == NULL) {
+ Tcl_SetObjResult(interp,
+ Tcl_ObjPrintf("Could not find control with id %d", id));
+ return TCL_ERROR;
+ }
+ buf[0] = 0;
+ SendMessageA(control, WM_GETTEXT, (WPARAM)sizeof(buf),
+ (LPARAM) buf);
+#endif
Tcl_ExternalToUtfDString(NULL, buf, -1, &ds);
Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL);
Tcl_DStringFree(&ds);
@@ -326,15 +377,21 @@ TestwineventObjCmd(
}
case WM_SETTEXT: {
Tcl_DString ds;
- BOOL result;
+ control = TestFindControl(hwnd, id);
+ if (control == NULL) {
+ Tcl_SetObjResult(interp,
+ Tcl_ObjPrintf("Could not find control with id %d", id));
+ return TCL_ERROR;
+ }
Tcl_UtfToExternalDString(NULL, Tcl_GetString(objv[4]), -1, &ds);
- result = SetDlgItemTextA(hwnd, id, Tcl_DStringValue(&ds));
+ result = SendMessageA(control, WM_SETTEXT, 0,
+ (LPARAM) Tcl_DStringValue(&ds));
Tcl_DStringFree(&ds);
if (result == 0) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to send text to dialog: ", -1));
- AppendSystemError(interp, GetLastError());
- return TCL_ERROR;
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to send text to dialog: ", -1));
+ AppendSystemError(interp, GetLastError());
+ return TCL_ERROR;
}
break;
}
@@ -395,7 +452,8 @@ TestfindwindowObjCmd(
if (objc == 3) {
class = Tcl_WinUtfToTChar(Tcl_GetString(objv[2]), -1, &classString);
}
-
+ if (title[0] == 0)
+ title = NULL;
hwnd = FindWindow(class, title);
if (hwnd == NULL) {