├── Grepy2.ico
├── Grepy2Help
├── GrepyMenu.PNG
├── GrepySearch.PNG
├── GrepyDetails.PNG
├── GrepyExample.PNG
├── GrepyOptions.PNG
├── Grepy2Help.hhp
├── Grepy2Help.vcxproj.filters
├── Table of Contents.hhc
├── View.htm
├── WhatIsGrepy.htm
├── CommandLine.htm
├── Menu.htm
├── Options.htm
├── Grepy2.htm
├── GrepyDetails.htm
├── Search.htm
└── Grepy2Help.vcxproj
├── App.config
├── Properties
├── Settings.settings
├── Settings.Designer.cs
├── AssemblyInfo.cs
├── Resources.Designer.cs
└── Resources.resx
├── CollectingFiles.cs
├── .gitattributes
├── NoMatchesFound.cs
├── BetterRichTextBox.Designer.cs
├── .gitignore
├── LICENSE.md
├── PleaseWait.cs
├── Grepy2.sln
├── README.md
├── SearchHelpForm.cs
├── NoMatchesFound.Designer.cs
├── CollectingFiles.Designer.cs
├── app.manifest
├── PleaseWait.Designer.cs
├── SearchHelpForm.Designer.cs
├── FolderSelectDialog.cs
├── ListViewColumnSorter.cs
├── BetterRichTextBox.cs
├── Globals.cs
├── GetFiles.cs
├── Grepy2.nsi
├── FontPicker.resx
├── OptionsForm.resx
├── PleaseWait.resx
├── SearchForm.resx
├── CollectingFiles.resx
├── NoMatchesFound.resx
├── SearchHelpForm.resx
├── ExplorerIntegration.cs
├── Grepy2.csproj
├── SearchForm.Designer.cs
├── FontPicker.cs
├── Config.cs
├── OptionsForm.cs
├── Program.cs
└── FontPicker.Designer.cs
/Grepy2.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/botman99/Grepy2/HEAD/Grepy2.ico
--------------------------------------------------------------------------------
/Grepy2Help/GrepyMenu.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/botman99/Grepy2/HEAD/Grepy2Help/GrepyMenu.PNG
--------------------------------------------------------------------------------
/Grepy2Help/GrepySearch.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/botman99/Grepy2/HEAD/Grepy2Help/GrepySearch.PNG
--------------------------------------------------------------------------------
/Grepy2Help/GrepyDetails.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/botman99/Grepy2/HEAD/Grepy2Help/GrepyDetails.PNG
--------------------------------------------------------------------------------
/Grepy2Help/GrepyExample.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/botman99/Grepy2/HEAD/Grepy2Help/GrepyExample.PNG
--------------------------------------------------------------------------------
/Grepy2Help/GrepyOptions.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/botman99/Grepy2/HEAD/Grepy2Help/GrepyOptions.PNG
--------------------------------------------------------------------------------
/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CollectingFiles.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace Grepy2
5 | {
6 | public partial class CollectingFiles : Form
7 | {
8 | public CollectingFiles()
9 | {
10 | InitializeComponent();
11 | }
12 |
13 | private void button1_Click(object sender, EventArgs e)
14 | {
15 | Globals.GetFiles.bShouldStopCurrentJob = true; // cancel the current GetFiles job
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/Grepy2Help/Grepy2Help.hhp:
--------------------------------------------------------------------------------
1 | [OPTIONS]
2 | Auto Index=Yes
3 | Compatibility=1.1 or later
4 | Compiled file=Grepy2Help.chm
5 | Contents file=Table of Contents.hhc
6 | Default topic=Grepy2.htm
7 | Display compile progress=No
8 | Full-text search=Yes
9 | Language=0x409 English (United States)
10 |
11 |
12 | [ALIAS]
13 | SearchHelp=Search.htm
14 | OptionsHelp=Options.htm
15 |
16 | [MAP]
17 | #define SearchHelp 1
18 | #define OptionsHelp 2
19 |
20 | [INFOTYPES]
21 |
22 |
--------------------------------------------------------------------------------
/NoMatchesFound.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | namespace Grepy2
12 | {
13 | public partial class NoMatchesFound : Form
14 | {
15 | public NoMatchesFound()
16 | {
17 | InitializeComponent();
18 |
19 | this.StartPosition = FormStartPosition.CenterParent;
20 | }
21 |
22 | private void OkButton_Click(object sender, EventArgs e)
23 | {
24 | Close();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Grepy2Help/Grepy2Help.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/BetterRichTextBox.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Grepy2
2 | {
3 | partial class BetterRichTextBox
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Component Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | components = new System.ComponentModel.Container();
32 | }
33 |
34 | #endregion
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # Windows shortcuts
18 | *.lnk
19 |
20 | # =========================
21 | # Operating System Files
22 | # =========================
23 |
24 | # OSX
25 | # =========================
26 |
27 | .DS_Store
28 | .AppleDouble
29 | .LSOverride
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear in the root of a volume
35 | .DocumentRevisions-V100
36 | .fseventsd
37 | .Spotlight-V100
38 | .TemporaryItems
39 | .Trashes
40 | .VolumeIcon.icns
41 |
42 | # Directories potentially created on remote AFP share
43 | .AppleDB
44 | .AppleDesktop
45 | Network Trash Folder
46 | Temporary Items
47 | .apdisk
48 |
49 | # Visual Studio folders
50 | .vs
51 | bin
52 | obj
53 |
54 | .p4config
55 | .p4ignore.txt
56 |
57 | Grepy2Help/Debug
58 | Grepy2Help/Release
59 | Grepy2Help/Grepy2Help.chm
60 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 |
3 | Copyright (c) 2015-2017 Jeffrey "botman" Broome
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Grepy2.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/PleaseWait.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | using System.Runtime.InteropServices;
5 |
6 | namespace Grepy2
7 | {
8 | public partial class PleaseWait : Form
9 | {
10 | [return: MarshalAs(UnmanagedType.Bool)]
11 | [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
12 | static extern bool PostMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
13 |
14 | public PleaseWait()
15 | {
16 |
17 | InitializeComponent();
18 | }
19 |
20 | private void PleaseWait_Shown(object sender, EventArgs e)
21 | {
22 | progressBar1.Value = 0;
23 |
24 | Application.DoEvents(); // this will cause the form to fully update itself before continuing (so that everything is fully rendered)
25 |
26 | Globals.bPleaseWaitDialogCancelled = false;
27 |
28 | HandleRef FormHandle = new HandleRef(this, Globals.MainFormHandle);
29 |
30 | PostMessage(FormHandle, Globals.WM_PLEASEWAITSHOWN_NOTIFY_MAIN_THREAD, IntPtr.Zero, IntPtr.Zero);
31 | }
32 |
33 | private void button1_Click(object sender, EventArgs e)
34 | {
35 | Globals.bPleaseWaitDialogCancelled = true;
36 | }
37 |
38 | public void UpdateProgressBar(int value)
39 | {
40 | progressBar1.Value = value;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Grepy2.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grepy2", "Grepy2.csproj", "{FCCC6E67-BE44-4866-ABEF-5BFC0BC58852}"
7 | EndProject
8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Grepy2Help", "Grepy2Help\Grepy2Help.vcxproj", "{78699A4F-A46F-4517-ABFD-5313530A1029}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|x86 = Debug|x86
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {FCCC6E67-BE44-4866-ABEF-5BFC0BC58852}.Debug|x86.ActiveCfg = Debug|x86
17 | {FCCC6E67-BE44-4866-ABEF-5BFC0BC58852}.Debug|x86.Build.0 = Debug|x86
18 | {FCCC6E67-BE44-4866-ABEF-5BFC0BC58852}.Release|x86.ActiveCfg = Release|x86
19 | {FCCC6E67-BE44-4866-ABEF-5BFC0BC58852}.Release|x86.Build.0 = Release|x86
20 | {78699A4F-A46F-4517-ABFD-5313530A1029}.Debug|x86.ActiveCfg = Debug|Win32
21 | {78699A4F-A46F-4517-ABFD-5313530A1029}.Debug|x86.Build.0 = Debug|Win32
22 | {78699A4F-A46F-4517-ABFD-5313530A1029}.Release|x86.ActiveCfg = Release|Win32
23 | {78699A4F-A46F-4517-ABFD-5313530A1029}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/Grepy2Help/Table of Contents.hhc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Grepy2Help/View.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | View
6 |
7 |
8 | Previous Next
9 | Grepy View Menu
10 | The View menu item contains the following:
11 |
12 | Horizontal Split - This splits the Grepy main window into two panes that run horizontally. The upper pane displays the file search results and the lower pane displays the search matches found within those files. The horizontal split is the default.
13 |
14 | Vertical Split - This splits the Grepy main window into two panes that run vertically. The left pane displays the file search results and the right pane displays the search matches found within those files.
15 |
16 | All Search Matches - This menu item can be used to display the search match results for all files (the same as what was initially displayed when a search is completed. This can be used after you have clicked on a file in the file search results pane (which displays the search matches for that one file) and you want to go back to displaying the search matches from all files.
17 |
18 | Display Line Numbers - This menu item will toggle whether line numbers are displayed in the search results pane.
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Grepy2")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Jeffrey Broome")]
12 | [assembly: AssemblyProduct("Grepy2")]
13 | [assembly: AssemblyCopyright("Copyright © 2017-2024")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("fccc6e67-be44-4866-abef-5bfc0bc58852")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("2.5.0.0")]
36 | [assembly: AssemblyFileVersion("2.5.0.0")]
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Grepy2
2 |
3 | Grepy is a Windows utility that allows you to quickly and easily search through files for a text string.
4 |
5 | Features:
6 |
7 | - Allows you to search through files for text using regular expressions.
8 | - The search results window displays file text before and after the search match to let you see the context around the match.
9 | - Grepy has a clean and uncluttered interface that allows you to search for what you want with minimal keystrokes and mouse clicks.
10 | - Uses Windows File Explorer integration so you can quickly search specific folders by right-clicking on them.
11 | - Saves previously used search expressions, filespecs and folders in a drop down list so you can quickly reuse previous entries (saves typing).
12 | - Saves the position and size of all windows, sliders and column sizes so the layout stays the way you want it to be.
13 | - Will automatically skip binary files (.exe, .obj, .lib, .bin, etc.) during searches to save time.
14 | - Lets you assign a custom editor application to use to open files (to override the default Windows File Association).
15 | - Uses a configurable number of background threads for file searching which allows you to immediately open files as the search results are populated.
16 | - Grepy is small (loads quickly) and fast (searches very quickly).
17 |
18 |
19 | Here's an example screenshot:
20 |
21 | 
22 |
23 | See the [Releases](https://github.com/botman99/Grepy2/releases) page to download the latest release.
24 |
25 | * Author: Jeffrey "botman" Broome
26 | * License: [MIT](http://opensource.org/licenses/mit-license.php)
27 |
28 |
--------------------------------------------------------------------------------
/SearchHelpForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 |
5 | namespace Grepy2
6 | {
7 | public partial class SearchHelpForm : Form
8 | {
9 | private bool bWindowInitComplete; // set form window is done initializing
10 |
11 | public SearchHelpForm()
12 | {
13 | bWindowInitComplete = false; // we aren't done initializing the window yet, don't overwrite any .config settings
14 |
15 | InitializeComponent();
16 |
17 | int pos_x = -1;
18 | int pos_y = -1;
19 | if( Config.Get(Config.KEY.SearchHelpPosX, ref pos_x) && Config.Get(Config.KEY.SearchHelpPosY, ref pos_y) )
20 | {
21 | this.StartPosition = FormStartPosition.Manual;
22 | this.Location = new Point(pos_x, pos_y);
23 | }
24 | else // otherwise, center the window on the parent form
25 | {
26 | this.StartPosition = FormStartPosition.CenterParent;
27 | }
28 | }
29 |
30 | private void SearchHelpForm_Shown(object sender, EventArgs e)
31 | {
32 | bWindowInitComplete = true; // window initialization is complete, okay to write config settings now
33 | }
34 |
35 | private void SearchHelpForm_Closing(object sender, FormClosingEventArgs e)
36 | {
37 | e.Cancel = true; // don't let the 'X' button close the form (the SearchForm will close this form)
38 | Hide();
39 | }
40 |
41 | private void SearchHelpForm_Move(object sender, EventArgs e)
42 | {
43 | if( bWindowInitComplete )
44 | {
45 | Config.Set(Config.KEY.SearchHelpPosX, Location.X);
46 | Config.Set(Config.KEY.SearchHelpPosY, Location.Y);
47 | }
48 | }
49 |
50 | private void SearchHelpMoreButton_Click(object sender, EventArgs e)
51 | {
52 | Help.ShowHelp(this, "Grepy2Help.chm", HelpNavigator.TopicId, "1");
53 | }
54 |
55 | private void SearchHelpOkButton_Click(object sender, EventArgs e)
56 | {
57 | Hide();
58 | }
59 |
60 | private void SearchHelpForm_LinkClicked(object sender, LinkClickedEventArgs e)
61 | {
62 | System.Diagnostics.Process.Start(e.LinkText);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Grepy2Help/WhatIsGrepy.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Grepy
6 |
7 |
8 | Previous Next
9 | What Is Grepy?
10 | Grepy is a Windows utility that allows you to quickly and easily search through files for a text string.
11 |
12 | Features:
13 |
14 | Allows you to search through files for text using regular expressions.
15 | The search results window displays file text before and after the search match to let you see the context around the match.
16 | Grepy has a clean and uncluttered interface that allows you to search for what you want with minimal keystrokes and mouse clicks.
17 | Uses Windows File Explorer integration so you can quickly search specific folders by right-clicking on them.
18 | Saves previously used search expressions, filespecs and folders in a drop down list so you can quickly reuse previous entries (saves typing).
19 | Saves the position and size of all windows, sliders and column sizes so the layout stays the way you want it to be.
20 | Will automatically skip binary files (.exe, .obj, .lib, .bin, etc.) during searches to save time.
21 | Lets you assign a custom editor application to use to open files (to override the default Windows File Association).
22 | Uses a configurable number of background threads for file searching which allows you to immediately open files as the search results are populated.
23 | Grepy is small (loads quickly) and fast (searches very quickly).
24 |
25 |
26 | Here's a sample screenshot of what Grepy looks like:
27 |
28 |
29 |
30 | Previous Next
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Grepy2Help/CommandLine.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | View
6 |
7 |
8 | Previous Next
9 | Grepy2 CommandLine
10 | Grepy2 supports the following command line arguments:
11 |
12 | Grepy2.exe [switches] [SearchFolder] SearchString FileSpec [FileSpec...]
13 | Where optional [switches] can be any of the following:
14 |
15 | -r = Recurse folders
16 | -cs = Use Case Sensitive searching
17 | -noregex = Don't use regular expressions when searching
18 |
19 | The optional SearchFolder can be specified if you want to search from a specific folder. If no SearchFolder is specified, Grepy will start searching from the current directory.
20 |
21 | The SearchString is the string of text that you want to search for. Regular Expressions are enabled by default so if you are using wildcard characters in your search string, make sure the search string is a valid regular expression.
22 |
23 | The FileSpec arguments are the file specification that you want to use when searching for the search string. Normal MS-DOS file specifications can be used here. Multiple file specifications can be provided on the command line.
24 |
25 | Examples:
26 | Grepy2 test *.*
27 | (Searches for the string "test" in all files in the current directory.)
28 | Grepy2 -r -cs Main *.cpp
29 | (Does a case sensitive search for the string "Main" in all .cpp files in the current directory and all subdirectories.)
30 | Grepy2 -r "C:\Projects" new *.h *.cpp
31 | (Searches for the string "new" in all .h and .cpp files in the 'C:\Projects' directory and all subdirectories.)
32 |
33 | NOTE: "Grepy2 -?" will output usage information to the console.
34 | Previous Next
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Grepy2Help/Menu.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Menu
6 |
7 |
8 | Previous Next
9 | Grepy Main Menu
10 | The main menu contains the following items:
11 |
12 |
13 |
14 | File - The File menu allows you to Exit from the application.
15 |
16 | Search - This opens the Search dialog where you specify the text string you wish to search for, the file specification you wish to use while searching and the folder where you wish to search (along with other options that control whether you want case sensitive searches, regular expression searches, etc.). The Search dialog can also be opened by using Ctrl + F as a keyboard shortcut.
17 |
18 | Options - This menu item opens the Options dialog where you can set application settings (like enabling or disabling Windows File Explorer integration, changing the number of search worker threads, and assigning a custom editor to use to open files from the search results).
19 |
20 | View - The View menu allows you to switch to a vertical layout or a horizontal layout (the default). The View menu also contains an "All Search Matches" item that allows you to display the search results from all files after you have clicked on a specific file to limit the search results to just that one file.
21 |
22 | Help - This menu item opens this help file.
23 |
24 | Stop Search - This menu item will only be displayed while a search is in progress. If you wish to cancel a search before it is done, you can click on the "Stop Search" menu item. Any results that have already been found will still be displayed so you can cancel a search early if you find what you want before the search is complete.
25 |
26 | Previous Next
27 |
28 |
29 |
--------------------------------------------------------------------------------
/NoMatchesFound.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Grepy2
2 | {
3 | partial class NoMatchesFound
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.label1 = new System.Windows.Forms.Label();
32 | this.OkButton = new System.Windows.Forms.Button();
33 | this.SuspendLayout();
34 | //
35 | // label1
36 | //
37 | this.label1.AutoSize = true;
38 | this.label1.Location = new System.Drawing.Point(60, 23);
39 | this.label1.Name = "label1";
40 | this.label1.Size = new System.Drawing.Size(127, 13);
41 | this.label1.TabIndex = 0;
42 | this.label1.Text = "No Matches Were Found";
43 | //
44 | // OkButton
45 | //
46 | this.OkButton.Location = new System.Drawing.Point(88, 65);
47 | this.OkButton.Name = "OkButton";
48 | this.OkButton.Size = new System.Drawing.Size(71, 25);
49 | this.OkButton.TabIndex = 1;
50 | this.OkButton.Text = "OK";
51 | this.OkButton.UseVisualStyleBackColor = true;
52 | this.OkButton.Click += new System.EventHandler(this.OkButton_Click);
53 | //
54 | // NoMatchesFound
55 | //
56 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
57 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
58 | this.ClientSize = new System.Drawing.Size(246, 102);
59 | this.Controls.Add(this.OkButton);
60 | this.Controls.Add(this.label1);
61 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
62 | this.MaximizeBox = false;
63 | this.MinimizeBox = false;
64 | this.Name = "NoMatchesFound";
65 | this.Text = "Grepy2";
66 | this.TopMost = true;
67 | this.ResumeLayout(false);
68 | this.PerformLayout();
69 |
70 | }
71 |
72 | #endregion
73 |
74 | private System.Windows.Forms.Label label1;
75 | private System.Windows.Forms.Button OkButton;
76 | }
77 | }
--------------------------------------------------------------------------------
/CollectingFiles.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Grepy2
2 | {
3 | partial class CollectingFiles
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.label1 = new System.Windows.Forms.Label();
32 | this.button1 = new System.Windows.Forms.Button();
33 | this.SuspendLayout();
34 | //
35 | // label1
36 | //
37 | this.label1.AutoSize = true;
38 | this.label1.Location = new System.Drawing.Point(16, 31);
39 | this.label1.Name = "label1";
40 | this.label1.Size = new System.Drawing.Size(256, 13);
41 | this.label1.TabIndex = 0;
42 | this.label1.Text = "Collecting the folders and files that will be searched...";
43 | //
44 | // button1
45 | //
46 | this.button1.Location = new System.Drawing.Point(88, 75);
47 | this.button1.Name = "button1";
48 | this.button1.Size = new System.Drawing.Size(115, 25);
49 | this.button1.TabIndex = 1;
50 | this.button1.Text = "Cancel Search";
51 | this.button1.UseVisualStyleBackColor = true;
52 | this.button1.Click += new System.EventHandler(this.button1_Click);
53 | //
54 | // CollectingFiles
55 | //
56 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
57 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
58 | this.ClientSize = new System.Drawing.Size(289, 121);
59 | this.Controls.Add(this.button1);
60 | this.Controls.Add(this.label1);
61 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
62 | this.MaximizeBox = false;
63 | this.MinimizeBox = false;
64 | this.Name = "CollectingFiles";
65 | this.ShowIcon = false;
66 | this.Text = "Collecting Files";
67 | this.TopMost = true;
68 | this.ResumeLayout(false);
69 | this.PerformLayout();
70 |
71 | }
72 |
73 | #endregion
74 |
75 | private System.Windows.Forms.Label label1;
76 | private System.Windows.Forms.Button button1;
77 | }
78 | }
--------------------------------------------------------------------------------
/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Grepy2.Properties
12 | {
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources
26 | {
27 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// Returns the cached ResourceManager instance used by this class.
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Grepy2.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// Overrides the current thread's CurrentUICulture property for all
56 | /// resource lookups using this strongly typed resource class.
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/PleaseWait.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Grepy2
2 | {
3 | partial class PleaseWait
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.label1 = new System.Windows.Forms.Label();
32 | this.button1 = new System.Windows.Forms.Button();
33 | this.progressBar1 = new System.Windows.Forms.ProgressBar();
34 | this.SuspendLayout();
35 | //
36 | // label1
37 | //
38 | this.label1.AutoSize = true;
39 | this.label1.Location = new System.Drawing.Point(31, 26);
40 | this.label1.Name = "label1";
41 | this.label1.Size = new System.Drawing.Size(162, 13);
42 | this.label1.TabIndex = 0;
43 | this.label1.Text = "Processing text to be displayed...";
44 | //
45 | // button1
46 | //
47 | this.button1.Location = new System.Drawing.Point(80, 90);
48 | this.button1.Name = "button1";
49 | this.button1.Size = new System.Drawing.Size(68, 25);
50 | this.button1.TabIndex = 1;
51 | this.button1.Text = "Cancel";
52 | this.button1.UseVisualStyleBackColor = true;
53 | this.button1.Click += new System.EventHandler(this.button1_Click);
54 | //
55 | // progressBar1
56 | //
57 | this.progressBar1.Location = new System.Drawing.Point(42, 51);
58 | this.progressBar1.Name = "progressBar1";
59 | this.progressBar1.Size = new System.Drawing.Size(140, 15);
60 | this.progressBar1.TabIndex = 2;
61 | //
62 | // PleaseWait
63 | //
64 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
65 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
66 | this.ClientSize = new System.Drawing.Size(224, 136);
67 | this.Controls.Add(this.progressBar1);
68 | this.Controls.Add(this.button1);
69 | this.Controls.Add(this.label1);
70 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
71 | this.MaximizeBox = false;
72 | this.MinimizeBox = false;
73 | this.Name = "PleaseWait";
74 | this.ShowIcon = false;
75 | this.Text = "Please Wait";
76 | this.Shown += new System.EventHandler(this.PleaseWait_Shown);
77 | this.ResumeLayout(false);
78 | this.PerformLayout();
79 |
80 | }
81 |
82 | #endregion
83 |
84 | private System.Windows.Forms.Label label1;
85 | private System.Windows.Forms.Button button1;
86 | private System.Windows.Forms.ProgressBar progressBar1;
87 | }
88 | }
--------------------------------------------------------------------------------
/Grepy2Help/Options.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Options
6 |
7 |
8 | Previous Next
9 | Grepy Options Dialog
10 | The Options dialog contains the following:
11 |
12 |
13 |
14 | Enable Windows File Explorer integration - Use this checkbox to enable or disable Windows File Explorer integration (where you can mouse right click on a folder or drive and run Grepy using that folder as the 'Folder To Search' in the Search dialog). You may need to run Grepy as an administrator to use this option (i.e. right click on the Grepy start menu item or desktop shortcut and select "Run as administrator").
15 |
16 | Number of search worker threads - Click the down arrow to open a drop down list to select the number of worker threads you want to use when searching the text files for a search match. Increasing the number of worker threads can make searching faster but will tie up more CPU resources. This number is limited to one less than the total number of CPU cores that you have on your machine.
17 |
18 | File Information Font - Select the font you wish to use for the File Information pane.
19 |
20 | Defer Rich Text display of search results until after search is complete - Normally while searching text files, Grepy will immediately display the search results in the lower (or right hand) pane. If a lot of text is being displayed, this can make Grepy become sluggish an unresponsive on some systems. If you have this problem, you can defer displaying all the search results until after the search is complete and then display everything all at once. Enabling this option can also make the search process slightly faster (although you don't see the results until the search is done).
21 |
22 | Search Results Font - Select the font you wish to use for the Search Results pane.
23 |
24 | Use Windows file association for editor - If this checkbox is checked, Grepy will use whatever Windows file association you have set for a file type when opening the file for editing. If you uncheck this checkbox, you can select a custom editor application to use when Grepy opens a file for editing.
25 |
26 | Custom Editor - This displays the currently set custom editor and any arguments used to open a file. You can use the "..." button to open a File Explorer dialog to choose the executable you want to use as a custom editor. You can manually edit the 'Custom Editor' field to add arguments that Grepy can use to fill in the filename ($F) and the line number to position to in the editor ($L). See your editor's documentation to find out how to specify these arguments.
27 |
28 | Previous Next
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Grepy2Help/Grepy2.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Menu
6 |
7 |
8 | Previous Next
9 | Grepy version 2.5.0
10 |
11 |
12 | What's New:
13 |
14 | Version 2.5.0 - December 15, 2024
15 |
16 | Make performance faster.
17 |
18 | Version 2.4.0 - July 9, 2024
19 |
20 | Fix a major performance and memory usage issue introduced in 2.3.0 version.
21 |
22 | Version 2.3.0 - July 6, 2024
23 |
24 | Remove 'Everything' search feature (since Everything can lock up for a while after deleting lots of files).
25 |
26 | Version 2.2.0 - August 22, 2020
27 |
28 | Position or Center dialogs properly using StartPosition.
29 |
30 | Version 2.1.2 - April 27, 2020
31 |
32 | Fixed a bug when detecting if Everything has indexed the drive being searched.
33 |
34 | Version 2.1.1 - April 19, 2020
35 |
36 | Added the ability to change File Information (ListBox) font and Search Results (RichText) font.
37 |
38 | Version 2.1.0 - March 29, 2020
39 |
40 | Replaced default RichTextBox with BetterRichTextBox which does auto-selection better.
41 |
42 | (there's mouse doubleclick word select mode and Ctrl mouse doubleclick advanced select mode. See "Grepy Details".)
43 |
44 | Added a View option to show or hide line numbers in the search results pane.
45 |
46 | Version 2.0.9 - August 17, 2019
47 |
48 | Added support for searching Microsoft UNC (Universal Naming Convention) file paths.
49 | Make sure Everything is not currently indexing before trying to search with Everything.
50 | Make sure Everything has indexed the drive being searched (so we don't use it to search drives not being indexed by Everything).
51 | Change the background color of the selected file so it's easy to see what was selected after clicking in the search results Rich Text Box.
52 | Fix an issue with no results returned when the "Folder To Search" was the root of the disk (i.e. "C:\").
53 | Fix an issue displaying the message "No files found matching the file specification:" when not finding any files that match the filespec.
54 |
55 | Version 2.0.8 - July 9, 2019
56 |
57 | Fix some crashing bugs and fix tab positions in RichTextBox.
58 |
59 | Version 2.0.7 - June 16, 2018
60 |
61 | Fix dialogs so they center on the parent.
62 |
63 | Version 2.0.6 - March 27, 2018
64 |
65 | Made the "No Matches Found" dialog be TopMost.
66 |
67 | Version 2.0.5 - January 9, 2018
68 |
69 | Fix a bug with processing Mac type text files (LF with no CR).
70 |
71 | Version 2.0.4 - August 28, 2017
72 |
73 | Fix a bug where adjusting 'Before' or 'After' slider when no matches are displayed would cause a crash.
74 | Added a "No Matches Found" dialog to display when no matches are found when searching for text.
75 |
76 | Version 2.0.3 - August 15, 2017
77 |
78 | Fix a bug with 'After' Preview not showing lines when match is within 5 lines of end of file.
79 |
80 | Version 2.0.2 - July 13, 2017
81 |
82 | Fix a bug with worker threads not stopping when search is cancelled.
83 |
84 | Version 2.0.1 - July 2, 2017
85 |
86 | Lower the priority of worker threads.
87 |
88 | Version 2.0.0 - April 29, 2017
89 |
90 | Initial version.
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/Grepy2Help/GrepyDetails.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Grepy Details
6 |
7 |
8 | Previous Next
9 | Grepy Details
10 | Below is a screenshot of Grepy explaining in detail what is displayed in each section of the application.
11 |
12 |
13 |
14 | Section 1 - Displays the main menu for Grepy. From the main menu, you access the Search feature, change Options settings in the application, change how search results are Viewed and have access to this Help file.
15 |
16 | Section 2 - Displays the statistics for the results of the search. This includes the text string that was searched for (in this case "new") and the file specification used for the search (in this case "*.cs"). It indicates how many times the search string was matched in the files searched and how many files contained matches.
17 |
18 | Section 3 - Displays the file information from the results of the search. It displays the file name, the file type, the folder containing the file, the number of times the search string was found in that file, the size of the file and the date and time that the file was last modified. You can click on the heading for any of these columns to sort the file information by that category (for example, click on the "Matches" heading to sort by the number of times the search string was found in each file). Note that the date is in Year/Month/Day format (for easier sorting).
19 |
20 | NOTE: You can double click on a row in Section 3 to open the file in a text editor. You can use the mouse right click in Section 3 to copy file names to the clipboard or to export this section to a CSV (comma separated values) file.
21 |
22 | Section 4 - Displays the search results for each file. Initially, this pane will display the matches from all the files displayed in Section 3. You can click on a specific file in Section 3 to have this section display only the matches from that specific file. In the "View" menu, you can click the "All Search Matches" to have Section 4 display the search results from all files again.
23 |
24 | NOTE: You can use the mouse right click in Section 4 to bring up a menu to select lines, copy to clipboard, or open a file in the editor. You can Ctrl + mouse left click to open a file in the editor (as long as you click on a line with text and not a blank line between text). You can mouse doubleclick (left mouse button) to automatically select the word under the cursor (in this case, "word" is a sequence of characters that are letters, numbers, or the underscore character). You can Ctrl + mouse doubleclick to do an "advanced" auto-select, where in this case, it will automatically select a sequence of characters under the cursor where characters are not spaces, tab characters or end of lines (i.e. not "whitespace").
25 |
26 | Section 5 - Displays a progress bar that is active while a search is in operation. It will also display how many folders and files will be searched looking for a match of the search string.
27 |
28 | Section 6 - These sliders are used to control the amount of Preview text displayed above and below the search match when the file is displayed in Section 4. You can adjust the Before or After slider to increase or decrease the number of lines displayed before the search match line and after the search match line (respectively). The range of the Before and After sliders is 0 to 5 lines of text.
29 |
30 | Previous Next
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Grepy2Help/Search.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Search
6 |
7 |
8 | Previous Next
9 | Grepy Search Dialog
10 | The Search dialog contains the following:
11 |
12 |
13 |
14 | Regular Expression - Check this checkbox when you wish to search using a regular expression.
15 |
16 | Match Case - Check this checkbox when you wish to perform a case sensitive search.
17 |
18 | Recursive Folder Search - Check this checkbox if you wish to search folders recursively (searching all folders and subfolders within the starting folder).
19 |
20 | Search For - Here you enter the text string or regular expression that you are searching for. When using a regular expression, don't forget to check the 'Regular Expression' checkbox. You can click the down arrow on the right to access the drop down list and select previously entered search strings (the most recently selected search string will be moved to the top of the list so that frequently used items remain in the drop down list).
21 |
22 | File Specification(s) - Enter the file specification of the files you want to search through here. Standard MS-DOS wildcard characters can be used in the file specification. You can provide multiple file specifications by separating them with a space. You can click the down arrow on the right to access the drop down list and select from previously used file specifications.
23 |
24 | Folder To Search - Enter the full path of the folder where you want to start the search. You can click the down arrow on the right to access the drop down list and select from previously used folder locations, or you can click the "..." button to open a File Explorer dialog to browse to the folder that you wish to use.
25 |
26 | NOTE: The "Help" button will give you a quick help list of regular expression characters that are valid when searching using regular expressions.
27 |
28 | Here's a quick summary of valid Regular Expression characters that can be used in the 'Search For' field when seaching for a regular expression.
29 |
30 |
31 |
32 | . - period, wildcard, matches any single character one time
33 | (to match a period character use \.)
34 | * - asterisk, matches the previous element zero or more times
35 | (.* matches any string of characters)
36 | + - plus sign, matches the previous element one or more times
37 | ? - question mark, matches the previous element zero or one time
38 | ^ - caret, matches the beginning of a line
39 | $ - dollar sign, matches the end of a line
40 | [abc] - matches any single character in the group
41 | (i.e. a, b, or c, case sensitive)
42 | [^abc] - matches any single character that is not in the group
43 | (i.e. not a, or b, or c, case sensitive)
44 | [a-e] - matches a range of characters
45 | (i.e. a, b, c, d, or e, case sensitive)
46 | \t - matches tab character
47 | \s - matches any whitespace character (space or tab)
48 | \S - matches any non-whitespace character (not space or tab)
49 | \d - matches any decimal digit (i.e. 0 through 9)
50 | \D - matches any character other than a decimal digit
51 | {n} - matches the previous element exactly n times
52 | (i.e. \d{3}, matches 3 digits in a row)
53 | (abc) - grouped expression (matches "abc", case sensitive)
54 | | - matches any one element of the group
55 | (i.e. (ab|bbb|c) matches "ab", "bbb" or "c")
56 | \ - escape, used to match characters that are used as regular expressions
57 | (i.e. "\\" matches backslash, "\*" matches asterisk)
58 |
59 |
60 |
61 | For more details see: http://msdn.microsoft.com/en-us/library/az24scfc.aspx
62 |
63 | Previous Next
64 |
65 |
66 |
--------------------------------------------------------------------------------
/Grepy2Help/Grepy2Help.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 |
15 | true
16 |
17 |
18 | true
19 |
20 |
21 |
22 | true
23 |
24 |
25 | true
26 |
27 |
28 | true
29 |
30 |
31 | true
32 |
33 |
34 |
35 | true
36 |
37 |
38 | true
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | {78699A4F-A46F-4517-ABFD-5313530A1029}
50 | MakeFileProj
51 |
52 |
53 |
54 | Makefile
55 | true
56 | v140
57 |
58 |
59 | Makefile
60 | false
61 | v140
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | "C:\Program Files (x86)\HTML Help Workshop\hhc.exe" Grepy2Help.hhp
75 | exit 0
76 | "C:\Program Files (x86)\HTML Help Workshop\hhc.exe" Grepy2Help.hhp
77 | exit 0
78 | WIN32;_DEBUG;$(NMakePreprocessorDefinitions)
79 | del Grepy2Help.chm
80 | $(SolutionDir)Grepy2Help\$(Configuration)\
81 |
82 |
83 | "C:\Program Files (x86)\HTML Help Workshop\hhc.exe" Grepy2Help.hhp
84 | exit 0
85 | "C:\Program Files (x86)\HTML Help Workshop\hhc.exe" Grepy2Help.hhp
86 | exit 0
87 | WIN32;NDEBUG;$(NMakePreprocessorDefinitions)
88 | del Grepy2Help.chm
89 | $(SolutionDir)Grepy2Help\$(Configuration)\
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/SearchHelpForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Grepy2
2 | {
3 | partial class SearchHelpForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SearchHelpForm));
32 | this.panel1 = new System.Windows.Forms.Panel();
33 | this.HelpRichTextBox = new System.Windows.Forms.RichTextBox();
34 | this.SearchHelpMoreButton = new System.Windows.Forms.Button();
35 | this.SearchHelpOkButton = new System.Windows.Forms.Button();
36 | this.panel1.SuspendLayout();
37 | this.SuspendLayout();
38 | //
39 | // panel1
40 | //
41 | this.panel1.Controls.Add(this.HelpRichTextBox);
42 | this.panel1.Location = new System.Drawing.Point(17, 17);
43 | this.panel1.Name = "panel1";
44 | this.panel1.Padding = new System.Windows.Forms.Padding(7);
45 | this.panel1.Size = new System.Drawing.Size(749, 387);
46 | this.panel1.TabIndex = 0;
47 | //
48 | // HelpRichTextBox
49 | //
50 | this.HelpRichTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
51 | this.HelpRichTextBox.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
52 | this.HelpRichTextBox.Location = new System.Drawing.Point(7, 7);
53 | this.HelpRichTextBox.Name = "HelpRichTextBox";
54 | this.HelpRichTextBox.ReadOnly = true;
55 | this.HelpRichTextBox.Size = new System.Drawing.Size(735, 373);
56 | this.HelpRichTextBox.TabIndex = 0;
57 | this.HelpRichTextBox.TabStop = false;
58 | this.HelpRichTextBox.Text = resources.GetString("HelpRichTextBox.Text");
59 | this.HelpRichTextBox.WordWrap = false;
60 | this.HelpRichTextBox.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.SearchHelpForm_LinkClicked);
61 | //
62 | // SearchHelpMoreButton
63 | //
64 | this.SearchHelpMoreButton.Location = new System.Drawing.Point(312, 421);
65 | this.SearchHelpMoreButton.Name = "SearchHelpMoreButton";
66 | this.SearchHelpMoreButton.Size = new System.Drawing.Size(71, 25);
67 | this.SearchHelpMoreButton.TabIndex = 1;
68 | this.SearchHelpMoreButton.Text = "More Help";
69 | this.SearchHelpMoreButton.UseVisualStyleBackColor = true;
70 | this.SearchHelpMoreButton.Click += new System.EventHandler(this.SearchHelpMoreButton_Click);
71 | //
72 | // SearchHelpOkButton
73 | //
74 | this.SearchHelpOkButton.Location = new System.Drawing.Point(399, 421);
75 | this.SearchHelpOkButton.Name = "SearchHelpOkButton";
76 | this.SearchHelpOkButton.Size = new System.Drawing.Size(71, 25);
77 | this.SearchHelpOkButton.TabIndex = 2;
78 | this.SearchHelpOkButton.Text = "OK";
79 | this.SearchHelpOkButton.UseVisualStyleBackColor = true;
80 | this.SearchHelpOkButton.Click += new System.EventHandler(this.SearchHelpOkButton_Click);
81 | //
82 | // SearchHelpForm
83 | //
84 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
85 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
86 | this.ClientSize = new System.Drawing.Size(782, 458);
87 | this.Controls.Add(this.SearchHelpOkButton);
88 | this.Controls.Add(this.SearchHelpMoreButton);
89 | this.Controls.Add(this.panel1);
90 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
91 | this.MaximizeBox = false;
92 | this.MinimizeBox = false;
93 | this.Name = "SearchHelpForm";
94 | this.ShowIcon = false;
95 | this.Text = "Search Help";
96 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SearchHelpForm_Closing);
97 | this.Shown += new System.EventHandler(this.SearchHelpForm_Shown);
98 | this.Move += new System.EventHandler(this.SearchHelpForm_Move);
99 | this.panel1.ResumeLayout(false);
100 | this.ResumeLayout(false);
101 |
102 | }
103 |
104 | #endregion
105 |
106 | private System.Windows.Forms.Panel panel1;
107 | private System.Windows.Forms.RichTextBox HelpRichTextBox;
108 | private System.Windows.Forms.Button SearchHelpMoreButton;
109 | private System.Windows.Forms.Button SearchHelpOkButton;
110 | }
111 | }
--------------------------------------------------------------------------------
/FolderSelectDialog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using System.Windows.Forms;
4 | using System.Reflection;
5 |
6 | namespace Grepy2
7 | {
8 | // based on https://www.lyquidity.com/devblog/?p=136
9 |
10 | class FolderSelectDialog
11 | {
12 | OpenFileDialog OpenFileDir = null;
13 |
14 | string name_string;
15 | Assembly assembly;
16 |
17 | public FolderSelectDialog()
18 | {
19 | OpenFileDir = new OpenFileDialog();
20 |
21 | OpenFileDir.Filter = "Folders|\n";
22 |
23 | OpenFileDir.Multiselect = false;
24 | OpenFileDir.AddExtension = false;
25 | OpenFileDir.CheckFileExists = false;
26 | OpenFileDir.DereferenceLinks = true;
27 | }
28 |
29 | public string InitialDirectory
30 | {
31 | get { return OpenFileDir.InitialDirectory; }
32 | set
33 | {
34 | bool bIsNull = ((value == null) || (value.Length == 0));
35 | OpenFileDir.InitialDirectory = bIsNull ? Environment.CurrentDirectory : value;
36 | }
37 | }
38 |
39 | public string Title
40 | {
41 | get { return OpenFileDir.Title; }
42 | set
43 | {
44 | OpenFileDir.Title = (value == null) ? "Select a folder" : value;
45 | }
46 | }
47 |
48 | public string FileName
49 | {
50 | get { return OpenFileDir.FileName; }
51 | }
52 |
53 | public bool ShowDialog()
54 | {
55 | return ShowDialog(IntPtr.Zero);
56 | }
57 |
58 | public bool ShowDialog(IntPtr hWndOwner)
59 | {
60 | if( Environment.OSVersion.Version.Major >= 6 ) // Vista/Win7/Win8/Win10
61 | {
62 | name_string = "System.Windows.Forms";
63 | assembly = null;
64 | AssemblyName[] referencedAssemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
65 | foreach (AssemblyName assemblyName in referencedAssemblies)
66 | {
67 | if (assemblyName.FullName.StartsWith(name_string))
68 | {
69 | assembly = Assembly.Load(assemblyName);
70 | break;
71 | }
72 | }
73 |
74 | Type typeIFileDialog = GetType("FileDialogNative.IFileDialog");
75 | object dialog = Call(OpenFileDir.GetType(), OpenFileDir, "CreateVistaDialog");
76 | Call(OpenFileDir.GetType(), OpenFileDir, "OnBeforeVistaDialog", dialog);
77 |
78 | uint options = (uint)Call(typeof(System.Windows.Forms.FileDialog), OpenFileDir, "GetOptions");
79 | options = options | (uint)GetEnum("FileDialogNative.FOS", "FOS_PICKFOLDERS");
80 | Call(typeIFileDialog, dialog, "SetOptions", options);
81 |
82 | object pFileDialogEvent = New("FileDialog.VistaDialogEvents", OpenFileDir);
83 |
84 | uint num_parms = 0;
85 |
86 | object[] parameters = new object[] { pFileDialogEvent, num_parms };
87 | Call(typeIFileDialog, dialog, "Advise", parameters);
88 |
89 | num_parms = (uint)parameters[1];
90 |
91 | try
92 | {
93 | // show the dialog
94 | int count = (int)Call(typeIFileDialog, dialog, "Show", hWndOwner);
95 | return (count == 0);
96 | }
97 | finally
98 | {
99 | // remove event handler
100 | Call(typeIFileDialog, dialog, "Unadvise", num_parms);
101 | GC.KeepAlive(pFileDialogEvent);
102 | }
103 | }
104 | else // XP and earlier
105 | {
106 | FolderBrowserDialog FolderBrowser = new FolderBrowserDialog();
107 |
108 | FolderBrowser.Description = this.Title;
109 | FolderBrowser.SelectedPath = this.InitialDirectory;
110 | FolderBrowser.ShowNewFolderButton = false;
111 |
112 | DialogResult dialog_result = FolderBrowser.ShowDialog();
113 | if( dialog_result == DialogResult.OK )
114 | {
115 | OpenFileDir.FileName = FolderBrowser.SelectedPath;
116 | return true;
117 | }
118 | }
119 | return false;
120 | }
121 |
122 | public Type GetType(string typeName)
123 | {
124 | Type type = null;
125 | string[] type_names = typeName.Split('.');
126 |
127 | if (type_names.Length > 0)
128 | {
129 | type = assembly.GetType(name_string + "." + type_names[0]);
130 | }
131 |
132 | for (int i = 1; i < type_names.Length; ++i)
133 | {
134 | type = type.GetNestedType(type_names[i], BindingFlags.NonPublic);
135 | }
136 |
137 | return type;
138 | }
139 |
140 | public object GetEnum(string typeName, string name)
141 | {
142 | Type type = GetType(typeName);
143 | FieldInfo fieldInfo = type.GetField(name);
144 | return fieldInfo.GetValue(null);
145 | }
146 |
147 | public object Call(Type type, object obj, string func, params object[] parameters)
148 | {
149 | MethodInfo methodInfo = type.GetMethod(func, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
150 | return methodInfo.Invoke(obj, parameters);
151 | }
152 |
153 | public object New(string name, params object[] parameters)
154 | {
155 | Type type = GetType(name);
156 |
157 | ConstructorInfo[] constructorInfos = type.GetConstructors();
158 | foreach (ConstructorInfo constructorInfo in constructorInfos)
159 | {
160 | try
161 | {
162 | return constructorInfo.Invoke(parameters);
163 | }
164 | catch
165 | {
166 | Console.WriteLine("constructorInfo.Invoke() failed");
167 | }
168 | }
169 |
170 | return null;
171 | }
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/ListViewColumnSorter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using System.Windows.Forms;
8 | using System.Collections;
9 | using System.Runtime.InteropServices;
10 |
11 | namespace Grepy2
12 | {
13 | // from http://support.microsoft.com/kb/319401 (with modifications for String.Compare)
14 |
15 | public class ListViewColumnSorter : IComparer
16 | {
17 | const Int32 HDF_SORTDOWN = 0x200;
18 | const Int32 HDF_SORTUP = 0x400;
19 | const Int32 HDI_FORMAT = 0x4;
20 | const Int32 HDM_GETITEM = 0x120b;
21 | const Int32 HDM_SETITEM = 0x120c;
22 | const Int32 LVM_GETHEADER = 0x101f;
23 |
24 | [StructLayout(LayoutKind.Sequential)]
25 | public struct LVCOLUMN
26 | {
27 | public Int32 mask;
28 | public Int32 cx;
29 | [MarshalAs(UnmanagedType.LPTStr)]
30 | public string pszText;
31 | public IntPtr hbm;
32 | public Int32 cchTextMax;
33 | public Int32 fmt;
34 | public Int32 iSubItem;
35 | public Int32 iImage;
36 | public Int32 iOrder;
37 | }
38 |
39 | [DllImport("user32.dll", CharSet = CharSet.Auto)]
40 | static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam);
41 |
42 | [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
43 | static extern IntPtr SendMessageLVCOLUMN(IntPtr hWnd, UInt32 msg, IntPtr wParam, ref LVCOLUMN lParam);
44 |
45 | private int ColumnToSort;
46 | private SortOrder OrderOfSort;
47 | private bool bCaseSensitiveColumnSort;
48 |
49 | public ListViewColumnSorter()
50 | {
51 | // Initialize the column to '0'
52 | ColumnToSort = 0;
53 |
54 | // Initialize the sort order to 'none'
55 | OrderOfSort = SortOrder.None;
56 | }
57 |
58 | public void SetCaseSensitiveColumnSort(bool bInCaseSensitive)
59 | {
60 | bCaseSensitiveColumnSort = bInCaseSensitive;
61 | }
62 |
63 | public int Compare(object x, object y)
64 | {
65 | int compareResult;
66 | ListViewItem listviewX, listviewY;
67 |
68 | // Cast the objects to be compared to ListViewItem objects
69 | listviewX = (ListViewItem)x;
70 | listviewY = (ListViewItem)y;
71 |
72 | // Compare the two items
73 | if( (ColumnToSort == 3) || (ColumnToSort == 4) ) // 'Matches' or 'Filesize', sort as numbers
74 | {
75 | string x_str = listviewX.SubItems[ColumnToSort].Text.ToString();
76 | string y_str = listviewY.SubItems[ColumnToSort].Text.ToString();
77 | int x_value = System.Convert.ToInt32(x_str);
78 | int y_value = System.Convert.ToInt32(y_str);
79 | compareResult = (x_value - y_value);
80 | }
81 | else
82 | {
83 | if( bCaseSensitiveColumnSort )
84 | {
85 | compareResult = String.Compare(listviewX.SubItems[ColumnToSort].Text,listviewY.SubItems[ColumnToSort].Text, StringComparison.Ordinal); // case sensitive
86 | }
87 | else
88 | {
89 | compareResult = String.Compare(listviewX.SubItems[ColumnToSort].Text,listviewY.SubItems[ColumnToSort].Text, StringComparison.OrdinalIgnoreCase); // case insensitive
90 | }
91 | }
92 |
93 | // Calculate correct return value based on object comparison
94 | if( OrderOfSort == SortOrder.Ascending )
95 | {
96 | // Ascending sort is selected, return normal result of compare operation
97 | return compareResult;
98 | }
99 | else if( OrderOfSort == SortOrder.Descending )
100 | {
101 | // Descending sort is selected, return negative result of compare operation
102 | return (-compareResult);
103 | }
104 | else
105 | {
106 | // Return '0' to indicate they are equal
107 | return 0;
108 | }
109 | }
110 |
111 | public int SortColumn
112 | {
113 | set { ColumnToSort = value; }
114 | get { return ColumnToSort; }
115 | }
116 |
117 | public SortOrder Order
118 | {
119 | set { OrderOfSort = value; }
120 | get { return OrderOfSort; }
121 | }
122 |
123 | public void SetSortIcon(ListView listview)
124 | {
125 | IntPtr clmHdr = SendMessage(listview.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
126 |
127 | for (int i = 0; i < listview.Columns.Count; i++)
128 | {
129 | IntPtr clmPtr = new IntPtr(i);
130 | LVCOLUMN lvColumn = new LVCOLUMN();
131 |
132 | lvColumn.mask = HDI_FORMAT;
133 | SendMessageLVCOLUMN(clmHdr, HDM_GETITEM, clmPtr, ref lvColumn);
134 |
135 | if (Order != SortOrder.None && i == ColumnToSort)
136 | {
137 | if (Order == SortOrder.Ascending)
138 | {
139 | lvColumn.fmt &= ~HDF_SORTDOWN;
140 | lvColumn.fmt |= HDF_SORTUP;
141 | }
142 | else
143 | {
144 | lvColumn.fmt &= ~HDF_SORTUP;
145 | lvColumn.fmt |= HDF_SORTDOWN;
146 | }
147 | }
148 | else
149 | {
150 | lvColumn.fmt &= ~HDF_SORTDOWN & ~HDF_SORTUP;
151 | }
152 |
153 | SendMessageLVCOLUMN(clmHdr, HDM_SETITEM, clmPtr, ref lvColumn);
154 | }
155 | }
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/BetterRichTextBox.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | using System.Runtime.InteropServices;
12 |
13 | namespace Grepy2
14 | {
15 | public partial class BetterRichTextBox : RichTextBox
16 | {
17 | [return: MarshalAs(UnmanagedType.Bool)]
18 | [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
19 | static extern bool PostMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
20 |
21 | const int WM_LBUTTONDOWN = 0x0201;
22 | const int WM_LBUTTONDBLCLK = 0x0203;
23 | const int WM_RBUTTONDOWN = 0x0204;
24 |
25 | private bool bIsFirstClick = false;
26 | private bool bWasCtrlPressedWhenClicked = false;
27 |
28 | public HandleRef FormHandle = new HandleRef();
29 | public Point RichTextMousePosition; // saves the position of the most recent mouse click location in the RichTextBox
30 |
31 | private System.Timers.Timer doubleClickTimer = new System.Timers.Timer();
32 |
33 |
34 | public BetterRichTextBox()
35 | {
36 | InitializeComponent();
37 | }
38 |
39 | protected override void OnHandleCreated(EventArgs e)
40 | {
41 | base.OnHandleCreated(e);
42 |
43 | // fix bug with AutoWordSelection (it is true by default but setting it to 'false' won't turn it off, you have to enable it then disable it to turn it off)
44 | this.AutoWordSelection = true;
45 | this.AutoWordSelection = false;
46 |
47 | doubleClickTimer.SynchronizingObject = this;
48 | doubleClickTimer.Elapsed += new System.Timers.ElapsedEventHandler(doubleClickTimerEvent);
49 | }
50 |
51 | protected override void OnPaint(PaintEventArgs pe)
52 | {
53 | base.OnPaint(pe);
54 | }
55 |
56 | private bool IsValidSelectionCharacter(char c)
57 | {
58 | if (bWasCtrlPressedWhenClicked && ((ModifierKeys & Keys.Control) == Keys.Control))
59 | {
60 | if (!Char.IsWhiteSpace(c))
61 | {
62 | return true;
63 | }
64 | }
65 |
66 | if (Char.IsLetterOrDigit(c) || (c == '_'))
67 | {
68 | return true;
69 | }
70 |
71 | return false;
72 | }
73 |
74 | protected override void WndProc(ref Message m)
75 | {
76 | if (m.Msg == WM_LBUTTONDBLCLK)
77 | {
78 | if (this.Text.Length > 0)
79 | {
80 | int start_index = Math.Min(this.SelectionStart, this.Text.Length - 1);
81 | int original_start_index = start_index;
82 | int end_index = start_index;
83 |
84 | while ((start_index >= 0) && IsValidSelectionCharacter(this.Text[start_index]))
85 | {
86 | start_index--;
87 | }
88 |
89 | if (start_index != original_start_index)
90 | {
91 | start_index++;
92 | }
93 |
94 | while ((end_index < this.Text.Length) && IsValidSelectionCharacter(this.Text[end_index]))
95 | {
96 | end_index++;
97 | }
98 |
99 | if (end_index != original_start_index)
100 | {
101 | end_index--;
102 | }
103 |
104 | this.SelectionStart = start_index;
105 | this.SelectionLength = end_index - start_index + 1;
106 | }
107 |
108 | doubleClickTimer.Enabled = false;
109 |
110 | bIsFirstClick = false;
111 | bWasCtrlPressedWhenClicked = false;
112 |
113 | return;
114 | }
115 | else if (m.Msg == WM_LBUTTONDOWN)
116 | {
117 | int xPos = (int)m.LParam & 0xffff; // get low word
118 | int yPos = ((int)m.LParam >> 16) & 0xffff; // get high word
119 |
120 | RichTextMousePosition = new Point(xPos, yPos);
121 |
122 | if (!bIsFirstClick)
123 | {
124 | bIsFirstClick = true;
125 |
126 | if( (ModifierKeys & Keys.Control) == Keys.Control )
127 | {
128 | bWasCtrlPressedWhenClicked = true;
129 | }
130 |
131 | doubleClickTimer.Interval = SystemInformation.DoubleClickTime;
132 | doubleClickTimer.Enabled = true;
133 | }
134 | else
135 | {
136 | bIsFirstClick = false; // we have seen two left clicks before the doubleClickTimer timed out, this is not a single click event (we should never get here)
137 | bWasCtrlPressedWhenClicked = false;
138 | }
139 | }
140 | else if (m.Msg == WM_RBUTTONDOWN)
141 | {
142 | int xPos = (int)m.LParam & 0xffff; // get low word
143 | int yPos = ((int)m.LParam >> 16) & 0xffff; // get high word
144 |
145 | RichTextMousePosition = new Point(xPos, yPos);
146 | }
147 |
148 | base.WndProc(ref m);
149 | }
150 |
151 | private void doubleClickTimerEvent(object source, System.Timers.ElapsedEventArgs e)
152 | {
153 | doubleClickTimer.Enabled = false;
154 |
155 | if (bIsFirstClick)
156 | {
157 | if (SelectionLength == 0) // was nothing selected between mouse down and mouse up event?
158 | {
159 | if( bWasCtrlPressedWhenClicked )
160 | {
161 | if (FormHandle.Handle != IntPtr.Zero)
162 | {
163 | PostMessage(FormHandle, Globals.WM_CTRL_CLICK_NOTIFY_MAIN_THREAD, IntPtr.Zero, IntPtr.Zero); // notify main Form thread that ctrl single click was detected
164 | }
165 | }
166 | }
167 |
168 | bIsFirstClick = false; // double click wasn't seen within the timeout, clear the bFirstClick bool
169 | bWasCtrlPressedWhenClicked = false;
170 | }
171 | }
172 |
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/Globals.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | using System.Threading;
5 |
6 | namespace Grepy2
7 | {
8 | // NOTE: We don't need any locking for the globals shared between the Main Form thread and any of the other threads.
9 | // The other threads will wait on their 'WaitHandle' and the Main Form thread won't Set() the handle until it has fully
10 | // initialized any variables needed by the other thread. Once Set() has been called, the main thread won't modify
11 | // any of these other thread variables. The main thread will wait until the other thread sends a Windows Message
12 | // to the WndProc() function to indicate that the other thread is done doing work. The other thread will fully
13 | // initialize any global variables that will be read by the main thread before the other thread sends the Windows Message.
14 |
15 | static class Globals
16 | {
17 | public const int WM_USER = 0x0400; // Windows private user messages
18 | public const int WM_GETFILES_NOTIFY_MAIN_THREAD = WM_USER; // notify main thread that collecting files is done
19 | public const int WM_WORKER_NOTIFY_MAIN_THREAD = WM_USER+1; // notify main thread that worker has searched file for search text
20 | public const int WM_SLIDERUPDATE_NOTIFY_MAIN_THREAD = WM_USER+2; // notify main thread that the Before/After preview slider has updated
21 | public const int WM_PLEASEWAITSHOWN_NOTIFY_MAIN_THREAD = WM_USER+3; // notify main thread that the "Please Wait" dialog has been shown
22 | public const int WM_CTRL_CLICK_NOTIFY_MAIN_THREAD = WM_USER+4; // notify main thread that RichTextBox Ctrl Single Click happened
23 |
24 | public struct GetFiles_s // struct for GetFiles thread
25 | {
26 | public AutoResetEvent WaitHandle;
27 | public bool bIsWorking; // is thread currently working on a job (set by thread, read by others)
28 | public bool bShouldStopCurrentJob; // thread should stop working on current job (cancel work, set by Main Form, ready by GetFiles thread)
29 | public bool bShouldExit; // thread should exit (quit)
30 | }
31 |
32 | public static GetFiles_s GetFiles;
33 |
34 |
35 | public struct Worker_s // struct for Worker threads
36 | {
37 | public AutoResetEvent WaitHandle;
38 | public bool bIsWorking; // is thread currently working on a job (set by thread, read by others)
39 | public bool bShouldExit; // thread should exit (quit)
40 |
41 | public int SearchFilesIndex; // index into the SearchFiles list that is assigned to this worker
42 | }
43 |
44 | public static Worker_s[] Workers;
45 |
46 |
47 | public enum SearchFileStatus
48 | {
49 | NotProcessed = 0,
50 | FileIsBinary,
51 | SearchTextNotFound,
52 | SearchTextFound
53 | };
54 |
55 | public class SearchMatchPosition // class for holding start position and length of a search text match within a line
56 | {
57 | public int StartPos;
58 | public int Length;
59 | }
60 |
61 | public class SearchLine // class for holding a line of text from the file
62 | {
63 | public int LineNumber; // line number in the file
64 | public string Line; // line of text from the file
65 | public bool bIsSearchTextMatch; // does this line contain a match for the search text (if not, it's a preview line above/below a match)
66 | public List SearchMatchPositions; // holds the start position and length of search text matches (there could be multiple matches per line of text)
67 | public int LinesBeforeNextMatch; // the number of lines between this line and the next search text match line in the SearchFile_s 'Lines' list (for the RichText display of lines without matches)
68 | }
69 |
70 | public class SearchFile // class for a file that will be searched for the search text
71 | {
72 | public SearchFileStatus Status; // has this file been processed yet by the worker threads (some files searched will contain no matches)
73 | public string Filename; // this is the full path filename
74 | public string BaseFilename;
75 | public string FileTypeName;
76 | public string FolderName;
77 | public int SearchMatchCount; // number of times the search text was found in this file
78 | public long FileLength;
79 | public DateTime FileLastWriteTime;
80 | public List Lines;
81 | public int Matches;
82 | }
83 |
84 | public static SearchFile[] SearchFiles;
85 | public static int SearchDirectoryCount; // number of directories we searched through to collect files to search
86 | public static int NumFilesSearched;
87 |
88 | public static bool bIsGrepyReadOnly = false;
89 |
90 | public static string ApplicationPathExe;
91 | public static int NumWorkerThreads;
92 |
93 | public static bool bShouldStopWorkerJobs = false; // cancel all worker jobs in progress
94 |
95 | public static bool bPleaseWaitDialogCancelled;
96 |
97 | // initialized by main (user) Form thread...
98 | public static IntPtr MainFormHandle;
99 | public static bool bRecursive = false; // should the GetFiles search be recursive?
100 | public static string SearchDirectory = "";
101 | public static string SearchString = "";
102 | public static List FileSpecs;
103 | public static bool bRegEx = false; // should the text search use regular expressions?
104 | public static bool bCaseSensitive = false; // should the text search be case sensitive?
105 |
106 | static Globals()
107 | {
108 | // do nothing
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/GetFiles.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | using System.Runtime.InteropServices;
6 | using System.Threading;
7 | using System.IO;
8 |
9 | namespace Grepy2
10 | {
11 | class GetFiles
12 | {
13 | [return: MarshalAs(UnmanagedType.Bool)]
14 | [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
15 | static extern bool PostMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
16 |
17 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
18 | public static extern IntPtr FindFirstFileW(string lpFileName, out WIN32_FIND_DATAW lpFindFileData);
19 |
20 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
21 | public static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATAW lpFindFileData);
22 |
23 | [DllImport("kernel32.dll")]
24 | public static extern bool FindClose(IntPtr hFindFile);
25 |
26 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
27 | public struct WIN32_FIND_DATAW {
28 | public FileAttributes dwFileAttributes;
29 | internal System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
30 | internal System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
31 | internal System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
32 | public int nFileSizeHigh;
33 | public int nFileSizeLow;
34 | public int dwReserved0;
35 | public int dwReserved1;
36 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
37 | public string cFileName;
38 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
39 | public string cAlternateFileName;
40 | }
41 |
42 | [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
43 | public static extern bool PathMatchSpecW(string pszFile, string pszSpec);
44 |
45 |
46 | private static HandleRef FormHandle;
47 |
48 | List filenames;
49 | HashSet folders;
50 |
51 | public GetFiles(IntPtr InHandle)
52 | {
53 | FormHandle = new HandleRef(this, InHandle);
54 |
55 | Globals.GetFiles.WaitHandle = new AutoResetEvent(false); // create a WaitHandle for syncronization
56 |
57 | Globals.GetFiles.bIsWorking = false;
58 | Globals.GetFiles.bShouldStopCurrentJob = false;
59 | Globals.GetFiles.bShouldExit = false;
60 | }
61 |
62 | public void Run()
63 | {
64 | while( !Globals.GetFiles.bShouldExit )
65 | {
66 | Globals.GetFiles.WaitHandle.WaitOne(); // wait for something to do
67 |
68 | Globals.GetFiles.bIsWorking = true;
69 |
70 | Globals.SearchDirectoryCount = 0;
71 |
72 | filenames = new List();
73 | folders = new HashSet();
74 |
75 | filenames = GetFilesForDirectory(Globals.SearchDirectory);
76 |
77 | if( !Globals.GetFiles.bShouldExit )
78 | {
79 | Globals.SearchFiles = new Globals.SearchFile[filenames.Count];
80 |
81 | for( int i = 0; (i < filenames.Count) && !Globals.GetFiles.bShouldStopCurrentJob; i++ )
82 | {
83 | Globals.SearchFile search_file = new Globals.SearchFile();
84 |
85 | search_file.Status = Globals.SearchFileStatus.NotProcessed;
86 | search_file.Filename = filenames[i];
87 | search_file.BaseFilename = Path.GetFileName(filenames[i]);
88 | search_file.FileTypeName = "";
89 | search_file.FolderName = Path.GetDirectoryName(filenames[i]);
90 | search_file.SearchMatchCount = 0;
91 | search_file.FileLength = 0;
92 | search_file.FileLastWriteTime = DateTime.MinValue;
93 | search_file.Lines = null;
94 | search_file.Matches = 0;
95 |
96 | Globals.SearchFiles[i] = search_file;
97 |
98 | if( !folders.Contains(search_file.FolderName) ) // keep track of the number of folders that will need to be searched
99 | {
100 | folders.Add(search_file.FolderName);
101 | }
102 | }
103 |
104 | Globals.SearchDirectoryCount = folders.Count;
105 |
106 | Globals.GetFiles.bIsWorking = false;
107 |
108 | PostMessage(FormHandle, Globals.WM_GETFILES_NOTIFY_MAIN_THREAD, IntPtr.Zero, IntPtr.Zero); // notify main Form thread that we are done (or were cancelled)
109 | }
110 | }
111 | }
112 |
113 | private List GetFilesForDirectory(string InDirectory)
114 | {
115 | List list = new List();
116 |
117 | IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
118 | WIN32_FIND_DATAW FindFileData;
119 |
120 | IntPtr hFind = FindFirstFileW(InDirectory + "\\*.*", out FindFileData);
121 | if (hFind != INVALID_HANDLE_VALUE)
122 | {
123 | do
124 | {
125 | if( Globals.GetFiles.bShouldStopCurrentJob || Globals.GetFiles.bShouldExit )
126 | {
127 | return list;
128 | }
129 |
130 | if (FindFileData.cFileName == "." || FindFileData.cFileName == "..")
131 | {
132 | continue;
133 | }
134 |
135 | if (Globals.bRecursive && ((FindFileData.dwFileAttributes & FileAttributes.Directory) != 0))
136 | {
137 | list.AddRange(GetFilesForDirectory(InDirectory + "\\" + FindFileData.cFileName));
138 |
139 | continue;
140 | }
141 |
142 | for( int index = 0; index < Globals.FileSpecs.Count; index++ )
143 | {
144 | if (PathMatchSpecW(FindFileData.cFileName, Globals.FileSpecs[index]))
145 | {
146 | list.Add(InDirectory + "\\" + FindFileData.cFileName);
147 | break;
148 | }
149 | }
150 | }
151 | while (FindNextFile(hFind, out FindFileData));
152 |
153 | FindClose(hFind);
154 |
155 | Thread.Sleep(0); // force context switch
156 | }
157 |
158 | return list;
159 | }
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/Grepy2.nsi:
--------------------------------------------------------------------------------
1 | ; Grepy2.nsi
2 | ;
3 | ; This script is based on example2.nsi, but it remembers the directory,
4 | ; has uninstall support and (optionally) installs start menu shortcuts.
5 | ;
6 | ;--------------------------------
7 |
8 | ; The name of the installer
9 | Name "Grepy2"
10 |
11 | !define VERSION '2.5.0'
12 |
13 | ; The file to write
14 | OutFile "Grepy2-${VERSION}.exe"
15 |
16 | ; The default installation directory
17 | InstallDir $PROGRAMFILES\Grepy2
18 |
19 | ; Registry key to check for directory (so if you install again, it will
20 | ; overwrite the old one automatically)
21 | InstallDirRegKey HKLM "Software\Grepy2" "Install_Dir"
22 |
23 | ; Request application privileges for Windows Vista
24 | RequestExecutionLevel admin
25 |
26 | ;--------------------------------
27 |
28 | ; Pages
29 |
30 | Page components
31 | Page directory
32 | Page instfiles
33 |
34 | UninstPage uninstConfirm
35 | UninstPage instfiles
36 |
37 | ;--------------------------------
38 |
39 | ; The stuff to install
40 | Section "Grepy2"
41 |
42 | SectionIn RO
43 |
44 | ; Set output path to the installation directory.
45 | SetOutPath $INSTDIR
46 |
47 | ; Put file there
48 | File "bin\x86\Release\Grepy2.exe"
49 | File "Grepy2Help\Grepy2Help.chm"
50 |
51 | ; Write the installation path into the registry
52 | WriteRegStr HKLM SOFTWARE\Grepy2 "Install_Dir" "$INSTDIR"
53 |
54 | ; Write the uninstall keys for Windows
55 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Grepy2" "DisplayName" "Grepy2"
56 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Grepy2" "DisplayIcon" "$INSTDIR\Grepy2.exe,0"
57 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Grepy2" "DisplayVersion" "${VERSION}"
58 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Grepy2" "HelpLink" '"$INSTDIR\Grepy2Help.chm"'
59 | WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Grepy2" "EstimatedSize" 800
60 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Grepy2" "UninstallString" '"$INSTDIR\uninstall.exe"'
61 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Grepy2" "Publisher" "Jeffrey Broome"
62 | WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Grepy2" "NoModify" 1
63 | WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Grepy2" "NoRepair" 1
64 | WriteUninstaller "uninstall.exe"
65 |
66 | SectionEnd
67 |
68 | ; Optional section (can be disabled by the user)
69 | Section "Start Menu Shortcuts"
70 |
71 | CreateDirectory "$SMPROGRAMS\Grepy2"
72 | CreateShortCut "$SMPROGRAMS\Grepy2\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
73 | CreateShortCut "$SMPROGRAMS\Grepy2\Grepy2.lnk" "$INSTDIR\Grepy2.exe" "" "$INSTDIR\Grepy2.exe" 0
74 | CreateShortCut "$SMPROGRAMS\Grepy2\Grepy2 Help.lnk" "$INSTDIR\Grepy2Help.chm" "" "$INSTDIR\Grepy2Help.chm" 0
75 |
76 | SectionEnd
77 |
78 | ; Optional section (can be disabled by the user)
79 | Section "Desktop Shortcut"
80 |
81 | CreateShortCut "$DESKTOP\Grepy2.lnk" "$INSTDIR\Grepy2.exe"
82 |
83 | SectionEnd
84 |
85 | ; Optional section (can be disabled by the user)
86 | Section "Enable Windows File Explorer Integration"
87 |
88 | ; Write the installation path into the registry
89 | WriteRegStr HKCR Drive\shell\Grepy2 "" "Grepy2..."
90 | WriteRegStr HKCR Drive\shell\Grepy2 "Icon" '"$INSTDIR\Grepy2.exe"'
91 | WriteRegStr HKCR Drive\shell\Grepy2\command "" '"$INSTDIR\Grepy2.exe" "%1"'
92 | WriteRegStr HKCR Directory\shell\Grepy2 "" "Grepy2..."
93 | WriteRegStr HKCR Directory\shell\Grepy2 "Icon" '"$INSTDIR\Grepy2.exe"'
94 | WriteRegStr HKCR Directory\shell\Grepy2\command "" '"$INSTDIR\Grepy2.exe" "%1"'
95 |
96 | WriteRegStr HKLM SOFTWARE\Classes\Directory\Background\shell\Grepy2 "" "Grepy2..."
97 | WriteRegStr HKLM SOFTWARE\Classes\Directory\Background\shell\Grepy2 "Icon" '"$INSTDIR\Grepy2.exe"'
98 | WriteRegStr HKLM SOFTWARE\Classes\Directory\Background\shell\Grepy2\command "" '"$INSTDIR\Grepy2.exe" "%V"'
99 |
100 | System::Call 'Shell32::SHChangeNotify(i 0x8000000, i 0, i 0, i 0)'
101 |
102 | SectionEnd
103 |
104 |
105 | ;--------------------------------
106 |
107 | ; Uninstaller
108 |
109 | Section "Uninstall"
110 |
111 | ; Remove registry keys
112 | DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Grepy2"
113 | DeleteRegKey HKLM SOFTWARE\Grepy2
114 |
115 | DeleteRegKey HKCR Drive\shell\Grepy2\command
116 | DeleteRegKey HKCR Drive\shell\Grepy2
117 | DeleteRegKey HKCR Directory\shell\Grepy2\command
118 | DeleteRegKey HKCR Directory\shell\Grepy2
119 | DeleteRegKey HKCR *\shell\Grepy2\command
120 | DeleteRegKey HKCR *\shell\Grepy2
121 |
122 | DeleteRegKey HKLM SOFTWARE\Classes\Directory\Background\shell\Grepy2\command
123 | DeleteRegKey HKLM SOFTWARE\Classes\Directory\Background\shell\Grepy2
124 |
125 | System::Call 'Shell32::SHChangeNotify(i 0x8000000, i 0, i 0, i 0)'
126 |
127 | ; Remove shortcuts, if any
128 | Delete $DESKTOP\Grepy2.lnk
129 | Delete "$SMPROGRAMS\Grepy2\*.*"
130 |
131 | ; Remove files and uninstaller
132 | Delete $INSTDIR\Grepy2.exe
133 | Delete $INSTDIR\Grepy2Help.chm
134 | Delete $INSTDIR\uninstall.exe
135 |
136 | IfFileExists $APPDATA\Grepy2\Grepy2.ini Remove_Ini Uninstall_Continue
137 | Remove_Ini:
138 | MessageBox MB_YESNO "Do you wish to remove the Grepy2.ini file?" IDNO Uninstall_Continue
139 | Delete "$APPDATA\Grepy2\Grepy2.ini"
140 | RMDir "$APPDATA\Grepy2"
141 | Uninstall_Continue:
142 |
143 | ; Remove directories used
144 | RMDir "$SMPROGRAMS\Grepy2"
145 | RMDir "$INSTDIR"
146 |
147 | SectionEnd
148 |
--------------------------------------------------------------------------------
/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/FontPicker.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/OptionsForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/PleaseWait.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/SearchForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/CollectingFiles.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/NoMatchesFound.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/SearchHelpForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Regular Expression - Enables searching using Regular Expressions.
122 | Match Case - Uses a case sensitive search.
123 | Recursive Folder Search - Searches the provided folder and all sub-folders within that folder.
124 |
125 | Regular Expression Examples:
126 | . - period, wildcard, matches any single character one time (to match a period character use \.)
127 | * - asterisk, matches the previous element zero or more times (.* matches any string of characters)
128 | + - plus sign, matches the previous element one or more times
129 | ? - question mark, matches the previous element zero or one time
130 | ^ - caret, matches the beginning of a line
131 | $ - dollar sign, matches the end of a line
132 | [abc] - matches any single character in the group (i.e. a, b, or c, case sensitive)
133 | [^abc] - matches any single character that is not in the group (i.e. not a, or b, or c, case sensitive)
134 | [a-e] - matches a range of characters (i.e. a, b, c, d, or e, case sensitive)
135 | \t - matches tab character
136 | \s - matches any whitespace character (space or tab)
137 | \S - matches any non-whitespace character (not space or tab)
138 | \d - matches any decimal digit (i.e. 0 through 9)
139 | \D - matches any character other than a decimal digit
140 | {n} - matches the previous element exactly n times (i.e. \d{3}, matches 3 digits in a row)
141 | (abc) - grouped expression (matches "abc", case sensitive)
142 | | - matches any one element of the group (i.e. (ab|bbb|c) matches "ab", "bbb" or "c")
143 | \ - escape, matches the character following the escape as long as it's not a regex expression
144 | (i.e. "\\" matches backslash)
145 |
146 | For more details see: http://msdn.microsoft.com/en-us/library/az24scfc.aspx
147 |
148 |
--------------------------------------------------------------------------------
/ExplorerIntegration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using System.Runtime.InteropServices;
4 | using System.Security.Principal;
5 | using System.Windows.Forms;
6 | using Microsoft.Win32;
7 |
8 | namespace Grepy2
9 | {
10 | public class ExplorerIntegration
11 | {
12 | ///
13 | /// Passed to to specify what
14 | /// information about the token to return.
15 | ///
16 | enum TokenInformationClass
17 | {
18 | TokenUser = 1,
19 | TokenGroups,
20 | TokenPrivileges,
21 | TokenOwner,
22 | TokenPrimaryGroup,
23 | TokenDefaultDacl,
24 | TokenSource,
25 | TokenType,
26 | TokenImpersonationLevel,
27 | TokenStatistics,
28 | TokenRestrictedSids,
29 | TokenSessionId,
30 | TokenGroupsAndPrivileges,
31 | TokenSessionReference,
32 | TokenSandBoxInert,
33 | TokenAuditPolicy,
34 | TokenOrigin,
35 | TokenElevationType,
36 | TokenLinkedToken,
37 | TokenElevation,
38 | TokenHasRestrictions,
39 | TokenAccessInformation,
40 | TokenVirtualizationAllowed,
41 | TokenVirtualizationEnabled,
42 | TokenIntegrityLevel,
43 | TokenUiAccess,
44 | TokenMandatoryPolicy,
45 | TokenLogonSid,
46 | MaxTokenInfoClass
47 | }
48 |
49 | ///
50 | /// The elevation type for a user token.
51 | ///
52 | enum TokenElevationType
53 | {
54 | TokenElevationTypeDefault = 1,
55 | TokenElevationTypeFull,
56 | TokenElevationTypeLimited
57 | }
58 |
59 | [DllImport("advapi32.dll", SetLastError = true)]
60 | static extern bool GetTokenInformation(IntPtr tokenHandle, TokenInformationClass tokenInformationClass, IntPtr tokenInformation, int tokenInformationLength, out int returnLength);
61 |
62 | bool bIsAdministrator;
63 |
64 | private bool IsUserAdministrator()
65 | {
66 | // http://www.davidmoore.info/blog/2011/06/20/how-to-check-if-the-current-user-is-an-administrator-even-if-uac-is-on/
67 |
68 | var identity = WindowsIdentity.GetCurrent();
69 |
70 | if (identity == null)
71 | {
72 | throw new InvalidOperationException("Couldn't get the current user identity");
73 | }
74 |
75 | var principal = new WindowsPrincipal(identity);
76 |
77 | // Check if this user has the Administrator role. If they do, return immediately.
78 | // If UAC is on, and the process is not elevated, then this will actually return false.
79 | if (principal.IsInRole(WindowsBuiltInRole.Administrator))
80 | {
81 | return true;
82 | }
83 |
84 | // If we're not running in Vista onwards, we don't have to worry about checking for UAC.
85 | if (Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6)
86 | {
87 | // Operating system does not support UAC; skipping elevation check.
88 | return false;
89 | }
90 |
91 | int tokenInfLength = Marshal.SizeOf(typeof(int));
92 | IntPtr tokenInformation = Marshal.AllocHGlobal(tokenInfLength);
93 |
94 | try
95 | {
96 | var token = identity.Token;
97 | var result = GetTokenInformation(token, TokenInformationClass.TokenElevationType, tokenInformation, tokenInfLength, out tokenInfLength);
98 |
99 | if (!result)
100 | {
101 | var exception = Marshal.GetExceptionForHR( Marshal.GetHRForLastWin32Error() );
102 | throw new InvalidOperationException("Couldn't get token information", exception);
103 | }
104 |
105 | var elevationType = (TokenElevationType)Marshal.ReadInt32(tokenInformation);
106 |
107 | switch (elevationType)
108 | {
109 | case TokenElevationType.TokenElevationTypeDefault:
110 | // TokenElevationTypeDefault - User is not using a split token, so they cannot elevate.
111 | return false;
112 |
113 | case TokenElevationType.TokenElevationTypeFull:
114 | // TokenElevationTypeFull - User has a split token, and the process is running elevated. Assuming they're an administrator.
115 | return true;
116 |
117 | case TokenElevationType.TokenElevationTypeLimited:
118 | // TokenElevationTypeLimited - User has a split token, but the process is not running elevated. Assuming they're an administrator.
119 | return true;
120 |
121 | default:
122 | // Unknown token elevation type.
123 | return false;
124 | }
125 | }
126 | finally
127 | {
128 | if (tokenInformation != IntPtr.Zero) Marshal.FreeHGlobal(tokenInformation);
129 | }
130 | }
131 |
132 | public bool IsEnabled(string where)
133 | {
134 | if( where == "here" )
135 | {
136 | string regPath = string.Format(@"SOFTWARE\Classes\Directory\Background\shell\Grepy2");
137 | try
138 | {
139 | return Registry.LocalMachine.OpenSubKey(regPath) != null;
140 | }
141 | catch( UnauthorizedAccessException )
142 | {
143 | return false;
144 | }
145 | }
146 | else
147 | {
148 | string regPath = string.Format(@"{0}\shell\Grepy2", where);
149 | try
150 | {
151 | return Registry.ClassesRoot.OpenSubKey(regPath) != null;
152 | }
153 | catch( UnauthorizedAccessException )
154 | {
155 | return false;
156 | }
157 | }
158 | }
159 |
160 | public void Enable(string where, string ApplicationExePath)
161 | {
162 | try
163 | {
164 | if( where == "here" )
165 | {
166 | string regPath = string.Format(@"SOFTWARE\Classes\Directory\Background\shell\Grepy2");
167 |
168 | RegistryKey keyName = Registry.LocalMachine.CreateSubKey(regPath);
169 | keyName.SetValue(null, "Grepy2...");
170 | RegistryKey keyIcon = Registry.LocalMachine.CreateSubKey(string.Format(@"{0}", regPath));
171 | keyIcon.SetValue("Icon", ApplicationExePath);
172 |
173 | string command = string.Format("\"{0}\" \"%V\"", ApplicationExePath);
174 |
175 | RegistryKey keyCommand = Registry.LocalMachine.CreateSubKey(string.Format(@"{0}\command", regPath));
176 | keyCommand.SetValue(null, command);
177 | }
178 | else
179 | {
180 | string regPath = string.Format(@"{0}\shell\Grepy2", where);
181 |
182 | RegistryKey keyName = Registry.ClassesRoot.CreateSubKey(regPath);
183 | keyName.SetValue(null, "Grepy2...");
184 |
185 | RegistryKey keyIcon = Registry.ClassesRoot.CreateSubKey(string.Format(@"{0}", regPath));
186 | keyIcon.SetValue("Icon", ApplicationExePath);
187 |
188 | string command = string.Format("\"{0}\" \"%1\"", ApplicationExePath);
189 |
190 | RegistryKey keyCommand = Registry.ClassesRoot.CreateSubKey(string.Format(@"{0}\command", regPath));
191 | keyCommand.SetValue(null, command);
192 | }
193 | }
194 | catch
195 | {
196 | bIsAdministrator = false;
197 | }
198 | }
199 |
200 | public void Disable(string where, string ApplicationExePath)
201 | {
202 | try
203 | {
204 | if( where == "here" )
205 | {
206 | string regPath = string.Format(@"SOFTWARE\Classes\Directory\Background\shell\Grepy2");
207 | Registry.LocalMachine.DeleteSubKeyTree(regPath);
208 | }
209 | else
210 | {
211 | string regPath = string.Format(@"{0}\shell\Grepy2", where);
212 | Registry.ClassesRoot.DeleteSubKeyTree(regPath);
213 | }
214 | }
215 | catch
216 | {
217 | bIsAdministrator = false;
218 | }
219 | }
220 |
221 | public void Set(string PathExe, bool bEnable)
222 | {
223 | bIsAdministrator = IsUserAdministrator();
224 |
225 | if( bIsAdministrator )
226 | {
227 | if( bEnable )
228 | {
229 | Enable("Drive", PathExe); // right clicking on a Disk (drive, like C:)
230 | Enable("Directory", PathExe); // right clicking on a folder (this can be a folder in the navigation pane on the left or in the file pane on the right)
231 | Enable("here", PathExe); // right clicking on the empty part of a folder in the file pane (i.e. use the folder I am clicking inside of)
232 | }
233 | else
234 | {
235 | Disable("Drive", PathExe);
236 | Disable("Directory", PathExe);
237 | Disable("here", PathExe); // right clicking on the empty part of a folder
238 | }
239 | }
240 |
241 | if( !bIsAdministrator )
242 | {
243 | MessageBox.Show("You need to run this program with Administrator Privileges to change Windows Explorer Integration.\n\n(Right click on the Grepy icon in the Start menu or on the desktop shortcut and select \"Run as administrator\" or \"More -> Run as administrator\".)",
244 | "Warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
245 | }
246 | }
247 | }
248 | }
249 |
--------------------------------------------------------------------------------
/Grepy2.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {FCCC6E67-BE44-4866-ABEF-5BFC0BC58852}
8 | WinExe
9 | Properties
10 | Grepy2
11 | Grepy2
12 | v4.5.2
13 | 512
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 | Grepy2.ico
37 |
38 |
39 | true
40 | bin\x86\Debug\
41 | DEBUG;TRACE
42 | full
43 | x86
44 | prompt
45 | MinimumRecommendedRules.ruleset
46 | true
47 |
48 |
49 | bin\x86\Release\
50 | TRACE
51 | true
52 | pdbonly
53 | x86
54 | prompt
55 | MinimumRecommendedRules.ruleset
56 | true
57 |
58 |
59 | app.manifest
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | Component
77 |
78 |
79 | BetterRichTextBox.cs
80 |
81 |
82 | Form
83 |
84 |
85 | CollectingFiles.cs
86 |
87 |
88 |
89 |
90 |
91 | Form
92 |
93 |
94 | FontPicker.cs
95 |
96 |
97 |
98 |
99 |
100 | Form
101 |
102 |
103 | MainForm.cs
104 |
105 |
106 | Form
107 |
108 |
109 | NoMatchesFound.cs
110 |
111 |
112 | Form
113 |
114 |
115 | OptionsForm.cs
116 |
117 |
118 | Form
119 |
120 |
121 | PleaseWait.cs
122 |
123 |
124 |
125 |
126 | Form
127 |
128 |
129 | SearchForm.cs
130 |
131 |
132 | Form
133 |
134 |
135 | SearchHelpForm.cs
136 |
137 |
138 |
139 | CollectingFiles.cs
140 |
141 |
142 | FontPicker.cs
143 |
144 |
145 | MainForm.cs
146 |
147 |
148 | NoMatchesFound.cs
149 |
150 |
151 | OptionsForm.cs
152 |
153 |
154 | PleaseWait.cs
155 |
156 |
157 | ResXFileCodeGenerator
158 | Resources.Designer.cs
159 | Designer
160 |
161 |
162 | True
163 | Resources.resx
164 |
165 |
166 | SearchForm.cs
167 |
168 |
169 | SearchHelpForm.cs
170 |
171 |
172 |
173 | SettingsSingleFileGenerator
174 | Settings.Designer.cs
175 |
176 |
177 | True
178 | Settings.settings
179 | True
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
196 |
--------------------------------------------------------------------------------
/SearchForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Grepy2
2 | {
3 | partial class SearchForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.RegExCheckBox = new System.Windows.Forms.CheckBox();
32 | this.MatchCaseCheckBox = new System.Windows.Forms.CheckBox();
33 | this.RecurseFolderCheckBox = new System.Windows.Forms.CheckBox();
34 | this.label1 = new System.Windows.Forms.Label();
35 | this.SearchForComboBox = new System.Windows.Forms.ComboBox();
36 | this.label2 = new System.Windows.Forms.Label();
37 | this.FileSpecComboBox = new System.Windows.Forms.ComboBox();
38 | this.label3 = new System.Windows.Forms.Label();
39 | this.FolderComboBox = new System.Windows.Forms.ComboBox();
40 | this.FoldersButton = new System.Windows.Forms.Button();
41 | this.SearchOkButton = new System.Windows.Forms.Button();
42 | this.SearchHelpButton = new System.Windows.Forms.Button();
43 | this.SearchCancelButton = new System.Windows.Forms.Button();
44 | this.SuspendLayout();
45 | //
46 | // RegExCheckBox
47 | //
48 | this.RegExCheckBox.AutoSize = true;
49 | this.RegExCheckBox.Location = new System.Drawing.Point(36, 21);
50 | this.RegExCheckBox.Name = "RegExCheckBox";
51 | this.RegExCheckBox.Size = new System.Drawing.Size(117, 17);
52 | this.RegExCheckBox.TabIndex = 1;
53 | this.RegExCheckBox.Text = "Regular Expression";
54 | this.RegExCheckBox.UseVisualStyleBackColor = true;
55 | //
56 | // MatchCaseCheckBox
57 | //
58 | this.MatchCaseCheckBox.AutoSize = true;
59 | this.MatchCaseCheckBox.Location = new System.Drawing.Point(217, 21);
60 | this.MatchCaseCheckBox.Name = "MatchCaseCheckBox";
61 | this.MatchCaseCheckBox.Size = new System.Drawing.Size(83, 17);
62 | this.MatchCaseCheckBox.TabIndex = 2;
63 | this.MatchCaseCheckBox.Text = "Match Case";
64 | this.MatchCaseCheckBox.UseVisualStyleBackColor = true;
65 | //
66 | // RecurseFolderCheckBox
67 | //
68 | this.RecurseFolderCheckBox.AutoSize = true;
69 | this.RecurseFolderCheckBox.Checked = true;
70 | this.RecurseFolderCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
71 | this.RecurseFolderCheckBox.Location = new System.Drawing.Point(364, 21);
72 | this.RecurseFolderCheckBox.Name = "RecurseFolderCheckBox";
73 | this.RecurseFolderCheckBox.Size = new System.Drawing.Size(143, 17);
74 | this.RecurseFolderCheckBox.TabIndex = 3;
75 | this.RecurseFolderCheckBox.Text = "Recursive Folder Search";
76 | this.RecurseFolderCheckBox.UseVisualStyleBackColor = true;
77 | //
78 | // label1
79 | //
80 | this.label1.AutoSize = true;
81 | this.label1.Location = new System.Drawing.Point(33, 55);
82 | this.label1.Name = "label1";
83 | this.label1.Size = new System.Drawing.Size(62, 13);
84 | this.label1.TabIndex = 0;
85 | this.label1.Text = "Search For:";
86 | //
87 | // SearchForComboBox
88 | //
89 | this.SearchForComboBox.FormattingEnabled = true;
90 | this.SearchForComboBox.Location = new System.Drawing.Point(36, 71);
91 | this.SearchForComboBox.MaxDropDownItems = 10;
92 | this.SearchForComboBox.Name = "SearchForComboBox";
93 | this.SearchForComboBox.Size = new System.Drawing.Size(471, 21);
94 | this.SearchForComboBox.TabIndex = 4;
95 | this.SearchForComboBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.SearchForComboBox_KeyDown);
96 | //
97 | // label2
98 | //
99 | this.label2.AutoSize = true;
100 | this.label2.Location = new System.Drawing.Point(33, 109);
101 | this.label2.Name = "label2";
102 | this.label2.Size = new System.Drawing.Size(218, 13);
103 | this.label2.TabIndex = 0;
104 | this.label2.Text = "File Specification(s) (use space for separator)";
105 | //
106 | // FileSpecComboBox
107 | //
108 | this.FileSpecComboBox.FormattingEnabled = true;
109 | this.FileSpecComboBox.Location = new System.Drawing.Point(36, 125);
110 | this.FileSpecComboBox.Name = "FileSpecComboBox";
111 | this.FileSpecComboBox.Size = new System.Drawing.Size(471, 21);
112 | this.FileSpecComboBox.TabIndex = 5;
113 | this.FileSpecComboBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.FileSpecComboBox_KeyDown);
114 | //
115 | // label3
116 | //
117 | this.label3.AutoSize = true;
118 | this.label3.Location = new System.Drawing.Point(33, 163);
119 | this.label3.Name = "label3";
120 | this.label3.Size = new System.Drawing.Size(92, 13);
121 | this.label3.TabIndex = 0;
122 | this.label3.Text = "Folder To Search:";
123 | //
124 | // FolderComboBox
125 | //
126 | this.FolderComboBox.FormattingEnabled = true;
127 | this.FolderComboBox.Location = new System.Drawing.Point(36, 179);
128 | this.FolderComboBox.Name = "FolderComboBox";
129 | this.FolderComboBox.Size = new System.Drawing.Size(441, 21);
130 | this.FolderComboBox.TabIndex = 6;
131 | this.FolderComboBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.FolderComboBox_KeyDown);
132 | //
133 | // FoldersButton
134 | //
135 | this.FoldersButton.Location = new System.Drawing.Point(478, 179);
136 | this.FoldersButton.Name = "FoldersButton";
137 | this.FoldersButton.Size = new System.Drawing.Size(30, 21);
138 | this.FoldersButton.TabIndex = 7;
139 | this.FoldersButton.Text = "...";
140 | this.FoldersButton.UseVisualStyleBackColor = true;
141 | this.FoldersButton.Click += new System.EventHandler(this.FoldersButton_Click);
142 | //
143 | // SearchOkButton
144 | //
145 | this.SearchOkButton.Location = new System.Drawing.Point(120, 233);
146 | this.SearchOkButton.Name = "SearchOkButton";
147 | this.SearchOkButton.Size = new System.Drawing.Size(71, 25);
148 | this.SearchOkButton.TabIndex = 8;
149 | this.SearchOkButton.Text = "OK";
150 | this.SearchOkButton.UseVisualStyleBackColor = true;
151 | this.SearchOkButton.Click += new System.EventHandler(this.SearchOkButton_Click);
152 | //
153 | // SearchHelpButton
154 | //
155 | this.SearchHelpButton.Location = new System.Drawing.Point(235, 233);
156 | this.SearchHelpButton.Name = "SearchHelpButton";
157 | this.SearchHelpButton.Size = new System.Drawing.Size(71, 25);
158 | this.SearchHelpButton.TabIndex = 9;
159 | this.SearchHelpButton.Text = "Help";
160 | this.SearchHelpButton.UseVisualStyleBackColor = true;
161 | this.SearchHelpButton.Click += new System.EventHandler(this.SearchHelpButton_Click);
162 | //
163 | // SearchCancelButton
164 | //
165 | this.SearchCancelButton.Location = new System.Drawing.Point(357, 233);
166 | this.SearchCancelButton.Name = "SearchCancelButton";
167 | this.SearchCancelButton.Size = new System.Drawing.Size(71, 25);
168 | this.SearchCancelButton.TabIndex = 10;
169 | this.SearchCancelButton.Text = "Cancel";
170 | this.SearchCancelButton.UseVisualStyleBackColor = true;
171 | this.SearchCancelButton.Click += new System.EventHandler(this.SearchCancelButton_Click);
172 | //
173 | // SearchForm
174 | //
175 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
176 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
177 | this.ClientSize = new System.Drawing.Size(545, 280);
178 | this.Controls.Add(this.SearchCancelButton);
179 | this.Controls.Add(this.SearchHelpButton);
180 | this.Controls.Add(this.SearchOkButton);
181 | this.Controls.Add(this.FoldersButton);
182 | this.Controls.Add(this.FolderComboBox);
183 | this.Controls.Add(this.label3);
184 | this.Controls.Add(this.FileSpecComboBox);
185 | this.Controls.Add(this.label2);
186 | this.Controls.Add(this.SearchForComboBox);
187 | this.Controls.Add(this.label1);
188 | this.Controls.Add(this.RecurseFolderCheckBox);
189 | this.Controls.Add(this.MatchCaseCheckBox);
190 | this.Controls.Add(this.RegExCheckBox);
191 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
192 | this.MaximizeBox = false;
193 | this.MinimizeBox = false;
194 | this.Name = "SearchForm";
195 | this.ShowIcon = false;
196 | this.Text = "Search";
197 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SearchForm_Closing);
198 | this.Load += new System.EventHandler(this.SearchForm_Load);
199 | this.Shown += new System.EventHandler(this.SearchForm_Shown);
200 | this.Move += new System.EventHandler(this.SearchForm_Move);
201 | this.ResumeLayout(false);
202 | this.PerformLayout();
203 |
204 | }
205 |
206 | #endregion
207 |
208 | private System.Windows.Forms.CheckBox RegExCheckBox;
209 | private System.Windows.Forms.CheckBox MatchCaseCheckBox;
210 | private System.Windows.Forms.CheckBox RecurseFolderCheckBox;
211 | private System.Windows.Forms.Label label1;
212 | private System.Windows.Forms.ComboBox SearchForComboBox;
213 | private System.Windows.Forms.Label label2;
214 | private System.Windows.Forms.ComboBox FileSpecComboBox;
215 | private System.Windows.Forms.Label label3;
216 | private System.Windows.Forms.ComboBox FolderComboBox;
217 | private System.Windows.Forms.Button FoldersButton;
218 | private System.Windows.Forms.Button SearchOkButton;
219 | private System.Windows.Forms.Button SearchHelpButton;
220 | private System.Windows.Forms.Button SearchCancelButton;
221 | }
222 | }
--------------------------------------------------------------------------------
/FontPicker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using System.Runtime.InteropServices;
11 |
12 | namespace Grepy2
13 | {
14 | public partial class FontPicker : Form
15 | {
16 | // NOTE: see http://sourceforge.net/projects/customfontdialog/
17 |
18 | [DllImport("user32.dll")]
19 | private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam, uint lParam);
20 |
21 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] // JLB
22 | class LOGFONT {
23 | public int lfHeight;
24 | public int lfWidth;
25 | public int lfEscapement;
26 | public int lfOrientation;
27 | public int lfWeight;
28 | public byte lfItalic;
29 | public byte lfUnderline;
30 | public byte lfStrikeOut;
31 | public byte lfCharSet;
32 | public byte lfOutPrecision;
33 | public byte lfClipPrecision;
34 | public byte lfQuality;
35 | public byte lfPitchAndFamily;
36 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
37 | public string lfFaceName;
38 | }
39 |
40 | private bool bFontPickerFormInitComplete;
41 | private bool bFixedWidthOnly;
42 | public Font SelectedFont;
43 |
44 | public FontPicker(Font InFont)
45 | {
46 | bFontPickerFormInitComplete = false;
47 |
48 | InitializeComponent();
49 |
50 | int pos_x = -1;
51 | int pos_y = -1;
52 | if( Config.Get(Config.KEY.FontPickerPosX, ref pos_x) && Config.Get(Config.KEY.FontPickerPosY, ref pos_y) )
53 | {
54 | this.StartPosition = FormStartPosition.Manual;
55 | this.Location = new Point(pos_x, pos_y);
56 | }
57 | else // otherwise, center the window on the main form
58 | {
59 | this.StartPosition = FormStartPosition.CenterParent;
60 | }
61 |
62 | bFixedWidthOnly = false;
63 | SelectedFont = null;
64 |
65 | using (Bitmap bmp = new Bitmap(1, 1))
66 | {
67 | using (Graphics g = Graphics.FromImage(bmp))
68 | {
69 | if( IsMonospaced(g, InFont) )
70 | {
71 | FixedWidthFontCheckBox.Checked = true; // this will cause InitializeFontList() to get called
72 | }
73 | }
74 | }
75 |
76 | if( !bFixedWidthOnly ) // if this is still false, we need to initialize the font list
77 | {
78 | InitializeFontList();
79 | }
80 |
81 | BoldCheckBox.Checked = InFont.Bold;
82 | ItalicCheckBox.Checked = InFont.Italic;
83 |
84 | SizeTextBox.Text = Convert.ToString(InFont.Size); // size must be set before selecting the font name
85 | if( SelectFontByName(InFont.Name) )
86 | {
87 | SelectedFont = InFont;
88 | }
89 |
90 | richTextBox1.Clear();
91 | richTextBox1.Font = InFont;
92 | richTextBox1.AppendText("The Quick Brown Fox Jumped Over The Lazy Dog's Back.");
93 | }
94 |
95 | private void FontPicker_Load(object sender, EventArgs e)
96 | {
97 | bFontPickerFormInitComplete = true; // window initialization is complete, okay to write config settings now
98 | }
99 |
100 | private void FontPicker_Move(object sender, EventArgs e)
101 | {
102 | if( bFontPickerFormInitComplete )
103 | {
104 | Config.Set(Config.KEY.FontPickerPosX, Location.X);
105 | Config.Set(Config.KEY.FontPickerPosY, Location.Y);
106 | }
107 | }
108 |
109 | private void OkButton_Click(object sender, EventArgs e)
110 | {
111 | if( SelectedFont != null )
112 | {
113 | this.DialogResult = DialogResult.OK;
114 | Close();
115 | }
116 | else
117 | {
118 | MessageBox.Show("'You haven't selected a Font", "Invalid Font");
119 | }
120 | }
121 |
122 | private void CancelButton_Click(object sender, EventArgs e)
123 | {
124 | this.SelectedFont = null;
125 | this.DialogResult = DialogResult.Cancel;
126 | Close();
127 | }
128 |
129 | static bool IsMonospaced(Graphics g, Font f)
130 | {
131 | float w1, w2;
132 |
133 | w1 = g.MeasureString("i", f).Width;
134 | w2 = g.MeasureString("W", f).Width;
135 | return w1 == w2;
136 | }
137 |
138 | static bool IsSymbolFont(Font font)
139 | {
140 | const byte SYMBOL_FONT = 2;
141 |
142 | LOGFONT logicalFont = new LOGFONT();
143 | font.ToLogFont(logicalFont);
144 | return logicalFont.lfCharSet == SYMBOL_FONT;
145 | }
146 |
147 | public void InitializeFontList()
148 | {
149 | SelectedFont = null;
150 | FontTextBox.Text = "";
151 |
152 | FontListBox.Items.Clear();
153 |
154 | using (Bitmap bmp = new Bitmap(1, 1))
155 | {
156 | using (Graphics g = Graphics.FromImage(bmp))
157 | {
158 | foreach (FontFamily f in FontFamily.Families)
159 | {
160 | try
161 | {
162 | if( (f.Name != null) || (f.Name != "") )
163 | {
164 | Font newfont = new Font(f, 10);
165 |
166 | if( !IsSymbolFont(newfont) )
167 | {
168 | if( !bFixedWidthOnly || IsMonospaced(g, newfont) )
169 | {
170 | FontListBox.Items.Add(newfont);
171 | }
172 | }
173 | }
174 | }
175 | catch {}
176 | }
177 | }
178 | }
179 | }
180 |
181 | private void ItalicCheckBox_CheckedChanged(object sender, EventArgs e)
182 | {
183 | UpdateSampleText();
184 | }
185 |
186 | private void BoldBox_CheckedChanged(object sender, EventArgs e)
187 | {
188 | UpdateSampleText();
189 | }
190 |
191 | private void FontList_DrawItem(object sender, DrawItemEventArgs e)
192 | {
193 | // Draw the background of the ListBox control for each item.
194 | e.DrawBackground();
195 |
196 | Font font = (Font)FontListBox.Items[e.Index];
197 | e.Graphics.DrawString(font.Name, font, Brushes.Black, e.Bounds, StringFormat.GenericDefault);
198 |
199 | // If the ListBox has focus, draw a focus rectangle around the selected item.
200 | e.DrawFocusRectangle();
201 |
202 | }
203 |
204 | private void FontListIndedChanged(object sender, EventArgs e)
205 | {
206 | if(FontListBox.SelectedItem != null)
207 | {
208 | if( !FontTextBox.Focused )
209 | {
210 | Font f = (Font)FontListBox.SelectedItem;
211 | FontTextBox.Text = f.Name;
212 | }
213 |
214 | UpdateSampleText();
215 | }
216 | }
217 |
218 | private void FixedWidthFontCheckBox_CheckedChanged(object sender, EventArgs e)
219 | {
220 | bFixedWidthOnly = FixedWidthFontCheckBox.Checked;
221 |
222 | InitializeFontList();
223 | }
224 |
225 | private void FontMouseClick(object sender, MouseEventArgs e)
226 | {
227 | FontTextBox.SelectAll();
228 | }
229 |
230 | private bool SelectFontByName(string InName)
231 | {
232 | for( int i = 0; i < FontListBox.Items.Count; i++ )
233 | {
234 | string str = ((Font)FontListBox.Items[i]).Name;
235 | if( String.Equals(str, InName, StringComparison.OrdinalIgnoreCase) )
236 | {
237 | FontListBox.SelectedIndex = i;
238 |
239 | const uint WM_VSCROLL = 0x0115;
240 | const uint SB_THUMBPOSITION = 4;
241 |
242 | uint b = ((uint)(FontListBox.SelectedIndex) << 16) | (SB_THUMBPOSITION & 0xffff);
243 | SendMessage(FontListBox.Handle, WM_VSCROLL, b, 0);
244 |
245 | return true;
246 | }
247 | }
248 |
249 | return false;
250 | }
251 |
252 | private void FontTextChanged(object sender, EventArgs e)
253 | {
254 | if( !FontTextBox.Focused )
255 | {
256 | return;
257 | }
258 |
259 | SelectFontByName(FontTextBox.Text);
260 | }
261 |
262 | private void SizeKeyDown(object sender, KeyEventArgs e)
263 | {
264 | switch (e.KeyData)
265 | {
266 | case Keys.D0:
267 | case Keys.D1:
268 | case Keys.D2:
269 | case Keys.D3:
270 | case Keys.D4:
271 | case Keys.D5:
272 | case Keys.D6:
273 | case Keys.D7:
274 | case Keys.D8:
275 | case Keys.D9:
276 | case Keys.End:
277 | case Keys.Enter:
278 | case Keys.Home:
279 | case Keys.Back:
280 | case Keys.Delete:
281 | case Keys.Escape:
282 | case Keys.Left:
283 | case Keys.Right:
284 | break;
285 |
286 | case Keys.Decimal:
287 | case (Keys)190: //decimal point
288 | if( SizeTextBox.Text.Contains(".") )
289 | {
290 | e.SuppressKeyPress = true;
291 | e.Handled = true;
292 | }
293 | break;
294 |
295 | default:
296 | e.SuppressKeyPress = true;
297 | e.Handled = true;
298 | break;
299 | }
300 | }
301 |
302 | private void SizeTextChanged(object sender, EventArgs e)
303 | {
304 | if( SizeListBox.Items.Contains(SizeTextBox.Text) )
305 | {
306 | SizeListBox.SelectedItem = SizeTextBox.Text;
307 | }
308 | else
309 | {
310 | SizeListBox.ClearSelected();
311 | }
312 |
313 | UpdateSampleText();
314 | }
315 |
316 | private void SizeSelectedIndexChanged(object sender, EventArgs e)
317 | {
318 | if(SizeListBox.SelectedItem != null)
319 | {
320 | SizeTextBox.Text = SizeListBox.SelectedItem.ToString();
321 | }
322 | }
323 |
324 | public int IndexOf(FontFamily ff)
325 | {
326 | for (int i = 1; i < FontListBox.Items.Count; i++)
327 | {
328 | Font f = (Font)FontListBox.Items[i];
329 |
330 | if( f.FontFamily.Name == ff.Name )
331 | {
332 | return i;
333 | }
334 | }
335 |
336 | return -1;
337 | }
338 |
339 | public FontFamily SelectedFontFamily
340 | {
341 | get
342 | {
343 | if( FontListBox.SelectedItem != null )
344 | {
345 | return ((Font)FontListBox.SelectedItem).FontFamily;
346 | }
347 |
348 | return null;
349 | }
350 | set
351 | {
352 | if( value == null )
353 | {
354 | FontListBox.ClearSelected();
355 | }
356 | else
357 | {
358 | FontListBox.SelectedIndex = IndexOf(value);
359 | }
360 |
361 | }
362 | }
363 |
364 | private void UpdateSampleText()
365 | {
366 | float size = SizeTextBox.Text != "" ? float.Parse(SizeTextBox.Text) : 1;
367 |
368 | FontStyle style = BoldCheckBox.Checked ? FontStyle.Bold : FontStyle.Regular;
369 |
370 | if( ItalicCheckBox.Checked )
371 | {
372 | style |= FontStyle.Italic;
373 | }
374 |
375 | richTextBox1.Clear();
376 |
377 | if( SelectedFontFamily != null)
378 | {
379 | SelectedFont = new Font(SelectedFontFamily, size, style);
380 |
381 | richTextBox1.Font = SelectedFont;
382 | richTextBox1.AppendText("The Quick Brown Fox Jumped Over The Lazy Dog's Back.");
383 | }
384 | }
385 | }
386 | }
387 |
--------------------------------------------------------------------------------
/Config.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using System.Timers;
6 | using System.IO;
7 | using System.Drawing;
8 |
9 | namespace Grepy2
10 | {
11 | static class Config
12 | {
13 | public enum KEY // everthing is 'int' unless otherwise noted
14 | {
15 | PosX,
16 | PosY,
17 | Width,
18 | Height,
19 | Maximized, // bool
20 | SplitterType, // int (0=horizontal, 1=vertical)
21 | SplitterHorizontalDistance,
22 | SplitterVerticalDistance,
23 | PreviewBeforeSlider,
24 | PreviewAfterSlider,
25 | ListViewColumnWidth, // array of int
26 | NumWorkerThreads,
27 |
28 | OptionsPosX,
29 | OptionsPosY,
30 | OptionsFontName, // string
31 | OptionsFontSize, // float
32 | OptionsFontBold, // bool
33 | OptionsFontItalic, // bool
34 | OptionsDeferRichTextDisplay, // bool
35 | OptionsUseWindowsFileAssociation, // bool
36 | OptionsCustomEditor, // string
37 |
38 | SearchPosX,
39 | SearchPosY,
40 | SearchRegularExpression, // bool
41 | SearchMatchCase, // bool
42 | SearchRecursive, // bool
43 | SearchText, // array of string
44 | SearchFileSpec, // array of string
45 | SearchFolder, // array of string
46 |
47 | SearchHelpPosX,
48 | SearchHelpPosY,
49 |
50 | DisplayLineNumbers, // bool
51 |
52 | FontPickerPosX,
53 | FontPickerPosY,
54 | FileListFont,
55 | SearchResultsFont
56 | };
57 |
58 | private static string ConfigFilename;
59 | private static Dictionary ConfigDictionary;
60 | private static Timer timer;
61 |
62 | static Config()
63 | {
64 | string AppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
65 | string AppDataFolder = AppDataPath + "\\Grepy2";
66 |
67 | Directory.CreateDirectory(AppDataFolder);
68 |
69 | ConfigFilename = AppDataPath + "\\Grepy2\\Grepy2.ini";
70 |
71 | ConfigDictionary = new Dictionary();
72 |
73 | Load();
74 |
75 | timer = new System.Timers.Timer();
76 | timer.Elapsed += new ElapsedEventHandler(OnTimerEvent);
77 | timer.AutoReset = false;
78 | timer.Enabled = false;
79 | }
80 |
81 | private static void OnTimerEvent(object source, ElapsedEventArgs e)
82 | {
83 | Save();
84 | }
85 |
86 | private static void Load()
87 | {
88 | string line;
89 |
90 | try
91 | {
92 | using( StreamReader sr = new StreamReader(ConfigFilename) )
93 | {
94 | while (sr.Peek() >= 0)
95 | {
96 | line = sr.ReadLine();
97 |
98 | while( (line.Length > 0) && ((line[0] == ' ') || (line[0] == '\t')) ) // remove leading whitespace
99 | {
100 | line = line.Substring(1, line.Length-1);
101 | }
102 |
103 | int end = line.Length-1;
104 | while( (line.Length > 0) && ((line[end] == ' ') || (line[end] == '\t')) ) // remove trailing whitespace
105 | {
106 | if( end > 0 )
107 | line = line.Substring(0, end);
108 | else
109 | line = "";
110 |
111 | end = line.Length-1;
112 | }
113 |
114 | if( (line.Length > 0) && (line[0] != '[') ) // not a blank line or a section?
115 | {
116 | int pos = line.IndexOf("=");
117 |
118 | if( (pos > 0) && (pos < (line.Length-1)) ) // '=' must not be the first or last character of the line
119 | {
120 | string key = line.Substring(0, pos);
121 | string value = line.Substring(pos+1, (line.Length-pos)-1);
122 |
123 | ConfigDictionary.Add(key, value);
124 | }
125 | }
126 | }
127 | }
128 | }
129 | catch( Exception )
130 | {
131 | Console.WriteLine("Config() - can't read config file: '{0}'", ConfigFilename);
132 | }
133 | }
134 |
135 | public static void Save()
136 | {
137 | timer.Enabled = false; // turn off the timer (in the event that Save was called directly)
138 |
139 | if( !Globals.bIsGrepyReadOnly )
140 | {
141 | try
142 | {
143 | using( StreamWriter sw = new StreamWriter(ConfigFilename) )
144 | {
145 | sw.WriteLine("[Grepy2]");
146 |
147 | foreach( KEY key in Enum.GetValues(typeof(KEY)) )
148 | {
149 | if( key == KEY.ListViewColumnWidth ||
150 | key == KEY.SearchText ||
151 | key == KEY.SearchFileSpec ||
152 | key == KEY.SearchFolder )
153 | {
154 | int count = 1;
155 | bool found = false;
156 | do
157 | {
158 | string key_string = string.Format("{0}{1}", key.ToString(), count);
159 | found = ConfigDictionary.ContainsKey(key_string);
160 | if( found )
161 | {
162 | sw.WriteLine(string.Format("{0}={1}", key_string, ConfigDictionary[key_string]));
163 | }
164 | count++;
165 | } while( found );
166 | }
167 | else
168 | {
169 | string key_string = key.ToString();
170 | if( ConfigDictionary.ContainsKey(key_string) )
171 | {
172 | sw.WriteLine(string.Format("{0}={1}", key_string, ConfigDictionary[key_string]));
173 | }
174 | }
175 | }
176 | }
177 | }
178 | catch( Exception )
179 | {
180 | Console.WriteLine("SaveConfig() - Error saving config file!");
181 | }
182 | }
183 | }
184 |
185 | public static bool Get(KEY key, ref string value)
186 | {
187 | string key_string = key.ToString();
188 | if( ConfigDictionary.ContainsKey(key_string) )
189 | {
190 | value = ConfigDictionary[key_string];
191 | return true;
192 | }
193 | return false;
194 | }
195 |
196 | public static void Set(KEY key, string value)
197 | {
198 | string key_string = key.ToString();
199 |
200 | if( ConfigDictionary.ContainsKey(key_string) ) // if the key/value pair exists...
201 | {
202 | ConfigDictionary.Remove(key_string); // ...remove the old key/value pair
203 | }
204 |
205 | ConfigDictionary.Add(key_string, value); // add the key/value pair to the dictionary
206 |
207 | timer.Enabled = true;
208 | timer.Interval = 1000;
209 | }
210 |
211 |
212 | public static bool Get(KEY key, ref int value)
213 | {
214 | string key_string = key.ToString();
215 | if( ConfigDictionary.ContainsKey(key_string) )
216 | {
217 | value = 0;
218 | Int32.TryParse(ConfigDictionary[key_string], out value);
219 | return true;
220 | }
221 | return false;
222 | }
223 |
224 | public static void Set(KEY key, int value)
225 | {
226 | Set(key, value.ToString());
227 | }
228 |
229 |
230 | public static bool Get(KEY key, ref bool value)
231 | {
232 | string key_string = key.ToString();
233 | if( ConfigDictionary.ContainsKey(key_string) )
234 | {
235 | value = ConfigDictionary[key_string] == "True";
236 | return true;
237 | }
238 | return false;
239 | }
240 |
241 | public static void Set(KEY key, bool value)
242 | {
243 | Set(key, value.ToString()); // set to 'False' or 'True'
244 | }
245 |
246 |
247 | public static bool Get(KEY key, ref List value)
248 | {
249 | value = new List();
250 |
251 | int count = 1;
252 | bool found = false;
253 | do
254 | {
255 | string key_string = string.Format("{0}{1}", key.ToString(), count);
256 | found = ConfigDictionary.ContainsKey(key_string);
257 | if( found )
258 | {
259 | value.Add(ConfigDictionary[key_string]);
260 | }
261 | count++;
262 | } while( found );
263 |
264 | return (value.Count() > 0);
265 | }
266 |
267 | public static void Set(KEY key, List StringList)
268 | {
269 | int count = 1;
270 | bool found = false;
271 | // remove ALL old key/value pairs from the dictionary (since the list parameter passed in can be different size than what's currently in dictionary)
272 | do
273 | {
274 | string key_string = string.Format("{0}{1}", key.ToString(), count);
275 | found = ConfigDictionary.ContainsKey(key_string);
276 | if( found )
277 | {
278 | ConfigDictionary.Remove(key_string);
279 | }
280 | count++;
281 | } while( found );
282 |
283 | // add the new key/value pairs to the dictionary
284 | for( int index = 0; index < StringList.Count; index++ )
285 | {
286 | string key_string = string.Format("{0}{1}", key.ToString(), index+1);
287 | ConfigDictionary.Add(key_string, StringList[index]);
288 | }
289 |
290 | timer.Enabled = true;
291 | timer.Interval = 1000;
292 | }
293 |
294 |
295 | public static bool Get(KEY key, ref List value)
296 | {
297 | value = new List();
298 |
299 | List StringList = new List();
300 |
301 | Get(key, ref StringList);
302 |
303 | for( int index = 0; index < StringList.Count; index++ )
304 | {
305 | value.Add(Convert.ToInt32(StringList[index]));
306 | }
307 |
308 | return (value.Count() > 0);
309 | }
310 |
311 | public static void Set(KEY key, List IntList)
312 | {
313 | List StringList = new List();
314 |
315 | for( int index = 0; index < IntList.Count; index++ )
316 | {
317 | StringList.Add(IntList[index].ToString());
318 | }
319 |
320 | Set(key, StringList);
321 | }
322 |
323 |
324 | public static bool Get(KEY key, ref Font value)
325 | {
326 | string FontString = "";
327 | if (Get(key, ref FontString))
328 | {
329 | string[] fields = FontString.Split(',');
330 |
331 | if (fields.Length == 4)
332 | {
333 | if ((fields[0].Substring(0,1) == "\"") && (fields[0].Substring(fields[0].Length - 1,1) == "\""))
334 | {
335 | fields[0] = fields[0].Substring(1, fields[0].Length - 2); // chop off the leading and trailing double quote
336 | }
337 |
338 | FontFamily font_family = new FontFamily(fields[0]);
339 |
340 | float size = float.Parse(fields[1]);
341 | int int_style = int.Parse(fields[2]);
342 |
343 | FontStyle style = FontStyle.Regular;
344 | if ((int_style & 1) != 0)
345 | {
346 | style = style | FontStyle.Bold;
347 | }
348 | if ((int_style & 2) != 0)
349 | {
350 | style = style | FontStyle.Italic;
351 | }
352 |
353 | GraphicsUnit graphics_unit = (GraphicsUnit) Enum.Parse(typeof(GraphicsUnit), fields[3]);
354 |
355 | value = new Font(font_family, size, style, graphics_unit);
356 | return true;
357 | }
358 | }
359 |
360 | return false;
361 | }
362 |
363 | public static void Set(KEY key, Font value)
364 | {
365 | int Style = 0; // Regular
366 | if( value.Style.HasFlag(FontStyle.Bold) )
367 | {
368 | Style |= 1;
369 | }
370 | if( value.Style.HasFlag(FontStyle.Italic) )
371 | {
372 | Style |= 2;
373 | }
374 |
375 | int GraphicsUnit = (int)value.Unit;
376 |
377 | Set(key, String.Format("\"{0}\",{1},{2},{3}", value.FontFamily.Name, value.SizeInPoints, Style, GraphicsUnit));
378 | }
379 | }
380 | }
381 |
--------------------------------------------------------------------------------
/OptionsForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 |
5 | using System.IO;
6 |
7 | namespace Grepy2
8 | {
9 | public partial class OptionsForm : Form
10 | {
11 | public bool DeferRichText
12 | {
13 | get { return this.DeferRichTextCheckBox.Checked; }
14 | }
15 |
16 | public bool UseWindowsFileAssociation
17 | {
18 | get { return this.WindowsFileAssociationCheckBox.Checked; }
19 | }
20 |
21 | public string CustomEditorText
22 | {
23 | get { return this.CustomEditorTextBox.Text.Trim(); }
24 | }
25 |
26 | public int NumberOfWorkerThreads
27 | {
28 | get { return this.WorkerThreadsComboBox.SelectedIndex + 1; }
29 | }
30 |
31 | private bool bWindowInitComplete; // set when form window is done initializing
32 |
33 | private ExplorerIntegration WindowsExplorerIntegration;
34 | private bool bWindowsExplorerIntegrationAtStart; // save the state of the Windows Explorer Integration check box at startup (so we can tell if it changed)
35 |
36 | public Font ListViewFont;
37 | public bool bListViewFontChanged = false;
38 | public Font RichTextBoxFont;
39 | public bool bRichTextBoxFontChanged = false;
40 |
41 | public OptionsForm(Font InListViewFont, Font InRichTextBoxFont)
42 | {
43 | bWindowInitComplete = false; // we aren't done initializing the window yet, don't overwrite any .config settings
44 |
45 | ListViewFont = InListViewFont;
46 | RichTextBoxFont = InRichTextBoxFont;
47 |
48 | this.DialogResult = DialogResult.Cancel; // set the default dialog result to 'Cancel'
49 |
50 | InitializeComponent();
51 |
52 | int pos_x = -1;
53 | int pos_y = -1;
54 | if( Config.Get(Config.KEY.OptionsPosX, ref pos_x) && Config.Get(Config.KEY.OptionsPosY, ref pos_y) )
55 | {
56 | this.StartPosition = FormStartPosition.Manual;
57 | this.Location = new Point(pos_x, pos_y);
58 | }
59 | else // otherwise, center the window on the parent form
60 | {
61 | this.StartPosition = FormStartPosition.CenterParent;
62 | }
63 | }
64 |
65 | private void OptionsForm_Load(object sender, EventArgs e)
66 | {
67 | WindowsExplorerIntegration = new ExplorerIntegration();
68 | bWindowsExplorerIntegrationAtStart = WindowsExplorerIntegration.IsEnabled("Directory");
69 |
70 | WindowsExplorerCheckBox.Checked = bWindowsExplorerIntegrationAtStart;
71 |
72 | int NumberOfProcessors = Math.Max(Environment.ProcessorCount - 1, 1); // subtract one from total numberr of logical processors (so we don't max out the CPU)
73 |
74 | for( int index = 1; index <= NumberOfProcessors; index++ )
75 | {
76 | WorkerThreadsComboBox.Items.Add(string.Format("{0}", index));
77 | }
78 |
79 | bool bDeferRichTextDisplay = false;
80 | Config.Get(Config.KEY.OptionsDeferRichTextDisplay, ref bDeferRichTextDisplay);
81 | DeferRichTextCheckBox.Checked = bDeferRichTextDisplay;
82 |
83 | bool bUseWindowsFileAssociation = true;
84 | Config.Get(Config.KEY.OptionsUseWindowsFileAssociation, ref bUseWindowsFileAssociation);
85 | WindowsFileAssociationCheckBox.Checked = bUseWindowsFileAssociation;
86 |
87 | CustomEditorTextBox.ReadOnly = bUseWindowsFileAssociation;
88 | CustomEditorButton.Enabled = !bUseWindowsFileAssociation;
89 |
90 | string CustomEditorString = "";
91 | if( Config.Get(Config.KEY.OptionsCustomEditor, ref CustomEditorString) )
92 | {
93 | CustomEditorTextBox.Text = CustomEditorString;
94 | }
95 |
96 | WorkerThreadsComboBox.SelectedIndex = Globals.NumWorkerThreads - 1;
97 |
98 | FileListFontTextBox.Text = string.Format(@"{0} {1} pt {2}", ListViewFont.Name, ListViewFont.Size, ListViewFont.Style.ToString());
99 | SearchResultsFontTextBox.Text = string.Format(@"{0} {1} pt {2}", RichTextBoxFont.Name, RichTextBoxFont.Size, RichTextBoxFont.Style.ToString());
100 |
101 | ToolTip OptionsToolTip = new ToolTip();
102 |
103 | OptionsToolTip.AutomaticDelay = 500;
104 |
105 | OptionsToolTip.SetToolTip(this.WindowsExplorerCheckBox, "Enable or disable having Grepy2 appear in the right-click menu in Windows File Explorer when right-clicking on a folder (or drive).");
106 |
107 | OptionsToolTip.SetToolTip(this.label6, "The number of worker threads that you wish to use when searching through files for the search text.");
108 | OptionsToolTip.SetToolTip(this.WorkerThreadsComboBox, "The number of worker threads that you wish to use when searching through files for the search text.");
109 |
110 | OptionsToolTip.SetToolTip(this.DeferRichTextCheckBox, "Enable to defer the displaying of search match text in the RichText box until after the search is complete (this can improve performance).");
111 |
112 | OptionsToolTip.SetToolTip(this.WindowsFileAssociationCheckBox, "Whether you wish to use the Windows application associated with a file type to edit the file or whether you wish to specify an editor to use to edit all files.");
113 | }
114 |
115 | private void OptionsForm_Shown(object sender, EventArgs e)
116 | {
117 | bWindowInitComplete = true; // window initialization is complete, okay to write config settings now
118 | }
119 |
120 | private void OptionsForm_Move(object sender, EventArgs e)
121 | {
122 | if( bWindowInitComplete )
123 | {
124 | Config.Set(Config.KEY.OptionsPosX, Location.X);
125 | Config.Set(Config.KEY.OptionsPosY, Location.Y);
126 | }
127 | }
128 |
129 | private void SaveConfig()
130 | {
131 | Config.Set(Config.KEY.OptionsDeferRichTextDisplay, DeferRichText);
132 | Config.Set(Config.KEY.OptionsUseWindowsFileAssociation, UseWindowsFileAssociation);
133 | Config.Set(Config.KEY.OptionsCustomEditor, CustomEditorText);
134 | }
135 |
136 | private void ValidateInput()
137 | {
138 | // verify that the Custom Editor executable exists
139 | bool bCustomEditorExecutableExists = false;
140 |
141 | string CustomEditorString = CustomEditorText;
142 |
143 | if( !UseWindowsFileAssociation )
144 | {
145 | if( CustomEditorString == "" )
146 | {
147 | MessageBox.Show("You must specify a custom editor executable filename if you are not using Windows file association.");
148 | return;
149 | }
150 |
151 | // if there's double quotes around the executable name, then get just that part (remove the filename, linenumber and other arguments)
152 | if( (CustomEditorString.Substring(0, 1) == "\"") && (CustomEditorString.Length > 1) )
153 | {
154 | int index = CustomEditorString.IndexOf('"', 1);
155 |
156 | if( index > 0 )
157 | {
158 | CustomEditorString = CustomEditorString.Substring(1, index - 1);
159 |
160 | // check that the executable file exists
161 | if( File.Exists(CustomEditorString) )
162 | {
163 | bCustomEditorExecutableExists = true;
164 | }
165 | }
166 |
167 | if( !bCustomEditorExecutableExists )
168 | {
169 | string msg = string.Format("Custom Editor executable '{0}' does not exist\n\n(or double quotes around the executable name are set up incorrectly.)", CustomEditorString);
170 | MessageBox.Show(msg);
171 | return;
172 | }
173 | }
174 | else
175 | {
176 | // otherwise, if there's no double quotes around the executable name, then check for space before arguments
177 | int space_index = CustomEditorString.IndexOf(" ", 0);
178 |
179 | if( space_index > 0 )
180 | {
181 | CustomEditorString = CustomEditorString.Substring(0, space_index);
182 | }
183 |
184 | if( !File.Exists(CustomEditorString) )
185 | {
186 | string msg = string.Format("Custom Editor executable '{0}' does not exist\n\n(or it is missing double quotes around it or there is no space before the filename or line number arguments.)", CustomEditorString);
187 | MessageBox.Show(msg);
188 | return;
189 | }
190 | }
191 | }
192 |
193 | if( bWindowsExplorerIntegrationAtStart != WindowsExplorerCheckBox.Checked )
194 | {
195 | // set windows explorer integration
196 | if( WindowsExplorerIntegration != null )
197 | {
198 | WindowsExplorerIntegration.Set( Globals.ApplicationPathExe, WindowsExplorerCheckBox.Checked );
199 | }
200 | }
201 |
202 | if (bListViewFontChanged)
203 | {
204 | Config.Set(Config.KEY.FileListFont, ListViewFont);
205 | }
206 |
207 | if (bRichTextBoxFontChanged)
208 | {
209 | Config.Set(Config.KEY.SearchResultsFont, RichTextBoxFont);
210 | }
211 |
212 | SaveConfig();
213 |
214 | this.DialogResult = DialogResult.OK;
215 |
216 | Close();
217 | }
218 |
219 | private void OptionsOkButton_Click(object sender, EventArgs e)
220 | {
221 | ValidateInput();
222 | }
223 |
224 | private void OptionsHelpButton_Click(object sender, EventArgs e)
225 | {
226 | Help.ShowHelp(this, "Grepy2Help.chm", HelpNavigator.TopicId, "2");
227 | }
228 |
229 | private void OptionsCancelButton_Click(object sender, EventArgs e)
230 | {
231 | Close();
232 | }
233 |
234 | private void WindowsFileAssociationCheckBox_CheckedChanged(object sender, EventArgs e)
235 | {
236 | CustomEditorTextBox.ReadOnly = WindowsFileAssociationCheckBox.Checked;
237 | CustomEditorButton.Enabled = !WindowsFileAssociationCheckBox.Checked;
238 | }
239 |
240 | private void CustomEditorButton_Click(object sender, EventArgs e)
241 | {
242 | OpenFileDialog openFileDialog = new OpenFileDialog();
243 |
244 | openFileDialog.Filter = "Executables (.exe)|*.exe|Command Files (*.cmd)|*.cmd|All Files (*.*)|*.*";
245 | openFileDialog.FilterIndex = 1;
246 |
247 | openFileDialog.Multiselect = false;
248 |
249 | if( openFileDialog.ShowDialog() == DialogResult.OK )
250 | {
251 | CustomEditorTextBox.Text = "\"" + openFileDialog.FileName + "\"";
252 | }
253 | }
254 |
255 | private void FileListFontButton_Click(object sender, EventArgs e)
256 | {
257 | FontPicker fontDialog = new FontPicker(ListViewFont);
258 |
259 | try
260 | {
261 | if( fontDialog.ShowDialog() != DialogResult.Cancel && (fontDialog.SelectedFont != null) )
262 | {
263 | ListViewFont = fontDialog.SelectedFont;
264 | bListViewFontChanged = true;
265 | FileListFontTextBox.Text = string.Format(@"{0} {1} pt {2}", ListViewFont.Name, ListViewFont.Size, ListViewFont.Style.ToString());
266 | }
267 | }
268 | catch (Exception)
269 | {
270 | MessageBox.Show("Sorry, this is not a TrueType font and can't be used. Please select another font.");
271 | }
272 | }
273 |
274 | private void SearchResultsFontButton_Click(object sender, EventArgs e)
275 | {
276 | FontPicker fontDialog = new FontPicker(RichTextBoxFont);
277 |
278 | try
279 | {
280 | if( fontDialog.ShowDialog() != DialogResult.Cancel && (fontDialog.SelectedFont != null) )
281 | {
282 | RichTextBoxFont = fontDialog.SelectedFont;
283 | bRichTextBoxFontChanged = true;
284 | SearchResultsFontTextBox.Text = string.Format(@"{0} {1} pt {2}", RichTextBoxFont.Name, RichTextBoxFont.Size, RichTextBoxFont.Style.ToString());
285 | }
286 | }
287 | catch (Exception)
288 | {
289 | MessageBox.Show("Sorry, this is not a TrueType font and can't be used. Please select another font.");
290 | }
291 |
292 | }
293 | }
294 | }
295 |
--------------------------------------------------------------------------------
/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Windows.Forms;
5 |
6 | using System.Runtime.InteropServices;
7 | using System.Reflection;
8 | using System.Threading;
9 | using System.IO;
10 | using System.Text.RegularExpressions;
11 |
12 | namespace Grepy2
13 | {
14 | static class Program
15 | {
16 | [DllImport("kernel32.dll")]
17 | public static extern bool AttachConsole(int dwProcessId);
18 | [DllImport("kernel32.dll")]
19 | public static extern bool FreeConsole();
20 | [DllImport("kernel32.dll")]
21 | public static extern IntPtr GetStdHandle(int dwStdHandle);
22 | [DllImport("user32.dll")]
23 | static extern uint MapVirtualKey(uint uCode, uint uMapType);
24 | [DllImport("kernel32.dll", EntryPoint = "WriteConsoleInputW", CharSet = CharSet.Unicode, SetLastError = true)]
25 | internal static extern bool WriteConsoleInput(IntPtr hConsoleInput, [MarshalAs(UnmanagedType.LPArray), In] INPUT_RECORD[] lpBuffer, int nLength, out int lpNumberOfEventsWritten);
26 |
27 | [StructLayout(LayoutKind.Explicit,CharSet=CharSet.Unicode)]
28 | public struct KEY_EVENT_RECORD
29 | {
30 | [FieldOffset(0),MarshalAs(UnmanagedType.Bool)]
31 | public bool bKeyDown;
32 | [FieldOffset(4),MarshalAs(UnmanagedType.U2)]
33 | public ushort wRepeatCount;
34 | [FieldOffset(6),MarshalAs(UnmanagedType.U2)]
35 | public ushort wVirtualKeyCode;
36 | [FieldOffset(8),MarshalAs(UnmanagedType.U2)]
37 | public ushort wVirtualScanCode;
38 | [FieldOffset(10)]
39 | public char UnicodeChar;
40 | [FieldOffset(12),MarshalAs(UnmanagedType.U4)]
41 | public int dwControlKeyState;
42 | }
43 |
44 | [StructLayout(LayoutKind.Explicit)]
45 | public struct INPUT_RECORD
46 | {
47 | [FieldOffset(0)]
48 | public ushort EventType;
49 | [FieldOffset(4)]
50 | public KEY_EVENT_RECORD KeyEvent;
51 | };
52 |
53 | const int STD_INPUT_HANDLE = -10;
54 | const int KEY_EVENT = 0x0001;
55 |
56 | private static Mutex m_Mutex;
57 | private static string CommandlineErrorMessage = "";
58 |
59 | ///
60 | /// The main entry point for the application.
61 | ///
62 | [STAThread]
63 | static void Main(string[] args)
64 | {
65 | // if some commandline arguments were given then try to process those arguments...
66 | if( args.Count() > 0 )
67 | {
68 | if( !ProcessCommandlineArguments(args) ) // if we can't process the commandline arguments, then provide help
69 | {
70 | AttachConsole(-1);
71 |
72 | IntPtr Handle = GetStdHandle(STD_INPUT_HANDLE);
73 |
74 | Console.WriteLine("");
75 | Console.WriteLine("");
76 |
77 | if( CommandlineErrorMessage != "" )
78 | {
79 | Console.WriteLine(CommandlineErrorMessage);
80 | }
81 |
82 | Console.WriteLine("");
83 | Console.WriteLine("Usage: Grepy2.exe [switches] [SearchFolder] SearchString FileSpec [FileSpec...]");
84 | Console.WriteLine("");
85 | Console.WriteLine(" where [switches] can be any of the following:");
86 | Console.WriteLine(" -r = Recurse folders");
87 | Console.WriteLine(" -cs = Use Case Sensitive searching");
88 | Console.WriteLine(" -noregex = Don't use regular expressions");
89 | Console.WriteLine("");
90 |
91 | INPUT_RECORD[] rec = new INPUT_RECORD[2];
92 |
93 | rec[0].EventType = KEY_EVENT;
94 | rec[0].KeyEvent.bKeyDown = true;
95 | rec[0].KeyEvent.dwControlKeyState = 0;
96 | rec[0].KeyEvent.UnicodeChar = '\r'; // carriage return
97 | rec[0].KeyEvent.wRepeatCount = 1;
98 | rec[0].KeyEvent.wVirtualKeyCode = 0x0d; // 0x0d = VK_Return
99 | uint mvk = MapVirtualKey(0x0d, 0); // MAPVK_VK_TO_VSC = 0
100 | rec[0].KeyEvent.wVirtualScanCode = (ushort)mvk;
101 |
102 | rec[1].EventType = KEY_EVENT;
103 | rec[1].KeyEvent.bKeyDown = false;
104 | rec[1].KeyEvent.dwControlKeyState = 0;
105 | rec[1].KeyEvent.UnicodeChar = '\r'; // carriage return
106 | rec[1].KeyEvent.wRepeatCount = 1;
107 | rec[1].KeyEvent.wVirtualKeyCode = 0x0d; // 0x0d = VK_Return
108 | mvk = MapVirtualKey(0x0d, 0); // MAPVK_VK_TO_VSC = 0
109 | rec[1].KeyEvent.wVirtualScanCode = (ushort)mvk;
110 |
111 | int numWritten = 0;
112 | WriteConsoleInput(Handle, rec, 2, out numWritten); // output a Return key to the input stream of the console
113 |
114 | FreeConsole();
115 |
116 | return;
117 | }
118 | }
119 |
120 | bool createdNew;
121 | m_Mutex = new Mutex(true, "Grepy2_Mutex", out createdNew); // check if there is another instance of Grepy already running...
122 | if (!createdNew)
123 | {
124 | Globals.bIsGrepyReadOnly = true; // ...if so, set the 'readonly' flag to indicate that this instance shouldn't write to the config file (we only want ONE writer)
125 | }
126 |
127 | Globals.ApplicationPathExe = Assembly.GetExecutingAssembly().Location;
128 |
129 | Application.EnableVisualStyles();
130 | Application.SetCompatibleTextRenderingDefault(false);
131 | Application.Run(new MainForm());
132 | }
133 |
134 | static bool ProcessCommandlineArguments(string[] args)
135 | {
136 | string SearchDirectory = "";
137 | string SearchString = "";
138 |
139 | if( args.Count() == 1 ) // if there's one argument, see if it is a folder name (to handle right clicking on folder in Windows Explorer)
140 | {
141 | // We have to "massage" the cmdline argument because of bad '\' parsing in CommandLineToArgvW...
142 | // http://weblogs.asp.net/jgalloway/archive/2006/10/05/_5B002E00_NET-Gotcha_5D00_-Commandline-args-ending-in-_5C002200_-are-subject-to-CommandLineToArgvW-whackiness.aspx
143 |
144 | // check if the first argument is a search directory...
145 | SearchDirectory = args[0];
146 |
147 | if( SearchDirectory.StartsWith("\"") )
148 | {
149 | SearchDirectory = SearchDirectory.Substring(1, SearchDirectory.Length-1);
150 | }
151 |
152 | if( SearchDirectory.EndsWith("\"") )
153 | {
154 | SearchDirectory = SearchDirectory.Substring(0, SearchDirectory.Length-1);
155 | }
156 |
157 | if( SearchDirectory.EndsWith(":") )
158 | {
159 | SearchDirectory = string.Format("{0}\\", SearchDirectory);
160 | }
161 |
162 | if( Directory.Exists(SearchDirectory) )
163 | {
164 | // store the specified commandline arguments in Globals so that the main form can use them
165 | Globals.SearchDirectory = Path.GetFullPath(SearchDirectory);;
166 |
167 | return true;
168 | }
169 |
170 | return false;
171 | }
172 |
173 | if( args.Count() < 2 ) // if not enough arguments specified, return failed result
174 | {
175 | return false;
176 | }
177 |
178 | bool bRecursiveSpecified = false;
179 | bool bCaseSensitiveSpecified = false;
180 | bool bNoRegExSpecified = false;
181 | bool bParsedFirstArgument = false;
182 | bool bSearchDirectorySpecified = false;
183 |
184 | List FileSpecs;
185 |
186 | FileSpecs = new List();
187 |
188 | // Commandline format is: "Grepy2.exe [switches] [SearchFolder] SearchString FileSpec [FileSpec...]"
189 | // The first argument could be a search folder or the search string (possibly surrounded by double quotes).
190 | // We detect if the first argument is a valid folder name and if so, we assume that is the search folder
191 | // and will be followed by the search string.
192 |
193 | // process commandline arguments and display SearchForm if needed...
194 | for( int index = 0; index < args.Count(); index++ )
195 | {
196 | if( args[index].ToLower() == "-r" ) // recursive directory search?
197 | {
198 | bRecursiveSpecified = true;
199 | continue;
200 | }
201 | if( args[index].ToLower() == "-cs" ) // case sensitive search?
202 | {
203 | bCaseSensitiveSpecified = true;
204 | continue;
205 | }
206 | if( args[index].ToLower() == "-noregex" ) // turn off regular expressions?
207 | {
208 | bNoRegExSpecified = true;
209 | continue;
210 | }
211 |
212 | if( !bParsedFirstArgument ) // have we not parsed the first commandline argument yet?
213 | {
214 | bParsedFirstArgument = true;
215 |
216 | // We have to "massage" the cmdline argument because of bad '\' parsing in CommandLineToArgvW...
217 | // http://weblogs.asp.net/jgalloway/archive/2006/10/05/_5B002E00_NET-Gotcha_5D00_-Commandline-args-ending-in-_5C002200_-are-subject-to-CommandLineToArgvW-whackiness.aspx
218 |
219 | // check if the first argument is a search directory...
220 | SearchDirectory = args[index];
221 |
222 | if( SearchDirectory.StartsWith("\"") )
223 | {
224 | SearchDirectory = SearchDirectory.Substring(1, SearchDirectory.Length-1);
225 | }
226 |
227 | if( SearchDirectory.EndsWith("\"") )
228 | {
229 | SearchDirectory = SearchDirectory.Substring(0, SearchDirectory.Length-1);
230 | }
231 |
232 | if( SearchDirectory.EndsWith(":") )
233 | {
234 | SearchDirectory = string.Format("{0}\\", SearchDirectory);
235 | }
236 |
237 | if( Directory.Exists(SearchDirectory) )
238 | {
239 | bSearchDirectorySpecified = true; // the first argument was the search directory
240 |
241 | SearchDirectory = Path.GetFullPath(SearchDirectory);
242 | }
243 | else
244 | {
245 | SearchString = args[index]; // if the first argument is not a valid directory, then it is the search string
246 | SearchDirectory = ""; // no directory specified, search using the current directory
247 | }
248 | }
249 | else // anything after the first argument is either the SearchString, or FileSpecs...
250 | {
251 | if( SearchString == "" )
252 | {
253 | SearchString = args[index];
254 | }
255 | else
256 | {
257 | FileSpecs.Add(args[index]);
258 | }
259 | }
260 | }
261 |
262 | if( bSearchDirectorySpecified && (SearchString == "") ) // if we specified a SearchDirectory, but no SearchString, return failed result
263 | {
264 | return false;
265 | }
266 | else if( (SearchString != "") && (FileSpecs.Count() == 0) ) // if we specified a search string but no file specs, return failed result
267 | {
268 | return false;
269 | }
270 |
271 | if( !bNoRegExSpecified )
272 | {
273 | try
274 | {
275 | Regex SearchRegEx = new Regex(SearchString, RegexOptions.IgnoreCase);
276 | }
277 | catch
278 | {
279 | CommandlineErrorMessage = string.Format("The SearchString '{0}' is not a valid regular expression.", SearchString);
280 | return false;
281 | }
282 | }
283 |
284 | if( !bSearchDirectorySpecified ) // if we didn't specifiy a search folder, then use the current directory
285 | {
286 | SearchDirectory = Directory.GetCurrentDirectory();
287 | }
288 |
289 | // store the specified commandline arguments in Globals so that the main form can use them
290 | Globals.SearchDirectory = SearchDirectory;
291 | Globals.SearchString = SearchString;
292 | Globals.FileSpecs = FileSpecs;
293 |
294 | Globals.bRecursive = bRecursiveSpecified;
295 | Globals.bCaseSensitive = bCaseSensitiveSpecified;
296 | Globals.bRegEx = !bNoRegExSpecified;
297 |
298 | //
299 | // TODO - Do we want to save the config settings here???
300 | //
301 |
302 | return true;
303 | }
304 | }
305 | }
306 |
--------------------------------------------------------------------------------
/FontPicker.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Grepy2
2 | {
3 | partial class FontPicker
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.label1 = new System.Windows.Forms.Label();
32 | this.label2 = new System.Windows.Forms.Label();
33 | this.FontTextBox = new System.Windows.Forms.TextBox();
34 | this.SizeTextBox = new System.Windows.Forms.TextBox();
35 | this.FontListBox = new System.Windows.Forms.ListBox();
36 | this.SizeListBox = new System.Windows.Forms.ListBox();
37 | this.groupBox1 = new System.Windows.Forms.GroupBox();
38 | this.ItalicCheckBox = new System.Windows.Forms.CheckBox();
39 | this.BoldCheckBox = new System.Windows.Forms.CheckBox();
40 | this.FixedWidthFontCheckBox = new System.Windows.Forms.CheckBox();
41 | this.groupBox2 = new System.Windows.Forms.GroupBox();
42 | this.FontOkButton = new System.Windows.Forms.Button();
43 | this.FontCancelButton = new System.Windows.Forms.Button();
44 | this.richTextBox1 = new System.Windows.Forms.RichTextBox();
45 | this.groupBox1.SuspendLayout();
46 | this.groupBox2.SuspendLayout();
47 | this.SuspendLayout();
48 | //
49 | // label1
50 | //
51 | this.label1.AutoSize = true;
52 | this.label1.Location = new System.Drawing.Point(28, 13);
53 | this.label1.Name = "label1";
54 | this.label1.Size = new System.Drawing.Size(40, 17);
55 | this.label1.TabIndex = 0;
56 | this.label1.Text = "Font:";
57 | //
58 | // label2
59 | //
60 | this.label2.AutoSize = true;
61 | this.label2.Location = new System.Drawing.Point(294, 13);
62 | this.label2.Name = "label2";
63 | this.label2.Size = new System.Drawing.Size(39, 17);
64 | this.label2.TabIndex = 1;
65 | this.label2.Text = "Size:";
66 | //
67 | // FontTextBox
68 | //
69 | this.FontTextBox.BackColor = System.Drawing.SystemColors.Window;
70 | this.FontTextBox.Location = new System.Drawing.Point(31, 33);
71 | this.FontTextBox.Name = "FontTextBox";
72 | this.FontTextBox.Size = new System.Drawing.Size(240, 23);
73 | this.FontTextBox.TabIndex = 1;
74 | this.FontTextBox.MouseClick += new System.Windows.Forms.MouseEventHandler(this.FontMouseClick);
75 | this.FontTextBox.TextChanged += new System.EventHandler(this.FontTextChanged);
76 | //
77 | // SizeTextBox
78 | //
79 | this.SizeTextBox.BackColor = System.Drawing.SystemColors.Window;
80 | this.SizeTextBox.Location = new System.Drawing.Point(296, 33);
81 | this.SizeTextBox.Name = "SizeTextBox";
82 | this.SizeTextBox.Size = new System.Drawing.Size(80, 23);
83 | this.SizeTextBox.TabIndex = 3;
84 | this.SizeTextBox.TextChanged += new System.EventHandler(this.SizeTextChanged);
85 | this.SizeTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.SizeKeyDown);
86 | //
87 | // FontListBox
88 | //
89 | this.FontListBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
90 | this.FontListBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
91 | this.FontListBox.FormattingEnabled = true;
92 | this.FontListBox.ItemHeight = 18;
93 | this.FontListBox.Location = new System.Drawing.Point(31, 56);
94 | this.FontListBox.Name = "FontListBox";
95 | this.FontListBox.Size = new System.Drawing.Size(240, 290);
96 | this.FontListBox.TabIndex = 2;
97 | this.FontListBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.FontList_DrawItem);
98 | this.FontListBox.SelectedIndexChanged += new System.EventHandler(this.FontListIndedChanged);
99 | //
100 | // SizeListBox
101 | //
102 | this.SizeListBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
103 | this.SizeListBox.FormattingEnabled = true;
104 | this.SizeListBox.ItemHeight = 17;
105 | this.SizeListBox.Items.AddRange(new object[] {
106 | "8",
107 | "9",
108 | "10",
109 | "11",
110 | "12",
111 | "14",
112 | "16",
113 | "18",
114 | "20",
115 | "22",
116 | "24",
117 | "26",
118 | "28",
119 | "36",
120 | "48",
121 | "72"});
122 | this.SizeListBox.Location = new System.Drawing.Point(296, 56);
123 | this.SizeListBox.Name = "SizeListBox";
124 | this.SizeListBox.Size = new System.Drawing.Size(80, 87);
125 | this.SizeListBox.TabIndex = 4;
126 | this.SizeListBox.SelectedIndexChanged += new System.EventHandler(this.SizeSelectedIndexChanged);
127 | //
128 | // groupBox1
129 | //
130 | this.groupBox1.Controls.Add(this.ItalicCheckBox);
131 | this.groupBox1.Controls.Add(this.BoldCheckBox);
132 | this.groupBox1.Location = new System.Drawing.Point(400, 33);
133 | this.groupBox1.Name = "groupBox1";
134 | this.groupBox1.Size = new System.Drawing.Size(112, 81);
135 | this.groupBox1.TabIndex = 7;
136 | this.groupBox1.TabStop = false;
137 | this.groupBox1.Text = "Font Style";
138 | //
139 | // ItalicCheckBox
140 | //
141 | this.ItalicCheckBox.AutoSize = true;
142 | this.ItalicCheckBox.Location = new System.Drawing.Point(20, 47);
143 | this.ItalicCheckBox.Name = "ItalicCheckBox";
144 | this.ItalicCheckBox.Size = new System.Drawing.Size(58, 21);
145 | this.ItalicCheckBox.TabIndex = 6;
146 | this.ItalicCheckBox.Text = "Italic";
147 | this.ItalicCheckBox.UseVisualStyleBackColor = true;
148 | this.ItalicCheckBox.CheckedChanged += new System.EventHandler(this.ItalicCheckBox_CheckedChanged);
149 | //
150 | // BoldCheckBox
151 | //
152 | this.BoldCheckBox.AutoSize = true;
153 | this.BoldCheckBox.Location = new System.Drawing.Point(20, 24);
154 | this.BoldCheckBox.Name = "BoldCheckBox";
155 | this.BoldCheckBox.Size = new System.Drawing.Size(58, 21);
156 | this.BoldCheckBox.TabIndex = 5;
157 | this.BoldCheckBox.Text = "Bold";
158 | this.BoldCheckBox.UseVisualStyleBackColor = true;
159 | this.BoldCheckBox.CheckedChanged += new System.EventHandler(this.BoldBox_CheckedChanged);
160 | //
161 | // FixedWidthFontCheckBox
162 | //
163 | this.FixedWidthFontCheckBox.AutoSize = true;
164 | this.FixedWidthFontCheckBox.Location = new System.Drawing.Point(296, 166);
165 | this.FixedWidthFontCheckBox.Name = "FixedWidthFontCheckBox";
166 | this.FixedWidthFontCheckBox.Size = new System.Drawing.Size(198, 21);
167 | this.FixedWidthFontCheckBox.TabIndex = 7;
168 | this.FixedWidthFontCheckBox.Text = "Show only fixed width fonts";
169 | this.FixedWidthFontCheckBox.UseVisualStyleBackColor = true;
170 | this.FixedWidthFontCheckBox.CheckedChanged += new System.EventHandler(this.FixedWidthFontCheckBox_CheckedChanged);
171 | //
172 | // groupBox2
173 | //
174 | this.groupBox2.Controls.Add(this.richTextBox1);
175 | this.groupBox2.Location = new System.Drawing.Point(284, 200);
176 | this.groupBox2.Name = "groupBox2";
177 | this.groupBox2.Size = new System.Drawing.Size(228, 130);
178 | this.groupBox2.TabIndex = 9;
179 | this.groupBox2.TabStop = false;
180 | this.groupBox2.Text = "Sample Text";
181 | //
182 | // FontOkButton
183 | //
184 | this.FontOkButton.Location = new System.Drawing.Point(284, 336);
185 | this.FontOkButton.Name = "FontOkButton";
186 | this.FontOkButton.Size = new System.Drawing.Size(95, 31);
187 | this.FontOkButton.TabIndex = 8;
188 | this.FontOkButton.Text = "Ok";
189 | this.FontOkButton.UseVisualStyleBackColor = true;
190 | this.FontOkButton.Click += new System.EventHandler(this.OkButton_Click);
191 | //
192 | // FontCancelButton
193 | //
194 | this.FontCancelButton.Location = new System.Drawing.Point(417, 336);
195 | this.FontCancelButton.Name = "FontCancelButton";
196 | this.FontCancelButton.Size = new System.Drawing.Size(95, 31);
197 | this.FontCancelButton.TabIndex = 9;
198 | this.FontCancelButton.Text = "Cancel";
199 | this.FontCancelButton.UseVisualStyleBackColor = true;
200 | this.FontCancelButton.Click += new System.EventHandler(this.CancelButton_Click);
201 | //
202 | // richTextBox1
203 | //
204 | this.richTextBox1.BackColor = System.Drawing.SystemColors.Control;
205 | this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill;
206 | this.richTextBox1.Location = new System.Drawing.Point(3, 19);
207 | this.richTextBox1.Name = "richTextBox1";
208 | this.richTextBox1.ReadOnly = true;
209 | this.richTextBox1.Size = new System.Drawing.Size(222, 108);
210 | this.richTextBox1.TabIndex = 0;
211 | this.richTextBox1.Text = "";
212 | //
213 | // FontPicker
214 | //
215 | this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 17F);
216 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
217 | this.ClientSize = new System.Drawing.Size(524, 379);
218 | this.Controls.Add(this.FontCancelButton);
219 | this.Controls.Add(this.FontOkButton);
220 | this.Controls.Add(this.groupBox2);
221 | this.Controls.Add(this.FixedWidthFontCheckBox);
222 | this.Controls.Add(this.groupBox1);
223 | this.Controls.Add(this.SizeListBox);
224 | this.Controls.Add(this.FontListBox);
225 | this.Controls.Add(this.SizeTextBox);
226 | this.Controls.Add(this.FontTextBox);
227 | this.Controls.Add(this.label2);
228 | this.Controls.Add(this.label1);
229 | this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
230 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
231 | this.MaximizeBox = false;
232 | this.MinimizeBox = false;
233 | this.Name = "FontPicker";
234 | this.ShowIcon = false;
235 | this.Text = "Font";
236 | this.Load += new System.EventHandler(this.FontPicker_Load);
237 | this.Move += new System.EventHandler(this.FontPicker_Move);
238 | this.groupBox1.ResumeLayout(false);
239 | this.groupBox1.PerformLayout();
240 | this.groupBox2.ResumeLayout(false);
241 | this.ResumeLayout(false);
242 | this.PerformLayout();
243 |
244 | }
245 |
246 | #endregion
247 |
248 | private System.Windows.Forms.Label label1;
249 | private System.Windows.Forms.Label label2;
250 | private System.Windows.Forms.TextBox FontTextBox;
251 | private System.Windows.Forms.TextBox SizeTextBox;
252 | private System.Windows.Forms.ListBox FontListBox;
253 | private System.Windows.Forms.ListBox SizeListBox;
254 | private System.Windows.Forms.GroupBox groupBox1;
255 | private System.Windows.Forms.CheckBox ItalicCheckBox;
256 | private System.Windows.Forms.CheckBox BoldCheckBox;
257 | private System.Windows.Forms.CheckBox FixedWidthFontCheckBox;
258 | private System.Windows.Forms.GroupBox groupBox2;
259 | private System.Windows.Forms.Button FontOkButton;
260 | private System.Windows.Forms.Button FontCancelButton;
261 | private System.Windows.Forms.RichTextBox richTextBox1;
262 | }
263 | }
--------------------------------------------------------------------------------