mirror of
https://github.com/notepad-plus-plus/notepad-plus-plus.git
synced 2025-12-08 06:09:42 +01:00
1. Make ghost typing Unicode supported so any language can be displayed. 2. Ghost typing's speed (slow, rapid and spped of light) can be set. 3. Any supported programming language (syntax highligting) can be applied. 4. All above supports are accessible via command line arguments.
346 lines
12 KiB
C++
346 lines
12 KiB
C++
// This file is part of Notepad++ project
|
|
// Copyright (C)2003 Don HO <don.h@free.fr>
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either
|
|
// version 2 of the License, or (at your option) any later version.
|
|
//
|
|
// Note that the GPL places important restrictions on "derived works", yet
|
|
// it does not provide a detailed definition of that term. To avoid
|
|
// misunderstandings, we consider an application to constitute a
|
|
// "derivative work" for the purpose of this license if it does any of the
|
|
// following:
|
|
// 1. Integrates source code from Notepad++.
|
|
// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable
|
|
// installer, such as those produced by InstallShield.
|
|
// 3. Links to a library or executes a program that does any of the above.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
|
#include <time.h>
|
|
#include <shlwapi.h>
|
|
#include "Notepad_plus_Window.h"
|
|
|
|
const TCHAR Notepad_plus_Window::_className[32] = TEXT("Notepad++");
|
|
HWND Notepad_plus_Window::gNppHWND = NULL;
|
|
|
|
|
|
|
|
namespace // anonymous
|
|
{
|
|
|
|
struct PaintLocker final
|
|
{
|
|
explicit PaintLocker(HWND handle)
|
|
: handle(handle)
|
|
{
|
|
// disallow drawing on the window
|
|
LockWindowUpdate(handle);
|
|
}
|
|
|
|
~PaintLocker()
|
|
{
|
|
// re-allow drawing for the window
|
|
LockWindowUpdate(NULL);
|
|
|
|
// force re-draw
|
|
InvalidateRect(handle, nullptr, TRUE);
|
|
RedrawWindow(handle, nullptr, NULL, RDW_ERASE | RDW_ALLCHILDREN | RDW_FRAME | RDW_INVALIDATE);
|
|
}
|
|
|
|
HWND handle;
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
nppClass.cbWndExtra = 0;
|
|
nppClass.hInstance = _hInst;
|
|
nppClass.hIcon = ::LoadIcon(hInst, MAKEINTRESOURCE(IDI_M30ICON));
|
|
nppClass.hCursor = ::LoadCursor(NULL, IDC_ARROW);
|
|
nppClass.hbrBackground = ::CreateSolidBrush(::GetSysColor(COLOR_MENU));
|
|
nppClass.lpszMenuName = MAKEINTRESOURCE(IDR_M30_MENU);
|
|
nppClass.lpszClassName = _className;
|
|
|
|
_isPrelaunch = cmdLineParams->_isPreLaunch;
|
|
|
|
if (!::RegisterClass(&nppClass))
|
|
{
|
|
throw std::runtime_error("Notepad_plus_Window::init : RegisterClass() function failed");
|
|
}
|
|
|
|
NppParameters *pNppParams = NppParameters::getInstance();
|
|
NppGUI & nppGUI = const_cast<NppGUI &>(pNppParams->getNppGUI());
|
|
|
|
if (cmdLineParams->_isNoPlugin)
|
|
_notepad_plus_plus_core._pluginsManager.disable();
|
|
|
|
_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.
|
|
|
|
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;
|
|
if(_isPrelaunch)
|
|
posInfo.showCmd = SW_HIDE;
|
|
else
|
|
posInfo.showCmd = nppGUI._isMaximized ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL;
|
|
|
|
posInfo.ptMinPosition.x = (LONG)-1;
|
|
posInfo.ptMinPosition.y = (LONG)-1;
|
|
posInfo.ptMaxPosition.x = (LONG)-1;
|
|
posInfo.ptMaxPosition.y = (LONG)-1;
|
|
posInfo.rcNormalPosition.left = nppGUI._appPos.left;
|
|
posInfo.rcNormalPosition.top = nppGUI._appPos.top;
|
|
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 ((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);
|
|
|
|
nppGUI._isCmdlineNosessionActivated = cmdLineParams->_isNoSession;
|
|
if (nppGUI._rememberLastSession && !cmdLineParams->_isNoSession)
|
|
_notepad_plus_plus_core.loadLastSession();
|
|
|
|
if (not cmdLineParams->_isPreLaunch)
|
|
{
|
|
if (cmdLineParams->isPointValid())
|
|
::ShowWindow(_hSelf, SW_SHOW);
|
|
else
|
|
::ShowWindow(_hSelf, nppGUI._isMaximized ? SW_MAXIMIZE : SW_SHOW);
|
|
}
|
|
else
|
|
{
|
|
_notepad_plus_plus_core._pTrayIco = new trayIconControler(_hSelf, IDI_M30ICON, IDC_MINIMIZED_TRAY, ::LoadIcon(_hInst, MAKEINTRESOURCE(IDI_M30ICON)), TEXT(""));
|
|
_notepad_plus_plus_core._pTrayIco->doTrayIcon(ADD);
|
|
}
|
|
|
|
if (cmdLine)
|
|
_notepad_plus_plus_core.loadCommandlineParams(cmdLine, cmdLineParams);
|
|
|
|
std::vector<generic_string> fileNames;
|
|
std::vector<generic_string> patterns;
|
|
patterns.push_back(TEXT("*.xml"));
|
|
|
|
generic_string nppDir = pNppParams->getNppPath();
|
|
|
|
LocalizationSwitcher & localizationSwitcher = pNppParams->getLocalizationSwitcher();
|
|
std::wstring localizationDir = nppDir;
|
|
PathAppend(localizationDir, TEXT("localization\\"));
|
|
|
|
_notepad_plus_plus_core.getMatchedFileNames(localizationDir.c_str(), patterns, fileNames, false, false);
|
|
for (size_t i = 0, len = fileNames.size(); i < len; ++i)
|
|
localizationSwitcher.addLanguageFromXml(fileNames[i].c_str());
|
|
|
|
fileNames.clear();
|
|
ThemeSwitcher & themeSwitcher = pNppParams->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 themeDir;
|
|
if (pNppParams->getAppDataNppDir() && pNppParams->getAppDataNppDir()[0])
|
|
{
|
|
themeDir = pNppParams->getAppDataNppDir();
|
|
PathAppend(themeDir, TEXT("themes\\"));
|
|
_notepad_plus_plus_core.getMatchedFileNames(themeDir.c_str(), patterns, fileNames, false, false);
|
|
for (size_t i = 0, len = fileNames.size() ; i < len ; ++i)
|
|
{
|
|
themeSwitcher.addThemeFromXml(fileNames[i].c_str());
|
|
}
|
|
}
|
|
|
|
fileNames.clear();
|
|
themeDir.clear();
|
|
themeDir = nppDir.c_str(); // <- should use the pointer to avoid the constructor of copy
|
|
PathAppend(themeDir, TEXT("themes\\"));
|
|
_notepad_plus_plus_core.getMatchedFileNames(themeDir.c_str(), patterns, fileNames, false, false);
|
|
for (size_t i = 0, len = fileNames.size(); i < len ; ++i)
|
|
{
|
|
generic_string themeName( themeSwitcher.getThemeFromXmlFileName(fileNames[i].c_str()) );
|
|
if (! themeSwitcher.themeNameExists(themeName.c_str()) )
|
|
{
|
|
themeSwitcher.addThemeFromXml(fileNames[i].c_str());
|
|
}
|
|
}
|
|
|
|
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);
|
|
|
|
// Notify plugins that Notepad++ is ready
|
|
SCNotification scnN;
|
|
scnN.nmhdr.code = NPPN_READY;
|
|
scnN.nmhdr.hwndFrom = _hSelf;
|
|
scnN.nmhdr.idFrom = 0;
|
|
_notepad_plus_plus_core._pluginsManager.notify(&scnN);
|
|
|
|
if (!cmdLineParams->_easterEggName.empty())
|
|
{
|
|
//::MessageBoxA(NULL, destStr.c_str(), "", MB_OK);
|
|
if (cmdLineParams->_quoteType == 0) // Easter Egg Name
|
|
{
|
|
int iQuote = _notepad_plus_plus_core.getQuoteIndexFrom(cmdLineParams->_easterEggName.c_str());
|
|
if (iQuote != -1)
|
|
{
|
|
_notepad_plus_plus_core.showQuoteFromIndex(iQuote);
|
|
}
|
|
}
|
|
else if (cmdLineParams->_quoteType == 1) // command line quote
|
|
{
|
|
_userQuote = cmdLineParams->_easterEggName;
|
|
_quoteParams.reset();
|
|
_quoteParams._quote = _userQuote.c_str();
|
|
_quoteParams._quoter = TEXT("Anonymous #999");
|
|
_quoteParams._shouldBeTrolling = false;
|
|
_quoteParams._lang = cmdLineParams->_langType;
|
|
if (cmdLineParams->_ghostTypingSpeed == 1)
|
|
_quoteParams._speed = QuoteParams::slow;
|
|
else if (cmdLineParams->_ghostTypingSpeed == 2)
|
|
_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
|
|
{
|
|
if (::PathFileExists(cmdLineParams->_easterEggName.c_str()))
|
|
{
|
|
std::string content = getFileContent(cmdLineParams->_easterEggName.c_str());
|
|
WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance();
|
|
_userQuote = wmc->char2wchar(content.c_str(), SC_CP_UTF8);
|
|
if (!_userQuote.empty())
|
|
{
|
|
_quoteParams.reset();
|
|
_quoteParams._quote = _userQuote.c_str();
|
|
_quoteParams._quoter = TEXT("Anonymous #999");
|
|
_quoteParams._shouldBeTrolling = false;
|
|
_quoteParams._lang = cmdLineParams->_langType;
|
|
if (cmdLineParams->_ghostTypingSpeed == 1)
|
|
_quoteParams._speed = QuoteParams::slow;
|
|
else if (cmdLineParams->_ghostTypingSpeed == 2)
|
|
_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();
|
|
// Lauch backup task
|
|
_notepad_plus_plus_core.launchDocumentBackupTask();
|
|
}
|
|
|
|
// Make this call later to take effect
|
|
::SendMessage(_hSelf, NPPM_INTERNAL_SETWORDCHARS, 0, 0);
|
|
|
|
if (pNppParams->doFunctionListExport())
|
|
::SendMessage(_hSelf, NPPM_INTERNAL_EXPORTFUNCLISTANDQUIT, 0, 0);
|
|
|
|
if (pNppParams->doPrintAndExit())
|
|
::SendMessage(_hSelf, NPPM_INTERNAL_PRNTANDQUIT, 0, 0);
|
|
}
|
|
|
|
|
|
bool Notepad_plus_Window::isDlgsMsg(MSG *msg) const
|
|
{
|
|
for (size_t i = 0, len = _notepad_plus_plus_core._hModelessDlgs.size(); i < len; ++i)
|
|
{
|
|
if (_notepad_plus_plus_core.processIncrFindAccel(msg))
|
|
return true;
|
|
|
|
if (_notepad_plus_plus_core.processFindAccel(msg))
|
|
return true;
|
|
|
|
if (::IsDialogMessageW(_notepad_plus_plus_core._hModelessDlgs[i], msg))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|