Merge pull request #2467 from RaiKoHoff/grepWin_Integration

Disable options which need write access to .ini-file, if no write access can be granted (permissions)
This commit is contained in:
Rainer Kottenhoff 2020-07-02 14:02:24 +02:00 committed by GitHub
commit b968099d02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 428 additions and 164 deletions

View File

@ -9,7 +9,7 @@ grepWin is a simple search and replace tool which can use [regular expressions](
In case you're not familiar with regular expressions, we have a very short [regular expression tutorial](https://tools.stefankueng.com/regexhelp.html) for you.
[![grepWin](https://raw.githubusercontent.com/stefankueng/grepWin/master/src/Resources/grepWin_search-small.png)](https://raw.githubusercontent.com/stefankueng/grepWin/master/src/Resources/grepWin_search.png)
[![grepWin](https://github.com/stefankueng/grepWin/raw/main/src/Resources/grepWin_search-small.png)](https://github.com/stefankueng/grepWin/raw/main/src/Resources/grepWin_search.png)
# Command line parameters
The command line parameters are listed on a [separate page](https://tools.stefankueng.com/grepWin_cmd.html).

View File

@ -199,6 +199,7 @@
</buildfiles>
</nant>
<property name="verstring" value="${environment::get-variable('MajorVersion')}.${environment::get-variable('MinorVersion')}.${environment::get-variable('MicroVersion')}" />
<property name="verstringfull" value="${verstring}.${environment::get-variable('WCREV')}" />
<copy file="bin\Release\grepWin.exe" tofile="bin\grepWin-${verstring}_portable.exe" />
<copy file="bin\Release64\grepWin.exe" tofile="bin\grepWin-x64-${verstring}_portable.exe" />
@ -216,6 +217,10 @@
<arg value="bin\grepWin-${verstring}-x64.msi" />
</exec>
<loadfile file="bin\checksum64.txt" property="checksum64" />
<!-- now write the version.txt file -->
<echo file="version.txt">${verstringfull}
https://tools.stefankueng.com/grepWin.html
</echo>
<loadfile file="choco\grepwin.nuspec" property="nuspecfile">
<filterchain>

View File

@ -342,16 +342,16 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Import Project="..\packages\boost.1.71.0.0\build\boost.targets" Condition="Exists('..\packages\boost.1.71.0.0\build\boost.targets')" />
<Import Project="..\packages\boost_iostreams-vc142.1.71.0.0\build\boost_iostreams-vc142.targets" Condition="Exists('..\packages\boost_iostreams-vc142.1.71.0.0\build\boost_iostreams-vc142.targets')" />
<Import Project="..\packages\boost_regex-vc142.1.71.0.0\build\boost_regex-vc142.targets" Condition="Exists('..\packages\boost_regex-vc142.1.71.0.0\build\boost_regex-vc142.targets')" />
<Import Project="..\packages\boost.1.72.0.0\build\boost.targets" Condition="Exists('..\packages\boost.1.72.0.0\build\boost.targets')" />
<Import Project="..\packages\boost_iostreams-vc142.1.72.0.0\build\boost_iostreams-vc142.targets" Condition="Exists('..\packages\boost_iostreams-vc142.1.72.0.0\build\boost_iostreams-vc142.targets')" />
<Import Project="..\packages\boost_regex-vc142.1.72.0.0\build\boost_regex-vc142.targets" Condition="Exists('..\packages\boost_regex-vc142.1.72.0.0\build\boost_regex-vc142.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\boost.1.71.0.0\build\boost.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost.1.71.0.0\build\boost.targets'))" />
<Error Condition="!Exists('..\packages\boost_iostreams-vc142.1.71.0.0\build\boost_iostreams-vc142.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_iostreams-vc142.1.71.0.0\build\boost_iostreams-vc142.targets'))" />
<Error Condition="!Exists('..\packages\boost_regex-vc142.1.71.0.0\build\boost_regex-vc142.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_regex-vc142.1.71.0.0\build\boost_regex-vc142.targets'))" />
<Error Condition="!Exists('..\packages\boost.1.72.0.0\build\boost.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost.1.72.0.0\build\boost.targets'))" />
<Error Condition="!Exists('..\packages\boost_iostreams-vc142.1.72.0.0\build\boost_iostreams-vc142.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_iostreams-vc142.1.72.0.0\build\boost_iostreams-vc142.targets'))" />
<Error Condition="!Exists('..\packages\boost_regex-vc142.1.72.0.0\build\boost_regex-vc142.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_regex-vc142.1.72.0.0\build\boost_regex-vc142.targets'))" />
</Target>
</Project>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="boost" version="1.71.0.0" targetFramework="native" />
<package id="boost_iostreams-vc142" version="1.71.0.0" targetFramework="native" />
<package id="boost_regex-vc142" version="1.71.0.0" targetFramework="native" />
<package id="boost" version="1.72.0.0" targetFramework="native" />
<package id="boost_iostreams-vc142" version="1.72.0.0" targetFramework="native" />
<package id="boost_regex-vc142" version="1.72.0.0" targetFramework="native" />
</packages>

View File

@ -1,6 +1,6 @@
// sktoolslib - common files for SK tools
// Copyright (C) 2012-2013 - Stefan Kueng
// Copyright (C) 2012-2013, 2020 - Stefan Kueng
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -76,10 +76,12 @@ public:
CFileDropTarget(HWND hTargetWnd)
: CIDropTarget(hTargetWnd)
, m_hParent(NULL)
, m_concat(0)
{}
CFileDropTarget(HWND hTargetWnd, HWND hParent)
: CIDropTarget(hTargetWnd)
, m_hParent(hParent)
, m_concat(0)
{
RegisterDragDrop(hTargetWnd, this);
// create the supported format:
@ -90,6 +92,7 @@ public:
ftetc.tymed = TYMED_HGLOBAL;
AddSuportedFormat(ftetc);
}
void SetMultipathConcatenate(wchar_t ch) { m_concat = ch; }
virtual bool OnDrop(FORMATETC* pFmtEtc, STGMEDIUM& medium, DWORD * /*pdwEffect*/)
{
if (m_hParent && (pFmtEtc->cfFormat == CF_HDROP) && (medium.tymed == TYMED_HGLOBAL))
@ -189,11 +192,22 @@ public:
std::unique_ptr<TCHAR[]> szFileName(new TCHAR[MAX_PATH_NEW]);
UINT cFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
std::wstring concatPaths;
for (UINT i = 0; i < cFiles; ++i)
{
DragQueryFile(hDrop, i, szFileName.get(), MAX_PATH_NEW);
::SendMessage(m_hTargetWnd, WM_SETTEXT, 0, (LPARAM)szFileName.get());
if (m_concat)
{
if (!concatPaths.empty())
concatPaths += m_concat;
concatPaths += szFileName.get();
}
else
::SendMessage(m_hTargetWnd, WM_SETTEXT, 0, (LPARAM)szFileName.get());
}
if (!concatPaths.empty())
::SendMessage(m_hTargetWnd, WM_SETTEXT, 0, (LPARAM)concatPaths.c_str());
//DragFinish(hDrop); // base class calls ReleaseStgMedium
}
GlobalUnlock(medium.hGlobal);
@ -202,4 +216,5 @@ public:
}
private:
HWND m_hParent;
wchar_t m_concat;
};

View File

@ -1,6 +1,6 @@
// sktoolslib - common files for SK tools
// Copyright (C) 2012-2013, 2017 - Stefan Kueng
// Copyright (C) 2012-2013, 2017, 2020 - Stefan Kueng
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -259,7 +259,7 @@ bool GDIHelpers::ShortHexStringToCOLORREF(const std::string& s, COLORREF* clr)
}
}
auto color = RGB(rgb[0], rgb[1], rgb[2]);
*clr = (RGB((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF)) | (color & 0xFF000000);
*clr = color;
return true;
}

View File

@ -41,15 +41,16 @@ IDI_GREPWIN ICON "grepWinNP3.ico"
IDD_SEARCHDLG DIALOGEX 0, 0, 600, 339
STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "grepWinNP3"
FONT 9, "MS Shell Dlg 2", 400, 0, 0x1
FONT 9, "Segoe UI", 400, 0, 0x1
BEGIN
LTEXT "Press F1 for help",IDC_HELPLABEL,362,50,104,8
RTEXT "About grepWinNP3",IDC_ABOUTLINK,449,2,136,8
PUSHBUTTON "/",IDC_PATHMRU,14,20,11,12
EDITTEXT IDC_SEARCHPATH,31,20,536,12,ES_AUTOHSCROLL,WS_EX_ACCEPTFILES
PUSHBUTTON "...",IDC_SEARCHPATHBROWSE,572,20,13,12
GROUPBOX "Search in",IDC_GROUPSEARCHIN,7,10,587,29
CONTROL "Regex search",IDC_REGEXRADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,84,50,100,10
CONTROL "Text search",IDC_TEXTRADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,198,50,105,10
LTEXT "Press F1 for help",IDC_HELPLABEL,362,50,104,8
RTEXT "",IDC_REGEXOKLABEL,476,50,98,8
LTEXT "Search &for:",IDC_SEARCHFORLABEL,14,65,46,8
EDITTEXT IDC_SEARCHTEXT,83,64,484,12,ES_AUTOHSCROLL
@ -64,6 +65,7 @@ BEGIN
PUSHBUTTON "Test regex",IDC_TESTREGEX,14,109,69,14
PUSHBUTTON "Add to Presets",IDC_ADDTOBOOKMARKS,117,109,76,14
PUSHBUTTON "Presets",IDC_BOOKMARKS,195,109,50,14
CONTROL "",IDC_UPDATELINK,"SysLink",LWS_RIGHT | NOT WS_VISIBLE | WS_TABSTOP | WS_DISABLED,262,110,292,11
GROUPBOX "Search",IDC_GROUPSEARCHFOR,7,41,587,86
CONTROL "All sizes",IDC_ALLSIZERADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,14,139,103,10
CONTROL "Size is",IDC_SIZERADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,14,152,44,10
@ -94,7 +96,6 @@ BEGIN
GROUPBOX "Limit search",IDC_GROUPLIMITSEARCH,7,128,587,65
CONTROL "",IDC_RESULTLIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,14,234,571,81
LTEXT "",IDC_SEARCHINFOLABEL,14,321,580,8
RTEXT "About grepWinNP3",IDC_ABOUTLINK,449,2,136,8
GROUPBOX "Search results",IDC_GROUPSEARCHRESULTS,7,214,587,118
CONTROL "Files",IDC_RESULTFILES,"Button",BS_AUTORADIOBUTTON | WS_GROUP,84,222,89,10
CONTROL "Content",IDC_RESULTCONTENT,"Button",BS_AUTORADIOBUTTON,200,222,104,10
@ -105,7 +106,7 @@ END
IDD_REGEXTEST DIALOGEX 0, 0, 401, 316
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Regex Test"
FONT 9, "MS Shell Dlg 2", 400, 0, 0x1
FONT 9, "Segoe UI", 400, 0, 0x1
BEGIN
LTEXT "Paste text to test the regex with:",IDC_INFOLABEL,7,7,387,8
CONTROL "",IDC_TEXTCONTENT,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x1084,7,17,387,89
@ -124,7 +125,7 @@ END
IDD_NAME DIALOGEX 0, 0, 186, 65
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Preset name"
FONT 9, "MS Shell Dlg 2", 400, 0, 0x1
FONT 9, "Segoe UI", 400, 0, 0x1
BEGIN
LTEXT "Enter a name for the regex:",IDC_INFOLABEL,7,7,172,8
EDITTEXT IDC_NAME,7,20,172,14,ES_AUTOHSCROLL
@ -135,7 +136,7 @@ END
IDD_BOOKMARKS DIALOGEX 0, 0, 240, 129
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Presets"
FONT 9, "MS Shell Dlg 2", 400, 0, 0x1
FONT 9, "Segoe UI", 400, 0, 0x1
BEGIN
CONTROL "",IDC_BOOKMARKS,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,16,226,85
DEFPUSHBUTTON "OK",IDOK,70,108,78,14
@ -146,7 +147,7 @@ END
IDD_ABOUT DIALOGEX 0, 0, 263, 86
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About grepWinNP3"
FONT 9, "MS Shell Dlg 2", 400, 0, 0x1
FONT 9, "Segoe UI", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,206,65,50,14
ICON IDI_GREPWIN,IDC_STATIC,17,18,20,20,SS_CENTERIMAGE
@ -159,7 +160,7 @@ END
IDD_MULTILINEEDIT DIALOGEX 0, 0, 317, 135
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Dialog"
FONT 9, "MS Shell Dlg 2", 400, 0, 0x1
FONT 9, "Segoe UI", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,157,114,73,14
PUSHBUTTON "Cancel",IDCANCEL,237,114,73,14
@ -169,7 +170,7 @@ END
IDD_SETTINGS DIALOGEX 0, 0, 317, 209
STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "grepWinNP3 Settings"
FONT 9, "MS Shell Dlg 2", 400, 0, 0x1
FONT 9, "Segoe UI", 400, 0, 0x1
BEGIN
GROUPBOX "Editor",IDC_EDITORGROUP,7,7,303,78
LTEXT "Command line to start an editor at a specific line:",IDC_STATIC1,13,19,288,8
@ -188,8 +189,9 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,204,180,50,13
PUSHBUTTON "Cancel",IDCANCEL,260,180,50,13
CONTROL "Only one instance",IDC_ONLYONE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,143,150,10
CONTROL "Dark mode",IDC_DARKMODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,155,157,10
LTEXT "",IDC_DARKMODEINFO,17,170,180,23,WS_DISABLED
CONTROL "Check for updates",IDC_DOUPDATECHECKS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED,7,155,150,10
CONTROL "Dark mode",IDC_DARKMODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,167,157,10
LTEXT "",IDC_DARKMODEINFO,17,182,180,23,WS_DISABLED
RTEXT "Max # of concurrent worker",IDC_TEXT_NUMOFWORKER,156,156,107,9,0,WS_EX_RIGHT
EDITTEXT IDC_MAXNUMWORKER,271,154,31,13,ES_RIGHT | ES_NUMBER | WS_GROUP,WS_EX_RIGHT
CONTROL "",IDC_SPIN_MAXWORKER,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNLEFT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP,271,154,10,13
@ -429,6 +431,7 @@ BEGIN
IDS_EXPORTPATHS "include file paths"
IDS_EXPORTMATCHLINENUMBER "include match line numbers"
IDS_EXPORTMATCHLINECONTENT "include match line text"
IDS_UPDATEAVAILABLE "grepWinNP3 %s is available"
END
#endif // Neutral resources

View File

@ -51,6 +51,12 @@
#include "COMPtrs.h"
#include "PreserveChdir.h"
#ifdef NP3_ALLOW_UPDATE
#include "TempFile.h"
#include "version.h"
#endif
#include <string>
#include <map>
#include <iostream>
@ -298,6 +304,7 @@ LRESULT CSearchDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
m_pDropTarget->AddSuportedFormat(ftetc);
ftetc.cfFormat=CF_HDROP;
m_pDropTarget->AddSuportedFormat(ftetc);
m_pDropTarget->SetMultipathConcatenate('|');
m_editFilePatterns.Subclass(hwndDlg, IDC_PATTERN);
m_editExcludeDirsPatterns.Subclass(hwndDlg, IDC_EXCLUDEDIRSPATTERN);
@ -452,6 +459,9 @@ LRESULT CSearchDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
m_resizer.AddControl(hwndDlg, IDC_TESTREGEX, RESIZER_TOPLEFT);
m_resizer.AddControl(hwndDlg, IDC_ADDTOBOOKMARKS, RESIZER_TOPLEFT);
m_resizer.AddControl(hwndDlg, IDC_BOOKMARKS, RESIZER_TOPLEFT);
#include "TempFile.h"
m_resizer.AddControl(hwndDlg, IDC_UPDATELINK, RESIZER_TOPRIGHT);
#include "version.h"
m_resizer.AddControl(hwndDlg, IDC_GROUPLIMITSEARCH, RESIZER_TOPLEFTRIGHT);
m_resizer.AddControl(hwndDlg, IDC_ALLSIZERADIO, RESIZER_TOPLEFT);
m_resizer.AddControl(hwndDlg, IDC_SIZERADIO, RESIZER_TOPLEFT);
@ -525,6 +535,19 @@ LRESULT CSearchDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
}
InitResultList();
#ifdef NP3_ALLOW_UPDATE
bool doCheck = true;
if (bPortable)
doCheck = !!_wtoi(g_iniFile.GetValue(L"global", L"CheckForUpdates", L"1"));
else
doCheck = !!DWORD(CRegStdDWORD(L"Software\\grepWin\\CheckForUpdates", 1));
if (doCheck)
{
m_updateCheckThread = std::move(std::thread([&]() { CheckForUpdates(); }));
ShowUpdateAvailable();
}
#endif
if (hInitProtection)
CloseHandle(hInitProtection);
hInitProtection = nullptr;
@ -545,6 +568,10 @@ LRESULT CSearchDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
return FALSE;
case WM_CLOSE:
{
#ifdef NP3_ALLOW_UPDATE
if (m_updateCheckThread.joinable())
m_updateCheckThread.join();
#endif
if (!DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\escclose", FALSE)))
{
if (IsEvaluationThreadRunning())
@ -612,6 +639,24 @@ LRESULT CSearchDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
break;
}
break;
#ifdef NP3_ALLOW_UPDATE
case IDC_UPDATELINK:
switch (((LPNMHDR)lParam)->code)
{
case NM_CLICK:
case NM_RETURN:
{
PNMLINK pNMLink = (PNMLINK)lParam;
LITEM item = pNMLink->item;
if (item.iLink == 0)
{
ShellExecute(*this, L"open", item.szUrl, nullptr, nullptr, SW_SHOW);
}
break;
}
}
break;
#endif
}
}
break;
@ -1008,6 +1053,10 @@ LRESULT CSearchDlg::DoCommand(int id, int msg)
break;
case IDCANCEL:
{
#ifdef NP3_ALLOW_UPDATE
if (m_updateCheckThread.joinable())
m_updateCheckThread.join();
#endif
if (DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\escclose", FALSE)))
{
if (IsEvaluationThreadRunning())
@ -1483,6 +1532,12 @@ LRESULT CSearchDlg::DoCommand(int id, int msg)
exportlinenumbers = includeMatchLineNumbers ? 1 : 0;
exportlinecontent = includeMatchLineTexts ? 1 : 0;
}
SHELLEXECUTEINFO sei = { 0 };
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.lpVerb = TEXT("open");
sei.lpFile = path.c_str();
sei.nShow = SW_SHOWNORMAL;
ShellExecuteEx(&sei);
}
}
}
@ -1977,7 +2032,7 @@ void CSearchDlg::DoListNotify(LPNMITEMACTIVATE lpNMItemActivate)
CStringUtils::trim(matchtext);
matchString += CStringUtils::Format(sFormat.c_str(), inf.matchlinesnumbers[i], matchtext.c_str());
}
if (inf.matchlines.size() >= 5)
if (inf.matchlines.size() > 5)
{
std::wstring sx = TranslatedString(hResource, IDS_XMOREMATCHES);
std::wstring ssx = CStringUtils::Format(sx.c_str(), int(inf.matchlines.size() - 5));
@ -3732,3 +3787,143 @@ bool CSearchDlg::FailedShowMessage(HRESULT hr)
}
return false;
}
#ifdef NP3_ALLOW_UPDATE
void CSearchDlg::CheckForUpdates(bool force)
{
bool bNewerAvailable = false;
// check for newer versions
bool doCheck = true;
if (bPortable)
doCheck = !!_wtoi(g_iniFile.GetValue(L"global", L"CheckForUpdates", L"1"));
else
doCheck = !!DWORD(CRegStdDWORD(L"Software\\grepWin\\CheckForUpdates", 1));
if (doCheck)
{
time_t now;
time(&now);
time_t last = 0;
if (bPortable)
{
last = _wtoll(g_iniFile.GetValue(L"global", L"CheckForUpdatesLast", L"0"));
}
else
{
last = _wtoll(((std::wstring)CRegStdString(L"Software\\grepWin\\CheckForUpdatesLast", L"0")).c_str());
}
double days = std::difftime(now, last) / (60LL * 60LL * 24LL);
if ((days >= 7.0) || force)
{
std::wstring tempfile = CTempFiles::Instance().GetTempFilePath(true);
std::wstring sCheckURL = L"https://raw.githubusercontent.com/stefankueng/grepWin/main/version.txt";
HRESULT res = URLDownloadToFile(nullptr, sCheckURL.c_str(), tempfile.c_str(), 0, nullptr);
if (res == S_OK)
{
if (bPortable)
{
g_iniFile.SetValue(L"global", L"CheckForUpdatesLast", std::to_wstring(now).c_str());
}
else
{
auto regLast = CRegStdString(L"Software\\grepWin\\CheckForUpdatesLast", L"0");
regLast = std::to_wstring(now);
}
std::ifstream File;
File.open(tempfile.c_str());
if (File.good())
{
char line[1024];
File.getline(line, sizeof(line));
auto verLine = CUnicodeUtils::StdGetUnicode(line);
bNewerAvailable = IsVersionNewer(verLine);
File.getline(line, sizeof(line));
auto updateurl = CUnicodeUtils::StdGetUnicode(line);
if (bNewerAvailable)
{
if (bPortable)
{
g_iniFile.SetValue(L"global", L"CheckForUpdatesVersion", verLine.c_str());
g_iniFile.SetValue(L"global", L"CheckForUpdatesUrl", updateurl.c_str());
}
else
{
auto regVersion = CRegStdString(L"Software\\grepWin\\CheckForUpdatesVersion", L"");
regVersion = verLine;
auto regUpdateUrl = CRegStdString(L"Software\\grepWin\\CheckForUpdatesUrl", L"");
regUpdateUrl = updateurl;
}
ShowUpdateAvailable();
}
}
File.close();
DeleteFile(tempfile.c_str());
}
}
}
}
void CSearchDlg::ShowUpdateAvailable()
{
std::wstring sVersion;
std::wstring updateUrl;
if (bPortable)
{
sVersion = g_iniFile.GetValue(L"global", L"CheckForUpdatesVersion", L"");
updateUrl = g_iniFile.GetValue(L"global", L"CheckForUpdatesUrl", L"");
}
else
{
sVersion = CRegStdString(L"Software\\grepWin\\CheckForUpdatesVersion", L"");
updateUrl = CRegStdString(L"Software\\grepWin\\CheckForUpdatesUrl", L"");
}
if (IsVersionNewer(sVersion))
{
auto sUpdateAvailable = TranslatedString(hResource, IDS_UPDATEAVAILABLE);
sUpdateAvailable = CStringUtils::Format(sUpdateAvailable.c_str(), sVersion.c_str());
auto sLinkText = CStringUtils::Format(L"<a href=\"%s\">%s</a>", updateUrl.c_str(), sUpdateAvailable.c_str());
SetDlgItemText(*this, IDC_UPDATELINK, sLinkText.c_str());
ShowWindow(GetDlgItem(*this, IDC_UPDATELINK), SW_SHOW);
}
}
bool CSearchDlg::IsVersionNewer(const std::wstring& sVer)
{
int major = 0;
int minor = 0;
int micro = 0;
int build = 0;
const wchar_t* pLine = sVer.c_str();
major = _wtoi(pLine);
pLine = wcschr(pLine, '.');
if (pLine)
{
pLine++;
minor = _wtoi(pLine);
pLine = wcschr(pLine, '.');
if (pLine)
{
pLine++;
micro = _wtoi(pLine);
pLine = wcschr(pLine, '.');
if (pLine)
{
pLine++;
build = _wtoi(pLine);
}
}
}
bool isNewer = false;
if (major > GREPWIN_VERMAJOR)
isNewer = true;
else if ((minor > GREPWIN_VERMINOR) && (major == GREPWIN_VERMAJOR))
isNewer = true;
else if ((micro > GREPWIN_VERMICRO) && (minor == GREPWIN_VERMINOR) && (major == GREPWIN_VERMAJOR))
isNewer = true;
else if ((build > GREPWIN_VERBUILD) && (micro == GREPWIN_VERMICRO) && (minor == GREPWIN_VERMINOR) && (major == GREPWIN_VERMAJOR))
isNewer = true;
return isNewer;
}
#endif

View File

@ -31,6 +31,9 @@
#include <vector>
#include <set>
#include <mutex>
#ifdef NP3_ALLOW_UPDATE
#include <thread>
#endif
#define SEARCH_START (WM_APP+1)
@ -119,6 +122,11 @@ protected:
void AutoSizeAllColumns();
int GetSelectedListIndex(int index);
bool FailedShowMessage(HRESULT hr);
#ifdef NP3_ALLOW_UPDATE
void CheckForUpdates(bool force = false);
void ShowUpdateAvailable();
bool IsVersionNewer(const std::wstring& sVer);
#endif
private:
static bool NameCompareAsc(const CSearchInfo& Entry1, const CSearchInfo& Entry2);
static bool SizeCompareAsc(const CSearchInfo& Entry1, const CSearchInfo& Entry2);
@ -199,6 +207,10 @@ private:
static UINT GREPWIN_STARTUPMSG;
#ifdef NP3_ALLOW_UPDATE
std::thread m_updateCheckThread;
#endif
CAutoComplete m_AutoCompleteFilePatterns;
CAutoComplete m_AutoCompleteExcludeDirsPatterns;
CAutoComplete m_AutoCompleteSearchPatterns;

View File

@ -184,6 +184,9 @@ LRESULT CSettingsDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
SendDlgItemMessage(hwndDlg, IDC_BACKUPINFOLDER, BM_SETCHECK, bPortable ? g_iniFile.GetBoolValue(L"settings", L"backupinfolder", false) : !!DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\backupinfolder", FALSE)) ? BST_CHECKED : BST_UNCHECKED, 0);
SendDlgItemMessage(hwndDlg, IDC_NOWARNINGIFNOBACKUP, BM_SETCHECK, bPortable ? g_iniFile.GetBoolValue(L"settings", L"nowarnifnobackup", false) : !!DWORD(CRegStdDWORD(L"Software\\grepWin\\nowarnifnobackup", FALSE)) ? BST_CHECKED : BST_UNCHECKED, 0);
SendDlgItemMessage(hwndDlg, IDC_ONLYONE, BM_SETCHECK, bPortable ? g_iniFile.GetBoolValue(L"global", L"onlyone", false) : !!DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\onlyone", FALSE)) ? BST_CHECKED : BST_UNCHECKED, 0);
#ifdef NP3_ALLOW_UPDATE
SendDlgItemMessage(hwndDlg, IDC_DOUPDATECHECKS, BM_SETCHECK, bPortable ? g_iniFile.GetBoolValue(L"global", L"CheckForUpdates", false) : !!DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\CheckForUpdates", FALSE)) ? BST_CHECKED : BST_UNCHECKED, 0);
#endif
SendDlgItemMessage(hwndDlg, IDC_DARKMODE, BM_SETCHECK, CTheme::Instance().IsDarkTheme() ? BST_CHECKED : BST_UNCHECKED, 0);
EnableWindow(GetDlgItem(*this, IDC_DARKMODE), CTheme::Instance().IsDarkModeAllowed());
@ -212,6 +215,9 @@ LRESULT CSettingsDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
m_resizer.AddControl(hwndDlg, IDC_BACKUPINFOLDER, RESIZER_TOPLEFTRIGHT);
m_resizer.AddControl(hwndDlg, IDC_NOWARNINGIFNOBACKUP, RESIZER_TOPLEFTRIGHT);
m_resizer.AddControl(hwndDlg, IDC_ONLYONE, RESIZER_TOPLEFTRIGHT);
#ifdef NP3_ALLOW_UPDATE
m_resizer.AddControl(hwndDlg, IDC_DOUPDATECHECKS, RESIZER_TOPLEFTRIGHT);
#endif
m_resizer.AddControl(hwndDlg, IDC_DARKMODE, RESIZER_TOPLEFT);
m_resizer.AddControl(hwndDlg, IDC_DARKMODEINFO, RESIZER_TOPLEFTRIGHT);
m_resizer.AddControl(hwndDlg, IDOK, RESIZER_BOTTOMRIGHT);
@ -302,6 +308,9 @@ LRESULT CSettingsDlg::DoCommand(int id, int /*msg*/)
g_iniFile.SetBoolValue(L"settings", L"backupinfolder", (IsDlgButtonChecked(*this, IDC_BACKUPINFOLDER) == BST_CHECKED));
g_iniFile.SetBoolValue(L"settings", L"nowarnifnobackup", (IsDlgButtonChecked(*this, IDC_NOWARNINGIFNOBACKUP) == BST_CHECKED));
g_iniFile.SetBoolValue(L"global", L"onlyone", (IsDlgButtonChecked(*this, IDC_ONLYONE) == BST_CHECKED));
#ifdef NP3_ALLOW_UPDATE
g_iniFile.SetBoolValue(L"global", L"CheckForUpdates", (IsDlgButtonChecked(*this, IDC_DOUPDATECHECKS) == BST_CHECKED));
#endif
g_iniFile.SetLongValue(L"global", L"MaxNumOfWorker", nWorker);
}
else
@ -314,6 +323,10 @@ LRESULT CSettingsDlg::DoCommand(int id, int /*msg*/)
nowarn = (IsDlgButtonChecked(*this, IDC_NOWARNINGIFNOBACKUP) == BST_CHECKED);
CRegStdDWORD regOnlyOne(L"Software\\grepWinNP3\\onlyone", FALSE);
regOnlyOne = (IsDlgButtonChecked(*this, IDC_ONLYONE) == BST_CHECKED);
#ifdef NP3_ALLOW_UPDATE
CRegStdDWORD regCheckForUpdates(L"Software\\grepWinNP3\\CheckForUpdates", FALSE);
regCheckForUpdates = (IsDlgButtonChecked(*this, IDC_DOUPDATECHECKS) == BST_CHECKED);
#endif
CRegStdDWORD nwrk(L"Software\\grepWinNP3\\MaxNumOfWorker", 1);
nwrk = nWorker;
}

View File

@ -6,13 +6,13 @@
//#pragma message(__LOC__"Run the NAnt script to get proper version info")
#define FILEVER 2, 1, 1, 15
#define PRODUCTVER 2, 1, 1, 15
#define STRFILEVER "2.1.1.15\0"
#define STRPRODUCTVER "2.1.1.15\0"
#define FILEVER 2, 1, 2, 16
#define PRODUCTVER 2, 1, 2, 16
#define STRFILEVER "2.1.2.16\0"
#define STRPRODUCTVER "2.1.2.16\0"
#define GREPWIN_VERMAJOR 2
#define GREPWIN_VERMINOR 1
#define GREPWIN_VERMICRO 1
#define GREPWIN_VERBUILD 15
#define GREPWIN_VERDATE "2020-06-16"
#define GREPWIN_VERMICRO 2
#define GREPWIN_VERBUILD 16
#define GREPWIN_VERDATE "2020-07-02"

View File

@ -78,6 +78,7 @@
#define IDS_EXPORTPATHS 165
#define IDS_EXPORTMATCHLINENUMBER 166
#define IDS_EXPORTMATCHLINECONTENT 167
#define IDS_UPDATEAVAILABLE 168
#define IDC_SEARCHTEXT 1000
#define IDC_REGEXRADIO 1001
#define IDC_TEXTRADIO 1002
@ -168,6 +169,8 @@
#define IDC_INVERSESEARCH 1091
#define IDC_SEARCHINFOUNDFILES 1092
#define IDC_EXPORT 1093
#define IDC_UPDATELINK 1094
#define IDC_DOUPDATECHECKS 1095
#define ID_REMOVEBOOKMARK 32771
#define ID_DUMMY_RENAMEPRESET 32774
#define ID_RENAMEBOOKMARK 32775
@ -178,9 +181,9 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 168
#define _APS_NEXT_RESOURCE_VALUE 169
#define _APS_NEXT_COMMAND_VALUE 32776
#define _APS_NEXT_CONTROL_VALUE 1094
#define _APS_NEXT_CONTROL_VALUE 1096
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif

View File

@ -4,7 +4,7 @@
<setenv>
<variable name="MajorVersion" value="2" />
<variable name="MinorVersion" value="0" />
<variable name="MicroVersion" value="1" />
<variable name="MicroVersion" value="2" />
<variable name="WCREV" value="$WCLOGCOUNT$" />
<variable name="WCDATE" value="$WCDATE$" />
</setenv>

View File

@ -93,6 +93,49 @@ constexpr bool SI_Success(const SI_Error rc) noexcept {
// ============================================================================
bool CanAccessPath(LPCWSTR lpIniFilePath, DWORD genericAccessRights)
{
bool bRet = false;
if (StrIsEmpty(lpIniFilePath)) {
return bRet;
}
DWORD length = 0;
SECURITY_INFORMATION const secInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
if (!::GetFileSecurity(lpIniFilePath, secInfo, NULL, 0, &length) && (ERROR_INSUFFICIENT_BUFFER == GetLastError())) {
PSECURITY_DESCRIPTOR security = static_cast<PSECURITY_DESCRIPTOR>(AllocMem(length, HEAP_ZERO_MEMORY));
if (security && ::GetFileSecurity(lpIniFilePath, secInfo, security, length, &length)) {
HANDLE hToken = NULL;
if (::OpenProcessToken(::GetCurrentProcess(), TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ, &hToken)) {
HANDLE hImpersonatedToken = NULL;
if (::DuplicateToken(hToken, SecurityImpersonation, &hImpersonatedToken)) {
GENERIC_MAPPING mapping = {0xFFFFFFFF};
PRIVILEGE_SET privileges = {0};
DWORD grantedAccess = 0, privilegesLength = sizeof(privileges);
BOOL result = FALSE;
mapping.GenericRead = FILE_GENERIC_READ;
mapping.GenericWrite = FILE_GENERIC_WRITE;
mapping.GenericExecute = FILE_GENERIC_EXECUTE;
mapping.GenericAll = FILE_ALL_ACCESS;
::MapGenericMask(&genericAccessRights, &mapping);
if (::AccessCheck(security, hImpersonatedToken, genericAccessRights,
&mapping, &privileges, &privilegesLength, &grantedAccess, &result)) {
bRet = (result == TRUE);
}
::CloseHandle(hImpersonatedToken);
}
::CloseHandle(hToken);
}
FreeMem(security);
}
}
return bRet;
}
// ----------------------------------------------------------------------------
// No mechanism for EXCLUSIVE WRITE / SHARD READ:
// cause we need completely synchronized exclusive access for READ _and_ WRITE
@ -265,13 +308,13 @@ extern "C" bool OpenSettingsFile(bool* keepCached)
//
extern "C" bool CloseSettingsFile(bool bSaveChanges, bool keepCached)
{
if (StrIsEmpty(Globals.IniFile) || !IsIniFileCached()) { return false; }
if (!Globals.bCanSaveIniFile || !IsIniFileCached()) { return false; }
bool const ok = bSaveChanges ? SaveIniFileCache(Globals.IniFile) : true;
bool const bSaved = bSaveChanges ? SaveIniFileCache(Globals.IniFile) : false;
if (!keepCached) { ResetIniFileCache(); }
return ok;
return bSaved;
}
@ -961,7 +1004,9 @@ extern "C" bool CreateIniFile(LPCWSTR pszIniFilePath, DWORD* pdwFileSize_out)
}
if (pdwFileSize_out) { *pdwFileSize_out = dwFileSize; }
if (dwFileSize == 0UL) {
Globals.bCanSaveIniFile = CanAccessPath(pszIniFilePath, GENERIC_WRITE);
if ((dwFileSize == 0UL) && Globals.bCanSaveIniFile) {
// Set at least Application Name Section
result = IniFileSetString(pszIniFilePath, _W(SAPPNAME), NULL, NULL);
}
@ -999,7 +1044,7 @@ void LoadSettings()
Globals.iCfgVersionRead = IniSectionGetInt(IniSecSettings, L"SettingsVersion", _ver);
Defaults.SaveSettings = StrIsNotEmpty(Globals.IniFile);
Settings.SaveSettings = IniSectionGetBool(IniSecSettings, L"SaveSettings", Defaults.SaveSettings);
Settings.SaveSettings = Defaults.SaveSettings && IniSectionGetBool(IniSecSettings, L"SaveSettings", Defaults.SaveSettings);
// --- first set "hard coded" .ini-Settings ---
@ -1979,7 +2024,7 @@ bool SaveAllSettings(bool bForceSaveSettings)
{
if (Flags.bDoRelaunchElevated) { return true; } // already saved before relaunch
if (Flags.bSettingsFileSoftLocked) { return false; }
WCHAR tchMsg[80];
GetLngString(IDS_MUI_SAVINGSETTINGS, tchMsg, COUNTOF(tchMsg));
@ -1996,7 +2041,7 @@ __try {
_SaveSettings(bForceSaveSettings);
if (StrIsNotEmpty(Globals.IniFile))
if (Globals.bCanSaveIniFile)
{
if (!Settings.SaveRecentFiles) {
// Cleanup unwanted MRUs
@ -2032,7 +2077,8 @@ __try {
}
// separate INI files for Style-Themes
if (Globals.idxSelectedTheme >= 2) {
if (Globals.idxSelectedTheme >= 2)
{
Style_SaveSettings(bForceSaveSettings);
}

View File

@ -28,6 +28,7 @@ extern "C" {
bool FindIniFile();
bool TestIniFile();
bool CanAccessPath(LPCWSTR lpIniFilePath, DWORD genericAccessRights);
bool CreateIniFile(LPCWSTR pszIniFilePath, DWORD* pdwFileSize_out);
void LoadSettings();
bool SaveWindowPositionSettings(bool bClearSettings);

View File

@ -287,7 +287,7 @@ static INT_PTR CALLBACK _InfoBoxLngDlgProc(HWND hwnd, UINT umsg, WPARAM wParam,
case IDIGNORE:
case IDTRYAGAIN:
case IDCONTINUE:
if (IsButtonChecked(hwnd, IDC_INFOBOXCHECK) && StrIsNotEmpty(lpMsgBox->lpstrSetting)) {
if (IsButtonChecked(hwnd, IDC_INFOBOXCHECK) && StrIsNotEmpty(lpMsgBox->lpstrSetting) ) {
IniFileSetInt(Globals.IniFile, Constants.SectionSuppressedMessages, lpMsgBox->lpstrSetting, LOWORD(wParam));
}
case IDNO:
@ -336,7 +336,9 @@ INT_PTR InfoBoxLng(UINT uType, LPCWSTR lpstrSetting, UINT uidMsg, ...)
break;
default:
IniFileDelete(Globals.IniFile, Constants.SectionSuppressedMessages, lpstrSetting, false);
if (Globals.bCanSaveIniFile) {
IniFileDelete(Globals.IniFile, Constants.SectionSuppressedMessages, lpstrSetting, false);
}
break;
}
@ -385,8 +387,7 @@ INT_PTR InfoBoxLng(UINT uType, LPCWSTR lpstrSetting, UINT uidMsg, ...)
}
msgBox.lpstrSetting = (LPWSTR)lpstrSetting;
msgBox.bDisableCheckBox = (StrIsEmpty(Globals.IniFile) || StrIsEmpty(lpstrSetting) || (iMode < 0)) ? true : false;
msgBox.bDisableCheckBox = (!Globals.bCanSaveIniFile || StrIsEmpty(lpstrSetting) || (iMode < 0)) ? true : false;
int idDlg;
switch (uType & MB_TYPEMASK) {

View File

@ -688,24 +688,22 @@ bool VerifyContrast(COLORREF cr1,COLORREF cr2)
// IsFontAvailable()
// Test if a certain font is installed on the system
//
int CALLBACK EnumFontsProc(CONST LOGFONT *plf,CONST TEXTMETRIC *ptm,DWORD FontType,LPARAM lParam)
static int CALLBACK EnumFontsProc(CONST LOGFONT *plf,CONST TEXTMETRIC *ptm,DWORD FontType,LPARAM lParam)
{
*((PBOOL)lParam) = true;
UNUSED(plf);
UNUSED(ptm);
UNUSED(FontType);
*((PBOOL)lParam) = true;
return 0;
}
bool IsFontAvailable(LPCWSTR lpszFontName)
{
BOOL fFound = FALSE;
HDC hDC = GetDC(NULL);
HDC const hDC = GetDC(NULL);
EnumFonts(hDC,lpszFontName,EnumFontsProc,(LPARAM)&fFound);
ReleaseDC(NULL,hDC);
return (bool)(fFound);
return fFound;
}
@ -713,22 +711,12 @@ bool IsFontAvailable(LPCWSTR lpszFontName)
//
// IsCmdEnabled()
//
bool IsCmdEnabled(HWND hwnd,UINT uId)
bool IsCmdEnabled(HWND hwnd, UINT uId)
{
HMENU hmenu;
UINT ustate;
hmenu = GetMenu(hwnd);
SendMessage(hwnd,WM_INITMENU,(WPARAM)hmenu,0);
ustate = GetMenuState(hmenu,uId,MF_BYCOMMAND);
if (ustate == 0xFFFFFFFF) {
return true;
}
return (!(ustate & (MF_GRAYED|MF_DISABLED)));
HMENU const hmenu = GetMenu(hwnd);
SendMessage(hwnd, WM_INITMENU,(WPARAM)hmenu, 0);
UINT const ustate = GetMenuState(hmenu, uId, MF_BYCOMMAND);
return ((ustate == 0xFFFFFFFF) ? true : (!(ustate & (MF_GRAYED | MF_DISABLED))));
}

View File

@ -293,12 +293,13 @@ void SetPreferredLanguage(LANGID iPreferredLanguageID)
{
StringCchCopyW(Settings2.PreferredLanguageLocaleName, COUNTOF(Settings2.PreferredLanguageLocaleName), szLocaleName);
if (StringCchCompareXIW(Settings2.PreferredLanguageLocaleName, Defaults2.PreferredLanguageLocaleName) != 0)
{
IniFileSetString(Globals.IniFile, Constants.Settings2_Section, L"PreferredLanguageLocaleName", Settings2.PreferredLanguageLocaleName);
}
else {
IniFileDelete(Globals.IniFile, Constants.Settings2_Section, L"PreferredLanguageLocaleName", false);
if (Globals.bCanSaveIniFile) {
if (StringCchCompareXIW(Settings2.PreferredLanguageLocaleName, Defaults2.PreferredLanguageLocaleName) != 0) {
IniFileSetString(Globals.IniFile, Constants.Settings2_Section, L"PreferredLanguageLocaleName", Settings2.PreferredLanguageLocaleName);
}
else {
IniFileDelete(Globals.IniFile, Constants.Settings2_Section, L"PreferredLanguageLocaleName", false);
}
}
}
}

View File

@ -1538,33 +1538,6 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
{
switch(umsg)
{
// Quickly handle painting and sizing messages, found in ScintillaWin.cxx
// Cool idea, don't know if this has any effect... ;-)
case WM_MOVE:
case WM_MOUSEACTIVATE:
case WM_NCHITTEST:
case WM_NCCALCSIZE:
case WM_NCPAINT:
case WM_PAINT:
case WM_ERASEBKGND:
case WM_NCMOUSEMOVE:
case WM_NCLBUTTONDOWN:
case WM_WINDOWPOSCHANGING:
case WM_WINDOWPOSCHANGED:
case WM_TIMER:
case WM_KILLFOCUS:
case WM_ENTERIDLE:
return DefWindowProc(hwnd, umsg, wParam, lParam);
// never send
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_KEYDOWN:
case WM_KEYUP:
return DefWindowProc(hwnd, umsg, wParam, lParam);
// -------------------------------------------------
case WM_CREATE:
return MsgCreate(hwnd, wParam, lParam);
@ -1719,7 +1692,7 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
}
return DefWindowProc(hwnd, umsg, wParam, lParam);
}
return 0; // 0 = swallow message
return 0;
}
@ -2166,25 +2139,29 @@ bool SelectExternalToolBar(HWND hwnd)
StringCchCopy(szFile, COUNTOF(szFile), s_tchToolbarBitmap);
PathRemoveExtension(szFile);
StringCchCat(szFile, COUNTOF(szFile), L"Hot.bmp");
if (PathIsExistingFile(szFile)) {
PathRelativeToApp(szFile, s_tchToolbarBitmapHot, COUNTOF(s_tchToolbarBitmapHot), true, true, true);
IniFileSetString(Globals.IniFile, L"Toolbar Images", L"BitmapHot", s_tchToolbarBitmapHot);
}
else {
StringCchCopy(s_tchToolbarBitmapHot, COUNTOF(s_tchToolbarBitmapHot), L"");
IniFileDelete(Globals.IniFile, L"Toolbar Images", L"BitmapHot", false);
if (Globals.bCanSaveIniFile) {
if (PathIsExistingFile(szFile)) {
PathRelativeToApp(szFile, s_tchToolbarBitmapHot, COUNTOF(s_tchToolbarBitmapHot), true, true, true);
IniFileSetString(Globals.IniFile, L"Toolbar Images", L"BitmapHot", s_tchToolbarBitmapHot);
}
else {
StringCchCopy(s_tchToolbarBitmapHot, COUNTOF(s_tchToolbarBitmapHot), L"");
IniFileDelete(Globals.IniFile, L"Toolbar Images", L"BitmapHot", false);
}
}
StringCchCopy(szFile, COUNTOF(szFile), s_tchToolbarBitmap);
PathRemoveExtension(szFile);
StringCchCat(szFile, COUNTOF(szFile), L"Disabled.bmp");
if (PathIsExistingFile(szFile)) {
PathRelativeToApp(szFile, s_tchToolbarBitmapDisabled, COUNTOF(s_tchToolbarBitmapDisabled), true, true, true);
IniFileSetString(Globals.IniFile, L"Toolbar Images", L"BitmapDisabled", s_tchToolbarBitmapDisabled);
}
else {
StringCchCopy(s_tchToolbarBitmapHot, COUNTOF(s_tchToolbarBitmapHot), L"");
IniFileDelete(Globals.IniFile, L"Toolbar Images", L"BitmapDisabled", false);
if (Globals.bCanSaveIniFile) {
if (PathIsExistingFile(szFile)) {
PathRelativeToApp(szFile, s_tchToolbarBitmapDisabled, COUNTOF(s_tchToolbarBitmapDisabled), true, true, true);
IniFileSetString(Globals.IniFile, L"Toolbar Images", L"BitmapDisabled", s_tchToolbarBitmapDisabled);
}
else {
StringCchCopy(s_tchToolbarBitmapHot, COUNTOF(s_tchToolbarBitmapHot), L"");
IniFileDelete(Globals.IniFile, L"Toolbar Images", L"BitmapDisabled", false);
}
}
Settings.ToolBarTheme = 2;
return true;
@ -3166,6 +3143,7 @@ LRESULT MsgInitMenu(HWND hwnd, WPARAM wParam, LPARAM lParam)
HMENU const hmenu = wParam ? (HMENU)wParam : GetMenu(hwnd);
if (!hmenu) { return 0; }
bool const sav = Globals.bCanSaveIniFile;
bool const ro = SciCall_GetReadOnly();
DocPos const iCurPos = SciCall_GetCurrentPos();
DocLn const iCurLine = SciCall_LineFromPosition(iCurPos);
@ -3456,12 +3434,12 @@ LRESULT MsgInitMenu(HWND hwnd, WPARAM wParam, LPARAM lParam)
CheckCmd(hmenu, IDM_VIEW_SCROLLPASTEOF, Settings.ScrollPastEOF);
CheckCmd(hmenu, IDM_VIEW_SHOW_HYPLNK_CALLTIP, Settings.ShowHypLnkToolTip);
bool b = Flags.bReuseWindow;
CheckCmd(hmenu, IDM_VIEW_REUSEWINDOW, b);
b = Flags.bSingleFileInstance;
CheckCmd(hmenu, IDM_VIEW_SINGLEFILEINSTANCE, b);
b = Flags.bStickyWindowPosition;
CheckCmd(hmenu, IDM_VIEW_STICKYWINPOS, b);
CheckCmd(hmenu, IDM_VIEW_REUSEWINDOW, Flags.bReuseWindow);
EnableCmd(hmenu, IDM_VIEW_REUSEWINDOW, sav);
CheckCmd(hmenu, IDM_VIEW_SINGLEFILEINSTANCE, Flags.bSingleFileInstance);
EnableCmd(hmenu, IDM_VIEW_SINGLEFILEINSTANCE, sav);
CheckCmd(hmenu, IDM_VIEW_STICKYWINPOS, Flags.bStickyWindowPosition);
EnableCmd(hmenu, IDM_VIEW_STICKYWINPOS, sav);
CheckCmd(hmenu, IDM_VIEW_ALWAYSONTOP, ((Settings.AlwaysOnTop || s_flagAlwaysOnTop == 2) && s_flagAlwaysOnTop != 1));
CheckCmd(hmenu, IDM_VIEW_MINTOTRAY, Settings.MinimizeToTray);
@ -3486,10 +3464,13 @@ LRESULT MsgInitMenu(HWND hwnd, WPARAM wParam, LPARAM lParam)
CheckCmd(hmenu, IDM_VIEW_SPLIT_UNDOTYPSEQ_LNBRK, Settings.SplitUndoTypingSeqOnLnBreak);
CheckCmd(hmenu, IDM_VIEW_NOSAVERECENT, Settings.SaveRecentFiles);
EnableCmd(hmenu, IDM_VIEW_NOSAVERECENT, sav);
CheckCmd(hmenu, IDM_VIEW_NOPRESERVECARET, Settings.PreserveCaretPos);
EnableCmd(hmenu, IDM_VIEW_NOPRESERVECARET, Settings.SaveRecentFiles);
EnableCmd(hmenu, IDM_VIEW_NOPRESERVECARET, Settings.SaveRecentFiles && sav);
CheckCmd(hmenu, IDM_VIEW_NOSAVEFINDREPL, Settings.SaveFindReplace);
EnableCmd(hmenu, IDM_VIEW_NOSAVEFINDREPL, sav);
CheckCmd(hmenu, IDM_VIEW_SAVEBEFORERUNNINGTOOLS, Settings.SaveBeforeRunningTools);
EnableCmd(hmenu, IDM_VIEW_SAVEBEFORERUNNINGTOOLS, sav);
CheckCmd(hmenu, IDM_VIEW_CHANGENOTIFY, Settings.FileWatchingMode);
@ -3699,8 +3680,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
InfoBoxLng(MB_ICONWARNING, NULL, IDS_MUI_READONLY_MODIFY, PathFindFileName(Globals.CurrentFile));
}
dwFileAttributes = GetFileAttributes(Globals.CurrentFile);
if (dwFileAttributes != INVALID_FILE_ATTRIBUTES)
s_bFileReadOnly = (dwFileAttributes & FILE_ATTRIBUTE_READONLY);
s_bFileReadOnly = (dwFileAttributes == INVALID_FILE_ATTRIBUTES) || (dwFileAttributes & FILE_ATTRIBUTE_READONLY);
UpdateToolbar();
}
@ -5375,7 +5355,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
case IDM_VIEW_STICKYWINPOS:
{
if (IsCmdEnabled(hwnd, IDM_VIEW_STICKYWINPOS)) {
Flags.bStickyWindowPosition = !Flags.bStickyWindowPosition; // toggle
if (Flags.bStickyWindowPosition) { InfoBoxLng(MB_OK, L"MsgStickyWinPos", IDS_MUI_STICKYWINPOS); }
@ -5399,23 +5379,27 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
case IDM_VIEW_REUSEWINDOW:
Flags.bReuseWindow = !Flags.bReuseWindow; // reverse
if (Flags.bReuseWindow != DefaultFlags.bReuseWindow) {
IniFileSetBool(Globals.IniFile, Constants.Settings2_Section, L"ReuseWindow", Flags.bReuseWindow);
}
else {
IniFileDelete(Globals.IniFile, Constants.Settings2_Section, L"ReuseWindow", false);
if (IsCmdEnabled(hwnd, IDM_VIEW_REUSEWINDOW)) {
Flags.bReuseWindow = !Flags.bReuseWindow; // reverse
if (Flags.bReuseWindow != DefaultFlags.bReuseWindow) {
IniFileSetBool(Globals.IniFile, Constants.Settings2_Section, L"ReuseWindow", Flags.bReuseWindow);
}
else {
IniFileDelete(Globals.IniFile, Constants.Settings2_Section, L"ReuseWindow", false);
}
}
break;
case IDM_VIEW_SINGLEFILEINSTANCE:
Flags.bSingleFileInstance = !Flags.bSingleFileInstance; // reverse
if (Flags.bSingleFileInstance != DefaultFlags.bSingleFileInstance) {
IniFileSetInt(Globals.IniFile, Constants.Settings2_Section, L"SingleFileInstance", Flags.bSingleFileInstance);
}
else {
IniFileDelete(Globals.IniFile, Constants.Settings2_Section, L"SingleFileInstance", false);
if (IsCmdEnabled(hwnd, IDM_VIEW_SINGLEFILEINSTANCE)) {
Flags.bSingleFileInstance = !Flags.bSingleFileInstance; // reverse
if (Flags.bSingleFileInstance != DefaultFlags.bSingleFileInstance) {
IniFileSetInt(Globals.IniFile, Constants.Settings2_Section, L"SingleFileInstance", Flags.bSingleFileInstance);
}
else {
IniFileDelete(Globals.IniFile, Constants.Settings2_Section, L"SingleFileInstance", false);
}
}
break;
@ -5543,9 +5527,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
if (IsCmdEnabled(hwnd, IDM_VIEW_SAVESETTINGSNOW)) {
bool bCreateFailure = false;
if (StrIsEmpty(Globals.IniFile)) {
if (StrIsNotEmpty(Globals.IniFileDefault)) {
StringCchCopy(Globals.IniFile, COUNTOF(Globals.IniFile), Globals.IniFileDefault);
if (CreateIniFile(Globals.IniFile, NULL)) {
@ -6123,7 +6105,9 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
WININFO const wi = GetMyWindowPlacement(Globals.hwndMain, NULL);
WCHAR tchDefWinPos[80];
StringCchPrintf(tchDefWinPos, COUNTOF(tchDefWinPos), L"%i,%i,%i,%i,%i", wi.x, wi.y, wi.cx, wi.cy, wi.max);
IniFileSetString(Globals.IniFile, Constants.Settings2_Section, L"DefaultWindowPosition", tchDefWinPos);
if (Globals.bCanSaveIniFile) {
IniFileSetString(Globals.IniFile, Constants.Settings2_Section, L"DefaultWindowPosition", tchDefWinPos);
}
g_DefWinInfo = GetWinInfoByFlag(-1); // use current win pos as new default
}
break;
@ -8862,7 +8846,7 @@ void UpdateMarginWidth()
void UpdateSaveSettingsCmds()
{
CheckCmd(Globals.hMainMenu, IDM_VIEW_SAVESETTINGS, Settings.SaveSettings && !Flags.bSettingsFileSoftLocked);
EnableCmd(Globals.hMainMenu, IDM_VIEW_SAVESETTINGS, StrIsNotEmpty(Globals.IniFile) && !Flags.bSettingsFileSoftLocked);
EnableCmd(Globals.hMainMenu, IDM_VIEW_SAVESETTINGS, Globals.bCanSaveIniFile && !Flags.bSettingsFileSoftLocked);
EnableCmd(Globals.hMainMenu, IDM_VIEW_SAVESETTINGSNOW, (StrIsNotEmpty(Globals.IniFile) || StrIsNotEmpty(Globals.IniFileDefault)) && !Flags.bSettingsFileSoftLocked);
EnableCmd(Globals.hMainMenu, CMD_OPENINIFILE, StrIsNotEmpty(Globals.IniFile) && !Flags.bSettingsFileSoftLocked);
}
@ -9334,7 +9318,7 @@ bool FileIO(bool fLoad,LPWSTR pszFileName,
}
DWORD const dwFileAttributes = GetFileAttributes(pszFileName);
s_bFileReadOnly = ((dwFileAttributes != INVALID_FILE_ATTRIBUTES) && (dwFileAttributes & FILE_ATTRIBUTE_READONLY));
s_bFileReadOnly = ((dwFileAttributes == INVALID_FILE_ATTRIBUTES) || (dwFileAttributes & FILE_ATTRIBUTE_READONLY));
EndWaitCursor();
@ -9939,9 +9923,8 @@ bool FileSave(bool bSaveAlways, bool bAsk, bool bSaveAs, bool bSaveCopy, bool bP
// Read only...
if (!bSaveAs && !bSaveCopy && StrIsNotEmpty(Globals.CurrentFile))
{
DWORD dwFileAttributes = GetFileAttributes(Globals.CurrentFile);
if (dwFileAttributes != INVALID_FILE_ATTRIBUTES)
s_bFileReadOnly = (dwFileAttributes & FILE_ATTRIBUTE_READONLY);
DWORD const dwFileAttributes = GetFileAttributes(Globals.CurrentFile);
s_bFileReadOnly = (dwFileAttributes == INVALID_FILE_ATTRIBUTES) || (dwFileAttributes & FILE_ATTRIBUTE_READONLY);
if (s_bFileReadOnly) {
INT_PTR const answer = InfoBoxLng(MB_YESNO | MB_ICONWARNING, NULL, IDS_MUI_READONLY_SAVE, PathFindFileName(Globals.CurrentFile));
if ((IDOK == answer) || (IDYES == answer)) {

View File

@ -434,7 +434,12 @@
<ClCompile Include="..\uchardet\uchardet\src\nsUniversalDetector.cpp" />
<ClCompile Include="..\uchardet\uchardet\src\nsUTF8Prober.cpp" />
<ClCompile Include="..\uchardet\uchardet\src\uchardet.cpp" />
<ClCompile Include="AccelKeys.c" />
<ClCompile Include="AccelKeys.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="Config\Config.cpp" />
<ClCompile Include="Dialogs.c" />
<ClCompile Include="Dlapi.c" />
@ -545,7 +550,12 @@
<ClInclude Include="..\uthash\utringbuffer.h" />
<ClInclude Include="..\uthash\utstack.h" />
<ClInclude Include="..\uthash\utstring.h" />
<ClInclude Include="AccelKeys.h" />
<ClInclude Include="AccelKeys.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="Config\Config.h" />
<ClInclude Include="Config\SimpleIni.h" />
<ClInclude Include="Dialogs.h" />

View File

@ -174,8 +174,6 @@ static void _FillThemesMenuTable()
{
Theme_Files[0].rid = IDM_THEMES_DEFAULT; // factory default
Theme_Files[1].rid = IDM_THEMES_FILE_ITEM; // NP3.ini settings
// names are filled by Style_InsertThemesMenu()
StringCchCopy(Theme_Files[1].szFilePath, COUNTOF(Theme_Files[1].szFilePath), Globals.IniFile);
unsigned iTheme = 1; // Standard
@ -183,6 +181,8 @@ static void _FillThemesMenuTable()
// find "themes" sub-dir (side-by-side to Notepad3.ini)
if (StrIsNotEmpty(Globals.IniFile)) {
StringCchCopy(tchThemeDir, COUNTOF(tchThemeDir), Globals.IniFile);
// names are filled by Style_InsertThemesMenu()
StringCchCopy(Theme_Files[iTheme].szFilePath, COUNTOF(Theme_Files[iTheme].szFilePath), Globals.IniFile);
}
else if (StrIsNotEmpty(Globals.IniFileDefault)) {
StringCchCopy(tchThemeDir, COUNTOF(tchThemeDir), Globals.IniFileDefault);
@ -232,16 +232,6 @@ static void _FillThemesMenuTable()
//=============================================================================
//
// Style_SetIniFile()
//
void Style_SetIniFile(LPCWSTR szIniFile)
{
StringCchCopy(Theme_Files[1].szFilePath, COUNTOF(Theme_Files[1].szFilePath), szIniFile);
_FillThemesMenuTable();
}
//=============================================================================
//
@ -484,8 +474,6 @@ void Style_Load()
_FillThemesMenuTable();
// get theme name from settings
unsigned iTheme = 1;
if (StrIsNotEmpty(Globals.SelectedThemeName)) {
for (; iTheme < ThemeItems_CountOf(); ++iTheme)

View File

@ -39,7 +39,6 @@ void Style_ToIniSection(bool bForceAll, bool bIsStdIniFile);
bool Style_ExportToFile(const WCHAR* szFile, bool bForceAll);
unsigned ThemeItems_CountOf();
void Style_SetIniFile(LPCWSTR szIniFile);
bool Style_InsertThemesMenu(HMENU hMenuBar);
void Style_DynamicThemesMenuCmd(int cmd);

View File

@ -293,6 +293,7 @@ typedef struct _globals_t
HINSTANCE hInstance;
HINSTANCE hPrevInst;
HINSTANCE hLngResContainer;
bool bCanSaveIniFile;
int iAvailLngCount;
bool bPrefLngNotAvail;
HWND hwndMain;