|  |  |  | @ -16,291 +16,331 @@ | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #include "lastRecentFileList.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "menuCmdID.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "localization.h" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::initMenu(HMENU hMenu, int idBase, int posBase, Accelerator *pAccelerator, bool doSubMenu) | 
			
		
	
		
			
				
					|  |  |  |  | // 引入LastRecentFileList类的头文件  
 | 
			
		
	
		
			
				
					|  |  |  |  | #include "lastRecentFileList.h"   | 
			
		
	
		
			
				
					|  |  |  |  | // 引入菜单命令ID的头文件  
 | 
			
		
	
		
			
				
					|  |  |  |  | #include "menuCmdID.h"   | 
			
		
	
		
			
				
					|  |  |  |  | // 引入本地化的头文件,可能用于支持多语言  
 | 
			
		
	
		
			
				
					|  |  |  |  | #include "localization.h"   | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // LastRecentFileList类的initMenu函数  
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::initMenu(HMENU hMenu, int idBase, int posBase, Accelerator* pAccelerator, bool doSubMenu) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (doSubMenu) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		_hParentMenu = hMenu; | 
			
		
	
		
			
				
					|  |  |  |  | 		_hMenu = ::CreatePopupMenu(); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	else | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		_hParentMenu = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 		_hMenu = hMenu; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	_idBase = idBase; | 
			
		
	
		
			
				
					|  |  |  |  | 	_posBase = posBase; | 
			
		
	
		
			
				
					|  |  |  |  | 	_pAccelerator = pAccelerator; | 
			
		
	
		
			
				
					|  |  |  |  | 	_nativeLangEncoding = NPP_CP_WIN_1252; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	for (size_t i = 0 ; i < sizeof(_idFreeArray) ; ++i) | 
			
		
	
		
			
				
					|  |  |  |  | 		_idFreeArray[i] = true; | 
			
		
	
		
			
				
					|  |  |  |  |     // 如果doSubMenu为真,表示需要创建一个弹出菜单  
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (doSubMenu) | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         // 设置父菜单句柄  
 | 
			
		
	
		
			
				
					|  |  |  |  |         _hParentMenu = hMenu; | 
			
		
	
		
			
				
					|  |  |  |  |         // 创建一个新的弹出菜单  
 | 
			
		
	
		
			
				
					|  |  |  |  |         _hMenu = ::CreatePopupMenu(); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     // 如果doSubMenu为假,表示直接使用传入的菜单句柄  
 | 
			
		
	
		
			
				
					|  |  |  |  |     else | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         // 设置父菜单句柄为NULL,表示主菜单  
 | 
			
		
	
		
			
				
					|  |  |  |  |         _hParentMenu = NULL; | 
			
		
	
		
			
				
					|  |  |  |  |         // 使用传入的菜单句柄作为当前菜单  
 | 
			
		
	
		
			
				
					|  |  |  |  |         _hMenu = hMenu; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 设置ID的基础值  
 | 
			
		
	
		
			
				
					|  |  |  |  |     _idBase = idBase; | 
			
		
	
		
			
				
					|  |  |  |  |     // 设置位置的基础值  
 | 
			
		
	
		
			
				
					|  |  |  |  |     _posBase = posBase; | 
			
		
	
		
			
				
					|  |  |  |  |     // 设置指向Accelerator对象的指针,用于处理键盘快捷键等加速功能  
 | 
			
		
	
		
			
				
					|  |  |  |  |     _pAccelerator = pAccelerator; | 
			
		
	
		
			
				
					|  |  |  |  |     // 设置本地化语言编码为Windows的1252编码,这是一种西欧语言编码  
 | 
			
		
	
		
			
				
					|  |  |  |  |     _nativeLangEncoding = NPP_CP_WIN_1252; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 初始化idFreeArray数组,所有元素都设置为true,表示ID可用  
 | 
			
		
	
		
			
				
					|  |  |  |  |     for (size_t i = 0; i < sizeof(_idFreeArray); ++i) | 
			
		
	
		
			
				
					|  |  |  |  |         _idFreeArray[i] = true; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // LastRecentFileList类的switchMode函数,用于切换模式  
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::switchMode() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	//Remove all menu items
 | 
			
		
	
		
			
				
					|  |  |  |  | 	::RemoveMenu(_hMenu, IDM_FILE_RESTORELASTCLOSEDFILE, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  | 	::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  | 	::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = 0; i < _size; ++i) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (_hParentMenu == NULL) // mode main menu
 | 
			
		
	
		
			
				
					|  |  |  |  | 	{	if (_size > 0) | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  | 			::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		// switch to sub-menu mode
 | 
			
		
	
		
			
				
					|  |  |  |  | 		_hParentMenu = _hMenu; | 
			
		
	
		
			
				
					|  |  |  |  | 		_hMenu = ::CreatePopupMenu(); | 
			
		
	
		
			
				
					|  |  |  |  | 		::RemoveMenu(_hMenu, _posBase+1, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	else // mode sub-menu
 | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		if (_size > 0) | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  | 			::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		// switch to main menu mode
 | 
			
		
	
		
			
				
					|  |  |  |  | 		::DestroyMenu(_hMenu); | 
			
		
	
		
			
				
					|  |  |  |  | 		_hMenu = _hParentMenu; | 
			
		
	
		
			
				
					|  |  |  |  | 		_hParentMenu = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	_hasSeparators = false; | 
			
		
	
		
			
				
					|  |  |  |  |     // 从菜单中移除所有相关菜单项  
 | 
			
		
	
		
			
				
					|  |  |  |  |     ::RemoveMenu(_hMenu, IDM_FILE_RESTORELASTCLOSEDFILE, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  |     ::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  |     ::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 遍历最近打开文件列表,移除所有菜单项  
 | 
			
		
	
		
			
				
					|  |  |  |  |     for (int i = 0; i < _size; ++i) | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         ::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 根据_hParentMenu的值判断当前模式,主菜单模式或子菜单模式  
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (_hParentMenu == NULL) // mode main menu(主菜单模式)  
 | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         if (_size > 0) // 如果最近打开文件列表不为空  
 | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             // 从主菜单中移除一些特定的菜单项(具体移除哪些项未给出)  
 | 
			
		
	
		
			
				
					|  |  |  |  |             ::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  |             ::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         // 切换到子菜单模式,创建一个新的弹出菜单作为当前菜单,并设置_hParentMenu为当前菜单(即新创建的弹出菜单)  
 | 
			
		
	
		
			
				
					|  |  |  |  |         // 同时移除一些特定的菜单项(具体移除哪些项未给出)  
 | 
			
		
	
		
			
				
					|  |  |  |  |         _hParentMenu = _hMenu; | 
			
		
	
		
			
				
					|  |  |  |  |         _hMenu = ::CreatePopupMenu(); | 
			
		
	
		
			
				
					|  |  |  |  |         ::RemoveMenu(_hMenu, _posBase + 1, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     else // mode sub-menu(子菜单模式)  
 | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         if (_size > 0) // 如果最近打开文件列表不为空  
 | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             // 从子菜单中移除一些特定的菜单项(具体移除哪些项未给出)  
 | 
			
		
	
		
			
				
					|  |  |  |  |             ::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  |             ::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         // switch to main menu mode
 | 
			
		
	
		
			
				
					|  |  |  |  |         ::DestroyMenu(_hMenu); | 
			
		
	
		
			
				
					|  |  |  |  |         _hMenu = _hParentMenu; | 
			
		
	
		
			
				
					|  |  |  |  |         _hParentMenu = NULL; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     _hasSeparators = false; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::updateMenu() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	NppParameters& nppParam = NppParameters::getInstance(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!_hasSeparators && _size > 0)  | 
			
		
	
		
			
				
					|  |  |  |  | 	{	 | 
			
		
	
		
			
				
					|  |  |  |  | 		//add separators
 | 
			
		
	
		
			
				
					|  |  |  |  | 		NativeLangSpeaker *pNativeLangSpeaker = nppParam.getNativeLangSpeaker(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		generic_string recentFileList = pNativeLangSpeaker->getSubMenuEntryName("file-recentFiles"); | 
			
		
	
		
			
				
					|  |  |  |  | 		generic_string openRecentClosedFile = pNativeLangSpeaker->getNativeLangMenuString(IDM_FILE_RESTORELASTCLOSEDFILE); | 
			
		
	
		
			
				
					|  |  |  |  | 		generic_string openAllFiles = pNativeLangSpeaker->getNativeLangMenuString(IDM_OPEN_ALL_RECENT_FILE); | 
			
		
	
		
			
				
					|  |  |  |  | 		generic_string cleanFileList = pNativeLangSpeaker->getNativeLangMenuString(IDM_CLEAN_RECENT_FILE_LIST); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		if (recentFileList == TEXT("")) | 
			
		
	
		
			
				
					|  |  |  |  | 			recentFileList = TEXT("&Recent Files"); | 
			
		
	
		
			
				
					|  |  |  |  | 		if (openRecentClosedFile == TEXT("")) | 
			
		
	
		
			
				
					|  |  |  |  | 			openRecentClosedFile = TEXT("Restore Recent Closed File"); | 
			
		
	
		
			
				
					|  |  |  |  | 		if (openAllFiles == TEXT("")) | 
			
		
	
		
			
				
					|  |  |  |  | 			openAllFiles = TEXT("Open All Recent Files"); | 
			
		
	
		
			
				
					|  |  |  |  | 		if (cleanFileList == TEXT("")) | 
			
		
	
		
			
				
					|  |  |  |  | 			cleanFileList = TEXT("Empty Recent Files List"); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!isSubMenuMode()) | 
			
		
	
		
			
				
					|  |  |  |  | 			::InsertMenu(_hMenu, _posBase + 0, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		::InsertMenu(_hMenu, _posBase + 1, MF_BYPOSITION, IDM_FILE_RESTORELASTCLOSEDFILE, openRecentClosedFile.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  | 		::InsertMenu(_hMenu, _posBase + 2, MF_BYPOSITION, IDM_OPEN_ALL_RECENT_FILE, openAllFiles.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  | 		::InsertMenu(_hMenu, _posBase + 3, MF_BYPOSITION, IDM_CLEAN_RECENT_FILE_LIST, cleanFileList.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  | 		::InsertMenu(_hMenu, _posBase + 4, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0); | 
			
		
	
		
			
				
					|  |  |  |  | 		_hasSeparators = true; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		if (isSubMenuMode()) | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			::InsertMenu(_hParentMenu, _posBase + 0, MF_BYPOSITION | MF_POPUP, reinterpret_cast<UINT_PTR>(_hMenu), (LPCTSTR)recentFileList.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  | 			::InsertMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	else if (_hasSeparators && _size == 0) 	//remove separators
 | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		::RemoveMenu(_hMenu, _posBase + 4, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  | 		::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  | 		::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  | 		::RemoveMenu(_hMenu, IDM_FILE_RESTORELASTCLOSEDFILE, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  | 		::RemoveMenu(_hMenu, _posBase + 0, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  | 		_hasSeparators = false; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		if (isSubMenuMode()) | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			// Remove "Recent Files" Entry and the separator from the main menu
 | 
			
		
	
		
			
				
					|  |  |  |  | 			::RemoveMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  | 			::RemoveMenu(_hParentMenu, _posBase + 0, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			// Remove the last left separator from the submenu
 | 
			
		
	
		
			
				
					|  |  |  |  | 			::RemoveMenu(_hMenu, 0, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	_pAccelerator->updateFullMenu(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	//Remove all menu items
 | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = 0; i < _size; ++i)  | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	//Then readd them, so everything stays in sync
 | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int j = 0; j < _size; ++j) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		generic_string strBuffer(BuildMenuFileName(nppParam.getRecentFileCustomLength(), j, _lrfl.at(j)._name)); | 
			
		
	
		
			
				
					|  |  |  |  | 		::InsertMenu(_hMenu, _posBase + j, MF_BYPOSITION, _lrfl.at(j)._id, strBuffer.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  |     // 获取 NppParameters 的单例实例  
 | 
			
		
	
		
			
				
					|  |  |  |  |     NppParameters& nppParam = NppParameters::getInstance(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 检查是否没有分隔符且大小大于0,满足条件则进入下面的 if 语句块  
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (!_hasSeparators && _size > 0) | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         // 获取本地化语言的发言人对象  
 | 
			
		
	
		
			
				
					|  |  |  |  |         NativeLangSpeaker* pNativeLangSpeaker = nppParam.getNativeLangSpeaker(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         // 从发言人对象中获取一些本地化菜单字符串  
 | 
			
		
	
		
			
				
					|  |  |  |  |         generic_string recentFileList = pNativeLangSpeaker->getSubMenuEntryName("file-recentFiles"); | 
			
		
	
		
			
				
					|  |  |  |  |         generic_string openRecentClosedFile = pNativeLangSpeaker->getNativeLangMenuString(IDM_FILE_RESTORELASTCLOSEDFILE); | 
			
		
	
		
			
				
					|  |  |  |  |         generic_string openAllFiles = pNativeLangSpeaker->getNativeLangMenuString(IDM_OPEN_ALL_RECENT_FILE); | 
			
		
	
		
			
				
					|  |  |  |  |         generic_string cleanFileList = pNativeLangSpeaker->getNativeLangMenuString(IDM_CLEAN_RECENT_FILE_LIST); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         // 如果获取的字符串为空,则使用默认的字符串进行初始化  
 | 
			
		
	
		
			
				
					|  |  |  |  |         if (recentFileList == TEXT("")) | 
			
		
	
		
			
				
					|  |  |  |  |             recentFileList = TEXT("&Recent Files"); | 
			
		
	
		
			
				
					|  |  |  |  |         if (openRecentClosedFile == TEXT("")) | 
			
		
	
		
			
				
					|  |  |  |  |             openRecentClosedFile = TEXT("Restore Recent Closed File"); | 
			
		
	
		
			
				
					|  |  |  |  |         if (openAllFiles == TEXT("")) | 
			
		
	
		
			
				
					|  |  |  |  |             openAllFiles = TEXT("Open All Recent Files"); | 
			
		
	
		
			
				
					|  |  |  |  |         if (cleanFileList == TEXT("")) | 
			
		
	
		
			
				
					|  |  |  |  |             cleanFileList = TEXT("Empty Recent Files List"); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         // 如果当前不是子菜单模式,则在菜单中插入一个分隔符  
 | 
			
		
	
		
			
				
					|  |  |  |  |         if (!isSubMenuMode()) | 
			
		
	
		
			
				
					|  |  |  |  |             ::InsertMenu(_hMenu, _posBase + 0, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         // 在菜单中插入四个子菜单项,分别是恢复最近关闭的文件、打开所有最近文件、清空最近文件列表和另一个分隔符  
 | 
			
		
	
		
			
				
					|  |  |  |  |         ::InsertMenu(_hMenu, _posBase + 1, MF_BYPOSITION, IDM_FILE_RESTORELASTCLOSEDFILE, openRecentClosedFile.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  |         ::InsertMenu(_hMenu, _posBase + 2, MF_BYPOSITION, IDM_OPEN_ALL_RECENT_FILE, openAllFiles.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  |         ::InsertMenu(_hMenu, _posBase + 3, MF_BYPOSITION, IDM_CLEAN_RECENT_FILE_LIST, cleanFileList.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  |         ::InsertMenu(_hMenu, _posBase + 4, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0); // 插入分隔符  
 | 
			
		
	
		
			
				
					|  |  |  |  |         // 设置标志表示已有分隔符  
 | 
			
		
	
		
			
				
					|  |  |  |  |         _hasSeparators = true; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         // 如果当前是子菜单模式,则在父菜单中插入子菜单和分隔符  
 | 
			
		
	
		
			
				
					|  |  |  |  |         if (isSubMenuMode()) | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             ::InsertMenu(_hParentMenu, _posBase + 0, MF_BYPOSITION | MF_POPUP, reinterpret_cast<UINT_PTR>(_hMenu), (LPCTSTR)recentFileList.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  |             ::InsertMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0); // 插入分隔符  
 | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     else if (_hasSeparators && _size == 0)  // 当已有分隔符且大小为0时,进入下面的 if 语句块,用于移除分隔符和菜单项  
 | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         // 从菜单中移除一个分隔符和清空最近文件列表的菜单项  
 | 
			
		
	
		
			
				
					|  |  |  |  |         ::RemoveMenu(_hMenu, _posBase + 4, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  |         ::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  |         ::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  |         ::RemoveMenu(_hMenu, IDM_FILE_RESTORELASTCLOSEDFILE, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  |         ::RemoveMenu(_hMenu, _posBase + 0, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  |         _hasSeparators = false; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         if (isSubMenuMode()) | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             // Remove "Recent Files" Entry and the separator from the main menu
 | 
			
		
	
		
			
				
					|  |  |  |  |             ::RemoveMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  |             ::RemoveMenu(_hParentMenu, _posBase + 0, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             // Remove the last left separator from the submenu
 | 
			
		
	
		
			
				
					|  |  |  |  |             ::RemoveMenu(_hMenu, 0, MF_BYPOSITION); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     _pAccelerator->updateFullMenu(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     //Remove all menu items
 | 
			
		
	
		
			
				
					|  |  |  |  |     for (int i = 0; i < _size; ++i) | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         ::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     //Then readd them, so everything stays in sync
 | 
			
		
	
		
			
				
					|  |  |  |  |     for (int j = 0; j < _size; ++j) | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         generic_string strBuffer(BuildMenuFileName(nppParam.getRecentFileCustomLength(), j, _lrfl.at(j)._name)); | 
			
		
	
		
			
				
					|  |  |  |  |         ::InsertMenu(_hMenu, _posBase + j, MF_BYPOSITION, _lrfl.at(j)._id, strBuffer.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::add(const TCHAR *fn)  | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | // 向最近的文件列表中添加一个文件名。如果达到用户定义的最大限制或列表被锁定,则不会添加。  
 | 
			
		
	
		
			
				
					|  |  |  |  | // 如果文件名已存在,则会先将其移除再添加。  
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::add(const TCHAR* fn) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (_userMax == 0 || _locked) | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	RecentItem itemToAdd(fn); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	int index = find(fn); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (index != -1) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		//already in list, bump upwards
 | 
			
		
	
		
			
				
					|  |  |  |  | 		remove(index); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (_size == _userMax) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		itemToAdd._id = _lrfl.back()._id; | 
			
		
	
		
			
				
					|  |  |  |  | 		_lrfl.pop_back();	//remove oldest
 | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	else | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		itemToAdd._id = popFirstAvailableID(); | 
			
		
	
		
			
				
					|  |  |  |  | 		++_size; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	_lrfl.push_front(itemToAdd); | 
			
		
	
		
			
				
					|  |  |  |  | 	updateMenu(); | 
			
		
	
		
			
				
					|  |  |  |  |     if (_userMax == 0 || _locked) // 如果用户定义的最大数量为0或列表被锁定,直接返回,不进行添加  
 | 
			
		
	
		
			
				
					|  |  |  |  |         return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     RecentItem itemToAdd(fn); // 创建一个新的RecentItem对象,使用传入的文件名初始化  
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     int index = find(fn); // 查找该文件名在列表中的索引  
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (index != -1) // 如果找到  
 | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         // 如果文件名已存在,先将其移除,然后重新添加  
 | 
			
		
	
		
			
				
					|  |  |  |  |         remove(index); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (_size == _userMax) // 如果列表已满  
 | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         itemToAdd._id = _lrfl.back()._id; // 使用最后一个元素的ID初始化新元素的ID  
 | 
			
		
	
		
			
				
					|  |  |  |  |         _lrfl.pop_back(); // 移除列表中的最后一个元素(即最旧的一个)  
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     else // 如果列表未满  
 | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         itemToAdd._id = popFirstAvailableID(); // 获取第一个可用的ID并初始化新元素的ID  
 | 
			
		
	
		
			
				
					|  |  |  |  |         ++_size; // 增加列表的大小  
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     _lrfl.push_front(itemToAdd); // 在列表的前面添加新元素  
 | 
			
		
	
		
			
				
					|  |  |  |  |     updateMenu(); // 更新菜单  
 | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::remove(const TCHAR *fn)  | 
			
		
	
		
			
				
					|  |  |  |  | {  | 
			
		
	
		
			
				
					|  |  |  |  | 	int index = find(fn); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (index != -1) | 
			
		
	
		
			
				
					|  |  |  |  | 		remove(index); | 
			
		
	
		
			
				
					|  |  |  |  | // 根据文件名从最近的文件列表中移除一个文件。如果找到,则移除;否则什么也不做。  
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::remove(const TCHAR* fn) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     int index = find(fn); // 查找文件名在列表中的索引  
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (index != -1) // 如果找到  
 | 
			
		
	
		
			
				
					|  |  |  |  |         remove(index); // 移除该元素  
 | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::remove(size_t index)  | 
			
		
	
		
			
				
					|  |  |  |  | // 根据索引从最近的文件列表中移除一个文件。如果索引有效,则移除;否则什么也不做。  
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::remove(size_t index) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (_size == 0 || _locked) | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	if (index < _lrfl.size()) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		::RemoveMenu(_hMenu, _lrfl.at(index)._id, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  | 		setAvailable(_lrfl.at(index)._id); | 
			
		
	
		
			
				
					|  |  |  |  | 		_lrfl.erase(_lrfl.begin() + index); | 
			
		
	
		
			
				
					|  |  |  |  | 		--_size; | 
			
		
	
		
			
				
					|  |  |  |  | 		updateMenu(); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  |     if (_size == 0 || _locked) // 如果列表为空或被锁定,直接返回,不进行移除操作  
 | 
			
		
	
		
			
				
					|  |  |  |  |         return; | 
			
		
	
		
			
				
					|  |  |  |  |     if (index < _lrfl.size()) // 如果索引有效  
 | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         ::RemoveMenu(_hMenu, _lrfl.at(index)._id, MF_BYCOMMAND); // 从菜单中移除该ID对应的菜单项  
 | 
			
		
	
		
			
				
					|  |  |  |  |         setAvailable(_lrfl.at(index)._id); // 将该ID标记为可用(可能是为了下次添加时重复使用)  
 | 
			
		
	
		
			
				
					|  |  |  |  |         _lrfl.erase(_lrfl.begin() + index); // 从列表中移除该元素  
 | 
			
		
	
		
			
				
					|  |  |  |  |         --_size; // 减少列表的大小  
 | 
			
		
	
		
			
				
					|  |  |  |  |         updateMenu(); // 更新菜单  
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::clear()  | 
			
		
	
		
			
				
					|  |  |  |  | // 清空最近的文件列表。所有文件名和ID都会被移除,菜单也会相应地更新。  
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::clear() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (_size == 0) | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = (_size-1); i >= 0; i--)  | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  | 		setAvailable(_lrfl.at(i)._id); | 
			
		
	
		
			
				
					|  |  |  |  | 		_lrfl.erase(_lrfl.begin() + i); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	_size = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 	updateMenu(); | 
			
		
	
		
			
				
					|  |  |  |  |     if (_size == 0) // 如果列表为空,直接返回,不进行任何操作  
 | 
			
		
	
		
			
				
					|  |  |  |  |         return; | 
			
		
	
		
			
				
					|  |  |  |  |     for (int i = (_size - 1); i >= 0; i--) // 从后向前遍历列表,因为移除元素会影响后续元素的索引  
 | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         ::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); // 从菜单中移除该ID对应的菜单项  
 | 
			
		
	
		
			
				
					|  |  |  |  |         setAvailable(_lrfl.at(i)._id); // 将该ID标记为可用(可能是为了下次添加时重复使用)  
 | 
			
		
	
		
			
				
					|  |  |  |  |         _lrfl.erase(_lrfl.begin() + i); // 从列表中移除该元素  
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     _size = 0; // 将列表大小设置为0  
 | 
			
		
	
		
			
				
					|  |  |  |  |     updateMenu(); // 更新菜单  
 | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 这段代码定义了一个名为LastRecentFileList的类,该类用于管理最近打开的文件列表。以下是详细的中文注释: | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | generic_string & LastRecentFileList::getItem(int id)  | 
			
		
	
		
			
				
					|  |  |  |  | cpp | 
			
		
	
		
			
				
					|  |  |  |  | // 根据ID从最近的文件列表中获取一个文件名。如果找到,则返回对应的文件名;否则返回列表中的第一个文件名。  
 | 
			
		
	
		
			
				
					|  |  |  |  | generic_string& LastRecentFileList::getItem(int id) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	int i = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 	for (; i < _size; ++i) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		if (_lrfl.at(i)._id == id) | 
			
		
	
		
			
				
					|  |  |  |  | 			break; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	if (i == _size) | 
			
		
	
		
			
				
					|  |  |  |  | 		i = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 	return _lrfl.at(i)._name;	//if not found, return first
 | 
			
		
	
		
			
				
					|  |  |  |  |     int i = 0; // 从索引0开始查找,因为如果ID不存在,可能会返回第一个文件名作为默认值。  
 | 
			
		
	
		
			
				
					|  |  |  |  |     for (; i < _size; ++i) // 遍历整个列表查找匹配的ID。如果找不到,i会等于_size,此时i会被重新设置为0。这是一个后备计划,以防ID不存在于列表  
 | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         if (_lrfl.at(i)._id == id) // 如果找到匹配的ID  
 | 
			
		
	
		
			
				
					|  |  |  |  |             break; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     if (i == _size) // 如果遍历完整个列表都没有找到匹配的ID  
 | 
			
		
	
		
			
				
					|  |  |  |  |         i = 0; // 将索引重置为0,这样可以从列表的第一个元素开始返回文件名作为默认值  
 | 
			
		
	
		
			
				
					|  |  |  |  |     return _lrfl.at(i)._name; // 返回找到的文件名或默认文件名  
 | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | generic_string & LastRecentFileList::getIndex(int index) | 
			
		
	
		
			
				
					|  |  |  |  | // 根据索引从最近的文件列表中获取一个文件名。如果索引有效,则返回对应的文件名;否则返回列表中的第一个文件名。  
 | 
			
		
	
		
			
				
					|  |  |  |  | generic_string& LastRecentFileList::getIndex(int index) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	return _lrfl.at(index)._name;	//if not found, return first
 | 
			
		
	
		
			
				
					|  |  |  |  |     return _lrfl.at(index)._name; // 返回找到的文件名或默认文件名  
 | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // 设置用户定义的最大最近文件列表大小。如果当前列表大小大于新设置的大小,则移除最旧的文件直到列表大小等于新设置的大小。  
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::setUserMaxNbLRF(int size) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	_userMax = size; | 
			
		
	
		
			
				
					|  |  |  |  | 	if (_size > _userMax)  | 
			
		
	
		
			
				
					|  |  |  |  | 	{	//start popping items
 | 
			
		
	
		
			
				
					|  |  |  |  | 		int toPop = _size-_userMax; | 
			
		
	
		
			
				
					|  |  |  |  | 		while (toPop > 0)  | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			::RemoveMenu(_hMenu, _lrfl.back()._id, MF_BYCOMMAND); | 
			
		
	
		
			
				
					|  |  |  |  | 			setAvailable(_lrfl.back()._id); | 
			
		
	
		
			
				
					|  |  |  |  | 			_lrfl.pop_back(); | 
			
		
	
		
			
				
					|  |  |  |  | 			toPop--; | 
			
		
	
		
			
				
					|  |  |  |  | 			_size--; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		updateMenu(); | 
			
		
	
		
			
				
					|  |  |  |  | 		_size = _userMax; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  |     _userMax = size; // 设置用户定义的最大列表大小  
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (_size > _userMax) // 如果当前列表大小大于新设置的大小  
 | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         int toPop = _size - _userMax; // 计算需要移除的文件数量  
 | 
			
		
	
		
			
				
					|  |  |  |  |         while (toPop > 0) // 当还有文件需要移除时  
 | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             ::RemoveMenu(_hMenu, _lrfl.back()._id, MF_BYCOMMAND); // 从菜单中移除该ID对应的菜单项  
 | 
			
		
	
		
			
				
					|  |  |  |  |             setAvailable(_lrfl.back()._id); // 将该ID标记为可用(可能是为了下次添加时重复使用)  
 | 
			
		
	
		
			
				
					|  |  |  |  |             _lrfl.pop_back(); // 从列表中移除该元素  
 | 
			
		
	
		
			
				
					|  |  |  |  |             toPop--; // 减少剩余需要移除的文件数量  
 | 
			
		
	
		
			
				
					|  |  |  |  |             _size--; // 减少当前列表大小  
 | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         updateMenu(); // 更新菜单  
 | 
			
		
	
		
			
				
					|  |  |  |  |         _size = _userMax; // 将当前列表大小设置为新设置的大小  
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // 将最近的文件列表保存到配置文件中。保存的文件名顺序与加载时相同。  
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::saveLRFL() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	NppParameters& nppParams = NppParameters::getInstance(); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (nppParams.writeRecentFileHistorySettings(_userMax)) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		for (int i = _size - 1; i >= 0; i--)	//reverse order: so loading goes in correct order
 | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			nppParams.writeHistory(_lrfl.at(i)._name.c_str()); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  |     NppParameters& nppParams = NppParameters::getInstance(); // 获取NppParameters的实例引用  
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (nppParams.writeRecentFileHistorySettings(_userMax)) // 如果成功写入最近的文件历史设置  
 | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         for (int i = _size - 1; i >= 0; i--) // 按照从后往前的顺序保存文件名,确保加载时的顺序正确  
 | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             nppParams.writeHistory(_lrfl.at(i)._name.c_str()); // 将文件名写入配置文件的历史记录部分  
 | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | int LastRecentFileList::find(const TCHAR *fn) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // 在最近的文件列表中查找指定的文件名。  
 | 
			
		
	
		
			
				
					|  |  |  |  | int LastRecentFileList::find(const TCHAR* fn) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = 0; i < _size; ++i) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		if (OrdinalIgnoreCaseCompareStrings(_lrfl.at(i)._name.c_str(), fn) == 0) | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			return i; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return -1; | 
			
		
	
		
			
				
					|  |  |  |  |     for (int i = 0; i < _size; ++i) // 遍历整个列表  
 | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         if (OrdinalIgnoreCaseCompareStrings(_lrfl.at(i)._name.c_str(), fn) == 0) // 如果找到匹配的文件名(忽略大小写)  
 | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             return i; // 返回该文件在列表中的索引  
 | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     return -1; // 如果未找到,返回-1  
 | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | int LastRecentFileList::popFirstAvailableID()  | 
			
		
	
		
			
				
					|  |  |  |  | // 弹出第一个可用的ID。  
 | 
			
		
	
		
			
				
					|  |  |  |  | int LastRecentFileList::popFirstAvailableID() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = 0 ; i < NB_MAX_LRF_FILE ; ++i) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		if (_idFreeArray[i]) | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			_idFreeArray[i] = false; | 
			
		
	
		
			
				
					|  |  |  |  | 			return i + _idBase; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return 0; | 
			
		
	
		
			
				
					|  |  |  |  |     for (int i = 0; i < NB_MAX_LRF_FILE; ++i) // 遍历所有可能的ID  
 | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         if (_idFreeArray[i]) // 如果该ID可用(未被使用)  
 | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             _idFreeArray[i] = false; // 标记该ID为已使用  
 | 
			
		
	
		
			
				
					|  |  |  |  |             return i + _idBase; // 返回该ID的值(从_idBase开始计算)  
 | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     return 0; // 如果所有ID都已使用,返回0(或默认值)  
 | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // 设置指定的ID为可用。  
 | 
			
		
	
		
			
				
					|  |  |  |  | void LastRecentFileList::setAvailable(int id) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	int index = id - _idBase; | 
			
		
	
		
			
				
					|  |  |  |  | 	_idFreeArray[index] = true; | 
			
		
	
		
			
				
					|  |  |  |  |     int index = id - _idBase; // 根据ID计算其在_idFreeArray中的索引  
 | 
			
		
	
		
			
				
					|  |  |  |  |     _idFreeArray[index] = true; // 将该索引对应的值设置为true,表示该ID可用  
 | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
	
		
			
				
					|  |  |  | 
 |