|  |  |  | @ -14,7 +14,7 @@ | 
			
		
	
		
			
				
					|  |  |  |  | // You should have received a copy of the GNU General Public License
 | 
			
		
	
		
			
				
					|  |  |  |  | // along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //fileBrowser类的具体实现
 | 
			
		
	
		
			
				
					|  |  |  |  | #include "fileBrowser.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "resource.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "tinyxml.h" | 
			
		
	
	
		
			
				
					|  |  |  | @ -41,7 +41,7 @@ | 
			
		
	
		
			
				
					|  |  |  |  | #define FB_CMD_FOLDALL 2 | 
			
		
	
		
			
				
					|  |  |  |  | #define FB_CMD_EXPANDALL 3 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //停止所有文件监视器
 | 
			
		
	
		
			
				
					|  |  |  |  | FileBrowser::~FileBrowser() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	for (const auto folder : _folderUpdaters) | 
			
		
	
	
		
			
				
					|  |  |  | @ -55,7 +55,7 @@ FileBrowser::~FileBrowser() | 
			
		
	
		
			
				
					|  |  |  |  | 		delete cd; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //将一个字符串分割成多个子字符串,函数使用了for循环依次检查字符串中的每个字符,当找到等于`sep`或者空字符的字符时,就把这之前的字符作为一个子字符串存储在`splitedStrings`向量中。
 | 
			
		
	
		
			
				
					|  |  |  |  | vector<generic_string> split(const generic_string & string2split, TCHAR sep) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	vector<generic_string> splitedStrings; | 
			
		
	
	
		
			
				
					|  |  |  | @ -71,7 +71,7 @@ vector<generic_string> split(const generic_string & string2split, TCHAR sep) | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return splitedStrings; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //检查子文件夹是否与根文件相关
 | 
			
		
	
		
			
				
					|  |  |  |  | bool isRelatedRootFolder(const generic_string & relatedRoot, const generic_string & subFolder) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (relatedRoot.empty()) | 
			
		
	
	
		
			
				
					|  |  |  | @ -91,11 +91,11 @@ bool isRelatedRootFolder(const generic_string & relatedRoot, const generic_strin | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return relatedRootArray[index2Compare] == subFolderArray[index2Compare]; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //消息处理
 | 
			
		
	
		
			
				
					|  |  |  |  | intptr_t CALLBACK FileBrowser::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	switch (message) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 	{//会话框初始化,包括创建工具条,树状视图的初始化等。
 | 
			
		
	
		
			
				
					|  |  |  |  | 		case WM_INITDIALOG : | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			NppParameters& nppParam = NppParameters::getInstance(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -175,7 +175,7 @@ intptr_t CALLBACK FileBrowser::run_dlgProc(UINT message, WPARAM wParam, LPARAM l | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			return TRUE; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		//处理黑暗模式刷新的消息
 | 
			
		
	
		
			
				
					|  |  |  |  | 		case NPPM_INTERNAL_REFRESHDARKMODE: | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			if (static_cast<BOOL>(lParam) != TRUE) | 
			
		
	
	
		
			
				
					|  |  |  | @ -185,7 +185,7 @@ intptr_t CALLBACK FileBrowser::run_dlgProc(UINT message, WPARAM wParam, LPARAM l | 
			
		
	
		
			
				
					|  |  |  |  | 			NppDarkMode::setTreeViewStyle(_treeView.getHSelf()); | 
			
		
	
		
			
				
					|  |  |  |  | 			return TRUE; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		//鼠标消息
 | 
			
		
	
		
			
				
					|  |  |  |  | 		case WM_MOUSEMOVE: | 
			
		
	
		
			
				
					|  |  |  |  | 			if (_treeView.isDragging()) | 
			
		
	
		
			
				
					|  |  |  |  | 				_treeView.dragItem(_hSelf, LOWORD(lParam), HIWORD(lParam)); | 
			
		
	
	
		
			
				
					|  |  |  | @ -197,13 +197,13 @@ intptr_t CALLBACK FileBrowser::run_dlgProc(UINT message, WPARAM wParam, LPARAM l | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				} | 
			
		
	
		
			
				
					|  |  |  |  | 			break; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		//通知消息
 | 
			
		
	
		
			
				
					|  |  |  |  | 		case WM_NOTIFY: | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			notified((LPNMHDR)lParam); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		return TRUE; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		//得到窗体的新宽度和高度,然后调整工具条和树形视图的位置和大小。
 | 
			
		
	
		
			
				
					|  |  |  |  | 		case WM_SIZE: | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			int width = LOWORD(lParam); | 
			
		
	
	
		
			
				
					|  |  |  | @ -220,28 +220,28 @@ intptr_t CALLBACK FileBrowser::run_dlgProc(UINT message, WPARAM wParam, LPARAM l | 
			
		
	
		
			
				
					|  |  |  |  | 				::MoveWindow(hwnd, 0, toolbarMenuRect.bottom + extraValue, width, height - toolbarMenuRect.bottom - extraValue, TRUE); | 
			
		
	
		
			
				
					|  |  |  |  | 			break; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		//文本菜单
 | 
			
		
	
		
			
				
					|  |  |  |  | 		case WM_CONTEXTMENU: | 
			
		
	
		
			
				
					|  |  |  |  | 			if (!_treeView.isDragging()) | 
			
		
	
		
			
				
					|  |  |  |  | 				showContextMenu(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); | 
			
		
	
		
			
				
					|  |  |  |  | 		return TRUE; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		//来自菜单的选择
 | 
			
		
	
		
			
				
					|  |  |  |  | 		case WM_COMMAND: | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			switch (LOWORD(wParam)) | 
			
		
	
		
			
				
					|  |  |  |  | 			{ | 
			
		
	
		
			
				
					|  |  |  |  | 			{//选择当前正在编辑的文件。
 | 
			
		
	
		
			
				
					|  |  |  |  | 				case FB_CMD_AIMFILE: | 
			
		
	
		
			
				
					|  |  |  |  | 				{ | 
			
		
	
		
			
				
					|  |  |  |  | 					selectCurrentEditingFile(); | 
			
		
	
		
			
				
					|  |  |  |  | 					break; | 
			
		
	
		
			
				
					|  |  |  |  | 				} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				//折叠
 | 
			
		
	
		
			
				
					|  |  |  |  | 				case FB_CMD_FOLDALL: | 
			
		
	
		
			
				
					|  |  |  |  | 				{ | 
			
		
	
		
			
				
					|  |  |  |  | 					_treeView.foldAll(); | 
			
		
	
		
			
				
					|  |  |  |  | 					break; | 
			
		
	
		
			
				
					|  |  |  |  | 				} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				//展开
 | 
			
		
	
		
			
				
					|  |  |  |  | 				case FB_CMD_EXPANDALL: | 
			
		
	
		
			
				
					|  |  |  |  | 				{ | 
			
		
	
		
			
				
					|  |  |  |  | 					_treeView.expandAll(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -253,7 +253,7 @@ intptr_t CALLBACK FileBrowser::run_dlgProc(UINT message, WPARAM wParam, LPARAM l | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 			break; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		//销毁
 | 
			
		
	
		
			
				
					|  |  |  |  | 		case WM_DESTROY: | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			::DestroyWindow(_hToolbarMenu); | 
			
		
	
	
		
			
				
					|  |  |  | @ -261,7 +261,7 @@ intptr_t CALLBACK FileBrowser::run_dlgProc(UINT message, WPARAM wParam, LPARAM l | 
			
		
	
		
			
				
					|  |  |  |  | 			destroyMenus(); | 
			
		
	
		
			
				
					|  |  |  |  | 			break; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		//添加
 | 
			
		
	
		
			
				
					|  |  |  |  | 		case FB_ADDFILE: | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -274,7 +274,7 @@ intptr_t CALLBACK FileBrowser::run_dlgProc(UINT message, WPARAM wParam, LPARAM l | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			break; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		//移除
 | 
			
		
	
		
			
				
					|  |  |  |  | 		case FB_RMFILE: | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -287,7 +287,7 @@ intptr_t CALLBACK FileBrowser::run_dlgProc(UINT message, WPARAM wParam, LPARAM l | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			break; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		//重命名
 | 
			
		
	
		
			
				
					|  |  |  |  | 		case FB_RNFILE: | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			const std::vector<generic_string> file2Change = *(std::vector<generic_string> *)lParam; | 
			
		
	
	
		
			
				
					|  |  |  | @ -324,7 +324,7 @@ intptr_t CALLBACK FileBrowser::run_dlgProc(UINT message, WPARAM wParam, LPARAM l | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return DockingDlgInterface::run_dlgProc(message, wParam, lParam); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //创建一个文件浏览器的时候,初始化弹出菜单。首先收集各种与菜单项相关的字符串,然后创建三种不同的菜单:全局菜单、根菜单、文件夹菜单和文件菜单,向这些菜单中插入各种菜单项。
 | 
			
		
	
		
			
				
					|  |  |  |  | void FileBrowser::initPopupMenus() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	NativeLangSpeaker* pNativeSpeaker = NppParameters::getInstance().getNativeLangSpeaker(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -370,7 +370,7 @@ void FileBrowser::initPopupMenus() | 
			
		
	
		
			
				
					|  |  |  |  | 	::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_EXPLORERHERE, explorerHere.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  | 	::InsertMenu(_hFileMenu, 0, MF_BYCOMMAND, IDM_FILEBROWSER_CMDHERE, cmdHere.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //通过一个给定的路径选中文件浏览器中的一个项目。它首先检查路径是否为空,然后通过遍历所有的文件夹来寻找对应的项目。
 | 
			
		
	
		
			
				
					|  |  |  |  | bool FileBrowser::selectItemFromPath(const generic_string& itemPath) const | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (itemPath.empty()) | 
			
		
	
	
		
			
				
					|  |  |  | @ -409,7 +409,7 @@ bool FileBrowser::selectItemFromPath(const generic_string& itemPath) const | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return false; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //选择当前正在编辑的文件。
 | 
			
		
	
		
			
				
					|  |  |  |  | bool FileBrowser::selectCurrentEditingFile() const | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	TCHAR currentDocPath[MAX_PATH] = { '\0' }; | 
			
		
	
	
		
			
				
					|  |  |  | @ -418,7 +418,7 @@ bool FileBrowser::selectCurrentEditingFile() const | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return selectItemFromPath(currentDocPathStr); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //摧毁创建的菜单
 | 
			
		
	
		
			
				
					|  |  |  |  | void FileBrowser::destroyMenus()  | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	::DestroyMenu(_hGlobalMenu); | 
			
		
	
	
		
			
				
					|  |  |  | @ -426,7 +426,7 @@ void FileBrowser::destroyMenus() | 
			
		
	
		
			
				
					|  |  |  |  | 	::DestroyMenu(_hFolderMenu); | 
			
		
	
		
			
				
					|  |  |  |  | 	::DestroyMenu(_hFileMenu); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //返回一个给定节点的完整路径。
 | 
			
		
	
		
			
				
					|  |  |  |  | generic_string FileBrowser::getNodePath(HTREEITEM node) const | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!node) return TEXT(""); | 
			
		
	
	
		
			
				
					|  |  |  | @ -460,12 +460,12 @@ generic_string FileBrowser::getNodePath(HTREEITEM node) const | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return fullPath; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //返回一个给定节点的名称。
 | 
			
		
	
		
			
				
					|  |  |  |  | generic_string FileBrowser::getNodeName(HTREEITEM node) const | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	return node ? _treeView.getItemDisplayName(node) : TEXT(""); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //打开选定的文件。如果选定的项目是一个文件,那么就打开它;否则,不执行任何操作。
 | 
			
		
	
		
			
				
					|  |  |  |  | void FileBrowser::openSelectFile() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	// Get the selected item
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -483,7 +483,7 @@ void FileBrowser::openSelectFile() | 
			
		
	
		
			
				
					|  |  |  |  | 	::PostMessage(_hParent, NPPM_DOOPEN, 0, reinterpret_cast<LPARAM>(_selectedNodeFullPath.c_str())); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //处理各种菜单操作的事件。例如,如果一个菜单项被双击,那么就调用函数进行对应的处理;如果一个节点标签被编辑,那么函数就保存新的标签。
 | 
			
		
	
		
			
				
					|  |  |  |  | void FileBrowser::notified(LPNMHDR notification) | 
			
		
	
		
			
				
					|  |  |  |  | {			 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (notification->code == DMN_CLOSE) | 
			
		
	
	
		
			
				
					|  |  |  | @ -673,7 +673,7 @@ void FileBrowser::notified(LPNMHDR notification) | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //获取给定项目(`hItem`)的节点类型。函数首先获取项目的索引(`iImage`),如果索引为`INDEX_LEAF`,则节点类型为文件;如果项目的参数(`lParam`)不为空并且`SortingData4lParam`类中`_rootPath`成员不为空,那么节点类型为根;否则,节点类型为文件夹。
 | 
			
		
	
		
			
				
					|  |  |  |  | BrowserNodeType FileBrowser::getNodeType(HTREEITEM hItem) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	TVITEM tvItem; | 
			
		
	
	
		
			
				
					|  |  |  | @ -697,7 +697,7 @@ BrowserNodeType FileBrowser::getNodeType(HTREEITEM hItem) | 
			
		
	
		
			
				
					|  |  |  |  | 		return browserNodeType_folder; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //(x, y)位置显示上下文菜单。函数首先检测给定位置是否在一个元素上,如果是的话就选中该元素,并获取该元素的节点类型,然后根据节点类型显示相应的上下文菜单。
 | 
			
		
	
		
			
				
					|  |  |  |  | void FileBrowser::showContextMenu(int x, int y) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	TVHITTESTINFO tvHitInfo{}; | 
			
		
	
	
		
			
				
					|  |  |  | @ -735,7 +735,7 @@ void FileBrowser::showContextMenu(int x, int y) | 
			
		
	
		
			
				
					|  |  |  |  | 			x, y, 0, _hSelf, NULL); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //执行与给定命令ID(`cmdID`)关联的上下文菜单命令。例如,如果命令ID为`IDM_FILEBROWSER_REMOVEROOTFOLDER`,则函数将删除选定的根文件夹。
 | 
			
		
	
		
			
				
					|  |  |  |  | void FileBrowser::popupMenuCmd(int cmdID) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	// get selected item handle
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -872,7 +872,7 @@ void FileBrowser::popupMenuCmd(int cmdID) | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //在目录`dir`中获取符合`patterns`模式的所有文件和子目录的结构信息,并将其保存到`directoryStructure`中。`isRecursive`参数指定是否递归遍历子目录,`isInHiddenDir`参数指示当前目录是否为隐藏目录。
 | 
			
		
	
		
			
				
					|  |  |  |  | void FileBrowser::getDirectoryStructure(const TCHAR *dir, const std::vector<generic_string> & patterns, FolderInfo & directoryStructure, bool isRecursive, bool isInHiddenDir) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (directoryStructure._parent == nullptr) // Root!
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -954,12 +954,13 @@ void FileBrowser::getDirectoryStructure(const TCHAR *dir, const std::vector<gene | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	::FindClose(hFile); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //添加根文件夹
 | 
			
		
	
		
			
				
					|  |  |  |  | void FileBrowser::addRootFolder(generic_string rootFolderPath) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | {//检查根文件夹路径是否存在
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!::PathFileExists(rootFolderPath.c_str())) | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// 检查根文件夹路径是否是一个目录
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!::PathIsDirectory(rootFolderPath.c_str())) | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -968,13 +969,13 @@ void FileBrowser::addRootFolder(generic_string rootFolderPath) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		rootFolderPath = rootFolderPath.substr(0, rootFolderPath.length() - 1); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// 遍历已添加的根文件夹更新器
 | 
			
		
	
		
			
				
					|  |  |  |  | 	for (const auto f : _folderUpdaters) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 	{		// 检查是否已经添加相同路径的根文件夹
 | 
			
		
	
		
			
				
					|  |  |  |  | 		if (f->_rootFolder._rootPath == rootFolderPath) | 
			
		
	
		
			
				
					|  |  |  |  | 			return; | 
			
		
	
		
			
				
					|  |  |  |  | 		else | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 		{			// 检查是否存在相关的根文件夹,以便选择目录
 | 
			
		
	
		
			
				
					|  |  |  |  | 			if (isRelatedRootFolder(f->_rootFolder._rootPath, rootFolderPath)) | 
			
		
	
		
			
				
					|  |  |  |  | 			{ | 
			
		
	
		
			
				
					|  |  |  |  | 				//do nothing, go down to select the dir
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -987,9 +988,9 @@ void FileBrowser::addRootFolder(generic_string rootFolderPath) | 
			
		
	
		
			
				
					|  |  |  |  | 					_treeView.selectItem(foundItem); | 
			
		
	
		
			
				
					|  |  |  |  | 				return; | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 			 | 
			
		
	
		
			
				
					|  |  |  |  | 			// 检查是否存在相对于要添加的根文件夹的子文件夹
 | 
			
		
	
		
			
				
					|  |  |  |  | 			if (isRelatedRootFolder(rootFolderPath, f->_rootFolder._rootPath)) | 
			
		
	
		
			
				
					|  |  |  |  | 			{ | 
			
		
	
		
			
				
					|  |  |  |  | 			{// 显示消息框,指示存在子文件夹,需要先移除
 | 
			
		
	
		
			
				
					|  |  |  |  | 				NppParameters::getInstance().getNativeLangSpeaker()->messageBox("FolderAsWorspaceSubfolderExists", | 
			
		
	
		
			
				
					|  |  |  |  | 					_hParent, | 
			
		
	
		
			
				
					|  |  |  |  | 					TEXT("A sub-folder of the folder you want to add exists.\rPlease remove its root from the panel before you add folder \"$STR_REPLACE$\"."), | 
			
		
	
	
		
			
				
					|  |  |  | @ -1001,10 +1002,10 @@ void FileBrowser::addRootFolder(generic_string rootFolderPath) | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// 设置要匹配的文件模式
 | 
			
		
	
		
			
				
					|  |  |  |  | 	std::vector<generic_string> patterns2Match; | 
			
		
	
		
			
				
					|  |  |  |  | 	patterns2Match.push_back(TEXT("*.*")); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// 获取根文件夹的名称并创建相应的文件夹信息对象
 | 
			
		
	
		
			
				
					|  |  |  |  | 	TCHAR *label = ::PathFindFileName(rootFolderPath.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  | 	TCHAR rootLabel[MAX_PATH] = {'\0'}; | 
			
		
	
		
			
				
					|  |  |  |  | 	wcscpy_s(rootLabel, label); | 
			
		
	
	
		
			
				
					|  |  |  | @ -1019,10 +1020,11 @@ void FileBrowser::addRootFolder(generic_string rootFolderPath) | 
			
		
	
		
			
				
					|  |  |  |  | 	_folderUpdaters.push_back(new FolderUpdater(directoryStructure, this)); | 
			
		
	
		
			
				
					|  |  |  |  | 	_folderUpdaters[_folderUpdaters.size() - 1]->startWatcher(); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //创建文件夹项目从目录结构
 | 
			
		
	
		
			
				
					|  |  |  |  | HTREEITEM FileBrowser::createFolderItemsFromDirStruct(HTREEITEM hParentItem, const FolderInfo & directoryStructure) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	HTREEITEM hFolderItem = nullptr; | 
			
		
	
		
			
				
					|  |  |  |  | 	// 如果是根目录,则创建根节点
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (directoryStructure._parent == nullptr && hParentItem == nullptr) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		TCHAR rootPath[MAX_PATH] = { '\0' }; | 
			
		
	
	
		
			
				
					|  |  |  | @ -1033,14 +1035,14 @@ HTREEITEM FileBrowser::createFolderItemsFromDirStruct(HTREEITEM hParentItem, con | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		SortingData4lParam* customData = new SortingData4lParam(rootPath, TEXT(""), true); | 
			
		
	
		
			
				
					|  |  |  |  | 		sortingDataArray.push_back(customData); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		// 添加根节点到树视图
 | 
			
		
	
		
			
				
					|  |  |  |  | 		hFolderItem = _treeView.addItem(directoryStructure._name.c_str(), TVI_ROOT, INDEX_CLOSE_ROOT, reinterpret_cast<LPARAM>(customData)); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	else | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		SortingData4lParam* customData = new SortingData4lParam(TEXT(""), directoryStructure._name, true); | 
			
		
	
		
			
				
					|  |  |  |  | 		sortingDataArray.push_back(customData); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		// 添加节点到树视图
 | 
			
		
	
		
			
				
					|  |  |  |  | 		hFolderItem = _treeView.addItem(directoryStructure._name.c_str(), hParentItem, INDEX_CLOSE_NODE, reinterpret_cast<LPARAM>(customData)); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1053,7 +1055,7 @@ HTREEITEM FileBrowser::createFolderItemsFromDirStruct(HTREEITEM hParentItem, con | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		SortingData4lParam* customData = new SortingData4lParam(TEXT(""), file._name, false); | 
			
		
	
		
			
				
					|  |  |  |  | 		sortingDataArray.push_back(customData); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		// 添加文件节点到树视图
 | 
			
		
	
		
			
				
					|  |  |  |  | 		_treeView.addItem(file._name.c_str(), hFolderItem, INDEX_LEAF, reinterpret_cast<LPARAM>(customData)); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1061,7 +1063,7 @@ HTREEITEM FileBrowser::createFolderItemsFromDirStruct(HTREEITEM hParentItem, con | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return hFolderItem; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //根据路径找到根目录
 | 
			
		
	
		
			
				
					|  |  |  |  | HTREEITEM FileBrowser::getRootFromFullPath(const generic_string & rootPath) const | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	HTREEITEM node = nullptr; | 
			
		
	
	
		
			
				
					|  |  |  | @ -1080,7 +1082,7 @@ HTREEITEM FileBrowser::getRootFromFullPath(const generic_string & rootPath) cons | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return node; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //在指定父节点下查找具有特定名称的子节点。
 | 
			
		
	
		
			
				
					|  |  |  |  | HTREEITEM FileBrowser::findChildNodeFromName(HTREEITEM parent, const generic_string& label) const | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	for (HTREEITEM hItemNode = _treeView.getChildFrom(parent); | 
			
		
	
	
		
			
				
					|  |  |  | @ -1102,7 +1104,7 @@ HTREEITEM FileBrowser::findChildNodeFromName(HTREEITEM parent, const generic_str | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return nullptr; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //得到所有根节点的路径
 | 
			
		
	
		
			
				
					|  |  |  |  | vector<generic_string> FileBrowser::getRoots() const | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	vector<generic_string> roots; | 
			
		
	
	
		
			
				
					|  |  |  | @ -1121,7 +1123,7 @@ vector<generic_string> FileBrowser::getRoots() const | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return roots; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //获取选中文件的路径
 | 
			
		
	
		
			
				
					|  |  |  |  | generic_string FileBrowser::getSelectedItemPath() const | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	generic_string itemPath; | 
			
		
	
	
		
			
				
					|  |  |  | @ -1132,7 +1134,7 @@ generic_string FileBrowser::getSelectedItemPath() const | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return itemPath; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //将传递的文件路径信息分组,按照共同路径和根路径进行分类。
 | 
			
		
	
		
			
				
					|  |  |  |  | std::vector<FileBrowser::FilesToChange> FileBrowser::getFilesFromParam(LPARAM lParam) const | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	const std::vector<generic_string> filesToChange = *(std::vector<generic_string>*)lParam; | 
			
		
	
	
		
			
				
					|  |  |  | @ -1189,7 +1191,7 @@ std::vector<FileBrowser::FilesToChange> FileBrowser::getFilesFromParam(LPARAM lP | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return groupedFiles; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //将文件组添加到树中,根据文件类型在树中创建相应的节点。
 | 
			
		
	
		
			
				
					|  |  |  |  | bool FileBrowser::addToTree(FilesToChange & group, HTREEITEM node) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (node == nullptr) // it's a root. Search the right root with rootPath
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1266,7 +1268,7 @@ bool FileBrowser::addToTree(FilesToChange & group, HTREEITEM node) | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //在树中查找并删除指定的文件组。
 | 
			
		
	
		
			
				
					|  |  |  |  | bool FileBrowser::deleteFromTree(FilesToChange & group) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	std::vector<HTREEITEM> foundItems = findInTree(group, nullptr); | 
			
		
	
	
		
			
				
					|  |  |  | @ -1283,7 +1285,7 @@ bool FileBrowser::deleteFromTree(FilesToChange & group) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return true; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //在树形结构中查找指定路径,首先判断当前节点是否为根节点,若是则根据根路径查找对应的根节点。然后根据路径数组的大小,判断是否继续查找子节点或者返回当前节点。
 | 
			
		
	
		
			
				
					|  |  |  |  | HTREEITEM FileBrowser::findInTree(const generic_string& rootPath, HTREEITEM node, std::vector<generic_string> linarPathArray) const | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (node == nullptr) // it's a root. Search the right root with rootPath
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1326,7 +1328,7 @@ HTREEITEM FileBrowser::findInTree(const generic_string& rootPath, HTREEITEM node | 
			
		
	
		
			
				
					|  |  |  |  | 		return nullptr; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //该函数也用于在树形结构中查找指定路径,但参数不同。参数group是一个包含文件信息和路径的对象,node表示当前节点。函数首先判断当前节点是否为根节点,若是则根据路径信息查找对应的根节点。然后根据路径信息的大小,判断是否继续查找子节点或者返回找到的节点集合。
 | 
			
		
	
		
			
				
					|  |  |  |  | std::vector<HTREEITEM> FileBrowser::findInTree(FilesToChange & group, HTREEITEM node) const | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (node == nullptr) // it's a root. Search the right root with rootPath
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1367,7 +1369,7 @@ std::vector<HTREEITEM> FileBrowser::findInTree(FilesToChange & group, HTREEITEM | 
			
		
	
		
			
				
					|  |  |  |  | 		return {}; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //找到指定父节点的子节点
 | 
			
		
	
		
			
				
					|  |  |  |  | std::vector<HTREEITEM> FileBrowser::findChildNodesFromNames(HTREEITEM parent, std::vector<generic_string> & labels) const | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	std::vector<HTREEITEM> itemNodes; | 
			
		
	
	
		
			
				
					|  |  |  | @ -1394,6 +1396,7 @@ std::vector<HTREEITEM> FileBrowser::findChildNodesFromNames(HTREEITEM parent, st | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return itemNodes; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | //移除已经在父节点中的名字。它遍历父节点的所有子节点,并将与给定标签集合中名字相匹配的标签清除。
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void FileBrowser::removeNamesAlreadyInNode(HTREEITEM parent, std::vector<generic_string> & labels) const | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
	
		
			
				
					|  |  |  | @ -1418,7 +1421,7 @@ void FileBrowser::removeNamesAlreadyInNode(HTREEITEM parent, std::vector<generic | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //在树形结构中重命名节点,找到匹配给定线性路径数组的节点,并将其重新命名为指定的字符串。
 | 
			
		
	
		
			
				
					|  |  |  |  | bool FileBrowser::renameInTree(const generic_string& rootPath, HTREEITEM node, const std::vector<generic_string>& linarPathArrayFrom, const generic_string & renameTo) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	HTREEITEM foundItem = findInTree(rootPath, node, linarPathArrayFrom); | 
			
		
	
	
		
			
				
					|  |  |  | @ -1433,7 +1436,7 @@ bool FileBrowser::renameInTree(const generic_string& rootPath, HTREEITEM node, c | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return true; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //排序回调函数,按照文件夹和文件名进行排序。首先是文件夹,然后是文件。如果两者都是文件夹或文件,那么比较它们的名字。
 | 
			
		
	
		
			
				
					|  |  |  |  | int CALLBACK FileBrowser::categorySortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM /*lParamSort*/) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	SortingData4lParam* item1 = reinterpret_cast<SortingData4lParam*>(lParam1); | 
			
		
	
	
		
			
				
					|  |  |  | @ -1449,7 +1452,7 @@ int CALLBACK FileBrowser::categorySortFunc(LPARAM lParam1, LPARAM lParam2, LPARA | 
			
		
	
		
			
				
					|  |  |  |  | 	else | 
			
		
	
		
			
				
					|  |  |  |  | 		return lstrcmpi(item1->_label.c_str(), item2->_label.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //将给定的完整路径添加到文件夹信息结构中。该路径可能是文件或目录,如果该路径已经存在于结构中,则返回false,如果成功添加,则返回true。
 | 
			
		
	
		
			
				
					|  |  |  |  | bool FolderInfo::addToStructure(generic_string & fullpath, std::vector<generic_string> linarPathArray) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (linarPathArray.size() == 1) // could be file or folder
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1494,7 +1497,7 @@ bool FolderInfo::addToStructure(generic_string & fullpath, std::vector<generic_s | 
			
		
	
		
			
				
					|  |  |  |  | 		return false; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //从文件夹信息结构中删除给定的线性路径数组。成功删除返回true,否则返回false。
 | 
			
		
	
		
			
				
					|  |  |  |  | bool FolderInfo::removeFromStructure(std::vector<generic_string> linarPathArray) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (linarPathArray.size() == 1) // could be file or folder
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1532,7 +1535,7 @@ bool FolderInfo::removeFromStructure(std::vector<generic_string> linarPathArray) | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return false; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //在文件夹信息结构中重命名给定的线性路径。它将 "linarPathArrayFrom" 指定的路径的名字更改为 "linarPathArrayTo" 指定的名字。
 | 
			
		
	
		
			
				
					|  |  |  |  | bool FolderInfo::renameInStructure(std::vector<generic_string> linarPathArrayFrom, std::vector<generic_string> linarPathArrayTo) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (linarPathArrayFrom.size() == 1) // could be file or folder
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1572,6 +1575,7 @@ bool FolderInfo::renameInStructure(std::vector<generic_string> linarPathArrayFro | 
			
		
	
		
			
				
					|  |  |  |  | 		return false; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | //打开监视器,创建一个事件对象并开启一个新的线程,线程开始运行 `watching` 函数。
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void FolderUpdater::startWatcher() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
	
		
			
				
					|  |  |  | @ -1579,6 +1583,7 @@ void FolderUpdater::startWatcher() | 
			
		
	
		
			
				
					|  |  |  |  | 	_EventHandle = ::CreateEvent(nullptr, TRUE, FALSE, nullptr); | 
			
		
	
		
			
				
					|  |  |  |  | 	_watchThreadHandle = ::CreateThread(NULL, 0, watching, this, 0, NULL); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | //停止监视器。它通过设定事件和关闭对应的线程实现。
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void FolderUpdater::stopWatcher() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
	
		
			
				
					|  |  |  | @ -1586,6 +1591,7 @@ void FolderUpdater::stopWatcher() | 
			
		
	
		
			
				
					|  |  |  |  | 	::CloseHandle(_watchThreadHandle); | 
			
		
	
		
			
				
					|  |  |  |  | 	::CloseHandle(_EventHandle); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | //根据动作类型的代码返回相应的动作名字。
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | LPCWSTR explainAction(DWORD dwAction) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
	
		
			
				
					|  |  |  | @ -1606,6 +1612,7 @@ LPCWSTR explainAction(DWORD dwAction) | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //负责监视目录下的文件变化。当有文件被创建、删除、重命名等操作时,就会将这个改动放入改动队列,并通过事件提醒主线程进行处理。
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | DWORD WINAPI FolderUpdater::watching(void *params) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
	
		
			
				
					|  |  |  | @ -1704,6 +1711,7 @@ DWORD WINAPI FolderUpdater::watching(void *params) | 
			
		
	
		
			
				
					|  |  |  |  | 	//printStr(L"Quit watching thread");
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return EXIT_SUCCESS; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | //根据改动的类型,调用不同的文件浏览器的方法,例如文件创建、删除、重命名等。
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void FolderUpdater::processChange(DWORD dwAction, std::vector<generic_string> filesToChange, FolderUpdater* thisFolderUpdater) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
	
		
			
				
					|  |  |  | 
 |