New feature: File browser

This commit is contained in:
Don Ho 2016-01-23 02:24:37 +01:00
parent 576de36a12
commit 07ce6c2516
20 changed files with 2555 additions and 32 deletions

View File

@ -885,5 +885,13 @@ bool str2Clipboard(const generic_string &str2cpy, HWND hwnd)
return true; return true;
} }
bool matchInList(const TCHAR *fileName, const std::vector<generic_string> & patterns)
{
for (size_t i = 0, len = patterns.size(); i < len; ++i)
{
if (PathMatchSpec(fileName, patterns[i].c_str()))
return true;
}
return false;
}

View File

@ -88,7 +88,7 @@ generic_string BuildMenuFileName(int filenameLen, unsigned int pos, const generi
std::string getFileContent(const TCHAR *file2read); std::string getFileContent(const TCHAR *file2read);
generic_string relativeFilePathToFullFilePath(const TCHAR *relativeFilePath); generic_string relativeFilePathToFullFilePath(const TCHAR *relativeFilePath);
void writeFileContent(const TCHAR *file2write, const char *content2write); void writeFileContent(const TCHAR *file2write, const char *content2write);
bool matchInList(const TCHAR *fileName, const std::vector<generic_string> & patterns);
class WcharMbcsConvertor final class WcharMbcsConvertor final
{ {

View File

@ -27,7 +27,7 @@
#include "Parameters.h" #include "Parameters.h"
#include "Process.h" #include "Processus.h"
void Process::run() void Process::run()

View File

@ -29,6 +29,8 @@
#ifndef PROCESSUS_H #ifndef PROCESSUS_H
#define PROCESSUS_H #define PROCESSUS_H
#include "common.h"
enum progType {WIN32_PROG, CONSOLE_PROG}; enum progType {WIN32_PROG, CONSOLE_PROG};
class Process class Process

View File

@ -47,6 +47,7 @@
#include "ProjectPanel.h" #include "ProjectPanel.h"
#include "documentMap.h" #include "documentMap.h"
#include "functionListPanel.h" #include "functionListPanel.h"
#include "fileBrowser.h"
#include "LongRunningOperation.h" #include "LongRunningOperation.h"
using namespace std; using namespace std;
@ -193,6 +194,7 @@ Notepad_plus::~Notepad_plus()
delete _pProjectPanel_3; delete _pProjectPanel_3;
delete _pDocMap; delete _pDocMap;
delete _pFuncList; delete _pFuncList;
delete _pFileBrowser;
} }
LRESULT Notepad_plus::init(HWND hwnd) LRESULT Notepad_plus::init(HWND hwnd)
@ -1090,16 +1092,6 @@ bool Notepad_plus::replaceInOpenedFiles() {
return true; return true;
} }
bool Notepad_plus::matchInList(const TCHAR *fileName, const vector<generic_string> & patterns)
{
for (size_t i = 0, len = patterns.size() ; i < len ; ++i)
{
if (PathMatchSpec(fileName, patterns[i].c_str()))
return true;
}
return false;
}
void Notepad_plus::wsTabConvert(spaceTab whichWay) void Notepad_plus::wsTabConvert(spaceTab whichWay)
{ {
@ -1435,7 +1427,6 @@ void Notepad_plus::getMatchedFileNames(const TCHAR *dir, const vector<generic_st
::FindClose(hFile); ::FindClose(hFile);
} }
bool Notepad_plus::replaceInFiles() bool Notepad_plus::replaceInFiles()
{ {
const TCHAR *dir2Search = _findReplaceDlg.getDir2Search(); const TCHAR *dir2Search = _findReplaceDlg.getDir2Search();
@ -2969,16 +2960,82 @@ void Notepad_plus::dropFiles(HDROP hdrop)
int filesDropped = ::DragQueryFile(hdrop, 0xffffffff, NULL, 0); int filesDropped = ::DragQueryFile(hdrop, 0xffffffff, NULL, 0);
BufferID lastOpened = BUFFER_INVALID; BufferID lastOpened = BUFFER_INVALID;
for (int i = 0 ; i < filesDropped ; ++i)
vector<generic_string> folderPaths;
vector<generic_string> filePaths;
for (int i = 0; i < filesDropped; ++i)
{ {
TCHAR pathDropped[MAX_PATH]; TCHAR pathDropped[MAX_PATH];
::DragQueryFile(hdrop, i, pathDropped, MAX_PATH); ::DragQueryFile(hdrop, i, pathDropped, MAX_PATH);
BufferID test = doOpen(pathDropped); if (::PathIsDirectory(pathDropped))
if (test != BUFFER_INVALID) {
lastOpened = test; size_t len = lstrlen(pathDropped);
//setLangStatus(_pEditView->getCurrentDocType()); if (len > 0 && pathDropped[len - 1] != TCHAR('\\'))
{
pathDropped[len] = TCHAR('\\');
pathDropped[len + 1] = TCHAR('\0');
}
folderPaths.push_back(pathDropped);
}
else
{
filePaths.push_back(pathDropped);
}
} }
if (lastOpened != BUFFER_INVALID) {
bool isOldMode = false;
if (isOldMode || folderPaths.size() == 0) // old mode or new mode + only files
{
BufferID lastOpened = BUFFER_INVALID;
for (int i = 0; i < filesDropped; ++i)
{
TCHAR pathDropped[MAX_PATH];
::DragQueryFile(hdrop, i, pathDropped, MAX_PATH);
BufferID test = doOpen(pathDropped);
if (test != BUFFER_INVALID)
lastOpened = test;
}
if (lastOpened != BUFFER_INVALID) {
switchToFile(lastOpened);
}
}
else if (not isOldMode && (folderPaths.size() != 0 && filePaths.size() != 0)) // new mode && both folders & files
{
// display error & do nothing
}
else if (not isOldMode && (folderPaths.size() != 0 && filePaths.size() == 0)) // new mode && only folders
{
launchFileBrowser();
// process new mode
for (int i = 0; i < filesDropped; ++i)
{
_pFileBrowser->addRootFolder(folderPaths[i]);
}
/*
for (int i = 0; i < filesDropped; ++i)
{
if (not _pFileBrowser->isAlreadyExist(folderPaths[i]))
{
vector<generic_string> patterns2Match;
patterns2Match.push_back(TEXT("*.*"));
FolderInfo directoryStructure;
getDirectoryStructure(folderPaths[i].c_str(), patterns2Match, directoryStructure, true, false);
_pFileBrowser->setDirectoryStructure(directoryStructure);
}
int j = 0;
j++;
}
*/
}
if (lastOpened != BUFFER_INVALID)
{
switchToFile(lastOpened); switchToFile(lastOpened);
} }
::DragFinish(hdrop); ::DragFinish(hdrop);
@ -4607,6 +4664,7 @@ void Notepad_plus::notifyBufferChanged(Buffer * buffer, int mask)
// Then we ask user to update // Then we ask user to update
didDialog = true; didDialog = true;
if (doReloadOrNot(buffer->getFullPathName(), buffer->isDirty()) != IDYES) if (doReloadOrNot(buffer->getFullPathName(), buffer->isDirty()) != IDYES)
break; //abort break; //abort
} }
@ -5294,6 +5352,45 @@ void Notepad_plus::launchAnsiCharPanel()
_pAnsiCharPanel->display(); _pAnsiCharPanel->display();
} }
void Notepad_plus::launchFileBrowser()
{
if (!_pFileBrowser)
{
_pFileBrowser = new FileBrowser;
_pFileBrowser->init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf());
tTbData data;
memset(&data, 0, sizeof(data));
_pFileBrowser->create(&data);
data.pszName = TEXT("ST");
::SendMessage(_pPublicInterface->getHSelf(), NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, (WPARAM)_pFileBrowser->getHSelf());
// define the default docking behaviour
data.uMask = DWS_DF_CONT_LEFT | DWS_ICONTAB;
data.hIconTab = (HICON)::LoadImage(_pPublicInterface->getHinst(), MAKEINTRESOURCE(IDR_PROJECTPANEL_ICO), IMAGE_ICON, 14, 14, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT);
data.pszModuleName = NPP_INTERNAL_FUCTION_STR;
NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker();
generic_string title_temp = pNativeSpeaker->getAttrNameStr(PM_PROJECTPANELTITLE, "FileBrowser", "PanelTitle");
static TCHAR title[32];
if (title_temp.length() < 32)
{
lstrcpy(title, title_temp.c_str());
data.pszName = title;
}
::SendMessage(_pPublicInterface->getHSelf(), NPPM_DMMREGASDCKDLG, 0, (LPARAM)&data);
COLORREF fgColor = (NppParameters::getInstance())->getCurrentDefaultFgColor();
COLORREF bgColor = (NppParameters::getInstance())->getCurrentDefaultBgColor();
_pFileBrowser->setBackgroundColor(bgColor);
_pFileBrowser->setForegroundColor(fgColor);
}
_pFileBrowser->display();
}
void Notepad_plus::launchProjectPanel(int cmdID, ProjectPanel ** pProjPanel, int panelID) void Notepad_plus::launchProjectPanel(int cmdID, ProjectPanel ** pProjPanel, int panelID)
{ {

View File

@ -105,7 +105,7 @@
#endif //DOCKINGMANAGER_H #endif //DOCKINGMANAGER_H
#ifndef PROCESSUS_H #ifndef PROCESSUS_H
#include "Process.h" #include "Processus.h"
#endif //PROCESSUS_H #endif //PROCESSUS_H
#ifndef AUTOCOMPLETION_H #ifndef AUTOCOMPLETION_H
@ -195,9 +195,7 @@ class VerticalFileSwitcher;
class ProjectPanel; class ProjectPanel;
class DocumentMap; class DocumentMap;
class FunctionListPanel; class FunctionListPanel;
class FileBrowser;
class Notepad_plus final class Notepad_plus final
@ -421,6 +419,8 @@ private:
ProjectPanel* _pProjectPanel_2 = nullptr; ProjectPanel* _pProjectPanel_2 = nullptr;
ProjectPanel* _pProjectPanel_3 = nullptr; ProjectPanel* _pProjectPanel_3 = nullptr;
FileBrowser* _pFileBrowser = nullptr;
DocumentMap* _pDocMap = nullptr; DocumentMap* _pDocMap = nullptr;
FunctionListPanel* _pFuncList = nullptr; FunctionListPanel* _pFuncList = nullptr;
@ -589,9 +589,7 @@ private:
bool findInOpenedFiles(); bool findInOpenedFiles();
bool findInCurrentFile(); bool findInCurrentFile();
bool matchInList(const TCHAR *fileName, const std::vector<generic_string> & patterns);
void getMatchedFileNames(const TCHAR *dir, const std::vector<generic_string> & patterns, std::vector<generic_string> & fileNames, bool isRecursive, bool isInHiddenDir); void getMatchedFileNames(const TCHAR *dir, const std::vector<generic_string> & patterns, std::vector<generic_string> & fileNames, bool isRecursive, bool isInHiddenDir);
void doSynScorll(HWND hW); void doSynScorll(HWND hW);
void setWorkingDir(const TCHAR *dir); void setWorkingDir(const TCHAR *dir);
bool str2Cliboard(const generic_string & str2cpy); bool str2Cliboard(const generic_string & str2cpy);
@ -623,6 +621,7 @@ private:
void launchProjectPanel(int cmdID, ProjectPanel ** pProjPanel, int panelID); void launchProjectPanel(int cmdID, ProjectPanel ** pProjPanel, int panelID);
void launchDocMap(); void launchDocMap();
void launchFunctionList(); void launchFunctionList();
void launchFileBrowser();
void showAllQuotes() const; void showAllQuotes() const;
static DWORD WINAPI threadTextPlayer(void *text2display); static DWORD WINAPI threadTextPlayer(void *text2display);
static DWORD WINAPI threadTextTroller(void *params); static DWORD WINAPI threadTextTroller(void *params);
@ -640,6 +639,8 @@ private:
} }
static DWORD WINAPI backupDocument(void *params); static DWORD WINAPI backupDocument(void *params);
//static DWORD WINAPI monitorFileOnChange(void * params);
//static DWORD WINAPI monitorDirectoryOnChange(void * params);
}; };

View File

@ -37,8 +37,117 @@
using namespace std; using namespace std;
/*
struct monitorFileParams {
WCHAR _fullFilePath[MAX_PATH];
};
DWORD WINAPI Notepad_plus::monitorFileOnChange(void * params)
{
monitorFileParams *mfp = (monitorFileParams *)params;
//Le répertoire à surveiller :
WCHAR folderToMonitor[MAX_PATH];
//::MessageBoxW(NULL, mfp->_fullFilePath, TEXT("PATH AFTER thread"), MB_OK);
lstrcpy(folderToMonitor, mfp->_fullFilePath);
//::PathRemoveFileSpecW(folderToMonitor);
HANDLE hDirectory = ::CreateFile(folderToMonitor,
FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
// buffer qui va récuppérer les informations de mise à jour
const int MAX_BUFFER = 1024;
BYTE buffer[MAX_BUFFER];
DWORD nombreDeByteRetournes = 0;
bool cond = true;
while (cond)
{
::Sleep(1000);
// surveille un changement dans le répertoire : il attend tant que rien ne se passe : cest synchrone.
BOOL res = ReadDirectoryChangesW(hDirectory, buffer, MAX_BUFFER,
TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE, &nombreDeByteRetournes, NULL, NULL);
if (res == FALSE)
continue;
// puis on transforme le buffer pour être lisible.
FILE_NOTIFY_INFORMATION *notifyInfo = (FILE_NOTIFY_INFORMATION *)buffer;
wchar_t fn[MAX_PATH];
memset(fn, 0, MAX_PATH*sizeof(wchar_t));
if (notifyInfo->Action != FILE_ACTION_MODIFIED)
continue;
// affiche le fichier qui a été modifié.
if (notifyInfo->FileNameLength <= 0)
continue;
TCHAR str2Display[512];
generic_strncpy(fn, notifyInfo->FileName, notifyInfo->FileNameLength / sizeof(wchar_t));
generic_sprintf(str2Display, TEXT("offset : %d\raction : %d\rfn len : %d\rfn : %s"), notifyInfo->NextEntryOffset, notifyInfo->Action, notifyInfo->FileNameLength, notifyInfo->FileName);
// on peut vérifier avec ceci :
//printInt(notifyInfo->NextEntryOffset);
//printInt(notifyInfo->FileNameLength);
MessageBox(NULL, str2Display, TEXT("name"), MB_OK);
}
return TRUE;
}
DWORD WINAPI Notepad_plus::monitorDirectoryOnChange(void * params)
{
monitorFileParams *mfp = (monitorFileParams *)params;
//Le répertoire à surveiller :
WCHAR folderToMonitor[MAX_PATH];
//::MessageBoxW(NULL, mfp->_fullFilePath, TEXT("PATH AFTER thread"), MB_OK);
lstrcpy(folderToMonitor, mfp->_fullFilePath);
//::PathRemoveFileSpecW(folderToMonitor);
HANDLE hDirectory = ::CreateFile(folderToMonitor,
FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
// buffer qui va récuppérer les informations de mise à jour
const int MAX_BUFFER = 1024;
BYTE buffer[MAX_BUFFER];
DWORD nombreDeByteRetournes = 0;
bool cond = true;
while (cond)
{
::Sleep(1000);
// surveille un changement dans le répertoire : il attend tant que rien ne se passe : cest synchrone.
ReadDirectoryChangesW(hDirectory, buffer, MAX_BUFFER,
TRUE, FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_FILE_NAME, &nombreDeByteRetournes, NULL, NULL);
// puis on transforme le buffer pour être lisible.
FILE_NOTIFY_INFORMATION *notifyInfo = (FILE_NOTIFY_INFORMATION *)buffer;
wchar_t fn[MAX_PATH];
memset(fn, 0, MAX_PATH*sizeof(wchar_t));
//if (notifyInfo->Action != FILE_ACTION_MODIFIED)
if (notifyInfo->Action != FILE_ACTION_ADDED && notifyInfo->Action != FILE_ACTION_REMOVED && notifyInfo->Action != FILE_ACTION_RENAMED_OLD_NAME && notifyInfo->Action != FILE_ACTION_RENAMED_NEW_NAME)
continue;
// affiche le fichier qui a été modifié.
//if (notifyInfo->FileNameLength <= 0)
//continue;
generic_strncpy(fn, notifyInfo->FileName, notifyInfo->FileNameLength / sizeof(wchar_t));
// on peut vérifier avec ceci :
//printInt(notifyInfo->FileNameLength);
MessageBox(NULL, fn, TEXT("name"), MB_OK);
}
return TRUE;
}
*/
BufferID Notepad_plus::doOpen(const generic_string& fileName, bool isRecursive, bool isReadOnly, int encoding, const TCHAR *backupFileName, time_t fileNameTimestamp) BufferID Notepad_plus::doOpen(const generic_string& fileName, bool isRecursive, bool isReadOnly, int encoding, const TCHAR *backupFileName, time_t fileNameTimestamp)
{ {
@ -256,6 +365,20 @@ BufferID Notepad_plus::doOpen(const generic_string& fileName, bool isRecursive,
_pluginsManager.notify(&scnN); _pluginsManager.notify(&scnN);
if (_pFileSwitcherPanel) if (_pFileSwitcherPanel)
_pFileSwitcherPanel->newItem(buf, currentView()); _pFileSwitcherPanel->newItem(buf, currentView());
/*
if (::PathFileExists(longFileName))
{
// Thread to
monitorFileParams *params = new monitorFileParams;
lstrcpy(params->_fullFilePath, longFileName);
//::MessageBoxW(NULL, params._fullFilePath, TEXT("PATH b4 thread"), MB_OK);
//HANDLE hThread = ::CreateThread(NULL, 0, monitorFileOnChange, params, 0, NULL);
HANDLE hThread = ::CreateThread(NULL, 0, monitorFileOnChange, params, 0, NULL);
::CloseHandle(hThread);
}
*/
} }
else else
{ {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,191 @@
// This file is part of Notepad++ project
// Copyright (C)2003 Don HO <don.h@free.fr>
//
// 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.
//
// Note that the GPL places important restrictions on "derived works", yet
// it does not provide a detailed definition of that term. To avoid
// misunderstandings, we consider an application to constitute a
// "derivative work" for the purpose of this license if it does any of the
// following:
// 1. Integrates source code from Notepad++.
// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable
// installer, such as those produced by InstallShield.
// 3. Links to a library or executes a program that does any of the above.
//
// 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.
#ifndef FILEBROWSER_H
#define FILEBROWSER_H
//#include <windows.h>
#ifndef DOCKINGDLGINTERFACE_H
#include "DockingDlgInterface.h"
#endif //DOCKINGDLGINTERFACE_H
#include "TreeView.h"
#include "fileBrowser_rc.h"
#define PM_NEWFOLDERNAME TEXT("Folder Name")
#define PM_NEWPROJECTNAME TEXT("Project Name")
#define PM_SAVEWORKSPACE TEXT("Save")
#define PM_SAVEASWORKSPACE TEXT("Save As...")
#define PM_SAVEACOPYASWORKSPACE TEXT("Save a Copy As...")
#define PM_NEWPROJECTWORKSPACE TEXT("Add New Project")
#define PM_EDITRENAME TEXT("Rename")
#define PM_EDITNEWFOLDER TEXT("Add Folder")
#define PM_EDITADDFILES TEXT("Add Files...")
#define PM_EDITADDFILESRECUSIVELY TEXT("Add Files from Directory...")
#define PM_EDITREMOVE TEXT("Remove\tDEL")
#define PM_EDITMODIFYFILE TEXT("Modify File Path")
#define PM_WORKSPACEMENUENTRY TEXT("Workspace")
#define PM_EDITMENUENTRY TEXT("Edit")
#define PM_MOVEUPENTRY TEXT("Move Up\tCtrl+Up")
#define PM_MOVEDOWNENTRY TEXT("Move Down\tCtrl+Down")
class TiXmlNode;
class changeInfo final
{
friend class FolderInfo;
public:
enum folderChangeAction{
add, remove, rename
};
private:
bool isFile; // true: file, false: folder
generic_string _fullFilePath;
std::vector<generic_string> _relativePath;
folderChangeAction _action;
};
class FileInfo final
{
friend class FileBrowser;
friend class FolderInfo;
public:
FileInfo(const generic_string & fn) { _path = fn; };
generic_string getLabel() { return ::PathFindFileName(_path.c_str()); };
private:
generic_string _path;
};
class FolderInfo final
{
friend class FileBrowser;
friend class FolderUpdater;
public:
void setPath(generic_string dn) { _path = dn; };
void addFile(generic_string fn) { _files.push_back(FileInfo(fn)); };
void addSubFolder(FolderInfo subDirectoryStructure) { _subFolders.push_back(subDirectoryStructure); };
bool compare(const FolderInfo & struct2compare, std::vector<changeInfo> & result);
static bool makeDiff(FolderInfo & struct1, FolderInfo & struct2static, std::vector<changeInfo> result);
generic_string getLabel();
private:
std::vector<FolderInfo> _subFolders;
std::vector<FileInfo> _files;
generic_string _path;
generic_string _contentHash;
};
enum BrowserNodeType {
browserNodeType_root = 0, browserNodeType_folder = 2, browserNodeType_file = 3
};
class FolderUpdater {
friend class FileBrowser;
public:
FolderUpdater(FolderInfo fi, HWND hFileBrowser) : _rootFolder(fi), _hFileBrowser(hFileBrowser) {};
~FolderUpdater() {};
bool updateTree(changeInfo changeInfo); // postMessage to FileBrowser to upgrade GUI
void startWatcher();
void stopWatcher();
private:
FolderInfo _rootFolder;
HWND _hFileBrowser = nullptr;
bool _toBeContinued = true;
HANDLE _watchThreadHandle = nullptr;
HANDLE _mutex = nullptr;
static DWORD WINAPI watching(void *param);
};
class FileBrowser : public DockingDlgInterface {
public:
FileBrowser(): DockingDlgInterface(IDD_FILEBROWSER) {};
~FileBrowser();
void init(HINSTANCE hInst, HWND hPere) {
DockingDlgInterface::init(hInst, hPere);
}
virtual void display(bool toShow = true) const {
DockingDlgInterface::display(toShow);
};
void setParent(HWND parent2set){
_hParent = parent2set;
};
virtual void setBackgroundColor(COLORREF bgColour) {
TreeView_SetBkColor(_treeView.getHSelf(), bgColour);
};
virtual void setForegroundColor(COLORREF fgColour) {
TreeView_SetTextColor(_treeView.getHSelf(), fgColour);
};
void addRootFolder(generic_string);
protected:
TreeView _treeView;
HIMAGELIST _hImaLst;
HWND _hToolbarMenu = NULL;
HMENU _hWorkSpaceMenu = NULL;
HMENU _hProjectMenu = NULL;
HMENU _hFolderMenu = NULL;
HMENU _hFileMenu = NULL;
std::vector<FolderUpdater> _folderUpdaters;
void initMenus();
void destroyMenus();
BOOL setImageList(int root_clean_id, int root_dirty_id, int project_id, int open_node_id, int closed_node_id, int leaf_id, int ivalid_leaf_id);
void addFiles(HTREEITEM hTreeItem);
void recursiveAddFilesFrom(const TCHAR *folderPath, HTREEITEM hTreeItem);
HTREEITEM addFolder(HTREEITEM hTreeItem, const TCHAR *folderName);
generic_string getRelativePath(const generic_string & fn, const TCHAR *workSpaceFileName);
void buildProjectXml(TiXmlNode *root, HTREEITEM hItem, const TCHAR* fn2write);
BrowserNodeType getNodeType(HTREEITEM hItem);
void popupMenuCmd(int cmdID);
POINT getMenuDisplayPoint(int iButton);
virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);
void notified(LPNMHDR notification);
void showContextMenu(int x, int y);
void openSelectFile();
void getDirectoryStructure(const TCHAR *dir, const std::vector<generic_string> & patterns, FolderInfo & directoryStructure, bool isRecursive, bool isInHiddenDir);
HTREEITEM createFolderItemsFromDirStruct(HTREEITEM hParentItem, const FolderInfo & directoryStructure);
};
#endif // FILEBROWSER_H

View File

@ -0,0 +1,52 @@
// This file is part of Notepad++ project
// Copyright (C)2003 Don HO <don.h@free.fr>
//
// 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.
//
// Note that the GPL places important restrictions on "derived works", yet
// it does not provide a detailed definition of that term. To avoid
// misunderstandings, we consider an application to constitute a
// "derivative work" for the purpose of this license if it does any of the
// following:
// 1. Integrates source code from Notepad++.
// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable
// installer, such as those produced by InstallShield.
// 3. Links to a library or executes a program that does any of the above.
//
// 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 <windows.h>
#include "FileBrowser_rc.h"
IDD_FILEBROWSER DIALOGEX 26, 41, 142, 324
STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE
CAPTION "File Browser"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
//CONTROL "",ID_PROJECTTREEVIEW,"SysTreeView32", TVS_HASBUTTONS | TVS_EDITLABELS | TVS_INFOTIP | TVS_HASLINES | WS_BORDER | WS_HSCROLL | WS_TABSTOP,7,7,172,93
END
/*
IDD_FILERELOCALIZER_DIALOG DIALOGEX 0, 0, 350, 48
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_TOOLWINDOW
CAPTION "Change file full path name"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,235,27,50,14
PUSHBUTTON "Cancel",IDCANCEL,290,27,50,14
EDITTEXT IDC_EDIT_FILEFULLPATHNAME,7,7,335,14,ES_AUTOHSCROLL
END
*/

View File

@ -0,0 +1,51 @@
// This file is part of Notepad++ project
// Copyright (C)2003 Don HO <don.h@free.fr>
//
// 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.
//
// Note that the GPL places important restrictions on "derived works", yet
// it does not provide a detailed definition of that term. To avoid
// misunderstandings, we consider an application to constitute a
// "derivative work" for the purpose of this license if it does any of the
// following:
// 1. Integrates source code from Notepad++.
// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable
// installer, such as those produced by InstallShield.
// 3. Links to a library or executes a program that does any of the above.
//
// 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.
#ifndef FILEBROWSER_RC_H
#define FILEBROWSER_RC_H
#define IDD_FILEBROWSER 3500
#define IDD_FILEBROWSER_MENU (IDD_FILEBROWSER + 10)
#define IDM_FILEBROWSER_RENAME (IDD_FILEBROWSER_MENU + 1)
#define IDM_FILEBROWSER_NEWFOLDER (IDD_FILEBROWSER_MENU + 2)
#define IDM_FILEBROWSER_ADDFILES (IDD_FILEBROWSER_MENU + 3)
#define IDM_FILEBROWSER_DELETEFOLDER (IDD_FILEBROWSER_MENU + 4)
#define IDM_FILEBROWSER_DELETEFILE (IDD_FILEBROWSER_MENU + 5)
#define IDM_FILEBROWSER_MODIFYFILEPATH (IDD_FILEBROWSER_MENU + 6)
#define IDM_FILEBROWSER_MOVEUP (IDD_FILEBROWSER_MENU + 8)
#define IDM_FILEBROWSER_MOVEDOWN (IDD_FILEBROWSER_MENU + 9)
#define IDD_FILEBROWSER_CTRL (IDD_FILEBROWSER + 30)
#define ID_FILEBROWSERTREEVIEW (IDD_FILEBROWSER_CTRL + 1)
#define IDB_FILEBROWSER_BTN (IDD_FILEBROWSER_CTRL + 2)
#define IDB_FILEBROWSER_EDIT_BTN (IDD_FILEBROWSER_CTRL + 3)
#endif // FILEBROWSER_RC_H

View File

@ -0,0 +1,112 @@
//
// The MIT License
//
// Copyright (c) 2010 James E Beveridge
//
// 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:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// 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.
// This sample code is for my blog entry titled, "Understanding ReadDirectoryChangesW"
// http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html
// See ReadMe.txt for overview information.
#include "ReadDirectoryChanges.h"
#include "ReadDirectoryChangesPrivate.h"
using namespace ReadDirectoryChangesPrivate;
///////////////////////////////////////////////////////////////////////////
// CReadDirectoryChanges
CReadDirectoryChanges::CReadDirectoryChanges(int nMaxCount)
: m_Notifications(nMaxCount)
{
m_hThread = NULL;
m_dwThreadId= 0;
m_pServer = new CReadChangesServer(this);
}
CReadDirectoryChanges::~CReadDirectoryChanges()
{
Terminate();
delete m_pServer;
}
void CReadDirectoryChanges::Init()
{
//
// Kick off the worker thread, which will be
// managed by CReadChangesServer.
//
m_hThread = (HANDLE)_beginthreadex(NULL,
0,
CReadChangesServer::ThreadStartProc,
m_pServer,
0,
&m_dwThreadId
);
}
void CReadDirectoryChanges::Terminate()
{
if (m_hThread)
{
::QueueUserAPC(CReadChangesServer::TerminateProc, m_hThread, (ULONG_PTR)m_pServer);
::WaitForSingleObjectEx(m_hThread, 10000, true);
::CloseHandle(m_hThread);
m_hThread = NULL;
m_dwThreadId = 0;
}
}
void CReadDirectoryChanges::AddDirectory( LPCTSTR szDirectory, BOOL bWatchSubtree, DWORD dwNotifyFilter, DWORD dwBufferSize )
{
if (!m_hThread)
Init();
CReadChangesRequest* pRequest = new CReadChangesRequest(m_pServer, szDirectory, bWatchSubtree, dwNotifyFilter, dwBufferSize);
QueueUserAPC(CReadChangesServer::AddDirectoryProc, m_hThread, (ULONG_PTR)pRequest);
}
void CReadDirectoryChanges::Push(DWORD dwAction, CStringW& wstrFilename)
{
TDirectoryChangeNotification dirChangeNotif = TDirectoryChangeNotification(dwAction, wstrFilename);
m_Notifications.push(dirChangeNotif);
}
bool CReadDirectoryChanges::Pop(DWORD& dwAction, CStringW& wstrFilename)
{
TDirectoryChangeNotification pair;
if (!m_Notifications.pop(pair))
return false;
dwAction = pair.first;
wstrFilename = pair.second;
return true;
}
bool CReadDirectoryChanges::CheckOverflow()
{
bool b = m_Notifications.overflow();
if (b)
m_Notifications.clear();
return b;
}

View File

@ -0,0 +1,164 @@
//
// The MIT License
//
// Copyright (c) 2010 James E Beveridge
//
// 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:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// 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.
// This sample code is for my blog entry titled, "Understanding ReadDirectoryChangesW"
// http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html
// See ReadMe.txt for overview information.
#pragma once
#define _CRT_SECURE_NO_DEPRECATE
#include "targetver.h"
#include <stdio.h>
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#endif
#include <windows.h>
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
#include <atlbase.h>
#include <atlstr.h>
#include <vector>
#include <list>
using namespace std;
#include "ThreadSafeQueue.h"
typedef pair<DWORD,CStringW> TDirectoryChangeNotification;
namespace ReadDirectoryChangesPrivate
{
class CReadChangesServer;
}
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Track changes to filesystem directories and report them
/// to the caller via a thread-safe queue.
/// </summary>
/// <remarks>
/// <para>
/// This sample code is based on my blog entry titled, "Understanding ReadDirectoryChangesW"
/// http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html
/// </para><para>
/// All functions in CReadDirectoryChangesServer run in
/// the context of the calling thread.
/// </para>
/// <example><code>
/// CReadDirectoryChanges changes;
/// changes.AddDirectory(_T("C:\\"), false, dwNotificationFlags);
///
/// const HANDLE handles[] = { hStopEvent, changes.GetWaitHandle() };
///
/// while (!bTerminate)
/// {
/// ::MsgWaitForMultipleObjectsEx(
/// _countof(handles),
/// handles,
/// INFINITE,
/// QS_ALLINPUT,
/// MWMO_INPUTAVAILABLE | MWMO_ALERTABLE);
/// switch (rc)
/// {
/// case WAIT_OBJECT_0 + 0:
/// bTerminate = true;
/// break;
/// case WAIT_OBJECT_0 + 1:
/// // We've received a notification in the queue.
/// {
/// DWORD dwAction;
/// CStringW wstrFilename;
/// changes.Pop(dwAction, wstrFilename);
/// wprintf(L"%s %s\n", ExplainAction(dwAction), wstrFilename);
/// }
/// break;
/// case WAIT_OBJECT_0 + _countof(handles):
/// // Get and dispatch message
/// break;
/// case WAIT_IO_COMPLETION:
/// // APC complete.No action needed.
/// break;
/// }
/// }
/// </code></example>
/// </remarks>
class CReadDirectoryChanges
{
public:
CReadDirectoryChanges(int nMaxChanges=1000);
~CReadDirectoryChanges();
void Init();
void Terminate();
/// <summary>
/// Add a new directory to be monitored.
/// </summary>
/// <param name="wszDirectory">Directory to monitor.</param>
/// <param name="bWatchSubtree">True to also monitor subdirectories.</param>
/// <param name="dwNotifyFilter">The types of file system events to monitor, such as FILE_NOTIFY_CHANGE_ATTRIBUTES.</param>
/// <param name="dwBufferSize">The size of the buffer used for overlapped I/O.</param>
/// <remarks>
/// <para>
/// This function will make an APC call to the worker thread to issue a new
/// ReadDirectoryChangesW call for the given directory with the given flags.
/// </para>
/// </remarks>
void AddDirectory( LPCTSTR wszDirectory, BOOL bWatchSubtree, DWORD dwNotifyFilter, DWORD dwBufferSize=16384 );
/// <summary>
/// Return a handle for the Win32 Wait... functions that will be
/// signaled when there is a queue entry.
/// </summary>
HANDLE GetWaitHandle() { return m_Notifications.GetWaitHandle(); }
bool Pop(DWORD& dwAction, CStringW& wstrFilename);
// "Push" is for usage by ReadChangesRequest. Not intended for external usage.
void Push(DWORD dwAction, CStringW& wstrFilename);
// Check if the queue overflowed. If so, clear it and return true.
bool CheckOverflow();
unsigned int GetThreadId() { return m_dwThreadId; }
protected:
ReadDirectoryChangesPrivate::CReadChangesServer* m_pServer;
HANDLE m_hThread;
unsigned int m_dwThreadId;
CThreadSafeQueue<TDirectoryChangeNotification> m_Notifications;
};

View File

@ -0,0 +1,178 @@
//
// The MIT License
//
// Copyright (c) 2010 James E Beveridge
//
// 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:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// 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.
// This sample code is for my blog entry titled, "Understanding ReadDirectoryChangesW"
// http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html
// See ReadMe.txt for overview information.
#include "ReadDirectoryChanges.h"
#include "ReadDirectoryChangesPrivate.h"
// The namespace is a convenience to emphasize that these are internals
// interfaces. The namespace can be safely removed if you need to.
namespace ReadDirectoryChangesPrivate
{
///////////////////////////////////////////////////////////////////////////
// CReadChangesRequest
CReadChangesRequest::CReadChangesRequest(CReadChangesServer* pServer, LPCTSTR sz, BOOL b, DWORD dw, DWORD size)
{
m_pServer = pServer;
m_dwFilterFlags = dw;
m_bIncludeChildren = b;
m_wstrDirectory = sz;
m_hDirectory = 0;
::ZeroMemory(&m_Overlapped, sizeof(OVERLAPPED));
// The hEvent member is not used when there is a completion
// function, so it's ok to use it to point to the object.
m_Overlapped.hEvent = this;
m_Buffer.resize(size);
m_BackupBuffer.resize(size);
}
CReadChangesRequest::~CReadChangesRequest()
{
// RequestTermination() must have been called successfully.
_ASSERTE(m_hDirectory == NULL);
}
bool CReadChangesRequest::OpenDirectory()
{
// Allow this routine to be called redundantly.
if (m_hDirectory)
return true;
m_hDirectory = ::CreateFileW(
m_wstrDirectory, // pointer to the file name
FILE_LIST_DIRECTORY, // access (read/write) mode
FILE_SHARE_READ // share mode
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE,
NULL, // security descriptor
OPEN_EXISTING, // how to create
FILE_FLAG_BACKUP_SEMANTICS // file attributes
| FILE_FLAG_OVERLAPPED,
NULL); // file with attributes to copy
if (m_hDirectory == INVALID_HANDLE_VALUE)
{
return false;
}
return true;
}
void CReadChangesRequest::BeginRead()
{
DWORD dwBytes=0;
// This call needs to be reissued after every APC.
::ReadDirectoryChangesW(
m_hDirectory, // handle to directory
&m_Buffer[0], // read results buffer
m_Buffer.size(), // length of buffer
m_bIncludeChildren, // monitoring option
m_dwFilterFlags, // filter conditions
&dwBytes, // bytes returned
&m_Overlapped, // overlapped buffer
&NotificationCompletion); // completion routine
}
//static
VOID CALLBACK CReadChangesRequest::NotificationCompletion(
DWORD dwErrorCode, // completion code
DWORD dwNumberOfBytesTransfered, // number of bytes transferred
LPOVERLAPPED lpOverlapped) // I/O information buffer
{
CReadChangesRequest* pBlock = (CReadChangesRequest*)lpOverlapped->hEvent;
if (dwErrorCode == ERROR_OPERATION_ABORTED)
{
::InterlockedDecrement(&pBlock->m_pServer->m_nOutstandingRequests);
delete pBlock;
return;
}
// Can't use sizeof(FILE_NOTIFY_INFORMATION) because
// the structure is padded to 16 bytes.
_ASSERTE(dwNumberOfBytesTransfered >= offsetof(FILE_NOTIFY_INFORMATION, FileName) + sizeof(WCHAR));
// This might mean overflow? Not sure.
if(!dwNumberOfBytesTransfered)
return;
pBlock->BackupBuffer(dwNumberOfBytesTransfered);
// Get the new read issued as fast as possible. The documentation
// says that the original OVERLAPPED structure will not be used
// again once the completion routine is called.
pBlock->BeginRead();
pBlock->ProcessNotification();
}
void CReadChangesRequest::ProcessNotification()
{
BYTE* pBase = m_BackupBuffer.data();
for (;;)
{
FILE_NOTIFY_INFORMATION& fni = (FILE_NOTIFY_INFORMATION&)*pBase;
CStringW wstrFilename(fni.FileName, fni.FileNameLength/sizeof(wchar_t));
// Handle a trailing backslash, such as for a root directory.
if (wstrFilename.Right(1) != L"\\")
wstrFilename = m_wstrDirectory + L"\\" + wstrFilename;
else
wstrFilename = m_wstrDirectory + wstrFilename;
// If it could be a short filename, expand it.
LPCWSTR wszFilename = PathFindFileNameW(wstrFilename);
int len = lstrlenW(wszFilename);
// The maximum length of an 8.3 filename is twelve, including the dot.
if (len <= 12 && wcschr(wszFilename, L'~'))
{
// Convert to the long filename form. Unfortunately, this
// does not work for deletions, so it's an imperfect fix.
wchar_t wbuf[MAX_PATH];
if (::GetLongPathNameW(wstrFilename, wbuf, _countof(wbuf)) > 0)
wstrFilename = wbuf;
}
m_pServer->m_pBase->Push(fni.Action, wstrFilename);
if (!fni.NextEntryOffset)
break;
pBase += fni.NextEntryOffset;
};
}
}

View File

@ -0,0 +1,177 @@
//
// The MIT License
//
// Copyright (c) 2010 James E Beveridge
//
// 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:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// 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.
// This sample code is for my blog entry titled, "Understanding ReadDirectoryChangesW"
// http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html
// See ReadMe.txt for overview information.
class CReadDirectoryChanges;
namespace ReadDirectoryChangesPrivate
{
class CReadChangesServer;
///////////////////////////////////////////////////////////////////////////
// All functions in CReadChangesRequest run in the context of the worker thread.
// One instance of this object is created for each call to AddDirectory().
class CReadChangesRequest
{
public:
CReadChangesRequest(CReadChangesServer* pServer, LPCTSTR sz, BOOL b, DWORD dw, DWORD size);
~CReadChangesRequest();
bool OpenDirectory();
void BeginRead();
// The dwSize is the actual number of bytes sent to the APC.
void BackupBuffer(DWORD dwSize)
{
// We could just swap back and forth between the two
// buffers, but this code is easier to understand and debug.
memcpy(&m_BackupBuffer[0], &m_Buffer[0], dwSize);
}
void ProcessNotification();
void RequestTermination()
{
::CancelIo(m_hDirectory);
::CloseHandle(m_hDirectory);
m_hDirectory = nullptr;
}
CReadChangesServer* m_pServer;
protected:
static VOID CALLBACK NotificationCompletion(
DWORD dwErrorCode, // completion code
DWORD dwNumberOfBytesTransfered, // number of bytes transferred
LPOVERLAPPED lpOverlapped); // I/O information buffer
// Parameters from the caller for ReadDirectoryChangesW().
DWORD m_dwFilterFlags;
BOOL m_bIncludeChildren;
CStringW m_wstrDirectory;
// Result of calling CreateFile().
HANDLE m_hDirectory;
// Required parameter for ReadDirectoryChangesW().
OVERLAPPED m_Overlapped;
// Data buffer for the request.
// Since the memory is allocated by malloc, it will always
// be aligned as required by ReadDirectoryChangesW().
vector<BYTE> m_Buffer;
// Double buffer strategy so that we can issue a new read
// request before we process the current buffer.
vector<BYTE> m_BackupBuffer;
};
///////////////////////////////////////////////////////////////////////////
// All functions in CReadChangesServer run in the context of the worker thread.
// One instance of this object is allocated for each instance of CReadDirectoryChanges.
// This class is responsible for thread startup, orderly thread shutdown, and shimming
// the various C++ member functions with C-style Win32 functions.
class CReadChangesServer
{
public:
CReadChangesServer(CReadDirectoryChanges* pParent)
{
m_bTerminate=false; m_nOutstandingRequests=0;m_pBase=pParent;
}
static unsigned int WINAPI ThreadStartProc(LPVOID arg)
{
CReadChangesServer* pServer = (CReadChangesServer*)arg;
pServer->Run();
return 0;
}
// Called by QueueUserAPC to start orderly shutdown.
static void CALLBACK TerminateProc(__in ULONG_PTR arg)
{
CReadChangesServer* pServer = (CReadChangesServer*)arg;
pServer->RequestTermination();
}
// Called by QueueUserAPC to add another directory.
static void CALLBACK AddDirectoryProc(__in ULONG_PTR arg)
{
CReadChangesRequest* pRequest = (CReadChangesRequest*)arg;
pRequest->m_pServer->AddDirectory(pRequest);
}
CReadDirectoryChanges* m_pBase;
volatile DWORD m_nOutstandingRequests;
protected:
void Run()
{
while (m_nOutstandingRequests || !m_bTerminate)
{
::SleepEx(INFINITE, true);
}
}
void AddDirectory( CReadChangesRequest* pBlock )
{
if (pBlock->OpenDirectory())
{
::InterlockedIncrement(&pBlock->m_pServer->m_nOutstandingRequests);
m_pBlocks.push_back(pBlock);
pBlock->BeginRead();
}
else
delete pBlock;
}
void RequestTermination()
{
m_bTerminate = true;
for (DWORD i=0; i<m_pBlocks.size(); ++i)
{
// Each Request object will delete itself.
m_pBlocks[i]->RequestTermination();
}
m_pBlocks.clear();
}
vector<CReadChangesRequest*> m_pBlocks;
bool m_bTerminate;
};
}

View File

@ -0,0 +1,116 @@
//
// The MIT License
//
// Copyright (c) 2010 James E Beveridge
//
// 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:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// 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.
// This sample code is for my blog entry titled, "Understanding ReadDirectoryChangesW"
// http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html
// See ReadMe.txt for overview information.
#include <list>
template <typename C>
class CThreadSafeQueue : protected std::list<C>
{
public:
CThreadSafeQueue(int nMaxCount)
{
m_bOverflow = false;
m_hSemaphore = ::CreateSemaphore(
NULL, // no security attributes
0, // initial count
nMaxCount, // max count
NULL); // anonymous
}
~CThreadSafeQueue()
{
::CloseHandle(m_hSemaphore);
m_hSemaphore = NULL;
}
void push(C& c)
{
CComCritSecLock<CComAutoCriticalSection> lock( m_Crit, true );
push_back( c );
lock.Unlock();
if (!::ReleaseSemaphore(m_hSemaphore, 1, NULL))
{
// If the semaphore is full, then take back the entry.
lock.Lock();
pop_back();
if (GetLastError() == ERROR_TOO_MANY_POSTS)
{
m_bOverflow = true;
}
}
}
bool pop(C& c)
{
CComCritSecLock<CComAutoCriticalSection> lock( m_Crit, true );
// If the user calls pop() more than once after the
// semaphore is signaled, then the semaphore count will
// get out of sync. We fix that when the queue empties.
if (empty())
{
while (::WaitForSingleObject(m_hSemaphore, 0) != WAIT_TIMEOUT)
1;
return false;
}
c = front();
pop_front();
return true;
}
// If overflow, use this to clear the queue.
void clear()
{
CComCritSecLock<CComAutoCriticalSection> lock( m_Crit, true );
for (DWORD i=0; i<size(); i++)
WaitForSingleObject(m_hSemaphore, 0);
__super::clear();
m_bOverflow = false;
}
bool overflow()
{
return m_bOverflow;
}
HANDLE GetWaitHandle() { return m_hSemaphore; }
protected:
HANDLE m_hSemaphore;
CComAutoCriticalSection m_Crit;
bool m_bOverflow;
};

View File

@ -0,0 +1,8 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

View File

@ -346,6 +346,8 @@
//See functionListPanel_rc.h //See functionListPanel_rc.h
//#define IDD_FUNCLIST_PANEL 3400 //#define IDD_FUNCLIST_PANEL 3400
//See fileBrowser_rc.h
//#define IDD_FILEBROWSER 3500
// See regExtDlg.h // See regExtDlg.h
//#define IDD_REGEXT 4000 //#define IDD_REGEXT 4000

View File

@ -26,7 +26,7 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "Notepad_plus_Window.h" #include "Notepad_plus_Window.h"
#include "Process.h" #include "Processus.h"
#include "Win32Exception.h" //Win32 exception #include "Win32Exception.h" //Win32 exception
#include "MiniDumper.h" //Write dump files #include "MiniDumper.h" //Write dump files

View File

@ -94,7 +94,7 @@
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed> <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\src\WinControls\AboutDlg;..\..\scintilla\include;..\include;..\src\WinControls;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\TabBar;..\src\WinControls\ToolBar;..\src\MISC\Process;..\src\ScitillaComponent;..\src\MISC;..\src\MISC\SysMsg;..\src\WinControls\StatusBar;..\src;..\src\WinControls\StaticDialog\RunDlg;..\src\tinyxml;..\src\WinControls\ColourPicker;..\src\Win32Explr;..\src\MISC\RegExt;..\src\WinControls\TrayIcon;..\src\WinControls\shortcut;..\src\WinControls\Grid;..\src\WinControls\ContextMenu;..\src\MISC\PluginsManager;..\src\WinControls\Preference;..\src\WinControls\WindowsDlg;..\src\WinControls\TaskList;..\src\WinControls\DockingWnd;..\src\WinControls\ToolTip;..\src\MISC\Exception;..\src\MISC\Common;..\src\tinyxml\tinyXmlA;..\src\WinControls\AnsiCharPanel;..\src\WinControls\ClipboardHistory;..\src\WinControls\FindCharsInRange;..\src\WinControls\VerticalFileSwitcher;..\src\WinControls\ProjectPanel;..\src\WinControls\DocumentMap;..\src\WinControls\FunctionList;..\src\uchardet;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\src\WinControls\AboutDlg;..\..\scintilla\include;..\include;..\src\WinControls;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\TabBar;..\src\WinControls\ToolBar;..\src\MISC\Process;..\src\ScitillaComponent;..\src\MISC;..\src\MISC\SysMsg;..\src\WinControls\StatusBar;..\src;..\src\WinControls\StaticDialog\RunDlg;..\src\tinyxml;..\src\WinControls\ColourPicker;..\src\Win32Explr;..\src\MISC\RegExt;..\src\WinControls\TrayIcon;..\src\WinControls\shortcut;..\src\WinControls\Grid;..\src\WinControls\ContextMenu;..\src\MISC\PluginsManager;..\src\WinControls\Preference;..\src\WinControls\WindowsDlg;..\src\WinControls\TaskList;..\src\WinControls\DockingWnd;..\src\WinControls\ToolTip;..\src\MISC\Exception;..\src\MISC\Common;..\src\tinyxml\tinyXmlA;..\src\WinControls\AnsiCharPanel;..\src\WinControls\ClipboardHistory;..\src\WinControls\FindCharsInRange;..\src\WinControls\VerticalFileSwitcher;..\src\WinControls\ProjectPanel;..\src\WinControls\DocumentMap;..\src\WinControls\FunctionList;..\src\uchardet;..\src\WinControls\FileBrowser;..\src\WinControls\ReadDirectoryChanges;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0501;_WINDOWS;_USE_64BIT_TIME_T;TIXML_USE_STL;TIXMLA_USE_STL;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0501;_WINDOWS;_USE_64BIT_TIME_T;TIXML_USE_STL;TIXMLA_USE_STL;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Async</ExceptionHandling> <ExceptionHandling>Async</ExceptionHandling>
<BasicRuntimeChecks>UninitializedLocalUsageCheck</BasicRuntimeChecks> <BasicRuntimeChecks>UninitializedLocalUsageCheck</BasicRuntimeChecks>
@ -167,7 +167,7 @@
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers> <OmitFramePointers>false</OmitFramePointers>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<AdditionalIncludeDirectories>..\src\WinControls\AboutDlg;..\..\scintilla\include;..\include;..\src\WinControls;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\TabBar;..\src\WinControls\ToolBar;..\src\MISC\Process;..\src\ScitillaComponent;..\src\MISC;..\src\MISC\SysMsg;..\src\WinControls\StatusBar;..\src;..\src\WinControls\StaticDialog\RunDlg;..\src\tinyxml;..\src\WinControls\ColourPicker;..\src\Win32Explr;..\src\MISC\RegExt;..\src\WinControls\TrayIcon;..\src\WinControls\shortcut;..\src\WinControls\Grid;..\src\WinControls\ContextMenu;..\src\MISC\PluginsManager;..\src\WinControls\Preference;..\src\WinControls\WindowsDlg;..\src\WinControls\TaskList;..\src\WinControls\DockingWnd;..\src\WinControls\ToolTip;..\src\MISC\Exception;..\src\MISC\Common;..\src\tinyxml\tinyXmlA;..\src\WinControls\AnsiCharPanel;..\src\WinControls\ClipboardHistory;..\src\WinControls\FindCharsInRange;..\src\WinControls\VerticalFileSwitcher;..\src\WinControls\ProjectPanel;..\src\WinControls\DocumentMap;..\src\WinControls\FunctionList;..\src\uchardet;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\src\WinControls\AboutDlg;..\..\scintilla\include;..\include;..\src\WinControls;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\TabBar;..\src\WinControls\ToolBar;..\src\MISC\Process;..\src\ScitillaComponent;..\src\MISC;..\src\MISC\SysMsg;..\src\WinControls\StatusBar;..\src;..\src\WinControls\StaticDialog\RunDlg;..\src\tinyxml;..\src\WinControls\ColourPicker;..\src\Win32Explr;..\src\MISC\RegExt;..\src\WinControls\TrayIcon;..\src\WinControls\shortcut;..\src\WinControls\Grid;..\src\WinControls\ContextMenu;..\src\MISC\PluginsManager;..\src\WinControls\Preference;..\src\WinControls\WindowsDlg;..\src\WinControls\TaskList;..\src\WinControls\DockingWnd;..\src\WinControls\ToolTip;..\src\MISC\Exception;..\src\MISC\Common;..\src\tinyxml\tinyXmlA;..\src\WinControls\AnsiCharPanel;..\src\WinControls\ClipboardHistory;..\src\WinControls\FindCharsInRange;..\src\WinControls\VerticalFileSwitcher;..\src\WinControls\ProjectPanel;..\src\WinControls\DocumentMap;..\src\WinControls\FunctionList;..\src\uchardet;..\src\WinControls\FileBrowser;..\src\WinControls\ReadDirectoryChanges;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0501;NDEBUG;_WINDOWS;_USE_64BIT_TIME_T;TIXML_USE_STL;TIXMLA_USE_STL;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0501;NDEBUG;_WINDOWS;_USE_64BIT_TIME_T;TIXML_USE_STL;TIXMLA_USE_STL;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessToFile>false</PreprocessToFile> <PreprocessToFile>false</PreprocessToFile>
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers> <PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
@ -263,9 +263,11 @@ copy ..\src\contextMenu.xml ..\bin64\contextMenu.xml
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\MISC\Common\LongRunningOperation.cpp" /> <ClCompile Include="..\src\MISC\Common\LongRunningOperation.cpp" />
<ClCompile Include="..\src\MISC\Common\mutex.cpp" /> <ClCompile Include="..\src\MISC\Common\mutex.cpp" />
<ClCompile Include="..\src\MISC\Process\Processus.cpp" />
<ClCompile Include="..\src\WinControls\AboutDlg\AboutDlg.cpp" /> <ClCompile Include="..\src\WinControls\AboutDlg\AboutDlg.cpp" />
<ClCompile Include="..\src\WinControls\AnsiCharPanel\ansiCharPanel.cpp" /> <ClCompile Include="..\src\WinControls\AnsiCharPanel\ansiCharPanel.cpp" />
<ClCompile Include="..\src\ScitillaComponent\AutoCompletion.cpp" /> <ClCompile Include="..\src\ScitillaComponent\AutoCompletion.cpp" />
<ClCompile Include="..\src\WinControls\FileBrowser\fileBrowser.cpp" />
<ClCompile Include="..\src\WinControls\Grid\BabyGrid.cpp" /> <ClCompile Include="..\src\WinControls\Grid\BabyGrid.cpp" />
<ClCompile Include="..\src\WinControls\Grid\BabyGridWrapper.cpp" /> <ClCompile Include="..\src\WinControls\Grid\BabyGridWrapper.cpp" />
<ClCompile Include="..\src\ScitillaComponent\Buffer.cpp" /> <ClCompile Include="..\src\ScitillaComponent\Buffer.cpp" />
@ -276,6 +278,8 @@ copy ..\src\contextMenu.xml ..\bin64\contextMenu.xml
<ClCompile Include="..\src\ScitillaComponent\columnEditor.cpp" /> <ClCompile Include="..\src\ScitillaComponent\columnEditor.cpp" />
<ClCompile Include="..\src\MISC\Common\Common.cpp" /> <ClCompile Include="..\src\MISC\Common\Common.cpp" />
<ClCompile Include="..\src\WinControls\ContextMenu\ContextMenu.cpp" /> <ClCompile Include="..\src\WinControls\ContextMenu\ContextMenu.cpp" />
<ClCompile Include="..\src\WinControls\ReadDirectoryChanges\ReadDirectoryChanges.cpp" />
<ClCompile Include="..\src\WinControls\ReadDirectoryChanges\ReadDirectoryChangesPrivate.cpp" />
<ClCompile Include="..\src\WinControls\TabBar\ControlsTab.cpp" /> <ClCompile Include="..\src\WinControls\TabBar\ControlsTab.cpp" />
<ClCompile Include="..\src\WinControls\DockingWnd\DockingCont.cpp" /> <ClCompile Include="..\src\WinControls\DockingWnd\DockingCont.cpp" />
<ClCompile Include="..\src\WinControls\DockingWnd\DockingManager.cpp" /> <ClCompile Include="..\src\WinControls\DockingWnd\DockingManager.cpp" />
@ -332,7 +336,6 @@ copy ..\src\contextMenu.xml ..\bin64\contextMenu.xml
<ClCompile Include="..\src\Misc\PluginsManager\PluginsManager.cpp" /> <ClCompile Include="..\src\Misc\PluginsManager\PluginsManager.cpp" />
<ClCompile Include="..\src\WinControls\Preference\preferenceDlg.cpp" /> <ClCompile Include="..\src\WinControls\Preference\preferenceDlg.cpp" />
<ClCompile Include="..\src\ScitillaComponent\Printer.cpp" /> <ClCompile Include="..\src\ScitillaComponent\Printer.cpp" />
<ClCompile Include="..\src\MISC\Process\Process.cpp" />
<ClCompile Include="..\src\WinControls\ProjectPanel\ProjectPanel.cpp" /> <ClCompile Include="..\src\WinControls\ProjectPanel\ProjectPanel.cpp" />
<ClCompile Include="..\src\MISC\RegExt\regExtDlg.cpp" /> <ClCompile Include="..\src\MISC\RegExt\regExtDlg.cpp" />
<ClCompile Include="..\src\WinControls\StaticDialog\RunDlg\RunDlg.cpp" /> <ClCompile Include="..\src\WinControls\StaticDialog\RunDlg\RunDlg.cpp" />
@ -491,6 +494,7 @@ copy ..\src\contextMenu.xml ..\bin64\contextMenu.xml
<ResourceCompile Include="..\src\ScitillaComponent\columnEditor.rc" /> <ResourceCompile Include="..\src\ScitillaComponent\columnEditor.rc" />
<ResourceCompile Include="..\src\WinControls\DockingWnd\DockingGUIWidget.rc" /> <ResourceCompile Include="..\src\WinControls\DockingWnd\DockingGUIWidget.rc" />
<ResourceCompile Include="..\src\WinControls\DocumentMap\documentMap.rc" /> <ResourceCompile Include="..\src\WinControls\DocumentMap\documentMap.rc" />
<ResourceCompile Include="..\src\WinControls\FileBrowser\fileBrowser.rc" />
<ResourceCompile Include="..\src\WinControls\FindCharsInRange\findCharsInRange.rc" /> <ResourceCompile Include="..\src\WinControls\FindCharsInRange\findCharsInRange.rc" />
<ResourceCompile Include="..\src\ScitillaComponent\FindReplaceDlg.rc" /> <ResourceCompile Include="..\src\ScitillaComponent\FindReplaceDlg.rc" />
<ResourceCompile Include="..\src\WinControls\FunctionList\functionListPanel.rc" /> <ResourceCompile Include="..\src\WinControls\FunctionList\functionListPanel.rc" />
@ -517,9 +521,12 @@ copy ..\src\contextMenu.xml ..\bin64\contextMenu.xml
<ClInclude Include="..\src\MISC\Common\LongRunningOperation.h" /> <ClInclude Include="..\src\MISC\Common\LongRunningOperation.h" />
<ClInclude Include="..\src\MISC\Common\mutex.h" /> <ClInclude Include="..\src\MISC\Common\mutex.h" />
<ClInclude Include="..\src\MISC\Common\mutex.hxx" /> <ClInclude Include="..\src\MISC\Common\mutex.hxx" />
<ClInclude Include="..\src\MISC\Process\Processus.h" />
<ClInclude Include="..\src\WinControls\AboutDlg\AboutDlg.h" /> <ClInclude Include="..\src\WinControls\AboutDlg\AboutDlg.h" />
<ClInclude Include="..\src\WinControls\AnsiCharPanel\ansiCharPanel.h" /> <ClInclude Include="..\src\WinControls\AnsiCharPanel\ansiCharPanel.h" />
<ClInclude Include="..\src\ScitillaComponent\AutoCompletion.h" /> <ClInclude Include="..\src\ScitillaComponent\AutoCompletion.h" />
<ClInclude Include="..\src\WinControls\FileBrowser\fileBrowser.h" />
<ClInclude Include="..\src\WinControls\FileBrowser\fileBrowser_rc.h" />
<ClInclude Include="..\src\WinControls\Grid\BabyGrid.h" /> <ClInclude Include="..\src\WinControls\Grid\BabyGrid.h" />
<ClInclude Include="..\src\WinControls\Grid\BabyGridWrapper.h" /> <ClInclude Include="..\src\WinControls\Grid\BabyGridWrapper.h" />
<ClInclude Include="..\src\ScitillaComponent\Buffer.h" /> <ClInclude Include="..\src\ScitillaComponent\Buffer.h" />
@ -532,6 +539,9 @@ copy ..\src\contextMenu.xml ..\bin64\contextMenu.xml
<ClInclude Include="..\src\ScitillaComponent\columnEditor.h" /> <ClInclude Include="..\src\ScitillaComponent\columnEditor.h" />
<ClInclude Include="..\src\MISC\Common\Common.h" /> <ClInclude Include="..\src\MISC\Common\Common.h" />
<ClInclude Include="..\src\WinControls\ContextMenu\ContextMenu.h" /> <ClInclude Include="..\src\WinControls\ContextMenu\ContextMenu.h" />
<ClInclude Include="..\src\WinControls\ReadDirectoryChanges\ReadDirectoryChanges.h" />
<ClInclude Include="..\src\WinControls\ReadDirectoryChanges\ReadDirectoryChangesPrivate.h" />
<ClInclude Include="..\src\WinControls\ReadDirectoryChanges\ThreadSafeQueue.h" />
<ClInclude Include="..\src\WinControls\TabBar\ControlsTab.h" /> <ClInclude Include="..\src\WinControls\TabBar\ControlsTab.h" />
<ClInclude Include="..\src\WinControls\DockingWnd\Docking.h" /> <ClInclude Include="..\src\WinControls\DockingWnd\Docking.h" />
<ClInclude Include="..\src\WinControls\DockingWnd\DockingCont.h" /> <ClInclude Include="..\src\WinControls\DockingWnd\DockingCont.h" />
@ -589,7 +599,6 @@ copy ..\src\contextMenu.xml ..\bin64\contextMenu.xml
<ClInclude Include="..\src\WinControls\Preference\preferenceDlg.h" /> <ClInclude Include="..\src\WinControls\Preference\preferenceDlg.h" />
<ClInclude Include="..\src\ScitillaComponent\Printer.h" /> <ClInclude Include="..\src\ScitillaComponent\Printer.h" />
<ClInclude Include="..\src\uchardet\prmem.h" /> <ClInclude Include="..\src\uchardet\prmem.h" />
<ClInclude Include="..\src\MISC\Process\Process.h" />
<ClInclude Include="..\src\WinControls\ProjectPanel\ProjectPanel.h" /> <ClInclude Include="..\src\WinControls\ProjectPanel\ProjectPanel.h" />
<ClInclude Include="..\src\WinControls\ProjectPanel\ProjectPanel_rc.h" /> <ClInclude Include="..\src\WinControls\ProjectPanel\ProjectPanel_rc.h" />
<ClInclude Include="..\src\MISC\RegExt\regExtDlg.h" /> <ClInclude Include="..\src\MISC\RegExt\regExtDlg.h" />