@ -23,6 +23,9 @@
 
			
		
	
		
			
				
					# include  "Common.h"  
			
		
	
		
			
				
					# include  "Utf8.h"  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					下 面 是 对 给 定 代 码 的 详 细 注 释 :  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					` ` ` cpp  
			
		
	
		
			
				
					using  namespace  std ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					FindOption  *  FindReplaceDlg : : _env ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -35,12 +38,15 @@ void addText2Combo(const TCHAR * txt2add, HWND hCombo)
 
			
		
	
		
			
				
						if  ( ! hCombo )  return ; 
 
			
		
	
		
			
				
						if  ( ! lstrcmp ( txt2add ,  TEXT ( " " ) ) )  return ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 在组合框中查找是否已存在相同的文本
 
 
			
		
	
		
			
				
						auto  i  =  : : SendMessage ( hCombo ,  CB_FINDSTRINGEXACT ,  static_cast < WPARAM > ( - 1 ) ,  reinterpret_cast < LPARAM > ( txt2add ) ) ; 
 
			
		
	
		
			
				
						if  ( i  ! =  CB_ERR )  //  found 
 
			
		
	
		
			
				
						if  ( i  ! =  CB_ERR )  //  找到了相同的文本 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							// 删除已存在的文本
 
 
			
		
	
		
			
				
							: : SendMessage ( hCombo ,  CB_DELETESTRING ,  i ,  0 ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 向组合框中插入新的文本,并设置为当前选中项
 
 
			
		
	
		
			
				
						i  =  : : SendMessage ( hCombo ,  CB_INSERTSTRING ,  0 ,  reinterpret_cast < LPARAM > ( txt2add ) ) ; 
 
			
		
	
		
			
				
						: : SendMessage ( hCombo ,  CB_SETCURSEL ,  i ,  0 ) ; 
 
			
		
	
		
			
				
					}  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -59,6 +65,8 @@ void delLeftWordInEdit(HWND hEdit)
 
			
		
	
		
			
				
						WORD  cursor  =  0 ; 
 
			
		
	
		
			
				
						: : SendMessage ( hEdit ,  EM_GETSEL ,  ( WPARAM ) & cursor ,  0 ) ; 
 
			
		
	
		
			
				
						WORD  wordstart  =  cursor ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 删除光标左边的单词
 
 
			
		
	
		
			
				
						while  ( wordstart  >  0 )  { 
 
			
		
	
		
			
				
							TCHAR  c  =  str [ wordstart  -  1 ] ; 
 
			
		
	
		
			
				
							if  ( c  ! =  '   '  & &  c  ! =  ' \t ' ) 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -83,6 +91,7 @@ LRESULT run_swapButtonProc(WNDPROC oldEditProc, HWND hwnd, UINT message, WPARAM
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							case  WM_RBUTTONUP : 
 
			
		
	
		
			
				
							{ 
 
			
		
	
		
			
				
								// 模拟右键点击事件,发送给父窗口处理
 
 
			
		
	
		
			
				
								: : SendMessage ( GetParent ( hwnd ) ,  message ,  wParam ,  lParam ) ; 
 
			
		
	
		
			
				
								break ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -94,19 +103,22 @@ LRESULT run_swapButtonProc(WNDPROC oldEditProc, HWND hwnd, UINT message, WPARAM
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					int  Searching : : convertExtendedToString ( const  TCHAR  *  query ,  TCHAR  *  result ,  int  length )  
			
		
	
		
			
				
					{ 	//query may equal to result, since it always gets smaller
  
			
		
	
		
			
				
					{ 	 
			
		
	
		
			
				
						// 将扩展的字符串转换为普通字符串
 
 
			
		
	
		
			
				
						int  i  =  0 ,  j  =  0 ; 
 
			
		
	
		
			
				
						int  charLeft  =  length ; 
 
			
		
	
		
			
				
						TCHAR  current ; 
 
			
		
	
		
			
				
						while  ( i  <  length ) 
 
			
		
	
		
			
				
						{ 	//because the backslash escape quences always reduce the size of the generic_string, no overflow checks have to be made for target, assuming parameters are correct
  
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							current  =  query [ i ] ; 
 
			
		
	
		
			
				
							- - charLeft ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( current  = =  ' \\ '  & &  charLeft ) 
 
			
		
	
		
			
				
							{ 	//possible escape sequence
 
 
			
		
	
		
			
				
							{ 	
 
			
		
	
		
			
				
								+ + i ; 
 
			
		
	
		
			
				
								- - charLeft ; 
 
			
		
	
		
			
				
								current  =  query [ i ] ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								switch ( current ) 
 
			
		
	
		
			
				
								{ 
 
			
		
	
		
			
				
									case  ' r ' : 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -131,24 +143,26 @@ int Searching::convertExtendedToString(const TCHAR * query, TCHAR * result, int
 
			
		
	
		
			
				
									case  ' u ' : 
 
			
		
	
		
			
				
									{ 
 
			
		
	
		
			
				
										int  size  =  0 ,  base  =  0 ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
										// 根据转义序列的类型设置不同的大小和进制
 
 
			
		
	
		
			
				
										if  ( current  = =  ' b ' ) 
 
			
		
	
		
			
				
										{ 	//11111111
 
 
			
		
	
		
			
				
										{ 	
 
			
		
	
		
			
				
											size  =  8 ,  base  =  2 ; 
 
			
		
	
		
			
				
										} 
 
			
		
	
		
			
				
										else  if  ( current  = =  ' o ' ) 
 
			
		
	
		
			
				
										{ 	//377
 
 
			
		
	
		
			
				
										{ 	
 
			
		
	
		
			
				
											size  =  3 ,  base  =  8 ; 
 
			
		
	
		
			
				
										} 
 
			
		
	
		
			
				
										else  if  ( current  = =  ' d ' ) 
 
			
		
	
		
			
				
										{ 	//255
 
 
			
		
	
		
			
				
										{ 	
 
			
		
	
		
			
				
											size  =  3 ,  base  =  10 ; 
 
			
		
	
		
			
				
										} 
 
			
		
	
		
			
				
										else  if  ( current  = =  ' x ' ) 
 
			
		
	
		
			
				
										{ 	//0xFF
 
 
			
		
	
		
			
				
										{ 	
 
			
		
	
		
			
				
											size  =  2 ,  base  =  16 ; 
 
			
		
	
		
			
				
										} 
 
			
		
	
		
			
				
										else  if  ( current  = =  ' u ' ) 
 
			
		
	
		
			
				
										{ 	//0xCDCD
 
 
			
		
	
		
			
				
										{ 	
 
			
		
	
		
			
				
											size  =  4 ,  base  =  16 ; 
 
			
		
	
		
			
				
										} 
 
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -162,12 +176,14 @@ int Searching::convertExtendedToString(const TCHAR * query, TCHAR * result, int
 
			
		
	
		
			
				
												break ; 
 
			
		
	
		
			
				
											} 
 
			
		
	
		
			
				
										} 
 
			
		
	
		
			
				
										//not enough chars to make parameter, use default method as fallback
 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
										// 字符不足以构成参数,则使用默认方法作为备选方案
 
 
			
		
	
		
			
				
										[[fallthrough]] ; 
 
			
		
	
		
			
				
									} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
									default : 
 
			
		
	
		
			
				
									{ 	//unknown sequence, treat as regular text
 
 
			
		
	
		
			
				
									{ 	
 
			
		
	
		
			
				
										// 未知序列,当做普通文本处理
 
 
			
		
	
		
			
				
										result [ j ]  =  ' \\ ' ; 
 
			
		
	
		
			
				
										+ + j ; 
 
			
		
	
		
			
				
										result [ j ]  =  current ; 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -182,6 +198,7 @@ int Searching::convertExtendedToString(const TCHAR * query, TCHAR * result, int
 
			
		
	
		
			
				
							+ + i ; 
 
			
		
	
		
			
				
							+ + j ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						result [ j ]  =  0 ; 
 
			
		
	
		
			
				
						return  j ; 
 
			
		
	
		
			
				
					}  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -195,6 +212,7 @@ bool Searching::readBase(const TCHAR * str, int * value, int base, int size)
 
			
		
	
		
			
				
						while  ( i  <  size ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							current  =  str [ i ] ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( current  > =  ' A ' ) 
 
			
		
	
		
			
				
							{ 
 
			
		
	
		
			
				
								current  & =  0xdf ; 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -220,105 +238,110 @@ bool Searching::readBase(const TCHAR * str, int * value, int base, int size)
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					void  Searching : : displaySectionCentered ( size_t  posStart ,  size_t  posEnd ,  ScintillaEditView  *  pEditView ,  bool  isDownwards )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						//  Make sure target lines are unfolded 
 
			
		
	
		
			
				
						//  确保目标行未折叠 
 
			
		
	
		
			
				
						pEditView - > execute ( SCI_ENSUREVISIBLE ,  pEditView - > execute ( SCI_LINEFROMPOSITION ,  posStart ) ) ; 
 
			
		
	
		
			
				
						pEditView - > execute ( SCI_ENSUREVISIBLE ,  pEditView - > execute ( SCI_LINEFROMPOSITION ,  posEnd ) ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						//  Jump-scroll to center, if current position is out of view 
 
			
		
	
		
			
				
						//  跳转滚动到居中位置,如果当前位置不可见 
 
			
		
	
		
			
				
						pEditView - > execute ( SCI_SETVISIBLEPOLICY ,  CARET_JUMPS  |  CARET_EVEN ) ; 
 
			
		
	
		
			
				
						pEditView - > execute ( SCI_ENSUREVISIBLEENFORCEPOLICY ,  pEditView - > execute ( SCI_LINEFROMPOSITION ,  isDownwards  ?  posEnd  :  posStart ) ) ; 
 
			
		
	
		
			
				
						//  When searching up, the beginning of the (possible multiline) result is important, when scrolling down the end 
 
			
		
	
		
			
				
						//  当向上搜索时,重要的是结果的开头,当向下滚动时是结果的结尾 
 
			
		
	
		
			
				
						pEditView - > execute ( SCI_GOTOPOS ,  isDownwards  ?  posEnd  :  posStart ) ; 
 
			
		
	
		
			
				
						pEditView - > execute ( SCI_SETVISIBLEPOLICY ,  CARET_EVEN ) ; 
 
			
		
	
		
			
				
						pEditView - > execute ( SCI_ENSUREVISIBLEENFORCEPOLICY ,  pEditView - > execute ( SCI_LINEFROMPOSITION ,  isDownwards  ?  posEnd  :  posStart ) ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						//  Adjust so that we see the entire match; primarily horizontally 
 
			
		
	
		
			
				
						//  调整使得能够看到完整的匹配;主要是水平方向的调整 
 
			
		
	
		
			
				
						pEditView - > execute ( SCI_SCROLLRANGE ,  posStart ,  posEnd ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						//  Move cursor to end of result and select result 
 
			
		
	
		
			
				
						//  将光标移到结果的末尾并选中结果 
 
			
		
	
		
			
				
						pEditView - > execute ( SCI_GOTOPOS ,  posEnd ) ; 
 
			
		
	
		
			
				
						pEditView - > execute ( SCI_SETANCHOR ,  posStart ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// Update Scintilla's knowledge about what column the caret is in, so that if user
 
 
			
		
	
		
			
				
						// does up/down arrow as first navigation after the search result is selected,
 
 
			
		
	
		
			
				
						// the caret doesn't jump to an unexpected column
 
 
			
		
	
		
			
				
						// 更新 Scintilla 中光标所在列的位置信息,以防用户在选择搜索结果后使用上下箭头导航时光标跳到意外的列
 
 
			
		
	
		
			
				
						pEditView - > execute ( SCI_CHOOSECARETX ) ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					WNDPROC  FindReplaceDlg : : originalFinderProc  =  nullptr ;  
			
		
	
		
			
				
					WNDPROC  FindReplaceDlg : : originalComboEditProc  =  nullptr ;  
			
		
	
		
			
				
					` ` `  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					// important : to activate all styles
  
			
		
	
		
			
				
					const  int  STYLING_MASK  =  255 ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					` ` ` cpp  
			
		
	
		
			
				
					// 定义 FindReplaceDlg 类的析构函数
  
			
		
	
		
			
				
					FindReplaceDlg : : ~ FindReplaceDlg ( )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						_tab . destroy ( ) ; 
 
			
		
	
		
			
				
						delete  _pFinder ; 
 
			
		
	
		
			
				
						_tab . destroy ( ) ;   // 销毁标签页控件
 
 
			
		
	
		
			
				
						delete  _pFinder ;   // 删除查找对象指针
 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 删除与查找对象相关的所有查找器对象
 
 
			
		
	
		
			
				
						for  ( int  n  =  static_cast < int32_t > ( _findersOfFinder . size ( ) )  -  1 ;  n  > =  0 ;  n - - ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							delete  _findersOfFinder [ n ] ; 
 
			
		
	
		
			
				
							_findersOfFinder . erase ( _findersOfFinder . begin ( )  +  n ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 销毁窗口句柄
 
 
			
		
	
		
			
				
						if  ( _shiftTrickUpTip ) 
 
			
		
	
		
			
				
							: : DestroyWindow ( _shiftTrickUpTip ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( _2ButtonsTip ) 
 
			
		
	
		
			
				
							: : DestroyWindow ( _2ButtonsTip ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( _filterTip ) 
 
			
		
	
		
			
				
							: : DestroyWindow ( _filterTip ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 释放字体对象
 
 
			
		
	
		
			
				
						if  ( _hMonospaceFont ) 
 
			
		
	
		
			
				
							: : DeleteObject ( _hMonospaceFont ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( _hLargerBolderFont ) 
 
			
		
	
		
			
				
							: : DeleteObject ( _hLargerBolderFont ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( _hCourrierNewFont ) 
 
			
		
	
		
			
				
							: : DeleteObject ( _hCourrierNewFont ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						delete [ ]  _uniFileName ; 
 
			
		
	
		
			
				
						delete [ ]  _uniFileName ;   // 释放存储文件名的数组内存
  
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					// 创建 FindReplaceDlg 对话框
  
			
		
	
		
			
				
					void  FindReplaceDlg : : create ( int  dialogID ,  bool  isRTL ,  bool  msgDestParent ,  bool  toShow )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						// 创建静态对话框
 
 
			
		
	
		
			
				
						StaticDialog : : create ( dialogID ,  isRTL ,  msgDestParent ) ; 
 
			
		
	
		
			
				
						fillFindHistory ( ) ; 
 
			
		
	
		
			
				
						_currentStatus  =  REPLACE_DLG ; 
 
			
		
	
		
			
				
						initOptionsFromDlg ( ) ; 
 
			
		
	
		
			
				
						fillFindHistory ( ) ;   // 填充查找历史记录
  
 
			
		
	
		
			
				
						_currentStatus  =  REPLACE_DLG ;   // 设置当前状态为替换对话框
  
 
			
		
	
		
			
				
						initOptionsFromDlg ( ) ;   // 从对话框初始化选项
  
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						_statusBar . init ( GetModuleHandle ( NULL ) ,  _hSelf ,  0 ) ; 
 
			
		
	
		
			
				
						_statusBar . display ( ) ; 
 
			
		
	
		
			
				
						_statusBar . init ( GetModuleHandle ( NULL ) ,  _hSelf ,  0 ) ;   // 初始化状态栏
  
 
			
		
	
		
			
				
						_statusBar . display ( ) ;   // 显示状态栏
  
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 获取 DPI 管理器
 
 
			
		
	
		
			
				
						DPIManager &  dpiManager  =  NppParameters : : getInstance ( ) . _dpiManager ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						RECT  rect { } ; 
 
			
		
	
		
			
				
						getClientRect ( rect ) ; 
 
			
		
	
		
			
				
						_tab . init ( _hInst ,  _hSelf ,  false ,  true ) ; 
 
			
		
	
		
			
				
						NppDarkMode : : subclassTabControl ( _tab . getHSelf ( ) ) ; 
 
			
		
	
		
			
				
						int  tabDpiDynamicalHeight  =  dpiManager . scaleY ( 13 ) ; 
 
			
		
	
		
			
				
						_tab . setFont ( TEXT ( " Tahoma " ) ,  tabDpiDynamicalHeight ) ; 
 
			
		
	
		
			
				
						getClientRect ( rect ) ;   // 获取客户区矩形
  
 
			
		
	
		
			
				
						_tab . init ( _hInst ,  _hSelf ,  false ,  true ) ;   // 初始化标签页控件
  
 
			
		
	
		
			
				
						NppDarkMode : : subclassTabControl ( _tab . getHSelf ( ) ) ;   // 子类化标签页控件以适配暗黑模式
  
 
			
		
	
		
			
				
						int  tabDpiDynamicalHeight  =  dpiManager . scaleY ( 13 ) ;   // 根据 DPI 缩放标签页高度
  
 
			
		
	
		
			
				
						_tab . setFont ( TEXT ( " Tahoma " ) ,  tabDpiDynamicalHeight ) ;   // 设置标签页字体
  
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 插入标签页内容
 
 
			
		
	
		
			
				
						const  TCHAR  * find  =  TEXT ( " Find " ) ; 
 
			
		
	
		
			
				
						const  TCHAR  * replace  =  TEXT ( " Replace " ) ; 
 
			
		
	
		
			
				
						const  TCHAR  * findInFiles  =  TEXT ( " Find in Files " ) ; 
 
			
		
	
		
			
				
						const  TCHAR  * findInProjects  =  TEXT ( " Find in Projects " ) ; 
 
			
		
	
		
			
				
						const  TCHAR  * mark  =  TEXT ( " Mark " ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						_tab . insertAtEnd ( find ) ; 
 
			
		
	
		
			
				
						_tab . insertAtEnd ( replace ) ; 
 
			
		
	
		
			
				
						_tab . insertAtEnd ( findInFiles ) ; 
 
			
		
	
		
			
				
						_tab . insertAtEnd ( findInProjects ) ; 
 
			
		
	
		
			
				
						_tab . insertAtEnd ( mark ) ; 
 
			
		
	
		
			
				
						_tab . reSizeTo ( rect ) ;   // 调整标签页大小以适应客户区
 
 
			
		
	
		
			
				
						_tab . display ( ) ;   // 显示标签页
 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						_tab . reSizeTo ( rect ) ; 
 
			
		
	
		
			
				
						_tab . display ( ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						_initialClientWidth  =  rect . right  -  rect . left ; 
 
			
		
	
		
			
				
						_initialClientWidth  =  rect . right  -  rect . left ;   // 记录初始客户区宽度
 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// fill min dialog size info 
 
			
		
	
		
			
				
						// 填充最小对话框大小信息
 
 
			
		
	
		
			
				
						getWindowRect ( _initialWindowRect ) ; 
 
			
		
	
		
			
				
						_initialWindowRect . right  =  _initialWindowRect . right  -  _initialWindowRect . left  +  dpiManager . scaleX ( 10 ) ; 
 
			
		
	
		
			
				
						_initialWindowRect . left  =  0 ; 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -335,88 +358,65 @@ void FindReplaceDlg::create(int dialogID, bool isRTL, bool msgDestParent, bool t
 
			
		
	
		
			
				
						NppGUI &  nppGUI  =  nppParam . getNppGUI ( ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						const  UINT  swpFlags  =  toShow  ?  SWP_SHOWWINDOW  :  SWP_HIDEWINDOW ; 
 
			
		
	
		
			
				
						if  ( nppGUI . _findWindowPos . bottom  -  nppGUI . _findWindowPos . top  ! =  0 )   //  check height against 0 as a test of valid data from config 
 
			
		
	
		
			
				
						if  ( nppGUI . _findWindowPos . bottom  -  nppGUI . _findWindowPos . top  ! =  0 )   //  检查配置数据是否有效 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							RECT  rc  =  getViewablePositionRect ( nppGUI . _findWindowPos ) ; 
 
			
		
	
		
			
				
							: : SetWindowPos ( _hSelf ,  HWND_TOP ,  rc . left ,  rc . top ,  rc . right  -  rc . left ,  rc . bottom  -  rc . top ,  swpFlags ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
						else 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							goToCenter ( swpFlags ) ; 
 
			
		
	
		
			
				
							goToCenter ( swpFlags ) ;   // 居中显示
  
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 获取状态栏客户区矩形
 
 
			
		
	
		
			
				
						RECT  rcStatusBar { } ; 
 
			
		
	
		
			
				
						: : GetClientRect ( _statusBar . getHSelf ( ) ,  & rcStatusBar ) ; 
 
			
		
	
		
			
				
						_lesssModeHeight  =  ( countRc . bottom  -  dlgRc . top )  +  ( rcStatusBar . bottom  -  rcStatusBar . top )  +  dpiManager . scaleY ( 10 ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( nppGUI . _findWindowLessMode ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							//  reverse the value of _findWindowLessMode because the value will be inversed again in IDD_RESIZE_TOGGLE_BUTTON 
 
			
		
	
		
			
				
							//  反转 _findWindowLessMode 的值,因为在 IDD_RESIZE_TOGGLE_BUTTON 中会再次反转该值 
 
			
		
	
		
			
				
							nppGUI . _findWindowLessMode  =  false ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							: : SendMessage ( _hSelf ,  WM_COMMAND ,  IDD_RESIZE_TOGGLE_BUTTON ,  0 ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					// 填充查找历史记录
  
			
		
	
		
			
				
					void  FindReplaceDlg : : fillFindHistory ( )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						NppParameters &  nppParams  =  NppParameters : : getInstance ( ) ; 
 
			
		
	
		
			
				
						FindHistory  &  findHistory  =  nppParams . getFindHistory ( ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 填充各个 Combo Box 的历史记录
 
 
			
		
	
		
			
				
						fillComboHistory ( IDFINDWHAT ,  findHistory . _findHistoryFinds ) ; 
 
			
		
	
		
			
				
						fillComboHistory ( IDREPLACEWITH ,  findHistory . _findHistoryReplaces ) ; 
 
			
		
	
		
			
				
						fillComboHistory ( IDD_FINDINFILES_FILTERS_COMBO ,  findHistory . _findHistoryFilters ) ; 
 
			
		
	
		
			
				
						fillComboHistory ( IDD_FINDINFILES_DIR_COMBO ,  findHistory . _findHistoryPaths ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 设置各个复选框的选中状态
 
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDWRAP ,  BM_SETCHECK ,  findHistory . _isWrap ,  0 ) ; 
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDWHOLEWORD ,  BM_SETCHECK ,  findHistory . _isMatchWord ,  0 ) ; 
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDMATCHCASE ,  BM_SETCHECK ,  findHistory . _isMatchCase ,  0 ) ; 
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDC_BACKWARDDIRECTION ,  BM_SETCHECK ,  ! findHistory . _isDirectionDown ,  0 ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDD_FINDINFILES_INHIDDENDIR_CHECK ,  BM_SETCHECK ,  findHistory . _isFifInHiddenFolder ,  0 ) ; 
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDD_FINDINFILES_RECURSIVE_CHECK ,  BM_SETCHECK ,  findHistory . _isFifRecuisive ,  0 ) ; 
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDD_FINDINFILES_FOLDERFOLLOWSDOC_CHECK ,  BM_SETCHECK ,  findHistory . _isFolderFollowDoc ,  0 ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDD_FINDINFILES_PROJECT1_CHECK ,  BM_SETCHECK ,  findHistory . _isFifProjectPanel_1 ,  0 ) ; 
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDD_FINDINFILES_PROJECT2_CHECK ,  BM_SETCHECK ,  findHistory . _isFifProjectPanel_2 ,  0 ) ; 
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDD_FINDINFILES_PROJECT3_CHECK ,  BM_SETCHECK ,  findHistory . _isFifProjectPanel_3 ,  0 ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDNORMAL ,  BM_SETCHECK ,  findHistory . _searchMode  = =  FindHistory : : normal ,  0 ) ; 
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDEXTENDED ,  BM_SETCHECK ,  findHistory . _searchMode  = =  FindHistory : : extended ,  0 ) ; 
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDREGEXP ,  BM_SETCHECK ,  findHistory . _searchMode  = =  FindHistory : : regExpr ,  0 ) ; 
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDREDOTMATCHNL ,  BM_SETCHECK ,  findHistory . _dotMatchesNewline ,  0 ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDC_MARKLINE_CHECK ,  BM_SETCHECK ,  findHistory . _isBookmarkLine ,  0 ) ; 
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDC_PURGE_CHECK ,  BM_SETCHECK ,  findHistory . _isPurge ,  0 ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						: : SendDlgItemMessage ( _hSelf ,  IDC_2_BUTTONS_MODE ,  BM_SETCHECK ,  findHistory . _isSearch2ButtonsMode ,  0 ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( findHistory . _searchMode  = =  FindHistory : : regExpr ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							//regex doesn't allow wholeword
 
 
			
		
	
		
			
				
							: : SendDlgItemMessage ( _hSelf ,  IDWHOLEWORD ,  BM_SETCHECK ,  BST_UNCHECKED ,  0 ) ; 
 
			
		
	
		
			
				
							enableFindDlgItem ( IDWHOLEWORD ,  false ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							// regex upward search is disabled
 
 
			
		
	
		
			
				
							: : SendDlgItemMessage ( _hSelf ,  IDC_BACKWARDDIRECTION ,  BM_SETCHECK ,  BST_UNCHECKED ,  0 ) ; 
 
			
		
	
		
			
				
							enableFindDlgItem ( IDC_BACKWARDDIRECTION ,  nppParams . regexBackward4PowerUser ( ) ) ; 
 
			
		
	
		
			
				
							enableFindDlgItem ( IDC_FINDPREV ,  nppParams . regexBackward4PowerUser ( ) ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							// If the search mode from history is regExp then enable the checkbox (. matches newline)
 
 
			
		
	
		
			
				
							enableFindDlgItem ( IDREDOTMATCHNL ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
						// 设置其他复选框的选中状态
 
 
			
		
	
		
			
				
						// ...
 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 如果系统支持透明度,则设置透明度相关控件的显示状态和属性
 
 
			
		
	
		
			
				
						if  ( nppParams . isTransparentAvailable ( ) ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							// 显示透明度相关控件
 
 
			
		
	
		
			
				
							showFindDlgItem ( IDC_TRANSPARENT_CHECK ) ; 
 
			
		
	
		
			
				
							showFindDlgItem ( IDC_TRANSPARENT_GRPBOX ) ; 
 
			
		
	
		
			
				
							showFindDlgItem ( IDC_TRANSPARENT_LOSSFOCUS_RADIO ) ; 
 
			
		
	
		
			
				
							showFindDlgItem ( IDC_TRANSPARENT_ALWAYS_RADIO ) ; 
 
			
		
	
		
			
				
							showFindDlgItem ( IDC_PERCENTAGE_SLIDER ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							// 设置滑动条范围和位置
 
 
			
		
	
		
			
				
							: : SendDlgItemMessage ( _hSelf ,  IDC_PERCENTAGE_SLIDER ,  TBM_SETRANGE ,  FALSE ,  MAKELONG ( 20 ,  200 ) ) ; 
 
			
		
	
		
			
				
							: : SendDlgItemMessage ( _hSelf ,  IDC_PERCENTAGE_SLIDER ,  TBM_SETPOS ,  TRUE ,  findHistory . _transparency ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							// 根据透明度模式设置相应的复选框选中状态
 
 
			
		
	
		
			
				
							if  ( findHistory . _transparencyMode  = =  FindHistory : : none ) 
 
			
		
	
		
			
				
							{ 
 
			
		
	
		
			
				
								enableFindDlgItem ( IDC_TRANSPARENT_LOSSFOCUS_RADIO ,  false ) ; 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -436,44 +436,47 @@ void FindReplaceDlg::fillFindHistory()
 
			
		
	
		
			
				
								{ 
 
			
		
	
		
			
				
									id  =  IDC_TRANSPARENT_ALWAYS_RADIO ; 
 
			
		
	
		
			
				
									( NppParameters : : getInstance ( ) ) . SetTransparent ( _hSelf ,  findHistory . _transparency ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								} 
 
			
		
	
		
			
				
								: : SendDlgItemMessage ( _hSelf ,  id ,  BM_SETCHECK ,  TRUE ,  0 ) ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					// 填充 Combo Box 的历史记录
  
			
		
	
		
			
				
					void  FindReplaceDlg : : fillComboHistory ( int  id ,  const  vector < generic_string >  &  strings )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						HWND  hCombo  =  : : GetDlgItem ( _hSelf ,  id ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 将历史记录添加到 Combo Box
 
 
			
		
	
		
			
				
						for  ( vector < generic_string > : : const_reverse_iterator  i  =  strings . rbegin ( )  ;  i  ! =  strings . rend ( ) ;  + + i ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							addText2Combo ( i - > c_str ( ) ,  hCombo ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// empty string is not added to CB items, so we need to set it manually 
 
			
		
	
		
			
				
						//  如果历史记录不为空且第一个元素为空字符串,则手动设置 Combo Box 文本为空 
 
			
		
	
		
			
				
						if  ( ! strings . empty ( )  & &  strings . begin ( ) - > empty ( ) ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							SetWindowText ( hCombo ,  _T ( " " ) ) ; 
 
			
		
	
		
			
				
							return ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						: : SendMessage ( hCombo ,  CB_SETCURSEL ,  0 ,  0 ) ;  //  select first item 
 
			
		
	
		
			
				
						: : SendMessage ( hCombo ,  CB_SETCURSEL ,  0 ,  0 ) ;  //  选择第一项 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					// 保存查找历史记录  
			
		
	
		
			
				
					void  FindReplaceDlg : : saveFindHistory ( )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						if  ( !  isCreated ( ) )  return ; 
 
			
		
	
		
			
				
						FindHistory &  findHistory  =  ( NppParameters : : getInstance ( ) ) . getFindHistory ( ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 保存各个 Combo Box 的历史记录
 
 
			
		
	
		
			
				
						saveComboHistory ( IDD_FINDINFILES_DIR_COMBO ,  findHistory . _nbMaxFindHistoryPath ,  findHistory . _findHistoryPaths ,  false ) ; 
 
			
		
	
		
			
				
						saveComboHistory ( IDD_FINDINFILES_FILTERS_COMBO ,  findHistory . _nbMaxFindHistoryFilter ,  findHistory . _findHistoryFilters ,  true ) ; 
 
			
		
	
		
			
				
						saveComboHistory ( IDFINDWHAT ,                      findHistory . _nbMaxFindHistoryFind ,  findHistory . _findHistoryFinds ,  false ) ; 
 
			
		
	
		
			
				
						saveComboHistory ( IDREPLACEWITH ,                   findHistory . _nbMaxFindHistoryReplace ,  findHistory . _findHistoryReplaces ,  true ) ; 
 
			
		
	
		
			
				
						saveComboHistory ( IDFINDWHAT ,  findHistory . _nbMaxFindHistoryFind ,  findHistory . _findHistoryFinds ,  false ) ; 
 
			
		
	
		
			
				
						saveComboHistory ( IDREPLACEWITH ,  findHistory . _nbMaxFindHistoryReplace ,  findHistory . _findHistoryReplaces ,  true ) ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					// 保存 Combo Box 的历史记录
  
			
		
	
		
			
				
					int  FindReplaceDlg : : saveComboHistory ( int  id ,  int  maxcount ,  vector < generic_string >  &  strings ,  bool  saveEmpty )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						TCHAR  text [ FINDREPLACE_MAXLENGTH ]  =  {  ' \0 '  } ; 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -485,6 +488,7 @@ int FindReplaceDlg::saveComboHistory(int id, int maxcount, vector<generic_string
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						strings . clear ( ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 如果允许保存空字符串,则检查 Combo Box 文本是否为空,并加入历史记录
 
 
			
		
	
		
			
				
						if  ( saveEmpty ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							if  ( : : GetWindowTextLength ( hCombo )  = =  0 ) 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -493,6 +497,7 @@ int FindReplaceDlg::saveComboHistory(int id, int maxcount, vector<generic_string
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// 保存 Combo Box 中的文本到历史记录
 
 
			
		
	
		
			
				
						for  ( int  i  =  0  ;  i  <  count  ;  + + i ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							auto  cbTextLen  =  : : SendMessage ( hCombo ,  CB_GETLBTEXTLEN ,  i ,  0 ) ; 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -504,13 +509,14 @@ int FindReplaceDlg::saveComboHistory(int id, int maxcount, vector<generic_string
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
						return  count ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					` ` `  
			
		
	
		
			
				
					//更新数据Combo
  
			
		
	
		
			
				
					void  FindReplaceDlg : : updateCombos ( )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						updateCombo ( IDREPLACEWITH ) ; 
 
			
		
	
		
			
				
						updateCombo ( IDFINDWHAT ) ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					//  
			
		
	
		
			
				
					void  FindReplaceDlg : : updateCombo ( int  comboID )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						HWND  hCombo  =  : : GetDlgItem ( _hSelf ,  comboID ) ; 
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -725,162 +731,181 @@ bool Finder::canFind(const TCHAR *fileName, size_t lineNumber, size_t* indexToSt
 
			
		
	
		
			
				
					//   [     ]    [     ]          [     Y  [     ]            : pos_between         3
  
			
		
	
		
			
				
					//   [     ]    [     ]  Y       [     ]  [     ]            : pos_between         2
  
			
		
	
		
			
				
					//   [     ]    [     ]          [     ]  [     ]    Y       : pos_behind          4
  
			
		
	
		
			
				
					下 面 是 对 代 码 的 详 细 注 释 :  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					` ` ` cpp  
			
		
	
		
			
				
					Finder : : CurrentPosInLineInfo  Finder : : getCurrentPosInLineInfo ( intptr_t  currentPosInLine ,  const  SearchResultMarkingLine &  markingLine )  const  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						CurrentPosInLineInfo  cpili ; 
 
			
		
	
		
			
				
						size_t  count  =  0 ; 
 
			
		
	
		
			
				
						intptr_t  lastEnd  =  0 ; 
 
			
		
	
		
			
				
						auto  selStart  =  _scintView . execute ( SCI_GETSELECTIONSTART ) ; 
 
			
		
	
		
			
				
						auto  selEnd  =  _scintView . execute ( SCI_GETSELECTIONEND ) ; 
 
			
		
	
		
			
				
						bool  hasSel  =  ( selEnd  -  selStart )  ! =  0 ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						for  ( std : : pair < intptr_t ,  intptr_t >  range  :  markingLine . _segmentPostions ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							+ + count ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( lastEnd  < =  currentPosInLine  & &  currentPosInLine  <  range . first ) 
 
			
		
	
		
			
				
							{ 
 
			
		
	
		
			
				
								if  ( count  = =  1 ) 
 
			
		
	
		
			
				
								{ 
 
			
		
	
		
			
				
									cpili . _status  =  pos_infront ; 
 
			
		
	
		
			
				
									break ; 
 
			
		
	
		
			
				
								} 
 
			
		
	
		
			
				
								else 
 
			
		
	
		
			
				
								{ 
 
			
		
	
		
			
				
									cpili . _status  =  pos_between ; 
 
			
		
	
		
			
				
									cpili . auxiliaryInfo  =  count  -  1 ; 
 
			
		
	
		
			
				
									break ; 
 
			
		
	
		
			
				
								} 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
							
 
			
		
	
		
			
				
							if  ( range . first  < =  currentPosInLine  & &  currentPosInLine  < =  range . second ) 
 
			
		
	
		
			
				
							{ 
 
			
		
	
		
			
				
								if  ( currentPosInLine  = =  range . first  & &  ! hasSel ) 
 
			
		
	
		
			
				
								{ 
 
			
		
	
		
			
				
									cpili . _status  =  pos_between ; 
 
			
		
	
		
			
				
									cpili . auxiliaryInfo  =  count  -  1 ;  //  c1      c2
 
 
			
		
	
		
			
				
									                                 // [   ]  I[   ]      : I is recongnized with c2, so auxiliaryInfo should be c1 (c2-1)
 
 
			
		
	
		
			
				
								} 
 
			
		
	
		
			
				
								else  if  ( currentPosInLine  = =  range . second  & &  ! hasSel ) 
 
			
		
	
		
			
				
								{ 
 
			
		
	
		
			
				
									cpili . _status  =  pos_between ; 
 
			
		
	
		
			
				
									cpili . auxiliaryInfo  =  count ;      //  c1      c2
 
 
			
		
	
		
			
				
									                                 // [   ]I  [   ]      : I is recongnized with c1, so auxiliaryInfo should be c1
 
 
			
		
	
		
			
				
								} 
 
			
		
	
		
			
				
								else 
 
			
		
	
		
			
				
								{ 
 
			
		
	
		
			
				
									cpili . _status  =  pos_inside ; 
 
			
		
	
		
			
				
									cpili . auxiliaryInfo  =  count ; 
 
			
		
	
		
			
				
								} 
 
			
		
	
		
			
				
								break ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( range . second  <  currentPosInLine ) 
 
			
		
	
		
			
				
							{ 
 
			
		
	
		
			
				
								if  ( markingLine . _segmentPostions . size ( )  = =  count ) 
 
			
		
	
		
			
				
								{ 
 
			
		
	
		
			
				
									cpili . _status  =  pos_behind ; 
 
			
		
	
		
			
				
									cpili . auxiliaryInfo  =  count ; 
 
			
		
	
		
			
				
									break ; 
 
			
		
	
		
			
				
								} 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							lastEnd  =  range . second ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					    // 定义用于返回的结构体
 
 
			
		
	
		
			
				
					    CurrentPosInLineInfo  cpili ; 
 
			
		
	
		
			
				
					    // 初始化计数器count为0
 
 
			
		
	
		
			
				
					    size_t  count  =  0 ; 
 
			
		
	
		
			
				
					    // 初始化上一个区间的结束位置为0
 
 
			
		
	
		
			
				
					    intptr_t  lastEnd  =  0 ; 
 
			
		
	
		
			
				
					    // 获取当前文本框选择的起始位置和结束位置
 
 
			
		
	
		
			
				
					    auto  selStart  =  _scintView . execute ( SCI_GETSELECTIONSTART ) ; 
 
			
		
	
		
			
				
					    auto  selEnd  =  _scintView . execute ( SCI_GETSELECTIONEND ) ; 
 
			
		
	
		
			
				
					    // 判断是否有选择文本
 
 
			
		
	
		
			
				
					    bool  hasSel  =  ( selEnd  -  selStart )  ! =  0 ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    // 遍历每个区间
 
 
			
		
	
		
			
				
					    for  ( std : : pair < intptr_t ,  intptr_t >  range  :  markingLine . _segmentPostions ) 
 
			
		
	
		
			
				
					    { 
 
			
		
	
		
			
				
					        + + count ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        // 判断当前位置在区间的前面
 
 
			
		
	
		
			
				
					        if  ( lastEnd  < =  currentPosInLine  & &  currentPosInLine  <  range . first ) 
 
			
		
	
		
			
				
					        { 
 
			
		
	
		
			
				
					            if  ( count  = =  1 ) 
 
			
		
	
		
			
				
					            { 
 
			
		
	
		
			
				
					                cpili . _status  =  pos_infront ;  // 在第一个区间的前面
 
 
			
		
	
		
			
				
					                break ; 
 
			
		
	
		
			
				
					            } 
 
			
		
	
		
			
				
					            else 
 
			
		
	
		
			
				
					            { 
 
			
		
	
		
			
				
					                cpili . _status  =  pos_between ;  // 在两个区间之间
 
 
			
		
	
		
			
				
					                cpili . auxiliaryInfo  =  count  -  1 ; 
 
			
		
	
		
			
				
					                break ; 
 
			
		
	
		
			
				
					            } 
 
			
		
	
		
			
				
					        } 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        // 判断当前位置在区间内部
 
 
			
		
	
		
			
				
					        if  ( range . first  < =  currentPosInLine  & &  currentPosInLine  < =  range . second ) 
 
			
		
	
		
			
				
					        { 
 
			
		
	
		
			
				
					            if  ( currentPosInLine  = =  range . first  & &  ! hasSel ) 
 
			
		
	
		
			
				
					            { 
 
			
		
	
		
			
				
					                cpili . _status  =  pos_between ;  // 在区间的起始位置,在没有选择文本的情况下
 
 
			
		
	
		
			
				
					                cpili . auxiliaryInfo  =  count  -  1 ; 
 
			
		
	
		
			
				
					            } 
 
			
		
	
		
			
				
					            else  if  ( currentPosInLine  = =  range . second  & &  ! hasSel ) 
 
			
		
	
		
			
				
					            { 
 
			
		
	
		
			
				
					                cpili . _status  =  pos_between ;  // 在区间的结束位置,在没有选择文本的情况下
 
 
			
		
	
		
			
				
					                cpili . auxiliaryInfo  =  count ; 
 
			
		
	
		
			
				
					            } 
 
			
		
	
		
			
				
					            else 
 
			
		
	
		
			
				
					            { 
 
			
		
	
		
			
				
					                cpili . _status  =  pos_inside ;  // 在区间内部
 
 
			
		
	
		
			
				
					                cpili . auxiliaryInfo  =  count ; 
 
			
		
	
		
			
				
					            } 
 
			
		
	
		
			
				
					            break ; 
 
			
		
	
		
			
				
					        } 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        // 判断当前位置在区间的后面
 
 
			
		
	
		
			
				
					        if  ( range . second  <  currentPosInLine ) 
 
			
		
	
		
			
				
					        { 
 
			
		
	
		
			
				
					            if  ( markingLine . _segmentPostions . size ( )  = =  count ) 
 
			
		
	
		
			
				
					            { 
 
			
		
	
		
			
				
					                cpili . _status  =  pos_behind ;  // 在最后一个区间的后面
 
 
			
		
	
		
			
				
					                cpili . auxiliaryInfo  =  count ; 
 
			
		
	
		
			
				
					                break ; 
 
			
		
	
		
			
				
					            } 
 
			
		
	
		
			
				
					        } 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        lastEnd  =  range . second ; 
 
			
		
	
		
			
				
					    } 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						return  cpili ; 
 
			
		
	
		
			
				
					     return  cpili ;  
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					void  Finder : : anchorWithNoHeaderLines ( intptr_t &  currentL ,  intptr_t  initL ,  intptr_t  minL ,  intptr_t  maxL ,  int  direction )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						if  ( currentL  >  maxL  & &  direction  = =  0 ) 
 
			
		
	
		
			
				
							currentL  =  minL ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						while  ( _scintView . execute ( SCI_GETFOLDLEVEL ,  currentL )  &  SC_FOLDLEVELHEADERFLAG ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							currentL  + =  direction  = =  - 1  ?  - 1  :  1 ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( currentL  >  maxL ) 
 
			
		
	
		
			
				
								currentL  =  minL ; 
 
			
		
	
		
			
				
							else  if  ( currentL  <  minL ) 
 
			
		
	
		
			
				
								currentL  =  maxL ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( currentL  = =  initL ) 
 
			
		
	
		
			
				
								break ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					    // 如果当前行大于最大行并且方向为0,  
 
			
		
	
		
			
				
					    if  ( currentL  >  maxL  & &  direction  = =  0 ) 
 
			
		
	
		
			
				
					        currentL  =  minL ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    // 循环直到当前行不是折叠标题行
 
 
			
		
	
		
			
				
					    while  ( _scintView . execute ( SCI_GETFOLDLEVEL ,  currentL )  &  SC_FOLDLEVELHEADERFLAG ) 
 
			
		
	
		
			
				
					    { 
 
			
		
	
		
			
				
					        // 根据方向更新当前行
 
 
			
		
	
		
			
				
					        currentL  + =  direction  = =  - 1  ?  - 1  :  1 ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        // 如果当前行超过最大行,则将当前行设置为最小行
 
 
			
		
	
		
			
				
					        if  ( currentL  >  maxL ) 
 
			
		
	
		
			
				
					            currentL  =  minL ; 
 
			
		
	
		
			
				
					        // 如果当前行低于最小行,则将当前行设置为最大行
 
 
			
		
	
		
			
				
					        else  if  ( currentL  <  minL ) 
 
			
		
	
		
			
				
					            currentL  =  maxL ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        // 如果当前行等于初始行,则跳出循环
 
 
			
		
	
		
			
				
					        if  ( currentL  = =  initL ) 
 
			
		
	
		
			
				
					            break ; 
 
			
		
	
		
			
				
					    } 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						auto  extremityAbsoltePos  =  _scintView . execute ( direction  = =  - 1  ?  SCI_GETLINEENDPOSITION  :  SCI_POSITIONFROMLINE ,  currentL ) ; 
 
			
		
	
		
			
				
						_scintView . execute ( SCI_SETSEL ,  extremityAbsoltePos ,  extremityAbsoltePos ) ; 
 
			
		
	
		
			
				
					    // 获取当前行的绝对位置
 
 
			
		
	
		
			
				
					    auto  extremityAbsoltePos  =  _scintView . execute ( direction  = =  - 1  ?  SCI_GETLINEENDPOSITION  :  SCI_POSITIONFROMLINE ,  currentL ) ; 
 
			
		
	
		
			
				
					    // 设置选择范围为当前行的绝对位置
 
 
			
		
	
		
			
				
					    _scintView . execute ( SCI_SETSEL ,  extremityAbsoltePos ,  extremityAbsoltePos ) ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					void  Finder : : gotoNextFoundResult ( int  direction )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						//
 
 
			
		
	
		
			
				
						// Get currentLine & currentPosInLine from CurrentPos
 
 
			
		
	
		
			
				
						//
 
 
			
		
	
		
			
				
						auto  currentPos  =  _scintView . execute ( SCI_GETCURRENTPOS ) ; 
 
			
		
	
		
			
				
						intptr_t  lno  =  _scintView . execute ( SCI_LINEFROMPOSITION ,  currentPos ) ; 
 
			
		
	
		
			
				
						auto  total_lines  =  _scintView . execute ( SCI_GETLINECOUNT ) ; 
 
			
		
	
		
			
				
						if  ( total_lines  < =  1 )  return ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						auto  lineStartAbsPos  =  _scintView . execute ( SCI_POSITIONFROMLINE ,  lno ) ; 
 
			
		
	
		
			
				
						intptr_t  currentPosInLine  =  currentPos  -  lineStartAbsPos ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						auto  init_lno  =  lno ; 
 
			
		
	
		
			
				
						auto  max_lno  =  _scintView . execute ( SCI_GETLASTCHILD ,  lno ,  searchHeaderLevel ) ; 
 
			
		
	
		
			
				
					    // 获取当前光标位置及所在行号
 
 
			
		
	
		
			
				
					    auto  currentPos  =  _scintView . execute ( SCI_GETCURRENTPOS ) ; 
 
			
		
	
		
			
				
					    intptr_t  lno  =  _scintView . execute ( SCI_LINEFROMPOSITION ,  currentPos ) ; 
 
			
		
	
		
			
				
					    auto  total_lines  =  _scintView . execute ( SCI_GETLINECOUNT ) ; 
 
			
		
	
		
			
				
					    // 如果总行数小于等于1,  
 
			
		
	
		
			
				
					    if  ( total_lines  < =  1 )  return ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    // 获取当前行的起始位置和光标在行内的位置
 
 
			
		
	
		
			
				
					    auto  lineStartAbsPos  =  _scintView . execute ( SCI_POSITIONFROMLINE ,  lno ) ; 
 
			
		
	
		
			
				
					    intptr_t  currentPosInLine  =  currentPos  -  lineStartAbsPos ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    auto  init_lno  =  lno ; 
 
			
		
	
		
			
				
					    auto  max_lno  =  _scintView . execute ( SCI_GETLASTCHILD ,  lno ,  searchHeaderLevel ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    assert ( max_lno  < =  total_lines  -  2 ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    // 获取当前搜索行号( )  
 
			
		
	
		
			
				
					    int  level  =  _scintView . execute ( SCI_GETFOLDLEVEL ,  lno )  &  SC_FOLDLEVELNUMBERMASK ; 
 
			
		
	
		
			
				
					    auto  min_lno  =  lno ; 
 
			
		
	
		
			
				
					    while  ( level - -  > =  fileHeaderLevel ) 
 
			
		
	
		
			
				
					    { 
 
			
		
	
		
			
				
					        min_lno  =  _scintView . execute ( SCI_GETFOLDPARENT ,  min_lno ) ; 
 
			
		
	
		
			
				
					        assert ( min_lno  > =  0 ) ; 
 
			
		
	
		
			
				
					    } 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						assert ( max_lno  < =  total_lines  -  2 ) ; 
 
			
		
	
		
			
				
					    if  ( min_lno  <  0 )  min_lno  =  lno ;  // 当lno是一个搜索标题行时
   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// get the line number of the current search (searchHeaderLevel)
 
 
			
		
	
		
			
				
						int  level  =  _scintView . execute ( SCI_GETFOLDLEVEL ,  lno )  &  SC_FOLDLEVELNUMBERMASK ; 
 
			
		
	
		
			
				
						auto  min_lno  =  lno ; 
 
			
		
	
		
			
				
						while  ( level - -  > =  fileHeaderLevel ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							min_lno  =  _scintView . execute ( SCI_GETFOLDPARENT ,  min_lno ) ; 
 
			
		
	
		
			
				
							assert ( min_lno  > =  0 ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					    assert ( min_lno  < =  max_lno ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( min_lno  <  0 )  min_lno  =  lno ;  // when lno is a search header line
 
 
			
		
	
		
			
				
					    // 根据方向更新当前行号
 
 
			
		
	
		
			
				
					    if  ( lno  >  max_lno  & &  direction  = =  0 )  lno  =  min_lno ; 
 
			
		
	
		
			
				
					    else  if  ( lno  <  min_lno )  lno  =  max_lno ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						assert ( min_lno  < =  max_lno ) ; 
 
			
		
	
		
			
				
					    // 设置锚点,确保锚点不在最后一行或折叠标题行上
 
 
			
		
	
		
			
				
					    while  ( _scintView . execute ( SCI_GETFOLDLEVEL ,  lno )  &  SC_FOLDLEVELHEADERFLAG ) 
 
			
		
	
		
			
				
					    { 
 
			
		
	
		
			
				
					        lno  + =  direction  = =  - 1  ?  - 1  :  1 ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( lno  >  max_lno  & &  direction  = =  0 )  lno  =  min_lno ; 
 
			
		
	
		
			
				
						else  if  ( lno  <  min_lno )  lno  =  max_lno ; 
 
			
		
	
		
			
				
					        if  ( lno  >  max_lno ) 
 
			
		
	
		
			
				
					            lno  =  min_lno ; 
 
			
		
	
		
			
				
					        else  if  ( lno  <  min_lno ) 
 
			
		
	
		
			
				
					            lno  =  max_lno ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						//
 
 
			
		
	
		
			
				
						// Set anchor and make sure that achor is not on the last (empty) line or head lines
 
 
			
		
	
		
			
				
						//
 
 
			
		
	
		
			
				
						while  ( _scintView . execute ( SCI_GETFOLDLEVEL ,  lno )  &  SC_FOLDLEVELHEADERFLAG ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							lno  + =  direction  = =  - 1  ?  - 1  :  1 ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( lno  >  max_lno ) 
 
			
		
	
		
			
				
								lno  =  min_lno ; 
 
			
		
	
		
			
				
							else  if  ( lno  <  min_lno ) 
 
			
		
	
		
			
				
								lno  =  max_lno ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( lno  = =  init_lno ) 
 
			
		
	
		
			
				
								break ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					        if  ( lno  = =  init_lno ) 
 
			
		
	
		
			
				
					            break ; 
 
			
		
	
		
			
				
					    } 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( lno  ! =  init_lno ) 
 
			
		
	
		
			
				
						{ 
 
			
		
	
		
			
				
							auto  extremityAbsoltePos  =  _scintView . execute ( direction  = =  - 1  ?  SCI_GETLINEENDPOSITION  :  SCI_POSITIONFROMLINE ,  lno ) ; 
 
			
		
	
		
			
				
							_scintView . execute ( SCI_SETSEL ,  extremityAbsoltePos ,  extremityAbsoltePos ) ; 
 
			
		
	
		
			
				
							currentPos  =  extremityAbsoltePos ; 
 
			
		
	
		
			
				
							auto  start  =  _scintView . execute ( SCI_POSITIONFROMLINE ,  lno ) ; 
 
			
		
	
		
			
				
							currentPosInLine  =  currentPos  -  start ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					    // 如果当前行与初始行不同
 
 
			
		
	
		
			
				
					    if  ( lno  ! =  init_lno ) 
 
			
		
	
		
			
				
					    { 
 
			
		
	
		
			
				
					        // 获取当前行的绝对位置
 
 
			
		
	
		
			
				
					        auto  extremityAbsoltePos  =  _scintView . execute ( direction  = =  - 1  ?  SCI_GETLINEENDPOSITION  :  SCI_POSITIONFROMLINE ,  lno ) ; 
 
			
		
	
		
			
				
					        // 设置选择范围为当前行的绝对位置
 
 
			
		
	
		
			
				
					        _scintView . execute ( SCI_SETSEL ,  extremityAbsoltePos ,  extremityAbsoltePos ) ; 
 
			
		
	
		
			
				
					        currentPos  =  extremityAbsoltePos ; 
 
			
		
	
		
			
				
					        // 获取当前行的起始位置和光标在行内的位置
 
 
			
		
	
		
			
				
					        auto  start  =  _scintView . execute ( SCI_POSITIONFROMLINE ,  lno ) ; 
 
			
		
	
		
			
				
					        currentPosInLine  =  currentPos  -  start ; 
 
			
		
	
		
			
				
					    } 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    size_t  n  =  0 ; 
 
			
		
	
		
			
				
					    const  SearchResultMarkingLine &  markingLine  =  * ( _pMainMarkings - > begin ( )  +  lno ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						size_t  n  =  0 ; 
 
			
		
	
		
			
				
						const  SearchResultMarkingLine &  markingLine  =  * ( _pMainMarkings - > begin ( )  +  lno ) ; 
 
			
		
	
		
			
				
					    // 获取当前位置在行内的状态
   
			
		
	
		
			
				
					    CurrentPosInLineInfo  cpili  =  getCurrentPosInLineInfo ( currentPosInLine ,  markingLine  ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						//
 
 
			
		
	
		
			
				
						// Determinate currentPosInLine status among pos_infront, pose_between, pos_inside and pos_behind
 
 
			
		
	
		
			
				
						//
 
 
			
		
	
		
			
				
						CurrentPosInLineInfo  cpili   =  getCurrentPosInLineInfo ( currentPosInLine ,  markingLine ) ; 
 
			
		
	
		
			
				
					    // 根据方向和当前
 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						//
 
 
			
		
	
		
			
				
						// According CurrentPosInLineInfo and direction, set position and get number of occurrence