Compare commits

...

26 Commits

Author SHA1 Message Date
pipi e5495abc21 1/24更改
10 months ago
por68nab5 50a338b162 Merge pull request 'lastRecentFileList注释' (#15) from YFX_BRANCH into master
10 months ago
Feixiu Yao 541a642a52 YFX_BRANCH注释
10 months ago
por68nab5 5e5c5aa9c7 Merge pull request '合并请求' (#14) from gongao_branch into master
10 months ago
gongao21 9cf97b6576 宫傲 无敌
10 months ago
por68nab5 689b83b158 Merge pull request 'lbs 合并' (#13) from lba_new into master
10 months ago
L.Andrew c20de0a141 lbs 无敌
10 months ago
por68nab5 7e1f9e1492 Merge pull request 'Parameters.h' (#12) from zhouyangbranch into master
10 months ago
por68nab5 8edeed63dc Merge pull request '1' (#11) from 陈劲宏-branch into master
10 months ago
chen 7e6995e745 重新上传
10 months ago
Zhouyang d8d51575af PR
10 months ago
por68nab5 ff0b7d307a Merge pull request 'wzh_branch2' (#9) from wzh_branch2 into master
10 months ago
por68nab5 7622346665 Merge pull request 'lgr代码阅读' (#8) from lgr2_b into master
10 months ago
p5sa938fq d2c54ed3c5 Update Window.h
10 months ago
pipi 9dd332731a 代码阅读
10 months ago
por68nab5 0229227cd5 Delete 'doc/~$泛读报告.docx'
10 months ago
pipi 194e350214 新的更改
10 months ago
pipi af6ed8c2bc 泛读报告_软件用例部分更
10 months ago
pipi 9f8f220ec6 新_泛读报告
10 months ago
pipi e6fe20b452 泛读报告软件用例部分更新
10 months ago
por68nab5 e68b1a62a0 Merge pull request 'NppDarkMode' (#5) from yaofeixiu_branch into master
11 months ago
pipi ff45e725cd 泛读报告_改
1 year ago
pipi 68e8e00c4a 泛读报告_改
1 year ago
pipi e798ee8049 泛读报告更改
1 year ago
pipi e4004a362a 泛读
1 year ago
pipi 8f194d0272 abc
1 year ago

File diff suppressed because it is too large Load Diff

@ -1,251 +0,0 @@
// This file is part of Notepad++ project
// Copyright (c) 2021 adzm / Adam D. Walling
// 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 3 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, see <https://www.gnu.org/licenses/>.
#pragma once
#include <windows.h>
#include "Common.h" // for generic_string
//这段代码定义了一个名为NppDarkMode的命名空间其中包含了一些结构体和函数。
namespace NppDarkMode
{
struct Colors
{
// 定义颜色结构体Colors包括背景颜色、柔和背景颜色、热点背景颜色、纯背景颜色、错误背景颜色、文本颜色、深色文本颜色、禁用文本颜色、链接文本颜色、边缘颜色、热点边缘颜色、禁用边缘颜色
COLORREF background = 0;
COLORREF softerBackground = 0;
COLORREF hotBackground = 0;
COLORREF pureBackground = 0;
COLORREF errorBackground = 0;
COLORREF text = 0;
COLORREF darkerText = 0;
COLORREF disabledText = 0;
COLORREF linkText = 0;
COLORREF edge = 0;
COLORREF hotEdge = 0;
COLORREF disabledEdge = 0;
};
struct Options
{
// 定义Options结构体用于存储暗黑模式的选项
bool enable = false;
bool enableMenubar = false;
bool enablePlugin = false;
};
struct NppDarkModeParams
{
// 定义NppDarkModeParams结构体用于存储暗黑模式的参数
const wchar_t* _themeClassName = nullptr;
bool _subclass = false;
bool _theme = false;
};
enum class ToolTipsType
{
// 定义ToolTipsType枚举用于标识不同类型的工具提示
tooltip,
toolbar,
listview,
treeview,
tabbar
};
enum ColorTone {
// 定义ColorTone枚举用于标识不同的颜色调
blackTone = 0,
redTone = 1,
greenTone = 2,
blueTone = 3,
purpleTone = 4,
cyanTone = 5,
oliveTone = 6,
customizedTone = 32
};
enum class TreeViewStyle
{
// 定义TreeViewStyle枚举用于标识不同的树形视图样式
classic = 0,
light = 1,
dark = 2
};
struct AdvOptDefaults
{
// 定义AdvOptDefaults结构体用于存储高级选项的默认值
generic_string _xmlFileName;
int _toolBarIconSet = -1;
int _tabIconSet = -1;
bool _tabUseTheme = false;
};
struct AdvancedOptions
{
// 定义AdvancedOptions结构体用于存储高级选项
bool _enableWindowsMode = false;
NppDarkMode::AdvOptDefaults _darkDefaults{ L"DarkModeDefault.xml", 0, 2, false };
NppDarkMode::AdvOptDefaults _lightDefaults{ L"", 4, 0, true };
};
void initDarkMode(); // 初始化暗黑模式从NppParameters中获取选项
void refreshDarkMode(HWND hwnd, bool forceRefresh = false); // 尝试应用新的选项发送NPPM_INTERNAL_REFRESHDARKMODE消息到hwnd的顶级父窗口
void initAdvancedOptions(); // 初始化高级选项
bool isEnabled(); // 获取暗黑模式是否启用的状态
bool isDarkMenuEnabled(); // 获取菜单栏是否使用暗黑模式的状态
bool isEnabledForPlugins(); // 获取插件是否使用暗黑模式的状态
bool isExperimentalActive(); // 获取实验性暗黑模式是否启用的状态
bool isExperimentalSupported(); // 获取实验性暗黑模式是否受支持的状态
bool isWindowsModeEnabled(); // 获取Windows模式是否启用的状态
void setWindowsMode(bool enable); // 设置Windows模式是否启用
generic_string getThemeName(); // 获取主题名称
void setThemeName(const generic_string& newThemeName); // 设置主题名称
int getToolBarIconSet(bool useDark); // 获取工具栏图标集
void setToolBarIconSet(int state2Set, bool useDark); // 设置工具栏图标集
int getTabIconSet(bool useDark); // 获取选项卡图标集
void setTabIconSet(bool useAltIcons, bool useDark); // 设置选项卡图标集
bool useTabTheme(); // 获取选项卡主题是否启用
void setAdvancedOptions(); // 设置高级选项
bool isWindows10(); // 获取Windows是否为10版本
bool isWindows11(); // 获取Windows是否为11版本
DWORD getWindowsBuildNumber(); // 获取Windows的构建版本号
COLORREF invertLightness(COLORREF c); // 反转颜色的亮度
COLORREF invertLightnessSofter(COLORREF c); // 反转柔和颜色的亮度
double calculatePerceivedLighness(COLORREF c); // 计算颜色的亮度
void setDarkTone(ColorTone colorToneChoice); // 设置暗黑模式的颜色调
COLORREF getBackgroundColor(); // 获取背景颜色
COLORREF getSofterBackgroundColor(); // 获取柔和背景颜色
COLORREF getHotBackgroundColor(); // 获取热点背景颜色
COLORREF getDarkerBackgroundColor(); // 获取深色背景颜色
COLORREF getErrorBackgroundColor(); // 获取错误背景颜色
COLORREF getTextColor(); // 获取文本颜色
COLORREF getDarkerTextColor(); // 获取深色文本颜色
COLORREF getDisabledTextColor(); // 获取禁用文本颜色
COLORREF getLinkTextColor(); // 获取链接文本颜色
COLORREF getEdgeColor(); // 获取边缘颜色
COLORREF getHotEdgeColor(); // 获取热点边缘颜色
COLORREF getDisabledEdgeColor(); // 获取禁用边缘颜色
HBRUSH getBackgroundBrush(); // 获取背景画刷
HBRUSH getDarkerBackgroundBrush(); // 获取深色背景画刷
HBRUSH getSofterBackgroundBrush(); // 获取柔和背景画刷
HBRUSH getHotBackgroundBrush(); // 获取热点背景画刷
HBRUSH getErrorBackgroundBrush(); // 获取错误背景画刷
HBRUSH getEdgeBrush(); // 获取边缘画刷
HBRUSH getHotEdgeBrush(); // 获取热点边缘画刷
HBRUSH getDisabledEdgeBrush(); // 获取禁用边缘画刷
COLORREF getIndividualTabColour(int colourIndex, bool themeDependant, bool saturated);
void setBackgroundColor(COLORREF c);
void setSofterBackgroundColor(COLORREF c);
void setHotBackgroundColor(COLORREF c);
void setDarkerBackgroundColor(COLORREF c);
void setErrorBackgroundColor(COLORREF c);
void setTextColor(COLORREF c);
void setDarkerTextColor(COLORREF c);
void setDisabledTextColor(COLORREF c);
void setLinkTextColor(COLORREF c);
void setEdgeColor(COLORREF c);
void setHotEdgeColor(COLORREF c);
void setDisabledEdgeColor(COLORREF c);
Colors getDarkModeDefaultColors();
void changeCustomTheme(const Colors& colors);
// handle events
void handleSettingChange(HWND hwnd, LPARAM lParam, bool isFromBtn = false);
bool isDarkModeReg();
// processes messages related to UAH / custom menubar drawing.
// return true if handled, false to continue with normal processing in your wndproc
bool runUAHWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT* lr);
void drawUAHMenuNCBottomLine(HWND hWnd);
// from DarkMode.h
void initExperimentalDarkMode();
void setDarkMode(bool useDark, bool fixDarkScrollbar);
void allowDarkModeForApp(bool allow);
bool allowDarkModeForWindow(HWND hWnd, bool allow);
void setTitleBarThemeColor(HWND hWnd);
// enhancements to DarkMode.h
void enableDarkScrollBarForWindowAndChildren(HWND hwnd);
inline void paintRoundFrameRect(HDC hdc, const RECT rect, const HPEN hpen, int width = 0, int height = 0);
void subclassButtonControl(HWND hwnd);
void subclassGroupboxControl(HWND hwnd);
void subclassTabControl(HWND hwnd);
void subclassComboBoxControl(HWND hwnd);
bool subclassTabUpDownControl(HWND hwnd);
void subclassAndThemeButton(HWND hwnd, NppDarkModeParams p);
void subclassAndThemeComboBox(HWND hwnd, NppDarkModeParams p);
void subclassAndThemeListBoxOrEditControl(HWND hwnd, NppDarkModeParams p, bool isListBox);
void subclassAndThemeListView(HWND hwnd, NppDarkModeParams p);
void themeTreeView(HWND hwnd, NppDarkModeParams p);
void themeToolbar(HWND hwnd, NppDarkModeParams p);
void themeRichEdit(HWND hwnd, NppDarkModeParams p);
void autoSubclassAndThemeChildControls(HWND hwndParent, bool subclass = true, bool theme = true);
void autoThemeChildControls(HWND hwndParent);
LRESULT darkToolBarNotifyCustomDraw(LPARAM lParam);
LRESULT darkListViewNotifyCustomDraw(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool isPlugin);
LRESULT darkTreeViewNotifyCustomDraw(LPARAM lParam);
void autoSubclassAndThemePluginDockWindow(HWND hwnd);
ULONG autoSubclassAndThemePlugin(HWND hwnd, ULONG dmFlags);
void autoSubclassAndThemeWindowNotify(HWND hwnd);
void setDarkTitleBar(HWND hwnd);
void setDarkExplorerTheme(HWND hwnd);
void setDarkScrollBar(HWND hwnd);
void setDarkTooltips(HWND hwnd, ToolTipsType type);
void setDarkLineAbovePanelToolbar(HWND hwnd);
void setDarkListView(HWND hwnd);
void disableVisualStyle(HWND hwnd, bool doDisable);
void calculateTreeViewStyle();
void setTreeViewStyle(HWND hwnd);
bool isThemeDark();
void setBorder(HWND hwnd, bool border = true);
BOOL CALLBACK enumAutocompleteProc(HWND hwnd, LPARAM lParam);
void setDarkAutoCompletion();
LRESULT onCtlColor(HDC hdc);
LRESULT onCtlColorSofter(HDC hdc);
LRESULT onCtlColorDarker(HDC hdc);
LRESULT onCtlColorError(HDC hdc);
LRESULT onCtlColorDarkerBGStaticText(HDC hdc, bool isTextEnabled);
INT_PTR onCtlColorListbox(WPARAM wParam, LPARAM lParam);
}
//这些函数主要用于初始化和管理Notepad++的暗黑模式,包括颜色设置、主题样式、窗口控件的主题化等功能。

@ -1,4 +1,6 @@
# git_read
阅读了NppDarkMode.cpp前2000行和NppDarkMode.h前160行文件
理解了暗模式的创建过程,定义画刷和画笔等
给结构体和主要函数增加了注释
## 阅读了总计7个用例分别各有一个用例顺序图和用例描述在前面有一个总体的用例图
## 第二部分首先是一个包图 ~~(可能不是很好)~~ ,然后有各个模块的介绍,其中有主要功能和主要函数,
## 最后一部分是我们小组在这次开源代码阅读的心得体会

Binary file not shown.

Binary file not shown.

@ -16,31 +16,31 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//该cpp文件实现了处理崩溃的类MiniDumper.h
#include <shlwapi.h>
#include "MiniDumper.h"
//消息标题
LPCTSTR msgTitle = TEXT("Notepad++ crash analysis");
MiniDumper::MiniDumper()
{
}
//写入崩溃转储的函数
bool MiniDumper::writeDump(EXCEPTION_POINTERS* pExceptionInfo)
{
TCHAR szDumpPath[MAX_PATH];
TCHAR szScratch[MAX_PATH];
LPCTSTR szResult = NULL;
bool retval = false;
//加载动态链接库
HMODULE hDll = ::LoadLibraryEx(TEXT("DBGHELP.DLL"), nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); //that wont work on older windows version than XP, #care :)
if (hDll)
{
MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress(hDll, "MiniDumpWriteDump");
if (pDump)
{
{//获取当前模块的文件路径
::GetModuleFileName(NULL, szDumpPath, MAX_PATH);
::PathRemoveFileSpec(szDumpPath);
wcscat_s(szDumpPath, TEXT("\\NppDump.dmp"));
@ -93,7 +93,7 @@ bool MiniDumper::writeDump(EXCEPTION_POINTERS * pExceptionInfo)
{
szResult = TEXT("Unable to load the debugging DLL,\r\nfind a recent copy of dbghelp.dll and install it.");
}
//弹出消息框显示结果
if (szResult)
::MessageBox(NULL, szResult, msgTitle, MB_OK);

@ -55,23 +55,31 @@ namespace // anonymous
void Notepad_plus_Window::setStartupBgColor(COLORREF BgColor)
{
RECT windowClientArea;
/// 定义窗口的变量
///
/// 获取对应的设备来方便绘制图形
/// 该函数用于设置窗口的整体颜色
///
HDC hdc = GetDCEx(_hSelf, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE); //lock window update flag due to PaintLocker
GetClientRect(_hSelf, &windowClientArea);
FillRect(hdc, &windowClientArea, CreateSolidBrush(BgColor));
ReleaseDC(_hSelf, hdc);
}
void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR* cmdLine, CmdLineParams* cmdLineParams)
{
/// 该函数用于在最初的时候初始化窗口变量,
/// 建立窗口变量
// 初始化时间戳
time_t timestampBegin = 0;
if (cmdLineParams->_showLoadingTime)
timestampBegin = time(NULL);
// 初始化窗口
Window::init(hInst, parent);
WNDCLASS nppClass{};
// 设置窗口类属性
nppClass.style = CS_BYTEALIGNWINDOW | CS_DBLCLKS;
nppClass.lpfnWndProc = Notepad_plus_Proc;
nppClass.cbClsExtra = 0;
@ -85,49 +93,56 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin
_isPrelaunch = cmdLineParams->_isPreLaunch;
// 注册窗口类
if (!::RegisterClass(&nppClass))
{
throw std::runtime_error("Notepad_plus_Window::init : RegisterClass() function failed");
}
// 获取 Notepad++ 参数实例
NppParameters& nppParams = NppParameters::getInstance();
NppGUI& nppGUI = nppParams.getNppGUI();
// 根据命令行参数禁用插件
if (cmdLineParams->_isNoPlugin)
_notepad_plus_plus_core._pluginsManager.disable();
// 设置命令行参数的会话状态
nppGUI._isCmdlineNosessionActivated = cmdLineParams->_isNoSession;
// 加载图标
_hIconAbsent = ::LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICONABSENT));
// 创建窗口
_hSelf = ::CreateWindowEx(
WS_EX_ACCEPTFILES | (_notepad_plus_plus_core._nativeLangSpeaker.isRTL() ? WS_EX_LAYOUTRTL : 0),
_className,
TEXT("Notepad++"),
(WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN),
// CreateWindowEx bug : set all 0 to walk around the pb
0, 0, 0, 0,
_hParent, nullptr, _hInst,
(LPVOID) this); // pass the ptr of this instantiated object
// for retrieve it in Notepad_plus_Proc from
// the CREATESTRUCT.lpCreateParams afterward.
(LPVOID)this);
if (NULL == _hSelf)
throw std::runtime_error("Notepad_plus_Window::init : CreateWindowEx() function return null");
// 锁定绘制
PaintLocker paintLocker{ _hSelf };
// 静态检查菜单和工具栏
_notepad_plus_plus_core.staticCheckMenuAndTB();
// 设置全局窗口句柄
gNppHWND = _hSelf;
// 移动窗口位置或设置默认位置
if (cmdLineParams->isPointValid())
{
::MoveWindow(_hSelf, cmdLineParams->_point.x, cmdLineParams->_point.y, nppGUI._appPos.right, nppGUI._appPos.bottom, TRUE);
}
else
{
// 设置窗口位置信息
WINDOWPLACEMENT posInfo{};
posInfo.length = sizeof(WINDOWPLACEMENT);
posInfo.flags = 0;
@ -136,6 +151,7 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin
else
posInfo.showCmd = nppGUI._isMaximized ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL;
// 设置窗口位置
posInfo.ptMinPosition.x = (LONG)-1;
posInfo.ptMinPosition.y = (LONG)-1;
posInfo.ptMaxPosition.x = (LONG)-1;
@ -145,36 +161,43 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin
posInfo.rcNormalPosition.bottom = nppGUI._appPos.top + nppGUI._appPos.bottom;
posInfo.rcNormalPosition.right = nppGUI._appPos.left + nppGUI._appPos.right;
//SetWindowPlacement will take care of situations, where saved position was in no longer available monitor
// 设置窗口位置
::SetWindowPlacement(_hSelf, &posInfo);
// 绘制暗色背景
if (NppDarkMode::isEnabled())
setStartupBgColor(NppDarkMode::getBackgroundColor()); //draw dark background when opening Npp without position data
setStartupBgColor(NppDarkMode::getBackgroundColor());
}
// 处理选项卡显示模式
if ((nppGUI._tabStatus & TAB_MULTILINE) != 0)
::SendMessage(_hSelf, WM_COMMAND, IDM_VIEW_DRAWTABBAR_MULTILINE, 0);
// 隐藏/显示菜单栏
if (!nppGUI._menuBarShow)
::SetMenu(_hSelf, NULL);
// 隐藏选项卡栏
if (cmdLineParams->_isNoTab || (nppGUI._tabStatus & TAB_HIDE))
{
const int tabStatusOld = nppGUI._tabStatus;
::SendMessage(_hSelf, NPPM_HIDETABBAR, 0, TRUE);
if (cmdLineParams->_isNoTab)
{
// Restore old settings when tab bar has been hidden from tab bar.
// 从选项卡栏隐藏后恢复旧设置
nppGUI._tabStatus = tabStatusOld;
}
}
// 设置窗口置顶
if (cmdLineParams->_alwaysOnTop)
::SendMessage(_hSelf, WM_COMMAND, IDM_VIEW_ALWAYSONTOP, 0);
// 加载上次会话
if (nppGUI._rememberLastSession && !nppGUI._isCmdlineNosessionActivated)
_notepad_plus_plus_core.loadLastSession();
// 导出功能列表或打印并退出
if (nppParams.doFunctionListExport() || nppParams.doPrintAndExit())
{
::ShowWindow(_hSelf, SW_HIDE);
@ -188,35 +211,33 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin
}
else
{
// 加载托盘图标
HICON icon = nullptr;
loadTrayIcon(_hInst, &icon);
_notepad_plus_plus_core._pTrayIco = new trayIconControler(_hSelf, IDI_M30ICON, NPPM_INTERNAL_MINIMIZED_TRAY, icon, TEXT(""));
_notepad_plus_plus_core._pTrayIco->doTrayIcon(ADD);
}
// 根据命令行参数和暗黑模式设置启动背景颜色
if (cmdLineParams->isPointValid() && NppDarkMode::isEnabled())
setStartupBgColor(NppDarkMode::getBackgroundColor()); //draw dark background when opening Npp through cmd with position data
setStartupBgColor(NppDarkMode::getBackgroundColor());
// 加载本地化文件
std::vector<generic_string> fileNames;
std::vector<generic_string> patterns;
patterns.push_back(TEXT("*.xml"));
generic_string nppDir = nppParams.getNppPath();
LocalizationSwitcher& localizationSwitcher = nppParams.getLocalizationSwitcher();
std::wstring localizationDir = nppDir;
pathAppend(localizationDir, TEXT("localization\\"));
_notepad_plus_plus_core.getMatchedFileNames(localizationDir.c_str(), 0, patterns, fileNames, false, false);
for (size_t i = 0, len = fileNames.size(); i < len; ++i)
localizationSwitcher.addLanguageFromXml(fileNames[i]);
// 加载主题文件
fileNames.clear();
ThemeSwitcher& themeSwitcher = nppParams.getThemeSwitcher();
// Get themes from both npp install themes dir and app data themes dir with the per user
// overriding default themes of the same name.
// 获取应用数据主题目录
generic_string appDataThemeDir = nppParams.isCloud() ? nppParams.getUserPath() : nppParams.getAppDataNppDir();
if (!appDataThemeDir.empty())
{
@ -228,14 +249,11 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin
}
}
// 加载主题文件
fileNames.clear();
generic_string nppThemeDir = nppDir.c_str(); // <- should use the pointer to avoid the constructor of copy
generic_string nppThemeDir = nppDir.c_str();
pathAppend(nppThemeDir, TEXT("themes\\"));
// Set theme directory to their installation directory
themeSwitcher.setThemeDirPath(nppThemeDir);
_notepad_plus_plus_core.getMatchedFileNames(nppThemeDir.c_str(), 0, patterns, fileNames, false, false);
for (size_t i = 0, len = fileNames.size(); i < len; ++i)
{
@ -247,7 +265,6 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin
if (!appDataThemeDir.empty())
{
generic_string appDataThemePath = appDataThemeDir;
if (!::PathFileExists(appDataThemePath.c_str()))
{
::CreateDirectory(appDataThemePath.c_str(), NULL);
@ -260,6 +277,7 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin
}
}
// 根据暗黑模式设置主题
if (NppDarkMode::isWindowsModeEnabled())
{
generic_string themePath;
@ -293,36 +311,44 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin
}
}
// Restore all dockable panels from the last session
// 恢复上次会话的情况
for (size_t i = 0, len = _notepad_plus_plus_core._internalFuncIDs.size(); i < len; ++i)
::SendMessage(_hSelf, WM_COMMAND, _notepad_plus_plus_core._internalFuncIDs[i], 0);
// 加载命令行参数中的文件
std::vector<generic_string> fns;
if (cmdLine)
fns = _notepad_plus_plus_core.loadCommandlineParams(cmdLine, cmdLineParams);
// Launch folder as workspace after all this dockable panel being restored from the last session
// To avoid dockable panel toggle problem.
if (cmdLineParams->_openFoldersAsWorkspace)
bool isSnapshotMode = nppGUI.isSnapshotMode();
if (isSnapshotMode)
{
generic_string emptyStr;
_notepad_plus_plus_core.launchFileBrowser(fns, emptyStr, true);
_notepad_plus_plus_core.checkModifiedDocument(false);
_notepad_plus_plus_core.launchDocumentBackupTask();
}
::SendMessage(_hSelf, WM_ACTIVATE, WA_ACTIVE, 0);
::SendMessage(_hSelf, NPPM_INTERNAL_CRLFFORMCHANGED, 0, 0);
::SendMessage(_hSelf, NPPM_INTERNAL_NPCFORMCHANGED, 0, 0);
// 设置单词字符和 NPC
::SendMessage(_hSelf, NPPM_INTERNAL_SETWORDCHARS, 0, 0);
::SendMessage(_hSelf, NPPM_INTERNAL_SETNPC, 0, 0);
::SendMessage(_hSelf, NPPM_INTERNAL_ENABLECHANGEHISTORY, 0, 0);
// 导出功能列表
if (nppParams.doFunctionListExport())
::SendMessage(_hSelf, NPPM_INTERNAL_EXPORTFUNCLISTANDQUIT, 0, 0);
// 打印
if (nppParams.doPrintAndExit())
::SendMessage(_hSelf, NPPM_INTERNAL_PRNTANDQUIT, 0, 0);
if (nppGUI._newDocDefaultSettings._addNewDocumentOnStartup && nppGUI._rememberLastSession)
// 计算加载时间并显示消息框
if (cmdLineParams->_showLoadingTime)
{
::SendMessage(_hSelf, WM_COMMAND, IDM_FILE_NEW, 0);
time_t timestampEnd = time(NULL);
double loadTime = difftime(timestampEnd, timestampBegin);
char dest[256];
sprintf(dest, "Loading time : %.0lf seconds", loadTime);
::MessageBoxA(NULL, dest, "", MB_OK);
}
// Notify plugins that Notepad++ is ready
SCNotification scnN{};
scnN.nmhdr.code = NPPN_READY;
scnN.nmhdr.hwndFrom = _hSelf;
@ -353,10 +379,9 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin
_quoteParams._speed = QuoteParams::rapid;
else if (cmdLineParams->_ghostTypingSpeed == 3)
_quoteParams._speed = QuoteParams::speedOfLight;
_notepad_plus_plus_core.showQuote(&_quoteParams);
}
else if (cmdLineParams->_quoteType == 2) // content drom file
else if (cmdLineParams->_quoteType == 2) // content from file
{
if (::PathFileExists(cmdLineParams->_easterEggName.c_str()))
{
@ -376,43 +401,18 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin
_quoteParams._speed = QuoteParams::rapid;
else if (cmdLineParams->_ghostTypingSpeed == 3)
_quoteParams._speed = QuoteParams::speedOfLight;
_notepad_plus_plus_core.showQuote(&_quoteParams);
}
}
}
}
if (cmdLineParams->_showLoadingTime)
{
time_t timestampEnd = time(NULL);
double loadTime = difftime(timestampEnd, timestampBegin);
char dest[256];
sprintf(dest, "Loading time : %.0lf seconds", loadTime);
::MessageBoxA(NULL, dest, "", MB_OK);
}
bool isSnapshotMode = nppGUI.isSnapshotMode();
if (isSnapshotMode)
{
_notepad_plus_plus_core.checkModifiedDocument(false);
// Lauch backup task
_notepad_plus_plus_core.launchDocumentBackupTask();
}
// Make this call later to take effect
::SendMessage(_hSelf, NPPM_INTERNAL_SETWORDCHARS, 0, 0);
::SendMessage(_hSelf, NPPM_INTERNAL_SETNPC, 0, 0);
if (nppParams.doFunctionListExport())
::SendMessage(_hSelf, NPPM_INTERNAL_EXPORTFUNCLISTANDQUIT, 0, 0);
if (nppParams.doPrintAndExit())
::SendMessage(_hSelf, NPPM_INTERNAL_PRNTANDQUIT, 0, 0);
}
/// <summary>
/// 用于检查MSG类型的变量msg是否是一种特定的消息
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
bool Notepad_plus_Window::isDlgsMsg(MSG *msg) const
{
for (size_t i = 0, len = _notepad_plus_plus_core._hModelessDlgs.size(); i < len; ++i)

@ -55,10 +55,10 @@ filePath : file or folder name to open (absolute or relative path name)\r\
");
class Notepad_plus_Window : public Window
class Notepad_plus_Window : public Window//用作程序的主窗口
{
public:
void init(HINSTANCE, HWND, const TCHAR *cmdLine, CmdLineParams *cmdLineParams);
void init(HINSTANCE, HWND, const TCHAR *cmdLine, CmdLineParams *cmdLineParams);//创建窗口
bool isDlgsMsg(MSG *msg) const;

@ -1560,13 +1560,17 @@ namespace NppDarkMode
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
//窗口子类化的示例,它为指定的窗口处理了自定义的边框绘制逻辑。
void subclassTabControl(HWND hwnd)
{
SetWindowSubclass(hwnd, TabSubclass, g_tabSubclassID, 0);
SetWindowSubclass(hwnd, TabSubclass, g_tabSubclassID, 0); //将窗口 hwnd 子类化为 TabSubclass并分配一个唯一的子类 ID g_tabSubclassID。
}
constexpr UINT_PTR g_customBorderSubclassID = 42;
//这个函数是一个回调函数,用于处理窗口消息。它被用作窗口子类的回调函数。
//当窗口接收到消息时,该函数会被调用来处理消息。
//注意,该函数的签名必须与 SUBCLASSPROC 类型匹配。
LRESULT CALLBACK CustomBorderSubclass(
HWND hWnd,
UINT uMsg,
@ -1580,6 +1584,9 @@ namespace NppDarkMode
static bool isHotStatic = false;
//在这个函数中,根据不同的消息类型进行不同的处理。
//其中WM_NCPAINT 消息用于非客户区绘制,即窗口的边框绘制。
//在这里,通过重绘窗口的边框,实现了自定义的边框绘制效果。
switch (uMsg)
{
case WM_NCPAINT:
@ -1635,19 +1642,25 @@ namespace NppDarkMode
return 0;
}
break;
//以上部分代码使用 GetWindowDC 函数获取窗口的设备上下文,然后根据窗口的样式和状态计算绘制边框所需的相关信息。
//通过调用 NppDarkMode::paintRoundFrameRect 函数来绘制圆角矩形边框,使用不同的画笔来绘制不同的边框样式。
//绘制完成后,通过 ReleaseDC 函数释放设备上下文。最后,返回值为 0表示消息已经被处理完毕。
case WM_NCCALCSIZE:
{
if (!NppDarkMode::isEnabled())
if (!NppDarkMode::isEnabled()) //检查是否启用了 NppDarkMode如果没有启用则直接跳过。
{
break;
}
auto lpRect = reinterpret_cast<LPRECT>(lParam);
::InflateRect(lpRect, -(::GetSystemMetrics(SM_CXEDGE)), -(::GetSystemMetrics(SM_CYEDGE)));
auto lpRect = reinterpret_cast<LPRECT>(lParam); //通过将 lParam 强制转换为 LPRECT 类型,获取指向窗口矩形结构的指针。
::InflateRect(lpRect, -(::GetSystemMetrics(SM_CXEDGE)), -(::GetSystemMetrics(SM_CYEDGE))); //利用 InflateRect 函数扩展客户区矩形的尺寸,将其减去窗口边框的宽度和高度(使用 SM_CXEDGE 和 SM_CYEDGE 系统度量值)。这样可以得到去除边框后的客户区矩形。
auto style = ::GetWindowLongPtr(hWnd, GWL_STYLE);
bool hasVerScrollbar = (style & WS_VSCROLL) == WS_VSCROLL;
//根据窗口的样式,检查是否有垂直和水平滚动条。如果有垂直滚动条,则将客户区矩形的右边减去垂直滚动条的宽度(使用 SM_CXVSCROLL 系统度量值)。
//如果有水平滚动条,则将客户区矩形的底部减去水平滚动条的高度(使用 SM_CYHSCROLL 系统度量值)。
if (hasVerScrollbar)
{
lpRect->right -= ::GetSystemMetrics(SM_CXVSCROLL);
@ -1659,10 +1672,14 @@ namespace NppDarkMode
lpRect->bottom -= ::GetSystemMetrics(SM_CYHSCROLL);
}
return 0;
return 0; //返回值为 0表示已经处理完 WM_NCCALCSIZE 消息。
}
break;
//在这个代码块中,首先检查是否启用了 NppDarkMode如果没有启用则直接跳过。
//然后,通过调用 GetFocus 函数检查窗口是否具有焦点,如果有焦点则跳过。
//接下来,创建一个 TRACKMOUSEEVENT 结构体,并设置其中的成员变量。这个结构体用于跟踪鼠标离开窗口的消息。通过调用 TrackMouseEvent 函数,将该结构体传递给系统,以便在鼠标离开窗口时收到 WM_MOUSELEAVE 消息。
//然后,检查 isHotStatic 变量的值。如果它为假,则将其设置为真,并通过调用 SetWindowPos 函数更新窗口的位置和大小。这里使用了 SWP_NOMOVE、SWP_NOSIZE 和 SWP_NOZORDER 标志,表示不改变窗口的位置、大小和层次关系,只刷新窗口的边框样式(使用 SWP_FRAMECHANGED 标志)。
case WM_MOUSEMOVE:
{
if (!NppDarkMode::isEnabled())
@ -1690,6 +1707,10 @@ namespace NppDarkMode
}
break;
//在这个代码块中,首先检查是否启用了 NppDarkMode如果没有启用则直接跳过。
//然后,检查 isHotStatic 变量的值。如果它为真,则将其设置为假,并通过调用 SetWindowPos 函数更新窗口的位置和大小。
//接下来,同样创建一个 TRACKMOUSEEVENT 结构体,并设置其中的成员变量。
//然后,通过调用 TrackMouseEvent 函数,取消对鼠标离开窗口的跟踪,并清除鼠标悬停时间。
case WM_MOUSELEAVE:
{
if (!NppDarkMode::isEnabled())
@ -1714,20 +1735,21 @@ namespace NppDarkMode
case WM_NCDESTROY:
{
RemoveWindowSubclass(hWnd, CustomBorderSubclass, uIdSubclass);
RemoveWindowSubclass(hWnd, CustomBorderSubclass, uIdSubclass); //调用 RemoveWindowSubclass 函数,将窗口子类移除,以确保在窗口销毁时不再收到自定义边框的消息。
}
break;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
return DefSubclassProc(hWnd, uMsg, wParam, lParam); //通过调用 DefSubclassProc 函数,将消息传递给默认的窗口过程进行处理。
}
void subclassCustomBorderForListBoxAndEditControls(HWND hwnd)
void subclassCustomBorderForListBoxAndEditControls(HWND hwnd) //hwnd为要进行子类化的窗口句柄。
{
SetWindowSubclass(hwnd, CustomBorderSubclass, g_customBorderSubclassID, 0);
}
constexpr UINT_PTR g_comboBoxSubclassID = 42;
constexpr UINT_PTR g_comboBoxSubclassID = 42; //标识子类化的ID
//子类函数 ComboBoxSubclass它是一个回调函数用于处理窗口消息。
LRESULT CALLBACK ComboBoxSubclass(
HWND hWnd,
UINT uMsg,
@ -1736,6 +1758,7 @@ namespace NppDarkMode
UINT_PTR uIdSubclass,
DWORD_PTR dwRefData
)
{
auto hwndEdit = reinterpret_cast<HWND>(dwRefData);
@ -1747,13 +1770,15 @@ namespace NppDarkMode
{
break;
}
//定义一个名为 rc 的 RECT 结构体,并使用 ::GetClientRect 函数获取窗口客户区的矩形区域信息。
RECT rc{};
::GetClientRect(hWnd, &rc);
//定义一个名为 ps 的 PAINTSTRUCT 结构体,并调用 ::BeginPaint 函数开始绘制操作,将得到的设备上下文句柄保存在 hdc 变量中。
PAINTSTRUCT ps{};
auto hdc = ::BeginPaint(hWnd, &ps);
//选择关联字体
::SelectObject(hdc, reinterpret_cast<HFONT>(::SendMessage(hWnd, WM_GETFONT, 0, 0)));
::SetBkColor(hdc, NppDarkMode::getBackgroundColor());
@ -1761,11 +1786,16 @@ namespace NppDarkMode
auto& dpiManager = NppParameters::getInstance()._dpiManager;
//定义一个名为 rcArrow 的 RECT 结构体变量,用于存储组合框箭头的位置和尺寸信息。
RECT rcArrow{};
//定义一个名为 cbi 的 COMBOBOXINFO 结构体,并设置其 cbSize 成员为结构体的大小。
//然后通过调用 ::GetComboBoxInfo 函数获取与指定组合框窗口相关的信息,并将结果存储在 cbi 变量中。
COMBOBOXINFO cbi{};
cbi.cbSize = sizeof(COMBOBOXINFO);
const bool resultCbi = ::GetComboBoxInfo(hWnd, &cbi) != FALSE;
//根据获取到的组合框信息或者客户区的尺寸,动态地确定箭头区域的位置和尺寸
if (resultCbi)
{
rcArrow = cbi.rcButton;
@ -1779,12 +1809,16 @@ namespace NppDarkMode
};
}
bool hasFocus = false;
bool hasFocus = false; //定义了一个 hasFocus 变量,并且获取了窗口是否启用的状态。
const bool isWindowEnabled = ::IsWindowEnabled(hWnd) == TRUE;
// CBS_DROPDOWN text is handled by parent by WM_CTLCOLOREDIT
auto style = ::GetWindowLongPtr(hWnd, GWL_STYLE);
//如果组合框是下拉列表框CBS_DROPDOWNLIST则根据获取到的组合框信息或者客户区的尺寸确定文本背景的矩形区域 rcTextBg并使用 FillRect 函数擦除文本背景。
//然后根据当前选中的项来设置文本颜色和背景颜色,并绘制文本到指定的位置上。
//最后,如果组合框有焦点且未展开下拉列表,则使用 DrawFocusRect 函数绘制焦点矩形框。
if ((style & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST)
{
hasFocus = ::GetFocus() == hWnd;
@ -1828,6 +1862,8 @@ namespace NppDarkMode
::DrawFocusRect(hdc, &rcTextBg);
}
}
//如果组合框是可编辑的下拉框CBS_DROPDOWN则判断编辑框是否拥有焦点并根据情况设置 hasFocus 变量的值。
else if ((style & CBS_DROPDOWN) == CBS_DROPDOWN && hwndEdit != nullptr)
{
hasFocus = ::GetFocus() == hwndEdit;
@ -1852,10 +1888,10 @@ namespace NppDarkMode
auto holdPen = static_cast<HPEN>(::SelectObject(hdc, hSelectedPen));
POINT edge[] = {
{rcArrow.left - 1, rcArrow.top},
{rcArrow.left - 1, rcArrow.bottom}
{rcArrow.left - 1, rcArrow.top}, //箭头区域左侧顶部
{rcArrow.left - 1, rcArrow.bottom} //箭头区域左侧底部
};
::Polyline(hdc, edge, _countof(edge));
::Polyline(hdc, edge, _countof(edge)); //绘制连线(边框线)
int roundCornerValue = NppDarkMode::isWindows11() ? dpiManager.scaleX(4) : 0;
NppDarkMode::paintRoundFrameRect(hdc, rc, hSelectedPen, roundCornerValue, roundCornerValue);
@ -1875,7 +1911,10 @@ namespace NppDarkMode
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
// 以上代码用于自定义列表框和编辑控件的边框和外观,通过调用 SetWindowSubclass 函数将子类函数与窗口句柄关联起来,实现自定义的绘制效果。
//给组合框控件设置子类化
void subclassComboBoxControl(HWND hwnd)
{
DWORD_PTR hwndEditData = 0;

@ -20,11 +20,11 @@
#include "Common.h" // for generic_string
namespace NppDarkMode
namespace NppDarkMode //命名空间NppDarkMode
{
struct Colors
struct Colors //Colors颜色结构体
{
COLORREF background = 0;
COLORREF background = 0; //COLORREF 是一个 32-bit 整型数值,它代表了一种颜色。
COLORREF softerBackground = 0;
COLORREF hotBackground = 0;
COLORREF pureBackground = 0;
@ -38,30 +38,30 @@ namespace NppDarkMode
COLORREF disabledEdge = 0;
};
struct Options
struct Options //Options选项结构体
{
bool enable = false;
bool enableMenubar = false;
bool enablePlugin = false;
};
struct NppDarkModeParams
struct NppDarkModeParams //params参数结构体
{
const wchar_t* _themeClassName = nullptr;
bool _subclass = false;
bool _theme = false;
};
enum class ToolTipsType
enum class ToolTipsType //域内枚举类型为ToolTipsType
{
tooltip,
tooltip, //括号里是常量
toolbar,
listview,
treeview,
tabbar
};
enum ColorTone {
enum ColorTone { //色温
blackTone = 0,
redTone = 1,
greenTone = 2,
@ -72,14 +72,14 @@ namespace NppDarkMode
customizedTone = 32
};
enum class TreeViewStyle
enum class TreeViewStyle //风格
{
classic = 0,
light = 1,
dark = 2
};
struct AdvOptDefaults
struct AdvOptDefaults //默认选项
{
generic_string _xmlFileName;
int _toolBarIconSet = -1;
@ -87,7 +87,7 @@ namespace NppDarkMode
bool _tabUseTheme = false;
};
struct AdvancedOptions
struct AdvancedOptions //高级选项
{
bool _enableWindowsMode = false;
@ -108,7 +108,7 @@ namespace NppDarkMode
bool isWindowsModeEnabled();
void setWindowsMode(bool enable);
generic_string getThemeName();
generic_string getThemeName(); //generic_string 类
void setThemeName(const generic_string& newThemeName);
int getToolBarIconSet(bool useDark);
void setToolBarIconSet(int state2Set, bool useDark);
@ -119,7 +119,7 @@ namespace NppDarkMode
bool isWindows10();
bool isWindows11();
DWORD getWindowsBuildNumber();
DWORD getWindowsBuildNumber(); //DWORD 就是 Double Word 每个word为2个字节的长度DWORD 双字即为4个字节每个字节是8位共32位。
COLORREF invertLightness(COLORREF c);
COLORREF invertLightnessSofter(COLORREF c);
@ -142,7 +142,7 @@ namespace NppDarkMode
COLORREF getHotEdgeColor();
COLORREF getDisabledEdgeColor();
HBRUSH getBackgroundBrush();
HBRUSH getBackgroundBrush(); //HBRUSH 取画刷
HBRUSH getDarkerBackgroundBrush();
HBRUSH getSofterBackgroundBrush();
HBRUSH getHotBackgroundBrush();
@ -152,7 +152,7 @@ namespace NppDarkMode
HBRUSH getHotEdgeBrush();
HBRUSH getDisabledEdgeBrush();
HPEN getDarkerTextPen();
HPEN getDarkerTextPen(); //画笔
HPEN getEdgePen();
HPEN getHotEdgePen();
HPEN getDisabledEdgePen();
@ -175,12 +175,12 @@ namespace NppDarkMode
Colors getDarkModeDefaultColors();
void changeCustomTheme(const Colors& colors);
// handle events
// handle events 处理事件
void handleSettingChange(HWND hwnd, LPARAM lParam, bool isFromBtn = false);
bool isDarkModeReg();
// processes messages related to UAH / custom menubar drawing.
// return true if handled, false to continue with normal processing in your wndproc
// processes messages related to UAH / custom menubar drawing. 处理相关信息
// return true if handled, false to continue with normal processing in your wndproc 解决了返回true否则false继续处理
bool runUAHWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT* lr);
void drawUAHMenuNCBottomLine(HWND hWnd);
@ -191,7 +191,7 @@ namespace NppDarkMode
bool allowDarkModeForWindow(HWND hWnd, bool allow);
void setTitleBarThemeColor(HWND hWnd);
// enhancements to DarkMode.h
// enhancements to DarkMode.h 对于DarkMode.h的改进
void enableDarkScrollBarForWindowAndChildren(HWND hwnd);
inline void paintRoundFrameRect(HDC hdc, const RECT rect, const HPEN hpen, int width = 0, int height = 0);
@ -235,13 +235,13 @@ namespace NppDarkMode
bool isThemeDark();
void setBorder(HWND hwnd, bool border = true);
BOOL CALLBACK enumAutocompleteProc(HWND hwnd, LPARAM lParam);
BOOL CALLBACK enumAutocompleteProc(HWND hwnd, LPARAM lParam); //Windows API中的回调函数用于枚举自动完成列表中的项。HWND hwnd自动完成列表的窗口句柄。 LPARAM lParam用户定义的附加参数。
void setDarkAutoCompletion();
LRESULT onCtlColor(HDC hdc);
LRESULT onCtlColor(HDC hdc); //LRESULT是一个数据类型指的是从窗口程序或者回调函数返回的32位值
LRESULT onCtlColorSofter(HDC hdc);
LRESULT onCtlColorDarker(HDC hdc);
LRESULT onCtlColorError(HDC hdc);
LRESULT onCtlColorDarkerBGStaticText(HDC hdc, bool isTextEnabled);
INT_PTR onCtlColorListbox(WPARAM wParam, LPARAM lParam);
INT_PTR onCtlColorListbox(WPARAM wParam, LPARAM lParam); //INT_PTR是特殊定义的类型是为了解决32位与64位编译器的兼容性而设置的关键字
}

@ -13,6 +13,21 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//此文件是 Notepad++ 项目的一部分
//版权所有 C2021 Don HO <don.h@free.fr>
//该程序是免费软件:您可以重新分发和 / 或修改它
//它根据 GNU 通用公共许可证的条款,由
//自由软件基金会Free Software Foundation许可证的第 3 版,或
//由您选择任何更高版本。
//
//分发该程序是希望它有用,
//但没有任何保证; 甚至没有默示保证
//适销性或特定用途的适用性。请参阅
//GNU 通用公共许可证了解更多详情。
//
//您应该已经收到了 GNU 通用公共许可证的副本
//以及这个程序。 如果没有,请参阅 < https://www.gnu.org/licenses/>。
#pragma once
@ -36,30 +51,33 @@
#ifdef _WIN64
#ifdef _M_ARM64
#define ARCH_TYPE IMAGE_FILE_MACHINE_ARM64
#define ARCH_TYPE IMAGE_FILE_MACHINE_ARM64//图像文件机常量
#else
#define ARCH_TYPE IMAGE_FILE_MACHINE_AMD64
#define ARCH_TYPE IMAGE_FILE_MACHINE_AMD64//图像文件机常量
#endif
#else
#define ARCH_TYPE IMAGE_FILE_MACHINE_I386
#define ARCH_TYPE IMAGE_FILE_MACHINE_I386//图像文件机常量
#endif
#define CMD_INTERPRETER TEXT("%COMSPEC%")
#define CMD_INTERPRETER TEXT("%COMSPEC%")//指向CMD启动
class NativeLangSpeaker;
const bool POS_VERTICAL = true;
const bool POS_HORIZOTAL = false;
const bool POS_VERTICAL = true;//垂直向量为1
const bool POS_HORIZOTAL = false;//水平向量为0
const int UDD_SHOW = 1; // 0000 0001
const int UDD_DOCKED = 2; // 0000 0010
// 0 : 0000 0000 hide & undocked
// 1 : 0000 0001 show & undocked
// 2 : 0000 0010 hide & docked
// 3 : 0000 0011 show & docked
//Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。
// 程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker就不用担心环境问题。
// 0 : 0000 0000 hide & undocked 隐藏且非环境化 0
// 1 : 0000 0001 show & undocked 显示且非环境化 1
// 2 : 0000 0010 hide & docked 隐藏且环境化 2
// 3 : 0000 0011 show & docked 显示且环境化 3
const int TAB_DRAWTOPBAR = 1; //0000 0000 0001
const int TAB_DRAWINACTIVETAB = 2; //0000 0000 0010
@ -76,7 +94,7 @@ const int TAB_ALTICONS = 1024; //0100 0000 0000
const bool activeText = true;
const bool activeNumeric = false;
enum class EolType: std::uint8_t
enum class EolType: std::uint8_t//end of line 类型
{
windows,
macos,
@ -88,9 +106,9 @@ enum class EolType: std::uint8_t
};
/*!
** \brief Convert an int into a FormatType
** \param value An arbitrary int
** \param defvalue The default value to use if an invalid value is provided
** \brief Convert an int into a FormatTypeint
** \param value An arbitrary intint
** \param defvalue The default value to use if an invalid value is provided使
*/
EolType convertIntToFormatType(int value, EolType defvalue = EolType::osdefault);
@ -98,16 +116,16 @@ EolType convertIntToFormatType(int value, EolType defvalue = EolType::osdefault)
enum UniMode {uni8Bit=0, uniUTF8=1, uni16BE=2, uni16LE=3, uniCookie=4, uni7Bit=5, uni16BE_NoBOM=6, uni16LE_NoBOM=7, uniEnd};
enum ChangeDetect { cdDisabled = 0x0, cdEnabledOld = 0x01, cdEnabledNew = 0x02, cdAutoUpdate = 0x04, cdGo2end = 0x08 };
enum BackupFeature {bak_none = 0, bak_simple = 1, bak_verbose = 2};
enum OpenSaveDirSetting {dir_followCurrent = 0, dir_last = 1, dir_userDef = 2};
enum MultiInstSetting {monoInst = 0, multiInstOnSession = 1, multiInst = 2};
enum ChangeDetect { cdDisabled = 0x0, cdEnabledOld = 0x01, cdEnabledNew = 0x02, cdAutoUpdate = 0x04, cdGo2end = 0x08 };//改变监控
enum BackupFeature {bak_none = 0, bak_simple = 1, bak_verbose = 2};//备份和还原
enum OpenSaveDirSetting {dir_followCurrent = 0, dir_last = 1, dir_userDef = 2};//打开已保存设置
enum MultiInstSetting {monoInst = 0, multiInstOnSession = 1, multiInst = 2};//
enum writeTechnologyEngine {defaultTechnology = 0, directWriteTechnology = 1};
enum urlMode {urlDisable = 0, urlNoUnderLineFg, urlUnderLineFg, urlNoUnderLineBg, urlUnderLineBg,
urlMin = urlDisable,
urlMax = urlUnderLineBg};
const int LANG_INDEX_INSTR = 0;
const int LANG_INDEX_INSTR = 0;//语言索引指令
const int LANG_INDEX_INSTR2 = 1;
const int LANG_INDEX_TYPE = 2;
const int LANG_INDEX_TYPE2 = 3;
@ -117,7 +135,7 @@ const int LANG_INDEX_TYPE5 = 6;
const int LANG_INDEX_TYPE6 = 7;
const int LANG_INDEX_TYPE7 = 8;
const int COPYDATA_PARAMS = 0;
const int COPYDATA_PARAMS = 0;//数据拷贝参数
//const int COPYDATA_FILENAMESA = 1; // obsolete, no more useful
const int COPYDATA_FILENAMESW = 2;
const int COPYDATA_FULL_CMDLINE = 3;
@ -154,7 +172,7 @@ void cutStringBy(const TCHAR *str2cut, std::vector<std::wstring> & patternVect,
// style names
const wchar_t g_npcStyleName[] = L"Non-printing characters custom color";
struct Position
struct Position//位置结构体初始值全部为0
{
intptr_t _firstVisibleLine = 0;
intptr_t _startPos = 0;
@ -167,7 +185,7 @@ struct Position
};
struct MapPosition
struct MapPosition//图位
{
private:
intptr_t _maxPeekLenInKB = 512; // 512 KB
@ -187,10 +205,11 @@ public:
bool _isWrap = false;
bool isValid() const { return (_firstVisibleDisplayLine != -1); };
bool canScroll() const { return (_KByteInDoc < _maxPeekLenInKB); }; // _nbCharInDoc < _maxPeekLen : Don't scroll the document for the performance issue
//展开文件
};
struct sessionFileInfo : public Position
struct sessionFileInfo : public Position//会话文件信息结构体
{
sessionFileInfo(const wchar_t* fn, const TCHAR *ln, int encoding, bool userReadOnly, const Position& pos, const TCHAR *backupFilePath, FILETIME originalFileLastModifTimestamp, const MapPosition & mapPos) :
Position(pos), _encoding(encoding), _isUserReadOnly(userReadOnly), _originalFileLastModifTimestamp(originalFileLastModifTimestamp), _mapPos(mapPos)
@ -218,7 +237,7 @@ struct sessionFileInfo : public Position
};
struct Session
struct Session//会话结构体
{
size_t nbMainFiles() const {return _mainViewFiles.size();};
size_t nbSubFiles() const {return _subViewFiles.size();};
@ -232,7 +251,7 @@ struct Session
std::vector<std::wstring> _fileBrowserRoots;
};
//定义了两个结构体CmdLineParams和CmdLineParamsDTO分别用来保存命令行参数和通过WM_COPYDATA和Notepad_plus::loadCommandlineParams发送CmdLineParams。
struct CmdLineParams
{
bool _isNoPlugin = false;
@ -277,6 +296,11 @@ struct CmdLineParams
};
// A POD class to send CmdLineParams through WM_COPYDATA and to Notepad_plus::loadCommandlineParams
//CmdLineParams结构体定义了一系列bool、intptr_t、POINT、LangType和std::wstring类型的成员变量用于保存命令行参数的各个属性。其中isPointValid()函数用于检查_point的坐标值是否有效。
//CmdLineParamsDTO结构体是一个POD普通数据类型用于通过WM_COPYDATA和Notepad_plus::loadCommandlineParams发送CmdLineParams。它定义了与CmdLineParams相同类型的成员变量并提供了一个静态的FromCmdLineParams函数用于将CmdLineParams转换为CmdLineParamsDTO。
//在FromCmdLineParams函数中通过将CmdLineParams的成员变量赋值给CmdLineParamsDTO的对应成员变量实现了将CmdLineParams转换为CmdLineParamsDTO的功能。
//整个代码主要是为了实现CmdLineParams和CmdLineParamsDTO之间的数据传递和转换。
struct CmdLineParamsDTO
{
bool _isReadOnly = false;
@ -315,12 +339,12 @@ struct CmdLineParamsDTO
}
};
struct FloatingWindowInfo
struct FloatingWindowInfo//浮动窗口信息结构体
{
int _cont = 0;
RECT _pos = {};
FloatingWindowInfo(int cont, int x, int y, int w, int h)
FloatingWindowInfo(int cont, int x, int y, int w, int h)//浮动窗口位置参数
: _cont(cont)
{
_pos.left = x;
@ -389,6 +413,53 @@ struct DockingManagerData final
};
//这段代码定义了几个用于样式处理的数据结构和函数。
//首先是Style结构体表示一个样式。其中包括了以下成员
//_styleID: 样式的ID用于标识不同的样式。
//_styleDesc: 样式的描述。
//_fgColor和_bgColor前景色和背景色用于设置文本的颜色。
//_colorStyle颜色样式指定了是对前景色、背景色还是都设置颜色。
//_isFontEnabled是否启用了字体样式。
//_fontName字体名称。
//_fontStyle字体样式。
//_fontSize字体大小。
//_nesting嵌套样式用于处理嵌套样式的情况。
////_keywords关键字列表。
//然后是GlobalOverride结构体表示全局的样式覆盖设置。其中包括了以下成员
//isEnable()方法:判断是否启用了样式覆盖。
//enableFg、enableBg、enableFont、enableFontSize、enableBold、enableItalic、enableUnderLine每个成员都表示是否启用了相应的样式覆盖。
//接下来是StyleArray结构体用于管理多个样式。其中有以下成员函数
//begin()和end():返回迭代器,用于遍历样式数组。
//clear():清空样式数组。
//getStyler(size_t index):根据索引返回样式。
//addStyler(int styleID, TiXmlNode* styleNode)根据给定的样式ID和XML节点添加一个样式。
//addStyler(int styleID, const std::wstring& styleName)根据给定的样式ID和样式名称添加一个样式。
//findByID(int id)根据样式ID查找样式。
//findByName(const std::wstring& name):根据样式名称查找样式。
//接下来是LexerStyler结构体表示一个语法分析器的样式器。其中包括以下成员
//operator=:重载赋值运算符。
//setLexerName(const TCHAR* lexerName):设置语法分析器名称。
//setLexerDesc(const TCHAR* lexerDesc):设置语法分析器描述。
//setLexerUserExt(const TCHAR* lexerUserExt):设置语法分析器的用户扩展。
//getLexerName() const、getLexerDesc() const、getLexerUserExt() const分别返回语法分析器名称、描述和用户扩展。
//_lexerName、_lexerDesc、_lexerUserExt分别存储语法分析器的名称、描述和用户扩展。
//然后是SortLexersInAlphabeticalOrder结构体用于对LexerStyler进行按字母顺序排序。
//最后是LexerStylerArray结构体用于管理多个语法分析器的样式器。其中有以下成员函数
//getNbLexer() const返回语法分析器的数量。
//clear():清空语法分析器数组。
//getLexerFromIndex(size_t index):根据索引返回语法分析器样式器。
//getLexerNameFromIndex(size_t index) const、getLexerDescFromIndex(size_t index) const分别根据索引返回语法分析器的名称和描述。
//getLexerStylerByName(const TCHAR* lexerName):根据语法分析器名称查找语法分析器样式器。
//addLexerStyler(const TCHAR* lexerName, const TCHAR* lexerDesc, const TCHAR* lexerUserExt, TiXmlNode* lexerNode)根据语法分析器的名称、描述、用户扩展和XML节点添加一个语法分析器样式器。
//sort():对语法分析器样式器按字母顺序排序。
//这段代码的作用是定义了一些数据结构和函数,用于管理编辑器中的样式和语法分析器的样式。通过定义这些数据结构和函数,可以方便地管理和设置编辑器的样式和语法分析器的样式。
//
//
const int FONTSTYLE_NONE = 0;
const int FONTSTYLE_BOLD = 1;
@ -403,6 +474,7 @@ const int COLORSTYLE_ALL = COLORSTYLE_FOREGROUND|COLORSTYLE_BACKGROUND;
struct Style final
{
int _styleID = STYLE_NOT_USED;
@ -424,6 +496,14 @@ struct Style final
};
//
//
//
//
//
//
//
struct GlobalOverride final
{
bool isEnable() const {return (enableFg || enableBg || enableFont || enableFontSize || enableBold || enableItalic || enableUnderLine);}
@ -436,6 +516,14 @@ struct GlobalOverride final
bool enableUnderLine = false;
};
//
//
//
//
//
//
//
struct StyleArray
{
auto begin() { return _styleVect.begin(); };
@ -482,6 +570,14 @@ protected:
};
//
//
//
//
//
//
//
struct LexerStyler : public StyleArray
{
@ -522,6 +618,15 @@ private :
std::wstring _lexerUserExt;
};
//
//
//
//
//
//
//
struct SortLexersInAlphabeticalOrder {
bool operator() (LexerStyler& l, LexerStyler& r) {
if (!lstrcmp(l.getLexerDesc(), TEXT("Search result")))
@ -532,6 +637,15 @@ struct SortLexersInAlphabeticalOrder {
}
};
//
//
//
//
//
//
//
struct LexerStylerArray
{
size_t getNbLexer() const { return _lexerStylerVect.size(); }
@ -567,6 +681,23 @@ private :
};
//
//
//
//
//
//NewDocDefaultSettings包含了一些默认的文档设置包括文件格式、Unicode模式、编码方式等。
//LangMenuItem定义了一个菜单项包含了语言类型、命令ID和语言名称。
//PrintSettings定义了打印设置包括是否打印行号、打印选项、页眉页脚内容、字体样式等。
//Date定义了日期类包含年、月、日并提供了日期的比较和转换方法。
//这些结构体和类用于在某个编辑器中管理文档、语言、打印、日期等相关的设置和功能。
//
struct NewDocDefaultSettings final
{
EolType _format = EolType::osdefault;
@ -578,6 +709,15 @@ struct NewDocDefaultSettings final
};
//
//
//
//
//
//
//
struct LangMenuItem final
{
LangType _langType = L_TEXT;
@ -587,7 +727,13 @@ struct LangMenuItem final
LangMenuItem(LangType lt, int cmdID = 0, const std::wstring& langName = TEXT("")):
_langType(lt), _cmdID(cmdID), _langName(langName){};
};
//
//
//
//
//
//
//
struct PrintSettings final {
bool _printLineNumber = true;
int _printOption = SC_PRINT_COLOURONWHITE;
@ -624,7 +770,13 @@ struct PrintSettings final {
return ((_marge.left != 0) || (_marge.top != 0) || (_marge.right != 0) || (_marge.bottom != 0));
};
};
//
//
//
//
//
//
//
class Date final
{
@ -702,7 +854,25 @@ private:
unsigned long _month = 4;
unsigned long _day = 26;
};
//
//
//这段代码定义了一个名为MatchedPairConf的类该类包含了一些成员变量和成员函数。
//
//MatchedPairConf类的成员变量包括
//- _matchedPairs一个包含字符对的向量用于存储匹配的字符对。
//- _matchedPairsInit用于在初始化时使用的_matchedPairs的副本。
//- _doHtmlXmlTag、_doParentheses、_doBrackets、_doCurlyBrackets、_doQuotes、_doDoubleQuotes表示是否执行相应类型的括号匹配的布尔变量。
//
//MatchedPairConf类的成员函数包括
//- hasUserDefinedPairs() const判断是否存在用户定义的字符对。
//- hasDefaultPairs() const判断是否存在默认的字符对包括圆括号、方括号、花括号、引号等。
//- hasAnyPairsPair() const判断是否存在任何类型的字符对。
//
//该类的目的是管理匹配括号的设置,包括用户定义的字符对和默认的字符对。
//
//
//
//
class MatchedPairConf final
{
@ -721,7 +891,13 @@ public:
bool _doQuotes = false;
bool _doDoubleQuotes = false;
};
//
//
//
//
//
//
//
struct DarkModeConf final
{
bool _isEnabled = false;
@ -731,7 +907,13 @@ struct DarkModeConf final
NppDarkMode::AdvancedOptions _advOptions{};
};
//
//
//
//
//
//
//
struct LargeFileRestriction final
{
int64_t _largeFileSizeDefInByte = NPP_STYLING_FILESIZE_LIMIT_DEFAULT;
@ -746,7 +928,13 @@ struct LargeFileRestriction final
bool _suppress2GBWarning = false;
};
//
//
//
//
//
//
//
struct NppGUI final
{
toolBarStatusType _toolBarStatus = TB_STANDARD;
@ -918,7 +1106,27 @@ struct NppGUI final
LargeFileRestriction _largeFileRestriction;
};
//
//这段代码定义了三个结构体和一个类。
//
//1. 结构体ScintillaViewParams:
//-成员变量包括一系列布尔变量和枚举类型变量用于记录Scintilla编辑器的各种参数设置。
//- 成员函数包括一个计算分心模式视图的填充长度的方法。
//
//2. 结构体Lang :
// -成员变量包括语言ID、语言名称、默认文件扩展名、关键词列表、行注释符号、块注释开始符号和结束符号等。
// - 成员函数包括设置默认文件扩展名、设置行注释符号、设置块注释开始符号、设置块注释结束符号以及获取 / 设置Tab信息等。
//
// 3. 类UserLangContainer :
// -成员变量包括样式数组、语言名称、文件扩展名、是否为深色模式、UDL版本、关键词列表、是否为前缀、是否忽略大小写、是否允许折叠注释、强制纯LC、小数分隔符以及是否紧凑折叠等。
// - 成员函数包括获取名称、获取文件扩展名、获取UDL版本等。
///
// 这些结构体和类都用于记录编辑器的各种设置参数,方便进行管理和访问。
//
//
//
//
//
struct ScintillaViewParams
{
bool _lineNumberMarginShow = true;
@ -974,7 +1182,13 @@ struct ScintillaViewParams
return paddingLen;
};
};
//
//
//
//
//
//
//
const int NB_LIST = 20;
const int NB_MAX_LRF_FILE = 30;
const int NB_MAX_USER_LANG = 30;
@ -994,7 +1208,13 @@ const int MASK_ReplaceBySpc = 0x80;
const int MASK_TabSize = 0x7F;
//
//
//
//
//
//
//
struct Lang final
{
@ -1068,7 +1288,13 @@ struct Lang final
}
};
//
//
//
//
//
//
//
class UserLangContainer final
{
@ -1149,7 +1375,39 @@ private:
#define MAX_EXTERNAL_LEXER_NAME_LEN 128
//
//这段代码定义了五个结构体和两个类。
//
//1. 类ExternalLangContainer:
//-成员变量包括字符串类型的_nameLexilla::CreateLexerFn类型的fnCL以及ExternalLexerAutoIndentMode类型的_autoIndentMode。
//- 没有定义成员函数。
//
//2. 结构体FindHistory :
// -成员变量包括多个布尔变量和整型变量,用于记录查找历史记录的各种参数设置。
// - 成员函数包括获取查找历史记录的路径、获取查找历史记录的过滤器、获取查找历史记录的查找内容等。
//
// 3. 结构体ColumnEditorParam :
// -成员变量包括leadingChoice枚举类型的_leadingChoice整型变量_initialNum、_increaseNum、_repeatNum和_formatChoice字符串类型的_insertedTextContent。
// - 没有定义成员函数。
//
// 4. 类LocalizationSwitcher :
// -成员变量包括LocalizationDefinition结构体类型的_localizationList、wstring类型的_nativeLangPath和string类型的_fileName。
// - 成员函数包括从xml文件中添加语言、根据xml文件名获取语言名称、根据语言名称获取xml文件路径、切换到指定语言以及获取_localizationList大小等。
//
// 5. 类ThemeSwitcher :
// -成员变量包括std::vector类型的_themeList、std::map类型的_themeStylerSavePath、wstring类型的_themeDirPath和wstring类型的_defaultThemeLabel。
// - 成员函数包括从xml文件中添加主题、根据xml文件名获取主题名称、根据主题名称获取xml文件路径、检查主题名称是否存在、获取_themeList大小、设置主题文件夹路径、获取主题文件夹路径、获取默认主题标签以及根据路径获取保存路径等。
//
// 6. 结构体UdlXmlFileState :
// -成员变量包括TiXmlDocument指针类型的_udlXmlDoc布尔类型的_isDirty和_isInDefaultSharedContainer以及pair<unsigned char, unsigned char>类型的_indexRange。
// - 构造函数用于初始化成员变量。
//
// 这些结构体和类用于记录各种设置参数和状态信息,方便进行管理和访问。
//
//
//
//
//
class ExternalLangContainer final
{
@ -1165,6 +1423,14 @@ public:
};
//
//
//
//
//
//
//
struct FindHistory final
{
enum searchMode{normal, extended, regExpr};
@ -1208,6 +1474,14 @@ struct FindHistory final
bool _regexBackward4PowerUser = false;
};
//
//
//
//
//
//
//
struct ColumnEditorParam final
{
enum leadingChoice : UCHAR { noneLeading, zeroLeading, spaceLeading };
@ -1223,6 +1497,14 @@ struct ColumnEditorParam final
leadingChoice _leadingChoice = noneLeading;
};
//
//
//
//
//
//
//
class LocalizationSwitcher final
{
friend class NppParameters;
@ -1269,6 +1551,14 @@ private:
};
//
//
//
//
//
//
//
class ThemeSwitcher final
{
friend class NppParameters;
@ -1340,6 +1630,14 @@ private:
};
//
//
//
//
//
//
//
struct UdlXmlFileState final {
TiXmlDocument* _udlXmlDoc = nullptr;
bool _isDirty = false;
@ -1634,6 +1932,48 @@ public:
return _workSpaceFilePathes[i].c_str();
};
//
//这段代码包含了两个类和一些常量和函数的定义:
//
//常量和变量的定义:
//
// NB_LANG整型常量表示语言的数量上限。
// RECENTFILES_SHOWFULLPATH和RECENTFILES_SHOWONLYFILENAME整型常量表示在最近文件列表中显示完整路径或仅显示文件名。
// 类DynamicMenu
// 公共成员函数包括attach方法用于将菜单附加到特定位置createMenu方法用于创建菜单clearMenu方法用于清空菜单getTopLevelItemNumber方法用于获取顶级菜单项的数量push_back方法用于向菜单添加菜单项getItemFromIndex方法用于根据索引获取菜单项erase方法用于根据索引删除菜单项getPosBase方法用于获取_posBase的值getLastCmdLabel方法用于获取_lastCmdLabel的值。
// 私有成员变量包括_menuItems类型为MenuItemUnit的vector_hMenu类型为HMENU_posBase类型为unsigned int_lastCmd类型为int和_lastCmdLabel类型为wstring。
// 类NppParameters
// 私有静态函数getInstancePointer用于获取NppParameters的实例指针。
// 静态函数getInstance用于获取NppParameters的实例。
// 静态函数getLangIDFromStr用于根据语言名称获取对应的LangType。
// 静态函数getLocPathFromStr用于根据本地化代码获取本地化文件路径。
// 成员函数load用于加载NppParameters的设置参数。
// 其他成员函数用于获取和操作NppParameters中的配置参数。
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
const std::vector<std::wstring> getFileBrowserRoots() const { return _fileBrowserRoot; };
std::wstring getFileBrowserSelectedItemPath() const { return _fileBrowserSelectedItemPath; };
@ -1886,7 +2226,92 @@ private:
std::wstring _startWithLocFileName;
bool _doFunctionListExport = false;
bool _doPrintAndExit = false;
//
//这段代码继续定义了NppParameters类的一些成员函数和成员变量
//-getFileBrowserRoots方法返回_fileBrowserRoot的引用用于获取文件浏览器的根路径列表。
//- getFileBrowserSelectedItemPath方法返回_fileBrowserSelectedItemPath的值表示文件浏览器中选定的路径。
//- setWorkSpaceFilePath和getLoadedSessionFilePath方法用于设置和获取工作空间文件路径。
// - setWorkingDir方法用于设置当前工作目录。
// - setStartWithLocFileName方法用于设置启动时的本地化文件名。
// - setFunctionListExportBoolean和doFunctionListExport方法用于设置和获取是否导出函数列表。
// - setPrintAndExitBoolean和doPrintAndExit方法用于设置和获取是否打印并退出。
// - loadSession方法用于加载会话配置。
// - getFindDlgTabTitiles方法返回_findDlgTabTitiles的引用其中存储了查找对话框选项卡的标题。
// - asNotepadStyle方法用于判断是否使用类似记事本的样式。
/* - reloadPluginCmds方法用于重新加载插件命令。
- getContextMenuFromXmlTreereloadContextMenuFromXmlTreeXML
- getWinVersion_winVersionWindows
- getFindHistory_findHistory
- safeWow64EnableWow64FsRedirection64
- getLocalizationSwitcherNppParameters
- getFileBrowserRoots
- getFileBrowserSelectedItemPath
- setWorkSpaceFilePath
- setWorkingDir
- setStartWithLocFileName使
- setFunctionListExportBoolean
- setPrintAndExitBoolean退
- loadSession
- setLoadedSessionFilePath
- getLoadedSessionFilePath
- langTypeToCommandIDID
- getFindDlgTabTitiles
- asNotepadStyle
- reloadPluginCmds
- getContextMenuFromXmlTreeXML
- reloadContextMenuFromXmlTree
- getWinVersion
- getWinVersionStr
- getWinVerBitStr
- getFindHistory
- safeWow64EnableWow64FsRedirectionWOW64
- getLocalizationSwitcher
- getThemeSwitcher
- getBlackList
- isInBlackList
- importUDLFromFile
- exportUDLToFile
- getNativeLangSpeaker
- setNativeLangSpeaker
- isLocal
- isCloud
- saveConfig_xmlXML
- getUserPath
- getUserDefineLangFolderPath
- getUserDefineLangPath
- writeSettingsFilesOnCloudForThe1stTime
- setCloudChoice
- removeCloudChoice
- isCloudPathChanged
- archType
- getCurrentDefaultBgColor
- getCurrentDefaultFgColor
- setCurrentDefaultBgColor
- setCurrentDefaultFgColor
- setCmdSettingsDir
- setTitleBarAdd
- getTitleBarAdd
- _dpiManagerDPI
- getSpecialFolderLocation
- setUdlXmlDirtyFromIndexUserDefineLang XML
- setUdlXmlDirtyFromXmlDocXMLUserDefineLang XML
- removeIndexFromXmlUdlsUserDefineLang XML
- isStylerDocLoadedstylers.xml
- _columnEditParamColumnEditorParam*/
//
//
//
//
//
//
//
//
//
//
//
//
ThemeSwitcher _themeSwitcher;
std::vector<MenuItemUnit> _contextMenuItems;
@ -2024,3 +2449,29 @@ private:
winVer getWindowsVersion();
};
//这段代码继续定义了NppParameters类的一些成员函数和成员变量
//
//- _themeSwitcher主题切换器。
//- _contextMenuItems和_tabContextMenuItems用于存储自定义右键菜单的菜单项。
//- _macroMenuItems和_runMenuItems用于存储宏和运行命令的菜单项。
//- _session会话对象用于存储会话信息。
//- _shortcutsPath、_contextMenuPath、_tabContextMenuPath、_sessionPath、_nppPath、_userPath、_stylerPath、_appdataNppDir、_pluginRootDir、_pluginConfDir、_userPluginConfDir、_currentDirectory、_workSpaceFilePathes用于存储文件路径和目录路径的字符串变量。
//- _fileBrowserRoot和_fileBrowserSelectedItemPath存储文件浏览器根路径和选定项目路径的变量。
//- _pAccelerator和_pScintAccelerator加速键和Scintilla的加速键。
//- _findDlgTabTitiles查找对话框选项卡的标题。
//- _asNotepadStyle表示是否将界面样式设置为类似记事本的风格。
//- _winVersionWindows的版本。
//- _platForm平台的类型。
//- _pNativeLangSpeaker与本地化语言相关的对象。
//- _currentDefaultBgColor和_currentDefaultFgColor当前默认的背景颜色和前景颜色。
//- _initialCloudChoice初始的云端路径选择。
//- _wingupFullPath、_wingupParams、_wingupDir和_isElevationRequired与升级Wingup相关的变量。
//- _doNppLogNetworkDriveIssue和_doNppLogNulContentCorruptionIssue用于记录是否需要进行网络驱动器和NUL内容损坏问题的日志记录。
//- _isEndSessionStarted和_isEndSessionCritical用于记录会话是否已开始和是否是临界会话。
//- _isPlaceHolderEnabled和_theWarningHasBeenGiven用于记录是否启用了占位符功能和警告是否已给出。
//- getWingupFullPath、getWingupParams、getWingupDir和shouldDoUAC获取与升级Wingup相关的参数。
//- setWingupFullPath、setWingupParams、setWingupDir和setElevationRequired设置与升级Wingup相关的参数。
//- doNppLogNetworkDriveIssue、doNppLogNulContentCorruptionIssue、endSessionStart、isEndSessionStarted、makeEndSessionCritical和isEndSessionCritical获取或设置与日志记录和会话状态相关的参数。
//- setPlaceHolderEnable、isPlaceHolderEnabled、setTheWarningHasBeenGiven和theWarningHasBeenGiven获取或设置与占位符功能和警告状态相关的参数。
//
//总体来说NppParameters类是Notepad++的参数配置类包含了各种相关的配置参数和操作函数。这些参数和函数用于管理和操作Notepad++的各种配置信息,如语言设置、样式设置、快捷键、宏命令、插件命令等。

@ -25,7 +25,7 @@
bool DocTabView::_hideTabBarStatus = false;
//向标签视图添加新的缓冲区,首先检查缓冲区是否有效(不是无效的缓冲区),然后检查是否已经存在相同的缓冲区。如果缓冲区有效且尚未存在,则将其添加到标签页视图中,并更新父窗口的大小。
void DocTabView::addBuffer(BufferID buffer)
{
if (buffer == BUFFER_INVALID) //valid only
@ -48,25 +48,25 @@ void DocTabView::addBuffer(BufferID buffer)
::SendMessage(_hParent, WM_SIZE, 0, 0);
}
//关闭指定的缓冲区,到要关闭的缓冲区的索引,然后从标签页视图中删除它,并通知父窗口进行调整。
void DocTabView::closeBuffer(BufferID buffer)
{
int indexToClose = getIndexByBuffer(buffer);
deletItemAt((size_t)indexToClose);
::SendMessage(_hParent, WM_SIZE, 0, 0);
}
//为特定的标签设置颜色。根据提供的缓冲区ID设置该缓冲区在标签页中的颜色。
void DocTabView::setIndividualTabColour(BufferID bufferId, int colorId)
{
bufferId->setDocColorId(colorId);
}
//获取特定标签的颜色,根据提供的标签索引,返回该标签的颜色。
int DocTabView::getIndividualTabColour(int tabIndex)
{
BufferID bufferId = getBufferByIndex(tabIndex);
return bufferId->getDocColorId();
}
//激活特定的缓冲区通过缓冲区的ID找到其索引位置并尝试激活该缓冲区如果成功则返回true否则返回false。
bool DocTabView::activateBuffer(BufferID buffer)
{
int indexToActivate = getIndexByBuffer(buffer);
@ -77,14 +77,14 @@ bool DocTabView::activateBuffer(BufferID buffer)
return true;
}
//获取当前激活的缓冲区。
BufferID DocTabView::activeBuffer()
{
int index = getCurrentTabIndex();
return getBufferByIndex(index);
}
//遍历所有标签页根据文件名查找匹配的缓冲区找到则返回其ID否则返回BUFFER_INVALID。
BufferID DocTabView::findBufferByName(const TCHAR* fullfilename) //-1 if not found, something else otherwise
{
TCITEM tie{};
@ -103,7 +103,7 @@ BufferID DocTabView::findBufferByName(const TCHAR * fullfilename) //-1 if not fo
return BUFFER_INVALID;
}
//通过缓冲区ID找到其在标签中的索引位置如果不存在则返回 - 1。
int DocTabView::getIndexByBuffer(BufferID id)
{
TCITEM tie{};
@ -118,7 +118,7 @@ int DocTabView::getIndexByBuffer(BufferID id)
return -1;
}
//通过缓冲区ID找到其在标签中的索引位置如果不存在则返回-1。
BufferID DocTabView::getBufferByIndex(size_t index)
{
TCITEM tie{};
@ -129,7 +129,7 @@ BufferID DocTabView::getBufferByIndex(size_t index)
return reinterpret_cast<BufferID>(tie.lParam);
}
//根据mask中的标志位更新与缓冲区相关的信息例如文件名变化、只读状态变化等。
void DocTabView::bufferUpdated(Buffer* buffer, int mask)
{
int index = getIndexByBuffer(buffer->getID());
@ -192,7 +192,7 @@ void DocTabView::bufferUpdated(Buffer * buffer, int mask)
::SendMessage(_hParent, WM_SIZE, 0, 0);
}
//根据给定的索引设置相应的缓冲区ID并更新标签显示的相关信息。
void DocTabView::setBuffer(size_t index, BufferID id)
{
if (index >= _nbItem)
@ -208,7 +208,7 @@ void DocTabView::setBuffer(size_t index, BufferID id)
::SendMessage(_hParent, WM_SIZE, 0, 0);
}
//根据隐藏/显示标签栏状态,调整标签页视图和文本编辑器视图的大小,并根据需要发送消息以更新可点击链接。
void DocTabView::reSizeTo(RECT& rc)
{
int borderWidth = ((NppParameters::getInstance()).getSVP())._borderWidth;

@ -14,11 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//该类继承自TabBarPlus类。该类负责管理文档选项卡视图并提供一系列方法用于添加、关闭、激活缓冲区以及设置选项卡的个性化选项等功能。
#pragma once
#include "TabBar.h"
#include "Buffer.h"
// 定义一些常量用作图片索引
const int SAVED_IMG_INDEX = 0;
const int UNSAVED_IMG_INDEX = 1;
const int REDONLY_IMG_INDEX = 2;
@ -33,7 +37,7 @@ public :
void destroy() override {
TabBarPlus::destroy();
};
//初始化函数传入实例句柄、父窗口句柄、ScintillaEditView指针、以及图片列表和选择的图片索引
void init(HINSTANCE hInst, HWND parent, ScintillaEditView* pView, std::vector<IconList*> pIconListVector, unsigned char indexChoice) {
TabBarPlus::init(hInst, parent);
_pView = pView;
@ -52,45 +56,50 @@ public :
TabBar::setImageList(_pIconListVector[_iconListIndexChoice]->getHandle());
return;
};
// 改变选中的图片列表
void changeIcons(unsigned char choice) {
if (choice >= _pIconListVector.size())
return;
_iconListIndexChoice = choice;
TabBar::setImageList(_pIconListVector[_iconListIndexChoice]->getHandle());
};
// 添加缓冲区
void addBuffer(BufferID buffer);
// 关闭缓冲区
void closeBuffer(BufferID buffer);
// 缓冲区更新
void bufferUpdated(Buffer* buffer, int mask);
// 激活缓冲区
bool activateBuffer(BufferID buffer);
// 获取当前激活的缓冲区
BufferID activeBuffer();
// 根据文件名查找缓冲区,返回索引值,如果未找到则返回-1
BufferID findBufferByName(const TCHAR* fullfilename); //-1 if not found, something else otherwise
// 根据缓冲区获取索引值
int getIndexByBuffer(BufferID id);
// 根据索引值获取缓冲区
BufferID getBufferByIndex(size_t index);
// 设置指定索引位置的缓冲区
void setBuffer(size_t index, BufferID id);
// 静态函数,用于设置隐藏或显示选项卡栏的状态
static bool setHideTabBarStatus(bool hideOrNot) {
bool temp = _hideTabBarStatus;
_hideTabBarStatus = hideOrNot;
return temp;
};
// 静态函数,获取隐藏或显示选项卡栏的状态
static bool getHideTabBarStatus() {
return _hideTabBarStatus;
};
// 重写父类的reSizeTo方法
void reSizeTo(RECT& rc) override;
// 获取ScintillaEditView指针
const ScintillaEditView* getScintillaEditView() const {
return _pView;
};
// 设置指定缓冲区的个性化选项卡颜色
void setIndividualTabColour(BufferID bufferId, int colorId);
// 获取指定索引位置的个性化选项卡颜色
int getIndividualTabColour(int tabIndex) override;
private:

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

@ -13,7 +13,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//处理工具栏按钮
#include <stdexcept>
#include "TabBar.h"
#include "Parameters.h"
@ -40,7 +40,7 @@ COLORREF TabBarPlus::_inactiveBgColour = RGB(192, 192, 192);
HWND TabBarPlus::_hwndArray[nbCtrlMax] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
int TabBarPlus::_nbCtrl = 0;
//初始化标签栏,创建窗口
void TabBar::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isMultiLine)
{
Window::init(hInst, parent);
@ -49,7 +49,7 @@ void TabBar::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isMultiLin
_isVertical = isVertical;
_isMultiLine = isMultiLine;
INITCOMMONCONTROLSEX icce{};
INITCOMMONCONTROLSEX icce{};//初始化通用控件库
icce.dwSize = sizeof(icce);
icce.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&icce);
@ -75,27 +75,27 @@ void TabBar::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isMultiLin
}
}
//清理与TabBar相关的资源
void TabBar::destroy()
{
if (_hFont)
{
::DeleteObject(_hFont);
_hFont = nullptr;
}
}//删除字体对象
if (_hLargeFont)
{
::DeleteObject(_hLargeFont);
_hLargeFont = nullptr;
}
}//删除字体大小格式
if (_hVerticalFont)
{
::DeleteObject(_hVerticalFont);
_hVerticalFont = nullptr;
}
//删除垂直字体对象
if (_hVerticalLargeFont)
{
::DeleteObject(_hVerticalLargeFont);
@ -106,13 +106,13 @@ void TabBar::destroy()
_hSelf = nullptr;
}
//在TabBar末尾插入一个新的选项卡并设置名称。使用TCITEM结构设置选项卡的属性并发送消息将选项卡插入TabBar中
int TabBar::insertAtEnd(const TCHAR* subTabName)
{
TCITEM tie{};
tie.mask = TCIF_TEXT | TCIF_IMAGE;
int index = -1;
//如果存在图像列表那么新TabItem应该被放置在列表的开始。
if (_hasImgLst)
index = 0;
tie.iImage = index;
@ -120,7 +120,7 @@ int TabBar::insertAtEnd(const TCHAR *subTabName)
return int(::SendMessage(_hSelf, TCM_INSERTITEM, _nbItem++, reinterpret_cast<LPARAM>(&tie)));
}
//获取当前选定选项卡的标题。
void TabBar::getCurrentTitle(TCHAR* title, int titleLen)
{
TCITEM tci{};
@ -130,7 +130,7 @@ void TabBar::getCurrentTitle(TCHAR *title, int titleLen)
::SendMessage(_hSelf, TCM_GETITEM, getCurrentTabIndex(), reinterpret_cast<LPARAM>(&tci));
}
//为TabBar中的选项卡设置字体。根据提供的参数创建新字体并发送消息为TabBar设置该字体
void TabBar::setFont(const TCHAR* fontName, int fontSize)
{
if (_hFont)
@ -147,7 +147,7 @@ void TabBar::setFont(const TCHAR *fontName, int fontSize)
::SendMessage(_hSelf, WM_SETFONT, reinterpret_cast<WPARAM>(_hFont), 0);
}
//激活指定索引处的选项卡。发送消息以确保在TabBar中激活指定索引处的选项卡。
void TabBar::activateAt(int index) const
{
if (getCurrentTabIndex() != index)
@ -163,14 +163,14 @@ void TabBar::activateAt(int index) const
}
}
//删除指定索引处的选项卡
void TabBar::deletItemAt(size_t index)
{
if (index == _nbItem - 1)
{
//prevent invisible tabs. If last visible tab is removed, other tabs are put in view but not redrawn
//Therefore, scroll one tab to the left if only one tab visible
if (_nbItem > 1)
if (_nbItem > 1)//至少两个
{
RECT itemRect{};
::SendMessage(_hSelf, TCM_GETITEMRECT, index, reinterpret_cast<LPARAM>(&itemRect));
@ -182,7 +182,7 @@ void TabBar::deletItemAt(size_t index)
//There seems to be no negative effect on any internal state of the tab control or the up/down control
int wParam = MAKEWPARAM(SB_THUMBPOSITION, index - 1);
::SendMessage(_hSelf, WM_HSCROLL, wParam, 0);
//TabBar控件向左滚动一个Tab项的位置。
wParam = MAKEWPARAM(SB_ENDSCROLL, index - 1);
::SendMessage(_hSelf, WM_HSCROLL, wParam, 0);
}
@ -192,14 +192,14 @@ void TabBar::deletItemAt(size_t index)
_nbItem--;
}
//设置TabBar中的图像列表。使用TCM_SETIMAGELIST消息来设置图像列表。
void TabBar::setImageList(HIMAGELIST himl)
{
_hasImgLst = true;
::SendMessage(_hSelf, TCM_SETIMAGELIST, 0, reinterpret_cast<LPARAM>(himl));
}
//调整TabBar的大小以适应给定的矩形区域。调整TabBar的显示方式并计算新的大小然后调整提供的矩形区域。
void TabBar::reSizeTo(RECT& rc2Ajust)
{
RECT rowRect{};
@ -208,6 +208,7 @@ void TabBar::reSizeTo(RECT & rc2Ajust)
// Important to do that!
// Otherwise, the window(s) it contains will take all the resouce of CPU
// We don't need to resize the contained windows if they are even invisible anyway
//调用display方法根据调整矩形的右边界是否大于10来决定是否显示TabBar中的窗口
display(rc2Ajust.right > 10);
RECT rc = rc2Ajust;
Window::reSizeTo(rc);
@ -226,7 +227,7 @@ void TabBar::reSizeTo(RECT & rc2Ajust)
if (rowCount == 1)
{
style &= ~TCS_BUTTONS;
}
}// 如果有多行Tab项至少两行则启用TabCtrl的按钮样式并计算间距的值
else // (rowCount >= 2)
{
style |= TCS_BUTTONS;
@ -249,15 +250,19 @@ void TabBar::reSizeTo(RECT & rc2Ajust)
}
}
//销毁TabBarPlus及其资源。
void TabBarPlus::destroy()
{
TabBar::destroy();
::DestroyWindow(_tooltips);
_tooltips = NULL;
}
/*
TabBarPlus
TabControl
TabBarPlus便
*/
void TabBarPlus::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isMultiLine)
{
Window::init(hInst, parent);
@ -290,7 +295,7 @@ void TabBarPlus::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isMult
{
throw std::runtime_error("TabBarPlus::init : CreateWindowEx() function return null");
}
//工具提示
_tooltips = ::CreateWindowEx(
0,
TOOLTIPS_CLASS,
@ -306,7 +311,7 @@ void TabBarPlus::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isMult
{
throw std::runtime_error("TabBarPlus::init : tooltip CreateWindowEx() function return null");
}
//暗色主题
NppDarkMode::setDarkTooltips(_tooltips, NppDarkMode::ToolTipsType::tooltip);
::SendMessage(_hSelf, TCM_SETTOOLTIPS, reinterpret_cast<WPARAM>(_tooltips), 0);
@ -317,12 +322,13 @@ void TabBarPlus::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isMult
_ctrlID = _nbCtrl;
}
else
{
{//查找第一个为空的位置并设置_ctrlID为该位置的值
int i = 0;
bool found = false;
for (; i < nbCtrlMax && !found; ++i)
if (!_hwndArray[i])
found = true;
//满了未找到,销毁
if (!found)
{
_ctrlID = -1;
@ -354,7 +360,7 @@ void TabBarPlus::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isMult
_hVerticalLargeFont = CreateFontIndirect(&lfVer);
}
//处理选项卡控件的自定义填充。
void TabBarPlus::doOwnerDrawTab()
{
::SendMessage(_hwndArray[0], TCM_SETPADDING, 0, MAKELPARAM(6, 0));
@ -363,6 +369,7 @@ void TabBarPlus::doOwnerDrawTab()
if (_hwndArray[i])
{
LONG_PTR style = ::GetWindowLongPtr(_hwndArray[i], GWL_STYLE);
//检查是否需要自定义
if (isOwnerDrawTab())
style |= TCS_OWNERDRAWFIXED;
else
@ -378,7 +385,7 @@ void TabBarPlus::doOwnerDrawTab()
}
}
//根据给定的索引为选项卡栏设置不同的颜色(如活动文本颜色、背景颜色等)。在更新颜色之后它调用doOwnerDrawTab()来刷新显示。
void TabBarPlus::setColour(COLORREF colour2Set, tabColourIndex i)
{
switch (i)
@ -404,7 +411,7 @@ void TabBarPlus::setColour(COLORREF colour2Set, tabColourIndex i)
doOwnerDrawTab();
}
//设置垂直选项卡
void TabBarPlus::doVertical()
{
for (int i = 0; i < _nbCtrl; ++i)
@ -414,7 +421,7 @@ void TabBarPlus::doVertical()
}
}
//显示多行选项卡
void TabBarPlus::doMultiLine()
{
for (int i = 0; i < _nbCtrl; ++i)
@ -423,7 +430,7 @@ void TabBarPlus::doMultiLine()
SendMessage(_hwndArray[i], WM_TABSETSTYLE, isMultiLine(), TCS_MULTILINE);
}
}
//向父窗口发送通知消息,其中包含有关选项卡索引和特定通知代码的信息。
void TabBarPlus::notify(int notifyCode, int tabIndex)
{
TBHDR nmhdr{};
@ -433,7 +440,7 @@ void TabBarPlus::notify(int notifyCode, int tabIndex)
nmhdr._tabOrigin = tabIndex;
::SendMessage(_hParent, WM_NOTIFY, 0, reinterpret_cast<LPARAM>(&nmhdr));
}
//启动对选项卡栏控件上的鼠标事件的跟踪,例如当鼠标进入或离开控件区域时。
void TabBarPlus::trackMouseEvent(DWORD event2check)
{
TRACKMOUSEEVENT tme = {};
@ -442,12 +449,13 @@ void TabBarPlus::trackMouseEvent(DWORD event2check)
tme.hwndTrack = _hSelf;
TrackMouseEvent(&tme);
}
//消息处理,处理窗口消息
LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
// Custom window message to change tab control style on the fly
//改变窗口样式
case WM_TABSETSTYLE:
{
LONG_PTR style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
@ -465,13 +473,13 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
return TRUE;
}
//深色模式
case NPPM_INTERNAL_REFRESHDARKMODE:
{
NppDarkMode::setDarkTooltips(hwnd, NppDarkMode::ToolTipsType::tabbar);
return TRUE;
}
//鼠标滚轮
case WM_MOUSEWHEEL:
{
// ..............................................................................
@ -489,7 +497,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
// CTRL + SHIFT + MOUSEWHEEL:
// will switch to the first/last tab
// ..............................................................................
//是否被拖动,如是,会交换当前鼠标所在位置和目标位置的数据
if (_isDragging)
return TRUE;
@ -581,7 +589,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
}
return TRUE;
}
//左键按下
case WM_LBUTTONDOWN:
{
if (::GetWindowLongPtr(_hSelf, GWL_STYLE) & TCS_BUTTONS)
@ -592,7 +600,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
setActiveTab(nTab);
}
}
//是否关闭
if (_drawTabCloseButton)
{
int xPos = LOWORD(lParam);
@ -621,7 +629,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
return TRUE;
}
//右键按下,处理选项
case WM_RBUTTONDOWN: //rightclick selects tab aswell
{
// TCS_BUTTONS doesn't select the tab
@ -637,7 +645,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
::CallWindowProc(_tabBarDefaultProc, hwnd, WM_LBUTTONDOWN, wParam, lParam);
return TRUE;
}
//鼠标移动
case WM_MOUSEMOVE:
{
if (_mightBeDragging && !_isDragging)
@ -670,7 +678,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
POINT p{};
p.x = LOWORD(lParam);
p.y = HIWORD(lParam);
//是否拖动tag光标移动tab数据交换判断并进行相关操作
if (_isDragging)
{
exchangeItemData(p);
@ -758,7 +766,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
break;
}
//鼠标移开,重绘鼠标区域,重置相关变量
case WM_MOUSELEAVE:
{
if (_isCloseHover)
@ -772,7 +780,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
notify(TCN_MOUSELEAVING, _currentHoverTabItem);
break;
}
//释放左键,告知操作结束
case WM_LBUTTONUP:
{
_mightBeDragging = false;
@ -820,7 +828,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
break;
}
//抓取鼠标输入的改变
case WM_CAPTURECHANGED:
{
if (_isDragging)
@ -830,20 +838,20 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
}
break;
}
//重绘tab
case WM_DRAWITEM:
{
drawItem((DRAWITEMSTRUCT*)lParam);
return TRUE;
}
//是否按下control键
case WM_KEYDOWN:
{
if (wParam == VK_LCONTROL)
::SetCursor(::LoadCursor(_hInst, MAKEINTRESOURCE(IDC_DRAG_PLUS_TAB)));
return TRUE;
}
//鼠标中键释放
case WM_MBUTTONUP:
{
int xPos = LOWORD(lParam);
@ -852,7 +860,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
notify(TCN_TABDELETE, currentTabOn);
return TRUE;
}
//双击鼠标左键
case WM_LBUTTONDBLCLK:
{
if (_isDbClk2Close)
@ -864,7 +872,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
}
return TRUE;
}
//如果程序正在使用暗黑模式将会用指定的画刷填充整个Tab的客户区代替了系统默认的橡皮擦背景操作。
case WM_ERASEBKGND:
{
if (!NppDarkMode::isEnabled())
@ -878,7 +886,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
return 1;
}
//在Tab控件需要重绘时调用这里会进行大量的绘制操作内容包括Tab本身和每一个Tab的文字、关闭按钮等元素。
case WM_PAINT:
{
if (!NppDarkMode::isEnabled())
@ -1049,7 +1057,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
return ::CallWindowProc(_tabBarDefaultProc, hwnd, Message, wParam, lParam);
}
//实现了Tab的绘制过程包括对Tab背景颜色、文字颜色的调整判断并处理当前Tab的激活状态处理Tab的图标和标题等。
void TabBarPlus::drawItem(DRAWITEMSTRUCT* pDrawItemStruct, bool isDarkMode)
{
RECT rect = pDrawItemStruct->rcItem;
@ -1371,7 +1379,7 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode)
::RestoreDC(hDC, nSavedDC);
}
//用于改变鼠标光标的形状,根据用户托拽标签的不同位置(是否在同一应用中、是否在一个有效的放置位置等)表现为不同的光标形状。
void TabBarPlus::draggingCursor(POINT screenPoint)
{
HWND hWin = ::WindowFromPoint(screenPoint);
@ -1394,7 +1402,7 @@ void TabBarPlus::draggingCursor(POINT screenPoint)
::SetCursor(::LoadCursor(_hInst, MAKEINTRESOURCE(IDC_DRAG_OUT_TAB)));
}
}
//简单地把指定的标签设为活动状态。
void TabBarPlus::setActiveTab(int tabIndex)
{
// TCM_SETCURFOCUS is busted on WINE/ReactOS for single line (non-TCS_BUTTONS) tabs...
@ -1407,7 +1415,7 @@ void TabBarPlus::setActiveTab(int tabIndex)
::SendMessage(_hSelf, TCM_SETCURSEL, tabIndex, 0);
notify(TCN_SELCHANGE, tabIndex);
}
//交换两个Tab的数据实现两个Tab的位置交换。
void TabBarPlus::exchangeTabItemData(int oldTab, int newTab)
{
//1. shift their data, and insert the source
@ -1449,7 +1457,7 @@ void TabBarPlus::exchangeTabItemData(int oldTab, int newTab)
//2. set to focus
setActiveTab(newTab);
}
//在接收到鼠标托拽消息的时候被调用,用于各个标签的排序和交换位置。
void TabBarPlus::exchangeItemData(POINT point)
{
// Find the destination tab...
@ -1486,7 +1494,7 @@ void TabBarPlus::exchangeItemData(POINT point)
}
//用于处理与关闭按钮相关的操作,如获取关闭按钮的大小及位置,判断是否点击到了关闭按钮等。
CloseButtonZone::CloseButtonZone()
{
// TODO: get width/height of close button dynamically

@ -15,48 +15,51 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//代码整体实现了一个创建和销毁窗口的功能
//在VerticalFileSwitcherListView.h、URLCtrl.h、TreeView.h、ToolTip.h等文件里都引用了Window.h
//基本上只要是会弹出窗口的功能都需要引用此头文件
#pragma once
#include <windows.h>
class Window
class Window//定义了一个窗口类,包括了窗口的初始化、销毁、显示、重绘等操作
{
public:
//! \name Constructors & Destructor
//@{
Window() = default;
Window(const Window&) = delete;
virtual ~Window() = default;
Window() = default;// 默认构造函数
Window(const Window&) = delete;// 禁用拷贝构造函数
virtual ~Window() = default;// 默认析构函数
//@}
// 初始化窗口
virtual void init(HINSTANCE hInst, HWND parent)
{
_hInst = hInst;
_hParent = parent;
}
virtual void destroy() = 0;
virtual void destroy() = 0;// 销毁窗口
virtual void display(bool toShow = true) const
virtual void display(bool toShow = true) const// 显示或隐藏窗口
{
::ShowWindow(_hSelf, toShow ? SW_SHOW : SW_HIDE);
}
// 调整窗口大小并重绘窗口内容
virtual void reSizeTo(RECT & rc) // should NEVER be const !!!
{
::MoveWindow(_hSelf, rc.left, rc.top, rc.right, rc.bottom, TRUE);
redraw();
}
// 调整窗口大小(传入宽度和高度)并重绘窗口内容
virtual void reSizeToWH(RECT& rc) // should NEVER be const !!!
{
::MoveWindow(_hSelf, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
redraw();
}
// 重绘窗口内容
virtual void redraw(bool forceUpdate = false) const
{
::InvalidateRect(_hSelf, nullptr, TRUE);
@ -64,24 +67,24 @@ public:
::UpdateWindow(_hSelf);
}
// 获取窗口客户区矩形
virtual void getClientRect(RECT & rc) const
{
::GetClientRect(_hSelf, &rc);
}
// 获取窗口矩形
virtual void getWindowRect(RECT & rc) const
{
::GetWindowRect(_hSelf, &rc);
}
// 获取窗口宽度
virtual int getWidth() const
{
RECT rc;
::GetClientRect(_hSelf, &rc);
return (rc.right - rc.left);
}
// 获取窗口高度
virtual int getHeight() const
{
RECT rc;
@ -90,7 +93,7 @@ public:
return (rc.bottom - rc.top);
return 0;
}
// 判断窗口是否可见
virtual bool isVisible() const
{
return (::IsWindowVisible(_hSelf)?true:false);

@ -16,60 +16,81 @@
// 引入LastRecentFileList类的头文件
#include "lastRecentFileList.h"
// 引入菜单命令ID的头文件
#include "menuCmdID.h"
// 引入本地化的头文件,可能用于支持多语言
#include "localization.h"
// LastRecentFileList类的initMenu函数
void LastRecentFileList::initMenu(HMENU hMenu, int idBase, int posBase, Accelerator* pAccelerator, bool doSubMenu)
{
// 如果doSubMenu为真表示需要创建一个弹出菜单
if (doSubMenu)
{
// 设置父菜单句柄
_hParentMenu = hMenu;
// 创建一个新的弹出菜单
_hMenu = ::CreatePopupMenu();
}
// 如果doSubMenu为假表示直接使用传入的菜单句柄
else
{
// 设置父菜单句柄为NULL表示主菜单
_hParentMenu = NULL;
// 使用传入的菜单句柄作为当前菜单
_hMenu = hMenu;
}
// 设置ID的基础值
_idBase = idBase;
// 设置位置的基础值
_posBase = posBase;
// 设置指向Accelerator对象的指针用于处理键盘快捷键等加速功能
_pAccelerator = pAccelerator;
// 设置本地化语言编码为Windows的1252编码这是一种西欧语言编码
_nativeLangEncoding = NPP_CP_WIN_1252;
// 初始化idFreeArray数组所有元素都设置为true表示ID可用
for (size_t i = 0; i < sizeof(_idFreeArray); ++i)
_idFreeArray[i] = true;
}
// LastRecentFileList类的switchMode函数用于切换模式
void LastRecentFileList::switchMode()
{
//Remove all menu items
// 从菜单中移除所有相关菜单项
::RemoveMenu(_hMenu, IDM_FILE_RESTORELASTCLOSEDFILE, MF_BYCOMMAND);
::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND);
::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND);
// 遍历最近打开文件列表,移除所有菜单项
for (int i = 0; i < _size; ++i)
{
::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND);
}
if (_hParentMenu == NULL) // mode main menu
{ if (_size > 0)
// 根据_hParentMenu的值判断当前模式主菜单模式或子菜单模式
if (_hParentMenu == NULL) // mode main menu主菜单模式
{
if (_size > 0) // 如果最近打开文件列表不为空
{
// 从主菜单中移除一些特定的菜单项(具体移除哪些项未给出)
::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION);
::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION);
}
// switch to sub-menu mode
// 切换到子菜单模式创建一个新的弹出菜单作为当前菜单并设置_hParentMenu为当前菜单即新创建的弹出菜单
// 同时移除一些特定的菜单项(具体移除哪些项未给出)
_hParentMenu = _hMenu;
_hMenu = ::CreatePopupMenu();
::RemoveMenu(_hMenu, _posBase + 1, MF_BYPOSITION);
}
else // mode sub-menu
else // mode sub-menu子菜单模式
{
if (_size > 0)
if (_size > 0) // 如果最近打开文件列表不为空
{
// 从子菜单中移除一些特定的菜单项(具体移除哪些项未给出)
::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION);
::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION);
}
@ -83,18 +104,22 @@ void LastRecentFileList::switchMode()
void LastRecentFileList::updateMenu()
{
// 获取 NppParameters 的单例实例
NppParameters& nppParam = NppParameters::getInstance();
// 检查是否没有分隔符且大小大于0满足条件则进入下面的 if 语句块
if (!_hasSeparators && _size > 0)
{
//add separators
// 获取本地化语言的发言人对象
NativeLangSpeaker* pNativeLangSpeaker = nppParam.getNativeLangSpeaker();
// 从发言人对象中获取一些本地化菜单字符串
generic_string recentFileList = pNativeLangSpeaker->getSubMenuEntryName("file-recentFiles");
generic_string openRecentClosedFile = pNativeLangSpeaker->getNativeLangMenuString(IDM_FILE_RESTORELASTCLOSEDFILE);
generic_string openAllFiles = pNativeLangSpeaker->getNativeLangMenuString(IDM_OPEN_ALL_RECENT_FILE);
generic_string cleanFileList = pNativeLangSpeaker->getNativeLangMenuString(IDM_CLEAN_RECENT_FILE_LIST);
// 如果获取的字符串为空,则使用默认的字符串进行初始化
if (recentFileList == TEXT(""))
recentFileList = TEXT("&Recent Files");
if (openRecentClosedFile == TEXT(""))
@ -104,23 +129,28 @@ void LastRecentFileList::updateMenu()
if (cleanFileList == TEXT(""))
cleanFileList = TEXT("Empty Recent Files List");
// 如果当前不是子菜单模式,则在菜单中插入一个分隔符
if (!isSubMenuMode())
::InsertMenu(_hMenu, _posBase + 0, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0);
// 在菜单中插入四个子菜单项,分别是恢复最近关闭的文件、打开所有最近文件、清空最近文件列表和另一个分隔符
::InsertMenu(_hMenu, _posBase + 1, MF_BYPOSITION, IDM_FILE_RESTORELASTCLOSEDFILE, openRecentClosedFile.c_str());
::InsertMenu(_hMenu, _posBase + 2, MF_BYPOSITION, IDM_OPEN_ALL_RECENT_FILE, openAllFiles.c_str());
::InsertMenu(_hMenu, _posBase + 3, MF_BYPOSITION, IDM_CLEAN_RECENT_FILE_LIST, cleanFileList.c_str());
::InsertMenu(_hMenu, _posBase + 4, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0);
::InsertMenu(_hMenu, _posBase + 4, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0); // 插入分隔符
// 设置标志表示已有分隔符
_hasSeparators = true;
// 如果当前是子菜单模式,则在父菜单中插入子菜单和分隔符
if (isSubMenuMode())
{
::InsertMenu(_hParentMenu, _posBase + 0, MF_BYPOSITION | MF_POPUP, reinterpret_cast<UINT_PTR>(_hMenu), (LPCTSTR)recentFileList.c_str());
::InsertMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0);
::InsertMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0); // 插入分隔符
}
}
else if (_hasSeparators && _size == 0) //remove separators
else if (_hasSeparators && _size == 0) // 当已有分隔符且大小为0时进入下面的 if 语句块,用于移除分隔符和菜单项
{
// 从菜单中移除一个分隔符和清空最近文件列表的菜单项
::RemoveMenu(_hMenu, _posBase + 4, MF_BYPOSITION);
::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND);
::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND);
@ -154,153 +184,163 @@ void LastRecentFileList::updateMenu()
}
}
// 向最近的文件列表中添加一个文件名。如果达到用户定义的最大限制或列表被锁定,则不会添加。
// 如果文件名已存在,则会先将其移除再添加。
void LastRecentFileList::add(const TCHAR* fn)
{
if (_userMax == 0 || _locked)
if (_userMax == 0 || _locked) // 如果用户定义的最大数量为0或列表被锁定直接返回不进行添加
return;
RecentItem itemToAdd(fn);
RecentItem itemToAdd(fn); // 创建一个新的RecentItem对象使用传入的文件名初始化
int index = find(fn);
if (index != -1)
int index = find(fn); // 查找该文件名在列表中的索引
if (index != -1) // 如果找到
{
//already in list, bump upwards
// 如果文件名已存在,先将其移除,然后重新添加
remove(index);
}
if (_size == _userMax)
if (_size == _userMax) // 如果列表已满
{
itemToAdd._id = _lrfl.back()._id;
_lrfl.pop_back(); //remove oldest
itemToAdd._id = _lrfl.back()._id; // 使用最后一个元素的ID初始化新元素的ID
_lrfl.pop_back(); // 移除列表中的最后一个元素(即最旧的一个)
}
else
else // 如果列表未满
{
itemToAdd._id = popFirstAvailableID();
++_size;
itemToAdd._id = popFirstAvailableID(); // 获取第一个可用的ID并初始化新元素的ID
++_size; // 增加列表的大小
}
_lrfl.push_front(itemToAdd);
updateMenu();
_lrfl.push_front(itemToAdd); // 在列表的前面添加新元素
updateMenu(); // 更新菜单
}
// 根据文件名从最近的文件列表中移除一个文件。如果找到,则移除;否则什么也不做。
void LastRecentFileList::remove(const TCHAR* fn)
{
int index = find(fn);
if (index != -1)
remove(index);
int index = find(fn); // 查找文件名在列表中的索引
if (index != -1) // 如果找到
remove(index); // 移除该元素
}
// 根据索引从最近的文件列表中移除一个文件。如果索引有效,则移除;否则什么也不做。
void LastRecentFileList::remove(size_t index)
{
if (_size == 0 || _locked)
if (_size == 0 || _locked) // 如果列表为空或被锁定,直接返回,不进行移除操作
return;
if (index < _lrfl.size())
if (index < _lrfl.size()) // 如果索引有效
{
::RemoveMenu(_hMenu, _lrfl.at(index)._id, MF_BYCOMMAND);
setAvailable(_lrfl.at(index)._id);
_lrfl.erase(_lrfl.begin() + index);
--_size;
updateMenu();
::RemoveMenu(_hMenu, _lrfl.at(index)._id, MF_BYCOMMAND); // 从菜单中移除该ID对应的菜单项
setAvailable(_lrfl.at(index)._id); // 将该ID标记为可用可能是为了下次添加时重复使用
_lrfl.erase(_lrfl.begin() + index); // 从列表中移除该元素
--_size; // 减少列表的大小
updateMenu(); // 更新菜单
}
}
// 清空最近的文件列表。所有文件名和ID都会被移除菜单也会相应地更新。
void LastRecentFileList::clear()
{
if (_size == 0)
if (_size == 0) // 如果列表为空,直接返回,不进行任何操作
return;
for (int i = (_size-1); i >= 0; i--)
for (int i = (_size - 1); i >= 0; i--) // 从后向前遍历列表,因为移除元素会影响后续元素的索引
{
::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND);
setAvailable(_lrfl.at(i)._id);
_lrfl.erase(_lrfl.begin() + i);
::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); // 从菜单中移除该ID对应的菜单项
setAvailable(_lrfl.at(i)._id); // 将该ID标记为可用可能是为了下次添加时重复使用
_lrfl.erase(_lrfl.begin() + i); // 从列表中移除该元素
}
_size = 0;
updateMenu();
_size = 0; // 将列表大小设置为0
updateMenu(); // 更新菜单
}
LastRecentFileList
cpp
// 根据ID从最近的文件列表中获取一个文件名。如果找到则返回对应的文件名否则返回列表中的第一个文件名。
generic_string& LastRecentFileList::getItem(int id)
{
int i = 0;
for (; i < _size; ++i)
int i = 0; // 从索引0开始查找因为如果ID不存在可能会返回第一个文件名作为默认值。
for (; i < _size; ++i) // 遍历整个列表查找匹配的ID。如果找不到i会等于_size此时i会被重新设置为0。这是一个后备计划以防ID不存在于列表
{
if (_lrfl.at(i)._id == id)
if (_lrfl.at(i)._id == id) // 如果找到匹配的ID
break;
}
if (i == _size)
i = 0;
return _lrfl.at(i)._name; //if not found, return first
if (i == _size) // 如果遍历完整个列表都没有找到匹配的ID
i = 0; // 将索引重置为0这样可以从列表的第一个元素开始返回文件名作为默认值
return _lrfl.at(i)._name; // 返回找到的文件名或默认文件名
}
// 根据索引从最近的文件列表中获取一个文件名。如果索引有效,则返回对应的文件名;否则返回列表中的第一个文件名。
generic_string& LastRecentFileList::getIndex(int index)
{
return _lrfl.at(index)._name; //if not found, return first
return _lrfl.at(index)._name; // 返回找到的文件名或默认文件名
}
// 设置用户定义的最大最近文件列表大小。如果当前列表大小大于新设置的大小,则移除最旧的文件直到列表大小等于新设置的大小。
void LastRecentFileList::setUserMaxNbLRF(int size)
{
_userMax = size;
if (_size > _userMax)
{ //start popping items
int toPop = _size-_userMax;
while (toPop > 0)
_userMax = size; // 设置用户定义的最大列表大小
if (_size > _userMax) // 如果当前列表大小大于新设置的大小
{
::RemoveMenu(_hMenu, _lrfl.back()._id, MF_BYCOMMAND);
setAvailable(_lrfl.back()._id);
_lrfl.pop_back();
toPop--;
_size--;
int toPop = _size - _userMax; // 计算需要移除的文件数量
while (toPop > 0) // 当还有文件需要移除时
{
::RemoveMenu(_hMenu, _lrfl.back()._id, MF_BYCOMMAND); // 从菜单中移除该ID对应的菜单项
setAvailable(_lrfl.back()._id); // 将该ID标记为可用可能是为了下次添加时重复使用
_lrfl.pop_back(); // 从列表中移除该元素
toPop--; // 减少剩余需要移除的文件数量
_size--; // 减少当前列表大小
}
updateMenu();
_size = _userMax;
updateMenu(); // 更新菜单
_size = _userMax; // 将当前列表大小设置为新设置的大小
}
}
// 将最近的文件列表保存到配置文件中。保存的文件名顺序与加载时相同。
void LastRecentFileList::saveLRFL()
{
NppParameters& nppParams = NppParameters::getInstance();
if (nppParams.writeRecentFileHistorySettings(_userMax))
NppParameters& nppParams = NppParameters::getInstance(); // 获取NppParameters的实例引用
if (nppParams.writeRecentFileHistorySettings(_userMax)) // 如果成功写入最近的文件历史设置
{
for (int i = _size - 1; i >= 0; i--) //reverse order: so loading goes in correct order
for (int i = _size - 1; i >= 0; i--) // 按照从后往前的顺序保存文件名,确保加载时的顺序正确
{
nppParams.writeHistory(_lrfl.at(i)._name.c_str());
nppParams.writeHistory(_lrfl.at(i)._name.c_str()); // 将文件名写入配置文件的历史记录部分
}
}
}
// 在最近的文件列表中查找指定的文件名。
int LastRecentFileList::find(const TCHAR* fn)
{
for (int i = 0; i < _size; ++i)
for (int i = 0; i < _size; ++i) // 遍历整个列表
{
if (OrdinalIgnoreCaseCompareStrings(_lrfl.at(i)._name.c_str(), fn) == 0)
if (OrdinalIgnoreCaseCompareStrings(_lrfl.at(i)._name.c_str(), fn) == 0) // 如果找到匹配的文件名(忽略大小写)
{
return i;
return i; // 返回该文件在列表中的索引
}
}
return -1;
return -1; // 如果未找到,返回-1
}
// 弹出第一个可用的ID。
int LastRecentFileList::popFirstAvailableID()
{
for (int i = 0 ; i < NB_MAX_LRF_FILE ; ++i)
for (int i = 0; i < NB_MAX_LRF_FILE; ++i) // 遍历所有可能的ID
{
if (_idFreeArray[i])
if (_idFreeArray[i]) // 如果该ID可用未被使用
{
_idFreeArray[i] = false;
return i + _idBase;
_idFreeArray[i] = false; // 标记该ID为已使用
return i + _idBase; // 返回该ID的值从_idBase开始计算
}
}
return 0;
return 0; // 如果所有ID都已使用返回0或默认值
}
// 设置指定的ID为可用。
void LastRecentFileList::setAvailable(int id)
{
int index = id - _idBase;
_idFreeArray[index] = true;
int index = id - _idBase; // 根据ID计算其在_idFreeArray中的索引
_idFreeArray[index] = true; // 将该索引对应的值设置为true表示该ID可用
}

@ -0,0 +1,69 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.32002.261
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Notepad++", "notepadPlus.vcxproj", "{FCF60E65-1B78-4D1D-AB59-4FC00AC8C248}"
ProjectSection(ProjectDependencies) = postProject
{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD} = {C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}
{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1} = {E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Lexilla", "..\..\lexilla\src\Lexilla.vcxproj", "{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Scintilla", "..\..\scintilla\win32\Scintilla.vcxproj", "{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|ARM64 = Release|ARM64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FCF60E65-1B78-4D1D-AB59-4FC00AC8C248}.Debug|ARM64.ActiveCfg = Debug|ARM64
{FCF60E65-1B78-4D1D-AB59-4FC00AC8C248}.Debug|ARM64.Build.0 = Debug|ARM64
{FCF60E65-1B78-4D1D-AB59-4FC00AC8C248}.Debug|Win32.ActiveCfg = Debug|Win32
{FCF60E65-1B78-4D1D-AB59-4FC00AC8C248}.Debug|Win32.Build.0 = Debug|Win32
{FCF60E65-1B78-4D1D-AB59-4FC00AC8C248}.Debug|x64.ActiveCfg = Debug|x64
{FCF60E65-1B78-4D1D-AB59-4FC00AC8C248}.Debug|x64.Build.0 = Debug|x64
{FCF60E65-1B78-4D1D-AB59-4FC00AC8C248}.Release|ARM64.ActiveCfg = Release|ARM64
{FCF60E65-1B78-4D1D-AB59-4FC00AC8C248}.Release|ARM64.Build.0 = Release|ARM64
{FCF60E65-1B78-4D1D-AB59-4FC00AC8C248}.Release|Win32.ActiveCfg = Release|Win32
{FCF60E65-1B78-4D1D-AB59-4FC00AC8C248}.Release|Win32.Build.0 = Release|Win32
{FCF60E65-1B78-4D1D-AB59-4FC00AC8C248}.Release|x64.ActiveCfg = Release|x64
{FCF60E65-1B78-4D1D-AB59-4FC00AC8C248}.Release|x64.Build.0 = Release|x64
{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}.Debug|ARM64.Build.0 = Debug|ARM64
{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}.Debug|Win32.ActiveCfg = Debug|Win32
{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}.Debug|Win32.Build.0 = Debug|Win32
{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}.Debug|x64.ActiveCfg = Debug|x64
{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}.Debug|x64.Build.0 = Debug|x64
{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}.Release|ARM64.ActiveCfg = Release|ARM64
{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}.Release|ARM64.Build.0 = Release|ARM64
{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}.Release|Win32.ActiveCfg = Release|Win32
{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}.Release|Win32.Build.0 = Release|Win32
{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}.Release|x64.ActiveCfg = Release|x64
{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}.Release|x64.Build.0 = Release|x64
{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}.Debug|ARM64.ActiveCfg = Debug|ARM64
{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}.Debug|ARM64.Build.0 = Debug|ARM64
{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}.Debug|Win32.ActiveCfg = Debug|Win32
{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}.Debug|Win32.Build.0 = Debug|Win32
{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}.Debug|x64.ActiveCfg = Debug|x64
{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}.Debug|x64.Build.0 = Debug|x64
{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}.Release|ARM64.ActiveCfg = Release|ARM64
{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}.Release|ARM64.Build.0 = Release|ARM64
{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}.Release|Win32.ActiveCfg = Release|Win32
{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}.Release|Win32.Build.0 = Release|Win32
{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}.Release|x64.ActiveCfg = Release|x64
{C5FBF9A9-FBEF-487B-A5ED-4542E6F03FCD}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {099D56D9-DBDD-43AF-AC8C-F27D522868D0}
EndGlobalSection
EndGlobal
Loading…
Cancel
Save