Notepad++ は、Windows に付属のメモ帳を置き換えるために使用される小さなテキスト エディター ソフトウェアです。ただし、Notepad++ ソフトウェアの作成者は横暴すぎます. 彼の見解に同意しない場合、Notepad++ はソース コードにランダムな文字を挿入します。国産のオープンソースクロスプラットフォームソフトNDD(メモ帳--)をオススメ、機能は全然弱くない、サイズが小さくて開く速度が速い、フォルダ比較機能あり、有料のbeyondCompareでも助かる. また、いくつかの興味深い機能を追加してプラグインを提供することもできます。たとえば、ChatGPT チャット ロボット プラグインを追加したいと考えています。ローカリゼーションの台頭に貢献する、より優れた国産ソフトウェアを楽しみにしています。
NDDの紹介(メモ帳--)
メモ帳 – C++ で書かれたテキスト エディターで、現在 Win/Linux/Mac プラットフォームをサポートしています。gitee でのプロジェクト名は NDD です。gitee 倉庫住所:
https://gitee.com/cxasm/notepad--
国産のUos/Linux系、Mac系の開発を中心に、テキスト編集ソフトの国産化を目指す。
Windows/Linux/Mac対応のテキストエディタで、類似ソフトを中国の国産品に置き換えるのが狙い。他の競合するメモ帳ソフトウェアと比較すると、クロスプラットフォームであり、Linux Mac オペレーティング システムをサポートするという利点があります。
直接ダウンロードして使用できます。ソフトウェア ダウンロード アドレスのリリース バージョンは次のとおりです。
https://gitee.com/cxasm/notepad--/releases/tag/v1.21
msvc ツールチェーンのダウンロードとインストール
Visual Studio を必要とせずに、スクリプト可能なスタンドアロン インストーラーを介して MSVC ツールセットを提供する Microsoft C++ ビルド ツール。このツールは、Windows をターゲットとする C++ ライブラリとアプリケーションをコマンド ライン インターフェイスからビルドする場合 (たとえば、継続的インテグレーション ワークフローで) に推奨されます。
msvc ツールを使用する理由 Visual Studio は大きすぎて数 G あり、既にバージョンをインストールしているため、新しいバージョンをインストールしたくありません。NDD ソース コードをコンパイルするときは、QT フレームワークが 5.11 以上である必要があることに注意してください。C++ コンパイラは、少なくとも c++17 以上をサポートする必要があります。サイズが約 1G の msvc ツール チェーンを直接ダウンロードします。ダウンロード速度は超高速です。
msvc ツールチェーンのダウンロード アドレス:
Microsoft C++ ビルド ツール - Visual Studio
これをインストールするときに注意する必要があるのは、Windows 用の c++ Cmake ツールをチェックする必要があることです。
NDD ソースコードのコンパイル
NDD リリース版は、使用可能な既製のソフトウェアを提供しますが、開発する場合、開発するプラグインは、MSVC と QT のバージョン (VS2019 および QT5.15.2) の同じセットを使用する必要があり、そうしないと互換性の問題が発生しやすくなります。プラグインの場合、ndd ソース コードを一緒に直接コンパイルするのが最も簡単で簡単です。最後にプラグインを提供したい場合でも、心配しないでください. 著者は、プラグインをカスタマイズすることをすべての人に奨励しており、人気のあるプラグインはリリース バージョンにマージされます.
ソースコードのコンパイルは比較的簡単です. 著者はコンパイルドキュメントを紹介しています. Windowsでの推奨コンパイル環境: vs2017以上, qtツールプラグイン. ソースコードのhow_buildディレクトリにCMakeLists.txtファイルがあるので、プロジェクトのルートディレクトリにコピーし、cmakeの環境を整えて、そのままコンパイルします。
cmake_minimum_required(VERSION 3.16)
project(NotePad-- VERSION 1.22.0)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
add_definitions(
-DCMAKE_CXX_STANDARD=17
)
set(CMAKE_PREFIX_PATH "D:/Qt5.12.11/Qt5.12.11/5.12.11/msvc2015_64/lib/cmake")
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets Concurrent Network PrintSupport XmlPatterns)
# qscint 关键依赖库
add_subdirectory(${PROJECT_SOURCE_DIR}/src/qscint)
# 插件库包含
# helloworld 动态插件库
add_subdirectory(${PROJECT_SOURCE_DIR}/src/plugin/helloworld)
# win下需要开启UNICODE进行支持TCHAR
if(CMAKE_HOST_WIN32)
add_definitions(-D_UNICODE -DUNICODE)
endif()
if(${PLUGIN_EN})
if(${PLUGIN_EN} STREQUAL on)
add_definitions(-DNO_PLUGIN=1)
endif(${PLUGIN_EN})
endif()
file(GLOB UI_SRC ${PROJECT_SOURCE_DIR}/src/*.ui)
set(UI_SRC ${UI_SRC} ${PROJECT_SOURCE_DIR}/src/cceditor/ccnotepad.ui)
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)
aux_source_directory(${PROJECT_SOURCE_DIR}/src/cceditor SRC)
if(CMAKE_HOST_WIN32)
# 添加 WIN32 保证主程序启动没有命令行
list(APPEND WIN_RCS ${PROJECT_SOURCE_DIR}/src/RealCompareToMinGw.rc)
add_executable(${PROJECT_NAME} WIN32 ${WIN_RCS} ${SRC} ${UI_SRC} ${PROJECT_SOURCE_DIR}/src/RealCompare.qrc)
else()
add_executable(${PROJECT_NAME} ${SRC} ${UI_SRC} ${PROJECT_SOURCE_DIR}/src/RealCompare.qrc)
endif()
target_include_directories(${PROJECT_NAME} PRIVATE
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/src/cceditor
${PROJECT_SOURCE_DIR}/src/qscint/src
${PROJECT_SOURCE_DIR}/src/qscint/src/Qsci
${PROJECT_SOURCE_DIR}/src/qscint/scintilla/src
${PROJECT_SOURCE_DIR}/src/qscint/scintilla/include
${PROJECT_SOURCE_DIR}/src/qscint/scintilla/lexlib
${PROJECT_SOURCE_DIR}/src/qscint/scintilla/boostregex
)
target_link_libraries(${PROJECT_NAME} qscint Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Concurrent Qt5::Network Qt5::PrintSupport Qt5::XmlPatterns)
# set(PROJECT_BINARY_DIR "${PROJECT_BINARY_DIR}/bin")
# set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
if(CMAKE_HOST_UNIX)
install(
TARGETS ${PROJECT_NAME}
DESTINATION "bin"
)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/src/linux/usr
DESTINATION "/")
include(${PROJECT_SOURCE_DIR}/cmake/deb_package_config.cmake)
include(CPack)
elseif(CMAKE_HOST_WIN32)
install(TARGETS ${PROJECT_NAME}
DESTINATION "/")
install(DIRECTORY ${PROJECT_SOURCE_DIR}/build/bin/
DESTINATION "/")
# 设置软件版本
set(CPACK_PACKAGE_NAME "NotePad--")
set(CPACK_PACKAGE_DESCRIPTION "NotePad--")
set(CPACK_PACKAGE_COPYRIGHT "Copyright (c) 2023")
set(CPACK_PACKAGE_VERSION "1.22.0")
set(CPACK_PACKAGE_VERSION_MAJOR "1")
set(CPACK_PACKAGE_VERSION_MINOR "22")
set(CPACK_PACKAGE_VERSION_PATCH "0")
#include(${PROJECT_SOURCE_DIR}/cmake/nsis_package_config.cmake)
include(CPack)
endif()
ソースコードのコンパイルに関する注意:
# qscint 关键依赖库
add_subdirectory(${PROJECT_SOURCE_DIR}/src/qscint)
......
target_link_libraries(${PROJECT_NAME} qscint Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Concurrent Qt5::Network Qt5::PrintSupport Qt5::XmlPatterns)
上記から、ソース コードに添付されている how_build フォルダー、コピーされたデフォルトの CmakeLists.txt ファイルには qscint の主要な依存ライブラリが含まれ、qscint によって生成された静的ライブラリがデフォルトであることがわかります。少しぎこちない感じです。結局、qscint ライブラリを動的に使用したいからです。
ここで NDD ソース コードをコンパイルし、これをコメント アウトして、最初に qscint を動的ライブラリとして個別にコンパイルします。qscint ダイナミック ライブラリをコンパイルするには、マクロ定義 add_definitions (-DQSCINTILLA_MAKE_DLL) を追加してQ_DECL_EXPORTを有効にする必要があることに注意してください。これにより、ダイナミック ライブラリが dll ファイルと lib ファイルを同時に生成します。
次に、NDD メイン プログラムの CmakeLists.txt ファイルを変更して、前の手順で生成された qscint ライブラリをインポートして使用します。
うまくいっていると思っていましたが、コンパイルでエラーが報告されました。
解決:
NDD ソース コードを再コンパイルするときは、ライブラリの使用方法を変更します。このライブラリを Windows でビルドする場合は O DECL EXPORT を使用し、Windows でこのライブラリを使用する場合は Q DECL IMPORT を使用する必要があります。
NDD プラグインのデモとコンパイル
プラグインの作成とコンパイル、プラグイン プログラミング開発ドキュメントを作成者が提供します。比較的簡単なcmakeのコンパイル方法を以下に示します。プラグインは qscintila ライブラリに依存する必要があります。最初に qscintila ライブラリをコンパイルします。ソース コードのメモ帳 - \src\qscint フォルダー、CmakeLists.txt ファイルは、何も変更せずに正常にコンパイルできます。注意する必要があるのは次のとおりです。
set(CMAKE_PREFIX_PATH "D:/Qt5.12.11/Qt5.12.11/5.12.11/msvc2015_64/lib/cmake")
add_definitions(-DBOOST_REGEX_STANDALONE)
マクロ定義 -DBOOST_REGEX_STANDALONE を追加します。それ以外の場合は、Boost ライブラリに依存する必要があります。さらに、これは独立して正常にコンパイルできます。デバッグおよびその他のモードで対応するライブラリの検索をサポートするために、次の構成が cmakeLists.txt に追加されることに注意してください。
link_directories(
${CMAKE_CURRENT_SOURCE_DIR}/
)
target_link_libraries(${PROJECT_NAME} PRIVATE
debug qmyedit_qt5d
optimized qmyedit_qt5)
さらに、qscintila ライブラリを動的に使用する場合は、マクロを定義する必要があることに注意してください。
add_definitions(-DQSCINTILLA_MAKE_DLL)
これは #define QSCINTILLA_EXPORT Q_DECL_EXPORT です。Q_DECL_EXPORT マクロは、主にこのクラスをエクスポートし、.dll を生成し、同時に .lib ファイルを生成します (ここでの lib ファイルはスタティック ライブラリではなく、外部リンク用であることに注意してください)。他のクラスが使用するインターフェイス。
cmake_minimum_required(VERSION 3.16)
project(qscint CXX)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_PREFIX_PATH "D:/Qt5.12.11/Qt5.12.11/5.12.11/msvc2015_64/lib/cmake")
add_definitions(-DBOOST_REGEX_STANDALONE)
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets Concurrent Network PrintSupport)
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)
aux_source_directory(${PROJECT_SOURCE_DIR}/scintilla/lexers SRC)
aux_source_directory(${PROJECT_SOURCE_DIR}/scintilla/lexlib SRC)
aux_source_directory(${PROJECT_SOURCE_DIR}/scintilla/src SRC)
aux_source_directory(${PROJECT_SOURCE_DIR}/scintilla/boostregex SRC)
file(GLOB MOC_HEADER ${PROJECT_SOURCE_DIR}/src/Qsci/*.h)
#message(${MOC_HEADER})
add_library(${PROJECT_NAME} STATIC ${SRC} ${MOC_HEADER})
# add_definitions(-DQSCINTILLA_MAKE_DLL)
# add_library(${PROJECT_NAME} SHARED ${SRC} ${MOC_HEADER})
target_compile_definitions(${PROJECT_NAME} PRIVATE SCINTILLA_QT SCI_LEXER INCLUDE_DEPRECATED_FEATURES)
target_include_directories(${PROJECT_NAME} PRIVATE
${PROJECT_SOURCE_DIR}/scintilla/lexlib
${PROJECT_SOURCE_DIR}/scintilla/boostregex
)
target_include_directories(${PROJECT_NAME} PUBLIC
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/src/Qsci
${PROJECT_SOURCE_DIR}/scintilla/src
${PROJECT_SOURCE_DIR}/scintilla/include)
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Concurrent Qt5::Network Qt5::PrintSupport)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "qmyedit_qt5")
else()
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "qmyedit_qt5d")
endif()
プラグインのデモ
#include <qobject.h>
#include <qstring.h>
#include <pluginGl.h>
#include <functional>
#include <qsciscintilla.h>
#include "qttestclass.h"
#include "NDDMyPlugin.h"
#define NDD_EXPORTDLL
#if defined(Q_OS_WIN)
#if defined(NDD_EXPORTDLL)
#define NDD_EXPORT __declspec(dllexport)
#else
#define NDD_EXPORT __declspec(dllimport)
#endif
#else
#define NDD_EXPORT __attribute__((visibility("default")))
#endif
#ifdef __cplusplus
extern "C" {
#endif
NDD_EXPORT bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData);
NDD_EXPORT int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit, NDD_PROC_DATA* procData);
#ifdef __cplusplus
}
#endif
NDDMyPlugin *nddMyPlugin = nullptr;
static NDD_PROC_DATA s_procData;
static QWidget* s_pMainNotepad = nullptr;
std::function<QsciScintilla* ()> s_getCurEdit;
bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
{
if(pProcData == NULL)
{
return false;
}
pProcData->m_strPlugName = QObject::tr("Hello World Plug");
pProcData->m_strComment = QObject::tr("char to Upper.");
pProcData->m_version = QString("v1.0");
pProcData->m_auther = QString("yangqq.xyz");
pProcData->m_menuType = 1;
return true;
}
//则点击菜单栏按钮时,会自动调用到该插件的入口点函数。
//pNotepad:就是CCNotepad的主界面指针
//strFileName:当前插件DLL的全路径,如果不关心,则可以不使用
//getCurEdit:从NDD主程序传递过来的仿函数,通过该函数获取当前编辑框操作对象QsciScintilla
//pProcData:如果pProcData->m_menuType = 0 ,则该指针为空;如果pProcData->m_menuType = 1,则该指针有值。目前需要关心s_procData.m_rootMenu
//开发者可以在该菜单下面,自行创建二级菜单
int NDD_PROC_MAIN(QWidget* pNotepad, const QString &strFileName, std::function<QsciScintilla*()>getCurEdit, NDD_PROC_DATA* pProcData)
{
QsciScintilla* pEdit = getCurEdit();
if (pEdit == nullptr)
{
return -1;
}
//务必拷贝一份pProcData,在外面会释放。
if (pProcData != nullptr)
{
s_procData = *pProcData;
}
s_pMainNotepad = pNotepad;
s_getCurEdit = getCurEdit;
//如果pProcData->m_menuType = 1;是自己要创建二级菜单的场景。则通过s_procData.m_rootMenu 获取该插件的菜单根节点。
//插件开发者自行在s_procData.m_rootMenu下添加新的二级菜单项目
//QMenu* menu = s_procData.m_rootMenu;
if (!nddMyPlugin)
{
nddMyPlugin = new NDDMyPlugin(s_pMainNotepad, strFileName, nullptr, s_pMainNotepad);
nddMyPlugin->getViewMenu(s_procData.m_rootMenu);
nddMyPlugin->setScintilla(s_getCurEdit);
}
return 0;
}
cmakeに付属
cmake_minimum_required(VERSION 3.16)
project(helloworld)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_PREFIX_PATH "D:/Qt5.12.11/Qt5.12.11/5.12.11/msvc2015_64/lib/cmake")
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets Concurrent Network PrintSupport XmlPatterns)
add_definitions(-D_UNICODE -DUNICODE)
file(GLOB UI_SRC ${PROJECT_SOURCE_DIR}/*.ui)
file(GLOB SRC ${PROJECT_SOURCE_DIR}/*.cpp)
file(GLOB MOC_HEADER ${PROJECT_SOURCE_DIR}/*.h)
# add_executable(${PROJECT_NAME} ${IS_WIN} ${SRC} ${UI_SRC} ${PROJECT_SOURCE_DIR}/src/RealCompare.qrc)
#link_directories(
# ${CMAKE_CURRENT_SOURCE_DIR}/
#)
find_library(QSCINT_LIB qmyedit_qt5 PATH ${CMAKE_CURRENT_SOURCE_DIR}/)
add_library(${PROJECT_NAME} SHARED ${SRC} ${UI_SRC} ${MOC_HEADER})
target_include_directories(${PROJECT_NAME} PRIVATE
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/../../include
${PROJECT_SOURCE_DIR}/../../qscint/src
${PROJECT_SOURCE_DIR}/../../qscint/src/Qsci
${PROJECT_SOURCE_DIR}/../../qscint/scintilla/src
${PROJECT_SOURCE_DIR}/../../qscint/scintilla/include
${PROJECT_SOURCE_DIR}/../../qscint/scintilla/lexlib
${PROJECT_SOURCE_DIR}/../../qscint/scintilla/boostregex
)
#set(QS_CINT_LIB ${CMAKE_CURRENT_SOURCE_DIR}/qmyedit_qt5.lib)
#target_link_libraries(${PROJECT_NAME} PRIVATE
# debug qmyedit_qt5_d
# optimized qmyedit_qt5)
target_link_libraries(${PROJECT_NAME} PRIVATE ${QSCINT_LIB} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Concurrent Qt5::Network Qt5::PrintSupport Qt5::XmlPatterns)
その他のリソース
Cmake コア知識ポイント sorting_cmake ファイル (glob_Jin Geng Mingshou のブログ - CSDN ブログ
Cmake リンク 外部 library_cmake リンク 動的 library_foam o0 のブログ - CSDN ブログ
QTの知識ポイントまとめ(3)_q_decl_import_Chiang Wood's Blog - CSDN Blog
[Qt] エラー: LNK1107: 無効または破損したファイル: 0x310_qt で読み取れません lnk1107_Guo Laoer のブログ - CSDN ブログ