⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 findreplacedlg.cpp

📁 Notepad++ 源代码,功能强大的编辑软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//this file is part of notepad++
//Copyright (C)2003 Don HO ( donho@altern.org )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#include "FindReplaceDlg.h"
#include "ScintillaEditView.h"
#include "Notepad_plus_msgs.h"
#include "constant.h"

// need this header for SHBrowseForFolder
#include <Shlobj.h>

void addText2Combo(const char * txt2add, HWND hCombo)
{	
	if (!hCombo) return;
	if (!strcmp(txt2add, "")) return;

	char text[MAX_PATH];
	int count = ::SendMessage(hCombo, CB_GETCOUNT, 0, 0);
	bool hasFound = false;
	int i = 0;
	for ( ; i < count ; i++)
	{
		::SendMessage(hCombo, CB_GETLBTEXT, i, (LPARAM)text);
		if (!strcmp(txt2add, text))
		{
			hasFound = true;
			break;
		}
	}
	if (!hasFound)
		i = ::SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)txt2add);
	::SendMessage(hCombo, CB_SETCURSEL, i, 0);
}

// Set a call back with the handle after init to set the path.
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/callbackfunctions/browsecallbackproc.asp
static int __stdcall BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM, LPARAM pData)
{
	if (uMsg == BFFM_INITIALIZED)
		SendMessage(hwnd, BFFM_SETSELECTION, TRUE, pData);
	return 0;
};

// important : to activate all styles
const int STYLING_MASK = 255;

void FindInFilesDlg::doDialog(bool isRTL) 
{
	if (!isCreated())
		create(IDD_FINDINFILES_DLG, isRTL);
	char dir[MAX_PATH];
	::GetCurrentDirectory(sizeof(dir), dir);
	::SetDlgItemText(_hSelf, IDD_FINDINFILES_DIR_COMBO, dir);

	LangType lt;
 	::SendMessage(_hParent, WM_COMMAND, IDC_GETCURRENTDOCTYPE, (LPARAM)&lt);
	const char *ext = NppParameters::getInstance()->getLangExtFromLangType(lt);
	if (ext && ext[0])
	{
		string filtres = "";
		vector<string> vStr;
		cutString(ext, vStr);
		for (size_t i = 0 ; i < vStr.size() ; i++)
		{
			filtres += "*.";
			filtres += vStr[i] + " ";
		}
		::SetDlgItemText(_hSelf, IDD_FINDINFILES_FILTERS_COMBO, filtres.c_str());
	}
	display();
}

BOOL CALLBACK FindInFilesDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message) 
	{
		case WM_COMMAND : 
		{
			switch (wParam)
			{
				case IDCANCEL :
					display(false);
					return TRUE;

				case IDOK :
				{
					char filters[256];
					char directory[MAX_PATH];
					::GetDlgItemText(_hSelf, IDD_FINDINFILES_FILTERS_COMBO, filters, sizeof(filters));
					addText2Combo(filters, ::GetDlgItem(_hSelf, IDD_FINDINFILES_FILTERS_COMBO));
					_filters = filters;

					::GetDlgItemText(_hSelf, IDD_FINDINFILES_DIR_COMBO, directory, sizeof(directory));
					addText2Combo(directory, ::GetDlgItem(_hSelf, IDD_FINDINFILES_DIR_COMBO));
					_directory = directory;
					if (directory[strlen(directory)-1] != '\\')
						_directory += "\\";

					::SendMessage(_hParent, WM_COMMAND, IDC_FINDINFILES_LAUNCH, 0);
					display(false);
					return TRUE;
				}

				case IDD_FINDINFILES_BROWSE_BUTTON :
				{
					// This code was copied and slightly modifed from:
					// http://www.bcbdev.com/faqs/faq62.htm

					// SHBrowseForFolder returns a PIDL. The memory for the PIDL is
					// allocated by the shell. Eventually, we will need to free this
					// memory, so we need to get a pointer to the shell malloc COM
					// object that will free the PIDL later on.
					LPMALLOC pShellMalloc = 0;
					if (::SHGetMalloc(&pShellMalloc) == NO_ERROR)
					{
						// If we were able to get the shell malloc object,
						// then proceed by initializing the BROWSEINFO stuct
						BROWSEINFO info;
						memset(&info, 0, sizeof(info));
						info.hwndOwner = _hSelf;
						info.pidlRoot = NULL;
						char szDisplayName[MAX_PATH];
						info.pszDisplayName = szDisplayName;
						string title = "Select a folder to search from";
						info.lpszTitle = title.c_str();
						info.ulFlags = 0;
						info.lpfn = BrowseCallbackProc;
						char directory[MAX_PATH];
						::GetDlgItemText(_hSelf, IDD_FINDINFILES_DIR_COMBO, directory, sizeof(directory));
						info.lParam = reinterpret_cast<LPARAM>(directory);

						// Execute the browsing dialog.
						LPITEMIDLIST pidl = ::SHBrowseForFolder(&info);

						// pidl will be null if they cancel the browse dialog.
						// pidl will be not null when they select a folder.
						if (pidl) 
						{
							// Try to convert the pidl to a display string.
							// Return is true if success.
							char szDir[MAX_PATH];
							if (::SHGetPathFromIDList(pidl, szDir))
								// Set edit control to the directory path.
								::SetDlgItemText(_hSelf, IDD_FINDINFILES_DIR_COMBO, szDir);
							pShellMalloc->Free(pidl);
						}
						pShellMalloc->Release();
					}
					return TRUE;
				}
			}
		}
	}
	return FALSE;
}

void FindReplaceDlg::create(int dialogID, bool isRTL) 
{
	StaticDialog::create(dialogID, isRTL);
	_currentStatus = REPLACE;

	initOptionsFromDlg();

	if ((NppParameters::getInstance())->isTransparentAvailable())
	{
		::ShowWindow(::GetDlgItem(_hSelf, IDC_TRANSPARENT_CHECK), SW_SHOW);
		::ShowWindow(::GetDlgItem(_hSelf, IDC_PERCENTAGE_SLIDER), SW_SHOW);
		
		::SendDlgItemMessage(_hSelf, IDC_PERCENTAGE_SLIDER, TBM_SETRANGE, FALSE, MAKELONG(20, 200));
		::SendDlgItemMessage(_hSelf, IDC_PERCENTAGE_SLIDER, TBM_SETPOS, TRUE, 150);
		if (!isCheckedOrNot(IDC_PERCENTAGE_SLIDER))
			::EnableWindow(::GetDlgItem(_hSelf, IDC_PERCENTAGE_SLIDER), FALSE);
	}
	RECT rect;
	::GetWindowRect(_hSelf, &rect);
	_findW = _replaceW = rect.right - rect.left;
	_findH = _replaceH = rect.bottom - rect.top;

	_findInFilesDlg.init(_hInst, _hSelf);

	goToCenter();
}

void FindReplaceDlg::notify(SCNotification *notification)
{
  switch (notification->nmhdr.code) 
  {
	case SCN_DOUBLECLICK :
	{
		try {
			// in getInfo() method the previous line is renew as current for next call
			const FoundInfo &fInfo = _pFinder->getInfo();

			int markedLine = _pFinder->getCurrentMarkedLine();

			// now we clean the previous mark
			if (markedLine != -1)
				(*_ppEditView)->execute(SCI_MARKERDELETE, markedLine, MARK_SYMBOLE);

			// After cleaning the previous mark, we can swich to another document
			::SendMessage(_hParent, WM_DOOPEN, 0, (LPARAM)fInfo._fullPath.c_str());
			(*_ppEditView)->execute(SCI_SETSEL, fInfo._start, fInfo._end);

			// we set the current mark here
			int nb = (*_ppEditView)->getCurrentLineNumber();
			_pFinder->setCurrentMarkedLine(nb);
			(*_ppEditView)->execute(SCI_MARKERADD, nb, MARK_SYMBOLE);

			// Then we colourise the double clicked line
			_pFinder->setFinderStyle();
			//_pFinder->showMargin(ScintillaEditView::_SC_MARGE_FOLDER, false);
			_pFinder->execute(SCI_SETLEXER, SCLEX_NULL);
			_pFinder->execute(SCI_STYLESETEOLFILLED, SCE_UNIVERSAL_FOUND_STYLE, true);
			int lno = _pFinder->getCurrentLineNumber();
			int start = _pFinder->execute(SCI_POSITIONFROMLINE, lno);
			int end = _pFinder->execute(SCI_GETLINEENDPOSITION, lno);
			// 
			_pFinder->execute(SCI_STARTSTYLING,  start,  STYLING_MASK);
			_pFinder->execute(SCI_SETSTYLING,  end - start + 2, SCE_UNIVERSAL_FOUND_STYLE);
			_pFinder->execute(SCI_COLOURISE,start, end + 1);
			_pFinder->execute(SCI_SETCURRENTPOS, start);
			_pFinder->execute(SCI_SETANCHOR, start);

		} catch(...){
		}
		break;
	}

	default :
		break;
  }
}

BOOL CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message) 
	{
		
		case WM_INITDIALOG :
		{
			// Wrap arround active by default
			::SendDlgItemMessage(_hSelf, IDWRAP, BM_SETCHECK, BST_CHECKED, 0);
			return TRUE;
		}
		
		case WM_HSCROLL :
		{
			if ((HWND)lParam == ::GetDlgItem(_hSelf, IDC_PERCENTAGE_SLIDER))
			{
				int percent = ::SendDlgItemMessage(_hSelf, IDC_PERCENTAGE_SLIDER, TBM_GETPOS, 0, 0);
				(NppParameters::getInstance())->SetTransparent(_hSelf, percent);
			}
			return TRUE;
		}
		
		case WM_SIZE:
		{
			resizeFinder();
			resizeStatusBar();
			return FALSE;
		}

		case WM_NOTIFY:
		{
			notify(reinterpret_cast<SCNotification *>(lParam));
			return FALSE;
		}
		
		case WM_ACTIVATE :
		{
			CharacterRange cr = (*_ppEditView)->getSelection();
			bool isSelected = (cr.cpMax - cr.cpMin) != 0;
			if (!isSelected)
			{
				::SendDlgItemMessage(_hSelf, IDC_IN_SELECTION_CHECK, BM_SETCHECK, BST_UNCHECKED, 0);
				_isInSelection = false;
			}
			::EnableWindow(::GetDlgItem(_hSelf, IDC_IN_SELECTION_CHECK), isSelected);
			return TRUE;
		}
		case WM_MODELESSDIALOG :
			return ::SendMessage(_hParent, WM_MODELESSDIALOG, wParam, lParam);

		case WM_COMMAND : 
		{
			switch (wParam)
			{
				case IDCANCEL : // Close
					display(false);
					if (_findInFilesDlg.isCreated())
						_findInFilesDlg.display(false);
					return TRUE;

				case IDOK : // Find Next
					processFindNext();
					return TRUE;

				case IDREPLACE :
					processReplace();
					return TRUE;

				case IDSWITCH :
					_currentStatus = !_currentStatus;
					doDialog(_currentStatus);
					return TRUE;

				case IDREPLACEALL :
				{
					(*_ppEditView)->execute(SCI_BEGINUNDOACTION);
					int nbReplaced = processAll(REPLACE_ALL);
					(*_ppEditView)->execute(SCI_ENDUNDOACTION);

					char result[64];
					if (nbReplaced < 0)
						strcpy(result, "The regular expression to search is formed badly");
					else
					{
						itoa(nbReplaced, result, 10);
						strcat(result, " tokens are replaced.");
					}
					::MessageBox(_hSelf, result, "", MB_OK);
					return TRUE;
				}

				case IDC_REPLACE_OPENEDFILES :
					replaceAllInOpenedDocs();
					return TRUE;

				case IDC_FINDALL_OPENEDFILES :
					findAllIn(ALL_OPEN_DOCS);
					return TRUE;

				case IDC_FINDINFILES :
					_findInFilesDlg.doDialog(_isRTL);
					return TRUE;

				case IDC_GETCURRENTDOCTYPE :
					*((LangType *)lParam) = (*_ppEditView)->getCurrentDocType();
					return TRUE;

				case IDC_FINDINFILES_LAUNCH : // Virtual Control which don't exist
				{
					findAllIn(FILES_IN_DIR);
					return TRUE;
				}


				case IDCMARKALL :
				{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -