summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpetasis <petasis@f3661a36-4baa-549a-d6c7-40e0ffef350e>2012-06-17 14:38:07 (GMT)
committerpetasis <petasis@f3661a36-4baa-549a-d6c7-40e0ffef350e>2012-06-17 14:38:07 (GMT)
commit12a89301cc95778ef358a70fd30bd789167deb55 (patch)
treefc6d670fc6b54dad8a320a2e090671dc51b0c8e2
parentecf7b7d7c1312357e11244124490df33f35c856a (diff)
downloadtkdnd-12a89301cc95778ef358a70fd30bd789167deb55.zip
tkdnd-12a89301cc95778ef358a70fd30bd789167deb55.tar.gz
tkdnd-12a89301cc95778ef358a70fd30bd789167deb55.tar.bz2
Fixes for type CF_HDROP (Windows)
-rw-r--r--Changelog4
-rw-r--r--win/TkDND_OleDND.cpp85
2 files changed, 47 insertions, 42 deletions
diff --git a/Changelog b/Changelog
index fe13114..4213c7c 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,7 @@
+2012-06-17 Petasis George <petasis@iit.demokritos.gr>
+ TkDND 2.5 released.
+ * win/TkDND_OleDND.cpp: Fixes for type CF_HDROP.
+
2012-06-07 Petasis George <petasis@iit.demokritos.gr>
* demos/basic.tcl: Updated demo with support for colours, which only
works for XDND right now.
diff --git a/win/TkDND_OleDND.cpp b/win/TkDND_OleDND.cpp
index ebec0d2..95f235d 100644
--- a/win/TkDND_OleDND.cpp
+++ b/win/TkDND_OleDND.cpp
@@ -39,6 +39,7 @@
*/
#include "OleDND.h"
+#include "Strsafe.h"
int TkDND_RegisterDragDropObjCmd(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *CONST objv[]) {
@@ -144,6 +145,7 @@ int TkDND_DoDragDropObjCmd(ClientData clientData, Tcl_Interp *interp,
ActionCopy, ActionMove, ActionLink, ActionAsk, ActionPrivate,
refuse_drop, ActionDefault
};
+ size_t buffer_size;
if (objc != 5 && objc != 6) {
Tcl_WrongNumArgs(interp, 1, objv, "path actions types data ?mouse-button?");
@@ -202,11 +204,11 @@ int TkDND_DoDragDropObjCmd(ClientData clientData, Tcl_Interp *interp,
case TYPE_CF_UNICODETEXT: {
m_pfmtetc[i].cfFormat = CF_UNICODETEXT;
unicode = Tcl_GetUnicodeFromObj(objv[4], &nDataLength);
- m_pstgmed[i].hGlobal = GlobalAlloc(GHND, (nDataLength+1) *
- sizeof(Tcl_UniChar));
+ buffer_size = (nDataLength+1) * sizeof(Tcl_UniChar);
+ m_pstgmed[i].hGlobal = GlobalAlloc(GHND, buffer_size);
if (m_pstgmed[i].hGlobal) {
ptr_u = (Tcl_UniChar *) GlobalLock(m_pstgmed[i].hGlobal);
- lstrcpyW((LPWSTR) ptr_u, (LPWSTR) unicode);
+ StringCchCopyW((LPWSTR) ptr_u, buffer_size, (LPWSTR) unicode);
GlobalUnlock(m_pstgmed[i].hGlobal);
}
break;
@@ -226,68 +228,67 @@ int TkDND_DoDragDropObjCmd(ClientData clientData, Tcl_Interp *interp,
case TYPE_CF_HDROP: {
LPDROPFILES pDropFiles;
Tcl_DString ds;
- Tcl_Obj **File;
- int file_nu;
+ Tcl_Obj **File, *native_files_obj = NULL, *obj;
+ int file_nu, j, size, len;
+ char *native_name;
+
status = Tcl_ListObjGetElements(interp, objv[4], &file_nu, &File);
- if (status !=TCL_OK) { elem_nu = i; goto error;}
+ if (status != TCL_OK) {elem_nu = i; goto error;}
+ /* What we expect is a list of filenames. Convert the filenames into
+ * the native format, and store the translated filenames into a new
+ * list... */
+ native_files_obj = Tcl_NewListObj(0, NULL);
+ if (native_files_obj == NULL) {elem_nu = i; goto error;}
+ size = 0;
+ for (j = 0; j < file_nu; ++j) {
+ Tcl_DStringInit(&ds);
+ native_name = Tcl_TranslateFileName(NULL,
+ Tcl_GetString(File[j]), &ds);
+ if (native_name == NULL) {
+ Tcl_DStringFree(&ds);
+ continue;
+ }
+ obj = Tcl_NewStringObj(native_name, -1);
+ Tcl_ListObjAppendElement(NULL, native_files_obj, obj);
+ /* Get the length in unicode... */
+ Tcl_GetUnicodeFromObj(obj, &len);
+ size += len + 1; // NULL character...
+ Tcl_DStringFree(&ds);
+ }
+
+ buffer_size = sizeof(wchar_t) * (size+1);
m_pfmtetc[i].cfFormat = CF_HDROP;
m_pstgmed[i].hGlobal = GlobalAlloc(GHND,
- (DWORD) (sizeof(DROPFILES)+(_MAX_PATH)*file_nu+1));
+ (DWORD) (sizeof(DROPFILES) + buffer_size));
if (m_pstgmed[i].hGlobal) {
TCHAR *CurPosition;
pDropFiles = (LPDROPFILES) GlobalLock(m_pstgmed[i].hGlobal);
// Set the offset where the starting point of the file start.
pDropFiles->pFiles = sizeof(DROPFILES);
// File contains wide characters?
-#ifdef UNICODE
pDropFiles->fWide = TRUE;
-#else
- pDropFiles->fWide = FALSE;
-#endif /* UNICODE */
CurPosition = (TCHAR *) (LPBYTE(pDropFiles) + sizeof(DROPFILES));
- for (i = 0; i < file_nu; i++) {
- char *native_name;
- TCHAR *pszFileName;
- TCHAR api_name[MAX_PATH+2];
- // Convert File Name to native paths...
- Tcl_DStringInit(&ds);
- native_name = Tcl_TranslateFileName(NULL,
- Tcl_GetString(File[i]), &ds);
- if (native_name != NULL) {
- if (Tcl_NumUtfChars(native_name, -1) > MAX_PATH) {
- native_name = "too long filename!";
- }
- }
-
- if (native_name != NULL) {
-#ifdef UNICODE
- Tcl_UtfToUniChar(native_name, (Tcl_UniChar *) api_name);
- pszFileName = api_name;
-#else /* UNICODE */
- lstrcpy(api_name, native_name);
- // Convert the file name using the system encoding.
- Tcl_DStringFree(&ds);
- Tcl_DStringInit(&ds);
- pszFileName = Tcl_UtfToExternalDString(NULL,
- api_name, -1, &ds);
-#endif /* UNICODE */
- }
+ Tcl_ListObjGetElements(NULL, native_files_obj, &file_nu, &File);
+ for (j = 0; j < file_nu; j++) {
+ TCHAR *pszFileName = (TCHAR *)
+ Tcl_GetUnicodeFromObj(File[j], &len);
// Copy the file name into global memory.
- lstrcpy(CurPosition, pszFileName);
+ StringCchCopyW(CurPosition, buffer_size, pszFileName);
+ // lstrcpy(CurPosition, pszFileName);
/*
* Move the current position beyond the file name copied, and
* don't forget the NULL terminator (+1)
*/
- CurPosition = 1 + _tcschr(pszFileName, '\0');
- Tcl_DStringFree(&ds);
+ CurPosition += 1 + _tcschr(pszFileName, '\0') - pszFileName;
}
/*
* Finally, add an additional null terminator, as per CF_HDROP
* Format specs.
*/
- CurPosition = '\0';
+ *CurPosition = '\0';
GlobalUnlock(m_pstgmed[i].hGlobal);
}
+ if (native_files_obj) Tcl_DecrRefCount(native_files_obj);
break;
}
}