[ttssh2-commit] [10400] 複数ファイルのDrag&Dropで複数のファイルが送信できない

Back to archive index
scmno****@osdn***** scmno****@osdn*****
2022年 12月 11日 (日) 21:07:36 JST


Revision: 10400
          https://osdn.net/projects/ttssh2/scm/svn/commits/10400
Author:   zmatsuo
Date:     2022-12-11 21:07:36 +0900 (Sun, 11 Dec 2022)
Log Message:
-----------
複数ファイルのDrag&Dropで複数のファイルが送信できない

- sendmemにAPI追加
  - 送信完了コールバック追加
- ファイルの送信完了ごとに次の送信を行えるよう修正

ticket #46070

Ticket Links:
------------
    https://osdn.net/projects/ttssh2/tracker/detail/46070

Modified Paths:
--------------
    trunk/teraterm/teraterm/sendmem.cpp
    trunk/teraterm/teraterm/sendmem.h
    trunk/teraterm/teraterm/vtwin.cpp

-------------- next part --------------
Modified: trunk/teraterm/teraterm/sendmem.cpp
===================================================================
--- trunk/teraterm/teraterm/sendmem.cpp	2022-12-11 12:07:26 UTC (rev 10399)
+++ trunk/teraterm/teraterm/sendmem.cpp	2022-12-11 12:07:36 UTC (rev 10400)
@@ -76,6 +76,8 @@
 	char *UILanguageFile;
 	wchar_t *dialog_caption;
 	wchar_t *filename;
+	void (*callback)(void *data);
+	void *callback_data;
 	//
 	size_t send_left;
 	size_t send_index;
@@ -142,6 +144,12 @@
 static void EndPaste()
 {
 	sendmem_work_t *p = sendmem_work;
+
+	if (p->callback != NULL) {
+		p->callback(p->callback_data);
+		p->callback = NULL;
+	}
+
 	free((void *)p->send_ptr);
 	p->send_ptr = NULL;
 
@@ -584,6 +592,15 @@
 	sm->delay_tick = delay_tick;
 }
 
+/**
+ *	\x91\x97\x90M\x8A\xAE\x97\xB9\x82ŃR\x81[\x83\x8B\x83o\x83b\x83N
+ */
+void SendMemInitSetCallback(SendMem *sm, void (*callback)(void *data), void *callback_data)
+{
+	sm->callback = callback;
+	sm->callback_data = callback_data;
+}
+
 // \x83Z\x83b\x83g\x82\xB7\x82\xE9\x82ƃ_\x83C\x83A\x83\x8D\x83O\x82\xAA\x8Fo\x82\xE9
 void SendMemInitDialog(SendMem *sm, HINSTANCE hInstance, HWND hWndParent, const char *UILanguageFile)
 {
@@ -646,7 +663,7 @@
 	return r;
 }
 #else
-BOOL SendMemSendFile(const wchar_t *filename, BOOL binary, SendMemDelayType delay_type, DWORD delay_tick, size_t send_max)
+SendMem *SendMemSendFileCom(const wchar_t *filename, BOOL binary, SendMemDelayType delay_type, DWORD delay_tick, size_t send_max)
 {
 	SendMem *sm;
 	if (!binary) {
@@ -654,7 +671,7 @@
 		wchar_t *str_ptr = LoadFileWW(filename, &str_len);
 		assert(str_ptr != NULL);
 		if (str_ptr == NULL) {
-			return FALSE;
+			return NULL;
 		}
 
 		// \x89\xFC\x8Ds\x82\xF0 CR \x82݂̂ɐ\xB3\x8BK\x89\xBB
@@ -669,7 +686,7 @@
 		unsigned char *data_ptr = LoadFileBinary(filename, &data_len);
 		assert(data_ptr != NULL);
 		if (data_ptr == NULL) {
-			return FALSE;
+			return NULL;
 		}
 		sm = SendMemBinary(data_ptr, data_len);
 	}
@@ -678,10 +695,27 @@
 	SendMemInitDialogFilename(sm, filename);
 	SendMemInitDelay(sm, delay_type, delay_tick, send_max);
 	SendMemStart(sm);
-	return TRUE;
+	return sm;
 }
 #endif
 
+BOOL SendMemSendFile(const wchar_t *filename, BOOL binary, SendMemDelayType delay_type, DWORD delay_tick, size_t send_max)
+{
+	SendMem *sm = SendMemSendFileCom(filename, binary, delay_type, delay_tick, send_max);
+	return (sm != NULL) ? TRUE : FALSE;
+}
+
+BOOL SendMemSendFile2(const wchar_t *filename, BOOL binary, SendMemDelayType delay_type, DWORD delay_tick, size_t send_max, void (*callback)(void *data), void *callback_data)
+{
+	SendMem *sm = SendMemSendFileCom(filename, binary, delay_type, delay_tick, send_max);
+	if (sm == NULL) {
+		return FALSE;
+	}
+
+	SendMemInitSetCallback(sm, callback, callback_data);
+	return TRUE;
+}
+
 /**
  *	\x92Z\x82\xA2\x95\xB6\x8E\x9A\x97\xF1\x82𑗐M\x82\xB7\x82\xE9
  *	@param[in]	str		malloc\x82\xB3\x82ꂽ\x97̈\xE6\x82̕\xB6\x8E\x9A\x97\xF1

Modified: trunk/teraterm/teraterm/sendmem.h
===================================================================
--- trunk/teraterm/teraterm/sendmem.h	2022-12-11 12:07:26 UTC (rev 10399)
+++ trunk/teraterm/teraterm/sendmem.h	2022-12-11 12:07:36 UTC (rev 10400)
@@ -46,6 +46,7 @@
 SendMem *SendMemBinary(void *ptr, size_t len);
 void SendMemInitEcho(SendMem *sm, BOOL echo);
 void SendMemInitSend(SendMem *sm, BOOL echo_only);
+void SendMemInitSetCallback(SendMem *sm, void (*callback)(void *data), void *callback_data);
 void SendMemInitDelay(SendMem *sm, SendMemDelayType delay_type, DWORD delay_tick, size_t send_max);
 void SendMemInitDialog(SendMem *sm, HINSTANCE hInstance, HWND hWndParent, const char *UILanguageFile);
 void SendMemInitDialogCaption(SendMem *sm, const wchar_t *caption);
@@ -59,6 +60,7 @@
 // convenient function
 BOOL SendMemPasteString(wchar_t *str);
 BOOL SendMemSendFile(const wchar_t *filename, BOOL binary, SendMemDelayType delay_type, DWORD delay_tick, size_t send_max);
+BOOL SendMemSendFile2(const wchar_t *filename, BOOL binary, SendMemDelayType delay_type, DWORD delay_tick, size_t send_max, void (*callback)(void *data), void *callback_data);
 
 #ifdef __cplusplus
 }

Modified: trunk/teraterm/teraterm/vtwin.cpp
===================================================================
--- trunk/teraterm/teraterm/vtwin.cpp	2022-12-11 12:07:26 UTC (rev 10399)
+++ trunk/teraterm/teraterm/vtwin.cpp	2022-12-11 12:07:36 UTC (rev 10400)
@@ -1595,149 +1595,210 @@
 	}
 }
 
+typedef struct DropData_tag {
+	// ini\x82ɕۑ\xB6\x82\xB3\x82\xEA\x82Ȃ\xA2\x81A\x8D\xA1\x8E\xC0\x8Ds\x82\xB5\x82Ă\xA2\x82\xE9Tera Term\x82ł̂ݗL\x8C\xF8\x82Ȑݒ\xE8
+	enum drop_type DefaultDropType;
+	unsigned char DefaultDropTypePaste;
+	bool DefaultShowDialog;
+	bool TransBin;
+	bool DoSameProcess;
+	enum drop_type DropType;
+	unsigned char DropTypePaste;
+
+	HWND vtwin;
+
+	int FileCount;
+	int DirectoryCount;
+	int SendIndex;
+} DropData_t;
+
+static DropData_t *DropData;
+
 /**
- *  \x83t\x83@\x83C\x83\x8B\x82\xAA\x83h\x83\x8D\x83b\x83v\x82\xB3\x82ꂽ
+ *	\x8F\x89\x8A\xFA\x89\xBB
+ */
+static DropData_t *DropInit()
+{
+	DropData_t *data =(DropData_t *)calloc(sizeof(*data), 1);
+	data->DefaultDropType = DROP_TYPE_CANCEL;
+	data->DefaultDropTypePaste = DROP_TYPE_PASTE_ESCAPE;
+	data->DefaultShowDialog = ts.ConfirmFileDragAndDrop ? true : false;
+	data->vtwin = HVTWin;
+	return data;
+}
+
+/**
+ *	\x91\x97\x90M\x8A\xAE\x97\xB9\x83R\x81[\x83\x8B\x83o\x83b\x83N
+ */
+static void DropSendCallback(void *callback_data)
+{
+	DropData_t *data = (DropData_t *)callback_data;
+	// \x8E\x9F\x82̑\x97\x90M\x82\xF0\x8Ds\x82\xA4
+	::PostMessage(data->vtwin, WM_USER_DROPNOTIFY, 0, 1);
+}
+
+/**
+ *  \x83t\x83@\x83C\x83\x8B\x82\xAA\x83h\x83\x8D\x83b\x83v\x92ʒm
+ *	@param	lparam		0	\x83t\x83@\x83C\x83\x8B\x82\xAA\x83h\x83\x8D\x83b\x83v\x82\xB3\x82ꂽ
+ *							ShowDialog\x82\xAA\x8EQ\x8FƂ\xB3\x82\xEA\x82\xE9
+ *						1	\x83t\x83@\x83C\x83\x8B\x82̓]\x91\x97\x82\xAA\x8A\xAE\x97\xB9\x82\xB5\x82\xBD
  *	@param	ShowDialog	0	\x95\\x8E\xA6\x82\xB5\x82Ă\xE0\x95\\x8E\xA6\x82\xB5\x82Ȃ\xAD\x82Ă\xE0\x97ǂ\xA2
  *						1	\x95K\x82\xB8\x95\\x8E\xA6\x82\xB7\x82\xE9
  */
-LRESULT CVTWindow::OnDropNotify(WPARAM ShowDialog, LPARAM)
+LRESULT CVTWindow::OnDropNotify(WPARAM ShowDialog, LPARAM lparam)
 {
-	// ini\x82ɕۑ\xB6\x82\xB3\x82\xEA\x82Ȃ\xA2\x81A\x8D\xA1\x8E\xC0\x8Ds\x82\xB5\x82Ă\xA2\x82\xE9Tera Term\x82ł̂ݗL\x8C\xF8\x82Ȑݒ\xE8
-	static enum drop_type DefaultDropType = DROP_TYPE_CANCEL;
-	static unsigned char DefaultDropTypePaste = DROP_TYPE_PASTE_ESCAPE;
-	static bool DefaultShowDialog = ts.ConfirmFileDragAndDrop ? true : false;
-	static bool TransBin;
+	DropData_t *data = DropData;
+	if (data == NULL) {
+		// \x8F\x89\x82߂ăt\x83@\x83C\x83\x8B\x82̃h\x83\x8D\x83b\x83v\x82\xAA\x94\xAD\x90\xB6\x82\xB5\x82\xBD
+		assert(lparam == 0);
+		data = DropInit();
+		DropData = data;
+	}
 
-	int FileCount = 0;
-	int DirectoryCount = 0;
-	for (int i = 0; i < DropListCount; i++) {
-		const wchar_t *FileName = DropLists[i];
-		const DWORD attr = GetFileAttributesW(FileName);
-		if (attr == INVALID_FILE_ATTRIBUTES) {
-			FileCount++;
-		} else if (attr & FILE_ATTRIBUTE_DIRECTORY) {
-			DirectoryCount++;
-		} else {
-			FileCount++;
+	switch (lparam) {
+	case 0: {
+		data->FileCount = 0;
+		data->DirectoryCount = 0;
+		for (int i = 0; i < DropListCount; i++) {
+			const wchar_t *FileName = DropLists[i];
+			const DWORD attr = GetFileAttributesW(FileName);
+			if (attr == INVALID_FILE_ATTRIBUTES) {
+				data->FileCount++;
+			} else if (attr & FILE_ATTRIBUTE_DIRECTORY) {
+				data->DirectoryCount++;
+			} else {
+				data->FileCount++;
+			}
 		}
-	}
 
-	bool DoSameProcess = false;
-	const bool isSSH = (cv.isSSH == 2);
-	enum drop_type DropType;
-	unsigned char DropTypePaste = DROP_TYPE_PASTE_ESCAPE;
-	if (DefaultDropType == DROP_TYPE_CANCEL) {
-		// default is not set
-		TransBin = ts.TransBin == 0 ? false : true;
-		if (!ShowDialog) {
-			if (FileCount == 1 && DirectoryCount == 0) {
-				if (ts.ConfirmFileDragAndDrop) {
+		data->DoSameProcess = false;
+		const bool isSSH = (cv.isSSH == 2);
+		data->DropTypePaste = DROP_TYPE_PASTE_ESCAPE;
+		if (data->DefaultDropType == DROP_TYPE_CANCEL) {
+			// default is not set
+			data->TransBin = ts.TransBin == 0 ? false : true;
+			if (!ShowDialog) {
+				if (data->FileCount == 1 && data->DirectoryCount == 0) {
+					if (ts.ConfirmFileDragAndDrop) {
+						if (isSSH) {
+							data->DropType = DROP_TYPE_SCP;
+						} else {
+							data->DropType = DROP_TYPE_SEND_FILE;
+						}
+						data->DoSameProcess = false;
+					} else {
+						data->DropType = DROP_TYPE_SEND_FILE;
+						data->DoSameProcess = data->DefaultShowDialog ? false : true;
+					}
+				}
+				else if (data->FileCount == 0 && data->DirectoryCount == 1) {
+					data->DropType = DROP_TYPE_PASTE_FILENAME;
+					data->DoSameProcess = data->DefaultShowDialog ? false : true;
+				}
+				else if (data->FileCount > 0 && data->DirectoryCount > 0) {
+					data->DropType = DROP_TYPE_PASTE_FILENAME;
+					data->DoSameProcess = false;
+				}
+				else if (data->FileCount > 0 && data->DirectoryCount == 0) {
+					// filename only
 					if (isSSH) {
-						DropType = DROP_TYPE_SCP;
+						data->DropType = DROP_TYPE_SCP;
 					} else {
-						DropType = DROP_TYPE_SEND_FILE;
+						data->DropType = DROP_TYPE_SEND_FILE;
 					}
-					DoSameProcess = false;
+					data->DoSameProcess = false;
 				} else {
-					DropType = DROP_TYPE_SEND_FILE;
-					DoSameProcess = DefaultShowDialog ? false : true;
+					// directory only
+					data->DropType = DROP_TYPE_PASTE_FILENAME;
+					data->DoSameProcess = ts.ConfirmFileDragAndDrop ? false : true;
 				}
-			} else if (FileCount == 0 && DirectoryCount == 1) {
-				DropType = DROP_TYPE_PASTE_FILENAME;
-				DoSameProcess = DefaultShowDialog ? false : true;
-			} else if (FileCount > 0 && DirectoryCount > 0) {
-				DropType = DROP_TYPE_PASTE_FILENAME;
-				DoSameProcess = false;
-			} else if (FileCount > 0 && DirectoryCount == 0) {
-				// filename only
-				if (isSSH) {
-					DropType = DROP_TYPE_SCP;
+			} else {
+				// show dialog
+				if (data->DirectoryCount > 0) {
+					data->DropType = DROP_TYPE_PASTE_FILENAME;
 				} else {
-					DropType = DROP_TYPE_SEND_FILE;
+					if (isSSH) {
+						data->DropType = DROP_TYPE_SCP;
+					} else {
+						data->DropType = DROP_TYPE_SEND_FILE;
+					}
 				}
-				DoSameProcess = false;
-			} else {
-				// directory only
-				DropType = DROP_TYPE_PASTE_FILENAME;
-				DoSameProcess = ts.ConfirmFileDragAndDrop ? false : true;
+				data->DoSameProcess = false;
 			}
 		} else {
-			// show dialog
-			if (DirectoryCount > 0) {
-				DropType = DROP_TYPE_PASTE_FILENAME;
+			if (data->DirectoryCount > 0 &&
+				(data->DefaultDropType == DROP_TYPE_SEND_FILE ||
+				 data->DefaultDropType == DROP_TYPE_SCP))
+			{	// \x83f\x83t\x83H\x83\x8B\x83g\x82̂܂܂ł͏\x88\x97\x9D\x82ł\xAB\x82Ȃ\xA2\x91g\x82ݍ\x87\x82킹
+				data->DropType = DROP_TYPE_PASTE_FILENAME;
+				data->DropTypePaste = data->DefaultDropTypePaste;
+				data->DoSameProcess = false;
 			} else {
-				if (isSSH) {
-					DropType = DROP_TYPE_SCP;
-				} else {
-					DropType = DROP_TYPE_SEND_FILE;
-				}
+				data->DropType = data->DefaultDropType;
+				data->DropTypePaste = data->DefaultDropTypePaste;
+				data->DoSameProcess = (ShowDialog || data->DefaultShowDialog) ? false : true;
 			}
-			DoSameProcess = false;
 		}
-	} else {
-		if (DirectoryCount > 0 &&
-			(DefaultDropType == DROP_TYPE_SEND_FILE ||
-			 DefaultDropType == DROP_TYPE_SCP))
-		{	// \x83f\x83t\x83H\x83\x8B\x83g\x82̂܂܂ł͏\x88\x97\x9D\x82ł\xAB\x82Ȃ\xA2\x91g\x82ݍ\x87\x82킹
-			DropType = DROP_TYPE_PASTE_FILENAME;
-			DropTypePaste = DefaultDropTypePaste;
-			DoSameProcess = false;
-		} else {
-			DropType = DefaultDropType;
-			DropTypePaste = DefaultDropTypePaste;
-			DoSameProcess = (ShowDialog || DefaultShowDialog) ? false : true;
+
+		data->SendIndex = 0;
+		// break;
+		// FALLTHROUGH
+	}
+	case 1:
+	next_file: {
+		if (data->SendIndex == DropListCount) {
+			// \x82\xB7\x82ׂđ\x97\x90M\x8A\xAE\x97\xB9
+			goto finish;
 		}
-	}
-
-	for (int i = 0; i < DropListCount; i++) {
+		int i = data->SendIndex;
+		data->SendIndex++;
 		const wchar_t *FileName = DropLists[i];
 
-		if (!DoSameProcess) {
+		if (!data->DoSameProcess) {
+			const bool isSSH = (cv.isSSH == 2);
 			bool DoSameProcessNextDrop;
-			bool DoNotShowDialog = !DefaultShowDialog;
+			bool DoNotShowDialog = !data->DefaultShowDialog;
 			SetDialogFont(ts.DialogFontNameW, ts.DialogFontPoint, ts.DialogFontCharSet,
 						  ts.UILanguageFileW, "Tera Term", "DLG_SYSTEM_FONT");
-			DropType =
-				ShowDropDialogBox(m_hInst, HVTWin,
-								  FileName, DropType,
+			data->DropType =
+				ShowDropDialogBox(m_hInst, HVTWin, FileName, data->DropType,
 								  DropListCount - i,
-								  (DirectoryCount == 0 && isSSH) ? true : false,
-								  DirectoryCount == 0 ? true : false,
-								  &TransBin,
+								  (data->DirectoryCount == 0 && isSSH) ? true : false, data->DirectoryCount == 0 ? true : false,
+								  &data->TransBin,
 								  &ts,
-								  &DropTypePaste,
-								  &DoSameProcess,
+								  &data->DropTypePaste, &data->DoSameProcess,
 								  &DoSameProcessNextDrop,
 								  &DoNotShowDialog);
-			if (DropType == DROP_TYPE_CANCEL) {
+			if (data->DropType == DROP_TYPE_CANCEL) {
 				goto finish;
 			}
 			if (DoSameProcessNextDrop) {
-				DefaultDropType = DropType;
+				data->DefaultDropType = data->DropType;
 			}
 			if (!ts.ConfirmFileDragAndDrop) {
-				DefaultShowDialog = !DoNotShowDialog;
+				data->DefaultShowDialog = !DoNotShowDialog;
 			}
 		}
 
-		switch (DropType) {
+		switch (data->DropType) {
 		case DROP_TYPE_CANCEL:
 		default:
 			// cancel
 			break;
-		case DROP_TYPE_SEND_FILE:
-			if (!TransBin) {
-				SendMemSendFile(FileName, FALSE, SENDMEM_DELAYTYPE_NO_DELAY, 0, 0);
+		case DROP_TYPE_SEND_FILE: {
+			if (!data->TransBin) {
+				SendMemSendFile2(FileName, FALSE, SENDMEM_DELAYTYPE_NO_DELAY, 0, 0, DropSendCallback, data);
 			}
 			else {
-				SendMemSendFile(FileName, TRUE, SENDMEM_DELAYTYPE_NO_DELAY, 0, 0);
+				SendMemSendFile2(FileName, TRUE, SENDMEM_DELAYTYPE_NO_DELAY, 0, 0, DropSendCallback, data);
 			}
 			break;
+		}
 		case DROP_TYPE_PASTE_FILENAME:
 		{
-			const bool escape = (DropTypePaste & DROP_TYPE_PASTE_ESCAPE) ? true : false;
+			const bool escape = (data->DropTypePaste & DROP_TYPE_PASTE_ESCAPE) ? true : false;
 
-			DefaultDropTypePaste = DropTypePaste;
+			data->DefaultDropTypePaste = data->DropTypePaste;
 
 			TermSendStartBracket();
 
@@ -1745,7 +1806,7 @@
 			TermPasteStringNoBracket(str, wcslen(str));
 			free(str);
 			if (DropListCount > 1 && i < DropListCount - 1) {
-				if (DropTypePaste & DROP_TYPE_PASTE_NEWLINE) {
+				if (data->DropTypePaste & DROP_TYPE_PASTE_NEWLINE) {
 					TermPasteStringNoBracket(L"\x0d", 1);	// \x89\xFC\x8Ds(CR,0x0d)
 				}
 				else {
@@ -1755,7 +1816,8 @@
 
 			TermSendEndBracket();
 
-			break;
+			// \x8E\x9F\x82̃t\x83@\x83C\x83\x8B\x82̏\x88\x97\x9D\x82\xD6
+			goto next_file;
 		}
 		case DROP_TYPE_SCP:
 		{
@@ -1767,7 +1829,7 @@
 			else {
 				// \x88ꊇ\x91\x97\x90M\x82̏ꍇ\x82̓^\x83C\x83}\x81[\x8F\x88\x97\x9D\x82\xF0\x8Ds\x82\xA4\x82\xB1\x82ƂŁA\x98A\x91\xB1\x91\x97\x90M\x82ɂ\xE6\x82\xE9
 				// \x83G\x83\x89\x81[\x82\xAA\x8BN\x82\xB1\x82\xE7\x82Ȃ\xA2\x82悤\x82ɂ\xB7\x82\xE9\x81B
-				if (DoSameProcess) {
+				if (data->DoSameProcess) {
 					int j;
 
 					DropListCountSendScp = DropListCount - i;
@@ -1788,8 +1850,9 @@
 					if (!SendScp(FileNames, FileCount, ts.ScpSendDir)) {
 						goto finish;
 					}
-					i += FileCount - 1;
-					break;
+
+					// \x8E\x9F\x82̃t\x83@\x83C\x83\x8B\x82̏\x88\x97\x9D\x82\xD6
+					goto next_file;
 				}
 			}
 
@@ -1796,9 +1859,15 @@
 		}
 		}
 	}
+		break;
+	case 2:
+	default:
+	finish:
+		// \x8FI\x97\xB9\x8F\x88\x97\x9D
+		DropListFree();
+		break;
+	}
 
-finish:
-	DropListFree();
 	return 0;
 }
 


ttssh2-commit メーリングリストの案内
Back to archive index