Page 1 of 1

Updated StringFinder X86 X64 windows only

Posted: Tue Jun 12, 2012 8:20 pm
by Zebuddi123
3/7/12 updated final version

now multi-threaded
real-time counter for hits, lines read, data read(size), timer
options for showing directory or not in file list view
double left mouse click open up the file in its associated app

windows x86 & x64

Md5 35ad7c0213bbc7d1866da011f604dc25

http://goo.gl/ne6fO

Zebuddi. :D


14/6/12
updated now compiles to x86 and x64
added Total file size searched
http://goo.gl/1WpLV includes source, executable`s X64, X86
MD5 3454390adf116c935959356284f27efc


Hi to all

Here is my string finding utility. it has been updated and now has these options and features

1. Threaded
2. case sensitivity
3. masks for file extensions
4. pretty quick - although i`m sure the Guru`s out there could double its speed with optimizations
5. right double click the filename section of the listview gadget will autoload the file depending on filetype and windows file association to that type
ie. .pb straight into PBIde .txt into notepad++ etc

it will look through any file type to find strings (word or sentence) in files. i use it find snippets i have written but only remember a small sentence procedure etc and hey presto ive got the file and line number etc

case sensitivity is taken care of via checkbox, unchecked - no case sensitivity, but the displayed line of the search term is left in its original form

masks can be any file extension *.pb .pb or even pb is fine as the wildcard and . are taken care of - no mask given all files will be searched regardless of file type

its 32 bit only im affraid as i have used Gnozals PureRESIZE lib (Thanks Gnozal) which is only x86

searching my C:\ dir with mask pb and term test no case sensitivity 11988 files 1,818,694 lines of code took 59 secs on a q6600. right double click on the filename field in the listview gadget will open the file with what ever is associated with the file type in windows. ie pb file loads straight into pb ide etc

Thanks to the PB team for a great tool to discover programming with :D

Code: Select all

; Zebuddi.; 29/4/2012
Enumeration 
	#Window_0
	#StatusBar_Window_0 
	#Button_dir
	#String_dir 
	#String_term 
	#Button_search 
	#ListIcon_7
	#Button_cancel
	#Text_6
	#String_mask
	#Frame3D_8
	#CheckBox_wholeword
	#CheckBox_sensitive
EndEnumeration
Define .i
; Constants
#RS_All = -1

; Structures
Structure RS_gadget_struct
	Window.i     
	Gadget.i     
	Left.i   
	Top.i         
	Right.i       
	Bottom.i     
	Lock_left.b
	Lock_top.b
	Lock_right.b
	Lock_bottom.b 
EndStructure     


Structure MemoryArray
	char.c[0]
	Byte.l[0]
EndStructure

Global title$= "Search Files/Dirs for Strings"
Global NewList FilesAndFolders.s(), tline.q,dir$,pattern$,level.l,f$,ccount,mask$
Global NewList RS_Gadgets.RS_gadget_struct()
;PROCEDURES

; RS_Register - Register gadget to be resized and how to resize.
; Specify #TRUE for each side of the gadget you want to LOCK, else #FALSE.
; Parameters:  WindowID (integer), GadgetID (integer), Left (boolean), Top (boolean), Right (boolean), Bottom (boolean).
Procedure RS_Register(RS_window.i, RS_gadget.i, RS_left.b, RS_top.b, RS_right.b, RS_bottom.b)
	
	AddElement(RS_Gadgets())
	
	With RS_Gadgets()
		
		\Gadget = RS_gadget
		\Window = RS_window
		\Lock_left = RS_left
		\Lock_top = RS_top
		\Lock_right = RS_right
		\Lock_bottom = RS_bottom
		
		If RS_left = #False
			\Left = WindowWidth(RS_window) - GadgetX(RS_gadget)
		EndIf
		
		If RS_top = #False
			\Top = WindowHeight(RS_window) - GadgetY(RS_gadget)
		EndIf
		
		If RS_right = #True
			\Right = WindowWidth(RS_window) - (GadgetX(RS_gadget) + GadgetWidth(RS_gadget))
		EndIf
		
		If RS_bottom = #True
			\Bottom = WindowHeight(RS_window) - (GadgetY(RS_gadget) + GadgetHeight(RS_gadget))
		EndIf
		
	EndWith
	
EndProcedure

Procedure.s CalcFileSizes(calcsize.i); calc size and return string from bytes 
	If calcsize < 1024
		ProcedureReturn StrD(calcsize,2)+" bytes"
	EndIf
	If calcsize >1024 And calcsize <1048576
		ProcedureReturn StrD(1024/calcsize,2)+" Kilobytes"
	EndIf
	If calcsize >1048576 And calcsize<1073741824
		ProcedureReturn StrD(calcsize/1048576,2)+" Megabytes"
	EndIf
	If calcsize >1073741824 And calcsize< 1099511627776
		ProcedureReturn StrD(1073741824/calcsize,2)+" Gigabytes"
	EndIf
EndProcedure
; RS_Unregister - Unregister gadget from resizing.
; Parameters: Window ID (integer), Gadget ID (integer). 
; Gadget ID = #RS_All To unregister all gadgets for Window ID.
Procedure RS_Unregister(RS_window.i, RS_gadget.i)
	
	ResetList(RS_Gadgets())
	
	ForEach RS_Gadgets()
		
		If RS_Gadgets()\Window = RS_window And (RS_Gadgets()\Gadget = RS_gadget Or RS_gadget = #RS_All)
			DeleteElement(RS_Gadgets())
		EndIf
		
	Next
	
EndProcedure

; RS_Resize - Resize all registered gadgets for the resizing window.
; Parameters: Event ID (integer), Event Window ID (integer).
Procedure RS_Resize(RS_Event.i, RS_window.i)
	
	If RS_Event = #PB_Event_SizeWindow And ListSize(RS_Gadgets()) > 0
		
		Define.i RS_gadget, RS_size, RS_x, RS_y, RS_w, RS_h
		
		ForEach RS_Gadgets()
			
			If RS_Gadgets()\Window = RS_window
				
				With RS_Gadgets()
					
					RS_gadget = \Gadget
					
					RS_x = GadgetX(RS_gadget)
					RS_y = GadgetY(RS_gadget)
					RS_w = #PB_Ignore:RS_h = #PB_Ignore
					
					If \Lock_left = #False   
						RS_x = (WindowWidth(RS_window) - \Left)
					EndIf
					
					If \Lock_top = #False
						RS_y = (WindowHeight(RS_window) - \Top)
					EndIf       
					
					If \Lock_right = #True
						RS_w = (WindowWidth(RS_window) - RS_x) - \Right
					EndIf
					
					If \Lock_bottom = #True
						RS_h = (WindowHeight(RS_window) - RS_y) - \Bottom
					EndIf       
					
					ResizeGadget(RS_gadget, RS_x, RS_y, RS_w, RS_h)
					
				EndWith
				
			EndIf
			
		Next
		
	EndIf
	
EndProcedure

Procedure.s FFormatNumber(Number.q) ;1000000===>1,000,000
	Buffer.s=Space(255)
	GetNumberFormat_(0,0,Str(Number),0,@Buffer,Len(Buffer)) ;API
	ProcedureReturn Buffer
EndProcedure

Procedure.l SearchDirectory(dir$, pattern$,List  List.s(), level.l = 0) 
	Protected eName$ 
	NewList Dirs.s() 
	If (level = 0) 
		ClearList(List()) 
	EndIf 
	If Right(dir$, 1) <> "\"  
		dir$ + "\" 
	EndIf 
	If ExamineDirectory(0, dir$, "")
		While NextDirectoryEntry(0) 
			If DirectoryEntryType(0) = #PB_DirectoryEntry_Directory 
				eName$ = DirectoryEntryName(0)   
				If (eName$ <> ".") And (eName$ <> "..")   
					AddElement(Dirs())  
					Dirs() = eName$ + "\" 
				EndIf   
			EndIf 
		Wend  
		FinishDirectory(0)
		If ExamineDirectory(0, dir$, pattern$) 
			While NextDirectoryEntry(0)  
				eName$ = DirectoryEntryName(0) 
				If (eName$ <> ".") And (eName$ <> "..") 
					AddElement(List())  
					List() = dir$ + eName$    
					ccount+1
					SetWindowTitle(#Window_0,"Searching for Files "+Str(ccount))
					If DirectoryEntryType(0) = #PB_DirectoryEntry_Directory  
						List() + "\"    
					EndIf   
				EndIf 
			Wend  
			FinishDirectory(0) 
		EndIf 
	EndIf
	If ListSize(Dirs())
		ForEach Dirs()  
			SearchDirectory(dir$ + Dirs(), pattern$, List(), level + 1) 
		Next
	EndIf 
	If (level = 0) 
		ForEach List()  
			List() = Mid(List(), Len(dir$) + 1, Len(List())) 
		Next 
		SortList(List(), 2) 
	EndIf
	If ListSize(List())>0
		ProcedureReturn 0
	Else
		ProcedureReturn -1
	EndIf
EndProcedure

ProcedureDLL.s GGetUserName() ; Retrieves the user name wich launch the current thread
	Username.s = Space(512) 
	nsize.l = 512 
	retour=GetUserName_(@Username, @nsize) 
	If retour=0 : Username="": EndIf ; If error return an Empty String
	ProcedureReturn Username
EndProcedure

Procedure ssearch(f)
	StatusBarText(#StatusBar_Window_0,0,"Hit`s   ")
	StatusBarText(#StatusBar_Window_0,1,"Number of Lines Read   ") 
	StatusBarText(#StatusBar_Window_0,2,"Time Taken   ") 
	ClearGadgetItems(#ListIcon_7)
	a$="":t$="":hits=0:st=0:et=0:line=0  
	filecount=0
	dd$=GetGadgetText(#String_dir)
	If Right(dd$,Len(dd$)-1)=":\"
		mresult=MessageRequester("Warning","You Have Elected To Search The Drive  "+UCase(dd$)+Chr(13)+Chr(13)+"This Could Take A long Time"+Chr(13)+"Depending On Your Computers SetUp"+Chr(13)+"Please Select Appropriate Selection To Continue",#PB_MessageRequester_YesNo|#MB_ICONWARNING)
		If mresult=#PB_MessageRequester_No
			ProcedureReturn 
		EndIf
	EndIf
	
	If GetGadgetText(#String_dir)>""    
		ClearGadgetItems(#ListIcon_7)   
		Delay(250)  
		ClearList(FilesAndFolders()) 
		If GetGadgetText(#String_term)>""   
			If GetGadgetText(#String_mask)=""
				mask$="*.*"
			Else
				mask$=GetGadgetText(#String_mask)
				If Left(mask$,2)<>"*."
					mask$=ReplaceString(mask$,"*","")
					mask$=ReplaceString(mask$,".","")
					mask$="*."+mask$
				EndIf
			EndIf
			gotsum=SearchDirectory(f$ ,mask$, FilesAndFolders(),1) 
			If gotsum >-1
				;SStartOfLinkedList(FilesAndFolders())   
				ResetList(FilesAndFolders())
				FirstElement(FilesAndFolders())
				st=ElapsedMilliseconds()    
				SetWindowTitle(#Window_0, "Working....") 
				t$=GetGadgetText(#String_term) 
				If GetGadgetState(#CheckBox_wholeword)=#PB_Checkbox_Checked
					t$=" "+t$+" "
				EndIf
				ForEach FilesAndFolders() 
					filecount+1      
					SetWindowTitle(#Window_0,"Working...  File Count ="+Str(filecount)+" "+GetFilePart(FilesAndFolders()))  
					line=0: a$=""
					If OpenFile(0,FilesAndFolders()) 
						myfilesize=myfilesize+FileSize(FilesAndFolders())
						While Eof(0)=0    
							If GetGadgetState(#CheckBox_sensitive)=#PB_Checkbox_Checked
								a$=ReadString(0)
							Else
								t$=LCase(t$)
								a$=ReadString(0)
								dummy$=a$
								a$=LCase(a$)
							EndIf
							tline+1
							line+1    
							If FindString(a$,t$,1)   
								hits+1     
								AddGadgetItem(#ListIcon_7, -1,"@ line "+Str(line)+Chr(10)+FilesAndFolders()+Chr(10)+dummy$)
							EndIf 
						Wend  
						CloseFile(0)       
					EndIf    
				Next  
				et=ElapsedMilliseconds()     
				SetWindowTitle(#Window_0,title$)   
				StatusBarText(#StatusBar_Window_0,0,"Hit`s "+Str(hits)+" From "+Str(filecount)+" File`s")
				StatusBarText(#StatusBar_Window_0,1,"Number of Lines Read   "+FFormatNumber(tline)+" ---  Total "+CalcFileSizes(myfilesize)) 
				StatusBarText(#StatusBar_Window_0,2,"Time Taken"+Chr(10)+Str((et-st)/1000)+" Sec`s")  
			Else	
				MessageRequester("Mask or Extension Error","No Files Found with Extension of"+Chr(13)+Chr(13)+mask$)
			EndIf
			
		Else 
			MessageRequester("ERROR","Search string cannot be Empty!!!")  
		EndIf    
	Else 
		MessageRequester("ERROR","Directory string cannot be Empty!!!")  
	EndIf  
	ClearList(FilesAndFolders())
EndProcedure

Procedure OpenWindow_Window_0() 
	If OpenWindow(#Window_0, 488, 71,  1065, 421, "Search Files/Dirs for Strings", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)  
		If CreateStatusBar(#StatusBar_Window_0, WindowID(#Window_0))  
			AddStatusBarField(200) 
			StatusBarText(#StatusBar_Window_0, 0, "Hit`s   ") 
			AddStatusBarField(465)
			StatusBarText(#StatusBar_Window_0, 1, "Number of Lines Read   ")  
			AddStatusBarField(500)
			StatusBarText(#StatusBar_Window_0, 2, "Time Taken   ")  
		EndIf
		SmartWindowRefresh(#Window_0, #True)
		ButtonGadget(#Button_dir, 510, 5, 60, 25, "Directory")
		StringGadget(#String_dir, 5, 5, 500, 25, "")
		StringGadget(#String_term, 5, 30, 500, 25, "")
		ButtonGadget(#Button_search, 510, 30, 60, 25, "Search")
		ButtonGadget(#Button_cancel, 1000, 15, 60, 25, "Cancel")
		ListIconGadget(#ListIcon_7, 0, 60, 1065, 340, "Line", 100, #PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_FullRowSelect|#PB_ListIcon_GridLines)
		AddGadgetColumn(#ListIcon_7, 2, "String",738)
		AddGadgetColumn(#ListIcon_7, 1, "Files", 350) 
		TextGadget(#Text_6, 590, 25, 30, 15, "Mask")
		StringGadget(#String_mask, 625, 25, 65, 25, "")
		Frame3DGadget(#Frame3D_8, 580, 5, 415, 50, "Options")
		CheckBoxGadget(#CheckBox_wholeword, 705, 20, 80, 25, "Whole Word")
		CheckBoxGadget(#CheckBox_sensitive, 810, 20, 170, 25, "Case Sensitive Word/Sentence")
		; 		; Gadget Resizing
		; 		PureRESIZE_SetGadgetResize(#ListIcon_7, 1, 1, 1, 1)
		; 		; Window Minimum Size
		; 		PureRESIZE_SetWindowMinimumSize(#Window_0, 1065, 423)
		; 		; Window Maximum Size
		; 		PureRESIZE_SetWindowMaximumSize(#Window_0, 1065, 880)
	EndIf
EndProcedure
OpenWindow_Window_0()
SetGadgetColor(#ListIcon_7,#PB_Gadget_BackColor,$C6FDFC)
SetGadgetColor(#ListIcon_7,#PB_Gadget_LineColor,$949595)
SetGadgetColor(#ListIcon_7,#PB_Gadget_FrontColor,$000000)
RS_Register(#window_0,#ListIcon_7,1,1,1,1)
Repeat
	Event = WaitWindowEvent()
	
	RS_Resize(Event,EventWindow())
	Select WaitWindowEvent()
		Case #PB_Event_Gadget   
			Select EventGadget()
				Case #Button_dir 
					f$=PathRequester("","c:\")  
					SetGadgetText(#String_dir,f$) 
				Case #Button_search 
					tline=0
					mythread=CreateThread(@ssearch(),0)
				Case  #ListIcon_7
					ev=EventType()
					If ev= #PB_EventType_RightDoubleClick
						gs=GetGadgetState(#ListIcon_7)  
						If gs>0
							sf$=GetGadgetItemText(#ListIcon_7,gs,1)
							RunProgram( sf$,"",GetPathPart(f$) ) 
						EndIf
					EndIf
				Case #Button_cancel
					If IsThread(mythread)
						KillThread(mythread)
					EndIf
					ClearList(FilesAndFolders())
					SetWindowTitle(#Window_0,"Search Cancelled By User "+GGetUserName())
			EndSelect
			; ////////////////////////
		Case #PB_Event_CloseWindow  
			Select EventWindow()   
				Case #Window_0    
					If IsThread(mythread)
						KillThread(mythread)
					EndIf
					ClearList(FilesAndFolders())
					CloseWindow(#Window_0)  
					Break 
			EndSelect
	EndSelect
ForEver
Zebuddi. :D

Re: Updated StringFinder X64 Compilable

Posted: Fri Jun 15, 2012 4:03 am
by IdeasVacuum
Works well - thanks for sharing :)
Edit: I like the ability to load the file - added a tooltip to the ListIcon to remind me how, and added left double click (I'm better with the left button lol).

Re: Updated StringFinder X64 Compilable

Posted: Fri Jun 15, 2012 5:55 am
by Kwai chang caine
Great !!! Thanks 8)

Re: Updated StringFinder X64 Compilable

Posted: Fri Jun 15, 2012 2:34 pm
by Zebuddi123
@IdeasVacuum

I have a tendency for a trigger finger that's why i chose rdc always double click when i mean single click (old age tremors possibly too) lol
Glad its found a use for someone else, any ideas on optimization for the search etc !!!

what routine have you use for the tooltip ?

@Kwaï chang caïne thanks, hope it comes in useful for you !!!

Zebuddi. :)