diff --git a/Versions/build.txt b/Versions/build.txt
index 47fe54a35..14057d17e 100644
--- a/Versions/build.txt
+++ b/Versions/build.txt
@@ -1 +1 @@
-2685
+2686
diff --git a/minipath/src/minipath.c b/minipath/src/minipath.c
index 6552a9982..24c80da81 100644
--- a/minipath/src/minipath.c
+++ b/minipath/src/minipath.c
@@ -191,15 +191,16 @@ static HMODULE __fastcall _LoadLanguageResources(const WCHAR* localeName, LANGID
StringCchCopyW(tchAvailLngs, 512, g_tchAvailableLanguages);
WCHAR tchUserLangMultiStrg[512] = { L'\0' };
if (!_LngStrToMultiLngStr(tchAvailLngs, tchUserLangMultiStrg, 512)) {
- GetLastErrorToMsgBox(L"_LngStrToMultiLngStr()", ERROR_MUI_INVALID_LOCALE_NAME);
+ GetLastErrorToMsgBox(L"Trying to load Language resource!", ERROR_MUI_INVALID_LOCALE_NAME);
return NULL;
}
// set the appropriate fallback list
DWORD langCount = 0;
// using SetProcessPreferredUILanguages is recommended for new applications (esp. multi-threaded applications)
- if (!SetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, tchUserLangMultiStrg, &langCount) || (langCount == 0)) {
- GetLastErrorToMsgBox(L"SetProcessPreferredUILanguages()", 0);
+ if (!SetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, tchUserLangMultiStrg, &langCount) || (langCount == 0))
+ {
+ GetLastErrorToMsgBox(L"Trying to set preferred Language!", ERROR_RESOURCE_LANG_NOT_FOUND);
return NULL;
}
SetThreadUILanguage(langID);
diff --git a/res/Notepad3.exe.manifest.conf b/res/Notepad3.exe.manifest.conf
index a6349de34..a681a8bd9 100644
--- a/res/Notepad3.exe.manifest.conf
+++ b/res/Notepad3.exe.manifest.conf
@@ -3,7 +3,7 @@
Notepad3 BETA
diff --git a/src/Dialogs.c b/src/Dialogs.c
index beab2c6a9..c31940fcc 100644
--- a/src/Dialogs.c
+++ b/src/Dialogs.c
@@ -140,9 +140,9 @@ int MessageBoxLng(HWND hwnd, UINT uType, UINT uidMsg, ...)
//=============================================================================
//
-// GetLastErrorToMsgBox()
+// MsgBoxLastError()
//
-DWORD GetLastErrorToMsgBox(LPWSTR lpszFunction, DWORD dwErrID)
+DWORD MsgBoxLastError(LPCWSTR lpszMessage, DWORD dwErrID)
{
// Retrieve the system error message for the last-error code
if (!dwErrID) {
@@ -162,12 +162,12 @@ DWORD GetLastErrorToMsgBox(LPWSTR lpszFunction, DWORD dwErrID)
if (lpMsgBuf) {
// Display the error message and exit the process
- size_t const len = StringCchLenW((LPCWSTR)lpMsgBuf, 0) + StringCchLenW((LPCWSTR)lpszFunction, 0) + 80;
+ size_t const len = StringCchLenW((LPCWSTR)lpMsgBuf, 0) + StringCchLenW(lpszMessage, 0) + 80;
LPWSTR lpDisplayBuf = (LPWSTR)AllocMem(len * sizeof(WCHAR), HEAP_ZERO_MEMORY);
if (lpDisplayBuf) {
StringCchPrintf(lpDisplayBuf, len, L"Error: '%s' failed with error id %d:\n%s.\n",
- lpszFunction, dwErrID, (LPCWSTR)lpMsgBuf);
+ lpszMessage, dwErrID, (LPCWSTR)lpMsgBuf);
// center message box to main
HWND focus = GetFocus();
@@ -197,7 +197,6 @@ typedef struct _infbox {
bool bDisableCheckBox;
} INFOBOXLNG, *LPINFOBOXLNG;
-
static INT_PTR CALLBACK _InfoBoxLngDlgProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
{
switch (umsg)
@@ -221,6 +220,9 @@ static INT_PTR CALLBACK _InfoBoxLngDlgProc(HWND hwnd, UINT umsg, WPARAM wParam,
case MB_ICONERROR: // = MB_ICONSTOP, MB_ICONHAND
SendDlgItemMessage(hwnd, IDC_INFOBOXICON, STM_SETICON, (WPARAM)Globals.hIconMsgError, 0);
break;
+ case MB_ICONSHIELD:
+ SendDlgItemMessage(hwnd, IDC_INFOBOXICON, STM_SETICON, (WPARAM)Globals.hIconMsgShield, 0);
+ break;
case MB_USERICON:
SendDlgItemMessage(hwnd, IDC_INFOBOXICON, STM_SETICON, (WPARAM)Globals.hIcon48, 0);
break;
@@ -293,6 +295,7 @@ static INT_PTR CALLBACK _InfoBoxLngDlgProc(HWND hwnd, UINT umsg, WPARAM wParam,
// InfoBoxLng()
//
//
+
INT_PTR InfoBoxLng(UINT uType, LPCWSTR lpstrSetting, UINT uidMsg, ...)
{
int const iMode = StrIsEmpty(lpstrSetting) ? 0 : IniFileGetInt(Globals.IniFile, Constants.SectionSuppressedMessages, lpstrSetting, 0);
diff --git a/src/Dialogs.h b/src/Dialogs.h
index a4702c5cf..7493147dd 100644
--- a/src/Dialogs.h
+++ b/src/Dialogs.h
@@ -51,7 +51,7 @@ void DialogAdminExe(HWND hwnd,bool);
int MessageBoxLng(HWND hwnd, UINT uType, UINT uIdMsg, ...);
INT_PTR InfoBoxLng(UINT uType, LPCWSTR lpstrSetting, UINT uidMessage, ...);
-DWORD GetLastErrorToMsgBox(LPWSTR lpszFunction, DWORD dwErrID);
+DWORD MsgBoxLastError(LPCWSTR lpszMessage, DWORD dwErrID);
bool SetWindowTitle(HWND hwnd, UINT uIDAppName, bool, UINT uIDUntitled, LPCWSTR lpszFile, int iFormat, bool, UINT uIDReadOnly, bool, LPCWSTR lpszExcerpt);
void SetAdditionalTitleInfo(LPCWSTR lpszAddTitleInfo);
diff --git a/src/Helpers.c b/src/Helpers.c
index 717dec9d5..18b76834f 100644
--- a/src/Helpers.c
+++ b/src/Helpers.c
@@ -28,6 +28,7 @@
#include "Encoding.h"
#include "MuiLanguage.h"
#include "Notepad3.h"
+#include "Dialogs.h"
#include "Config/Config.h"
#include "Scintilla.h"
@@ -212,26 +213,26 @@ void GetWinVersionString(LPWSTR szVersionStr, size_t cchVersionStr)
{
StringCchCopy(szVersionStr, cchVersionStr, L"OS Version: Windows ");
- if (IsWin10()) {
+ if (IsWin10OrHigher()) {
StringCchCat(szVersionStr, cchVersionStr, IsWinServer() ? L"Server 2016 " : L"10 ");
}
- else if (IsWin81()) {
+ else if (IsWin81OrHigher()) {
StringCchCat(szVersionStr, cchVersionStr, IsWinServer() ? L"Server 2012 R2 " : L"8.1");
}
- else if (IsWin8()) {
+ else if (IsWin8OrHigher()) {
StringCchCat(szVersionStr, cchVersionStr, IsWinServer() ? L"Server 2012 " : L"8");
}
- else if (IsWin71()) {
+ else if (IsWin71OrHigher()) {
StringCchCat(szVersionStr, cchVersionStr, IsWinServer() ? L"Server 2008 R2 " : L"7 (SP1)");
}
- else if (IsWin7()) {
+ else if (IsWin7OrHigher()) {
StringCchCat(szVersionStr, cchVersionStr, IsWinServer() ? L"Server 2008 " : L"7");
}
else {
StringCchCat(szVersionStr, cchVersionStr, IsWinServer() ? L"Unkown Server " : L"?");
}
- if (IsWin10()) {
+ if (IsWin10OrHigher()) {
WCHAR win10ver[80] = { L'\0' };
if (s_OSversion.dwOSVersionInfoSize == 0) { _GetTrueWindowsVersion(); }
DWORD const build = s_OSversion.dwBuildNumber;
@@ -267,6 +268,55 @@ bool SetClipboardTextW(HWND hwnd, LPCWSTR pszTextW, size_t cchTextW)
}
+//=============================================================================
+//
+// ConvertIconToBitmap()
+//
+HBITMAP ConvertIconToBitmap(const HICON hIcon, const int cx, const int cy)
+{
+ const HDC hScreenDC = GetDC(NULL);
+ const HBITMAP hbmpTmp = CreateCompatibleBitmap(hScreenDC, cx, cy);
+ const HDC hMemDC = CreateCompatibleDC(hScreenDC);
+ const HBITMAP hOldBmp = SelectObject(hMemDC, hbmpTmp);
+ DrawIconEx(hMemDC, 0, 0, hIcon, cx, cy, 0, NULL, DI_NORMAL);
+ SelectObject(hMemDC, hOldBmp);
+
+ const HBITMAP hDibBmp = (HBITMAP)CopyImage((HANDLE)hbmpTmp, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
+
+ DeleteObject(hbmpTmp);
+ DeleteDC(hMemDC);
+ ReleaseDC(NULL, hScreenDC);
+
+ return hDibBmp;
+}
+
+
+//=============================================================================
+//
+// SetUACIcon()
+//
+void SetUACIcon(const HMENU hMenu, const UINT nItem)
+{
+ static bool bInitialized = false;
+ if (bInitialized) { return; }
+
+ //const int cx = GetSystemMetrics(SM_CYMENU) - 4;
+ //const int cy = cx;
+ int const cx = GetSystemMetrics(SM_CXSMICON);
+ int const cy = GetSystemMetrics(SM_CYSMICON);
+
+ if (Globals.hIconMsgShieldSmall)
+ {
+ MENUITEMINFO mii = { 0 };
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_BITMAP;
+ mii.hbmpItem = ConvertIconToBitmap(Globals.hIconMsgShieldSmall, cx, cy);
+ SetMenuItemInfo(hMenu, nItem, FALSE, &mii);
+ }
+ bInitialized = true;
+}
+
+
//=============================================================================
//
// GetCurrentDPI()
@@ -275,7 +325,7 @@ DPI_T GetCurrentDPI(HWND hwnd) {
DPI_T curDPI = { 0, 0 };
- if (IsWin10()) {
+ if (IsWin10OrHigher()) {
HMODULE const hModule = GetModuleHandle(L"user32.dll");
if (hModule) {
FARPROC const pfnGetDpiForWindow = GetProcAddress(hModule, "GetDpiForWindow");
@@ -285,7 +335,7 @@ DPI_T GetCurrentDPI(HWND hwnd) {
}
}
- if ((curDPI.x == 0) && IsWin81()) {
+ if ((curDPI.x == 0) && IsWin81OrHigher()) {
HMODULE hShcore = LoadLibrary(L"shcore.dll");
if (hShcore) {
FARPROC const pfnGetDpiForMonitor = GetProcAddress(hShcore, "GetDpiForMonitor");
@@ -420,36 +470,67 @@ HRESULT PrivateSetCurrentProcessExplicitAppUserModelID(PCWSTR AppID)
//=============================================================================
//
-// IsElevated()
+// IsProcessElevated()
//
-bool IsElevated() {
+// PURPOSE: The function gets the elevation information of the current
+// process. It dictates whether the process is elevated or not. Token
+// elevation is only available on Windows Vista and newer operating
+// systems, thus IsProcessElevated throws a C++ exception if it is called
+// on systems prior to Windows Vista. It is not appropriate to use this
+// function to determine whether a process is run as administartor.
+//
+// RETURN VALUE: Returns TRUE if the process is elevated. Returns FALSE if
+// it is not.
+//
+// NOTE: TOKEN_INFORMATION_CLASS provides TokenElevationType to check the
+// elevation type (TokenElevationTypeDefault / TokenElevationTypeLimited /
+// TokenElevationTypeFull) of the process. It is different from
+// TokenElevation in that, when UAC is turned off, elevation type always
+// returns TokenElevationTypeDefault even though the process is elevated
+// (Integrity Level == High). In other words, it is not safe to say if the
+// process is elevated based on elevation type. Instead, we should use
+// TokenElevation.
+//
+bool IsProcessElevated() {
+
+ // When the process is run on operating systems prior to Windows
+ // Vista, GetTokenInformation returns FALSE with the
+ // ERROR_INVALID_PARAMETER error code because TokenElevation is
+ // not supported on those operating systems.
+ if (!IsVistaOrHigher()) { return false; }
bool bIsElevated = false;
HANDLE hToken = NULL;
+ Globals.dwLastError = ERROR_SUCCESS;
- if (!IsVista())
- return false;
-
- if (OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&hToken)) {
-
- TOKEN_ELEVATION te;
+ if (OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&hToken))
+ {
+ TOKEN_ELEVATION elevationToken;
DWORD expectedRetVal = sizeof(TOKEN_ELEVATION);
DWORD dwReturnLength = 0;
- if (GetTokenInformation(hToken,TokenElevation,&te,expectedRetVal,&dwReturnLength)) {
- if (dwReturnLength == expectedRetVal)
- bIsElevated = (bool)te.TokenIsElevated;
+ if (GetTokenInformation(hToken,TokenElevation,&elevationToken,expectedRetVal,&dwReturnLength))
+ {
+ if (dwReturnLength == expectedRetVal) {
+ bIsElevated = elevationToken.TokenIsElevated;
+ }
}
- if (hToken)
+ if (hToken) {
CloseHandle(hToken);
+ hToken = NULL;
+ }
+ }
+ else {
+ Globals.dwLastError = GetLastError();
+ //GetLastErrorToMessageBox(L"IsProcessElevated()", Globals.dwLastError);
}
return bIsElevated;
}
-
+#if 0
//=============================================================================
//
-// IsUserAdmin()
+// IsUserInAdminGroup()
//
// Routine Description: This routine returns true if the caller's
// process is a member of the Administrators local group. Caller is NOT
@@ -460,7 +541,8 @@ bool IsElevated() {
// true - Caller has Administrators local group.
// false - Caller does not have Administrators local group. --
//
-bool IsUserAdmin()
+
+bool IsUserInAdminGroup()
{
PSID AdminGroup;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
@@ -473,6 +555,175 @@ bool IsUserAdmin()
}
return(bIsAdmin);
}
+#endif
+
+//=============================================================================
+//
+// IsUserInAdminGroup()
+//
+// PURPOSE: The function checks whether the primary access token of the
+// process belongs to user account that is a member of the local
+// Administrators group, even if it currently is not elevated.
+//
+// RETURN VALUE: Returns TRUE if the primary access token of the process
+// belongs to user account that is a member of the local Administrators
+// group. Returns FALSE if the token does not.
+//
+//
+//
+bool IsUserInAdminGroup()
+{
+ BOOL fInAdminGroup = FALSE;
+ HANDLE hToken = NULL;
+ HANDLE hTokenToCheck = NULL;
+
+ Globals.dwLastError = ERROR_SUCCESS;
+ const WCHAR* pLastErrMsg = L"";
+
+ do {
+ // Open the primary access token of the process for query and duplicate.
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &hToken))
+ {
+ Globals.dwLastError = GetLastError();
+ pLastErrMsg = L"OpenProcessToken()";
+ break;
+ }
+
+ DWORD cbSize = 0;
+
+ // Determine token type: limited, elevated, or default.
+ TOKEN_ELEVATION_TYPE elevType;
+ if (!GetTokenInformation(hToken, TokenElevationType, &elevType, sizeof(elevType), &cbSize))
+ {
+ Globals.dwLastError = GetLastError();
+ pLastErrMsg = L"GetTokenInformation()";
+ break;
+ }
+
+ // If limited, get the linked elevated token for further check.
+ if (TokenElevationTypeLimited == elevType)
+ {
+ if (!GetTokenInformation(hToken, TokenLinkedToken, &hTokenToCheck, sizeof(hTokenToCheck), &cbSize))
+ {
+ Globals.dwLastError = GetLastError();
+ pLastErrMsg = L"GetTokenInformation()";
+ break;
+ }
+ }
+
+ // CheckTokenMembership requires an impersonation token. If we just got a
+ // linked token, it already is an impersonation token. If we did not get
+ // a linked token, duplicate the original into an impersonation token for
+ // CheckTokenMembership.
+ if (!hTokenToCheck)
+ {
+ if (!DuplicateToken(hToken, SecurityIdentification, &hTokenToCheck))
+ {
+ Globals.dwLastError = GetLastError();
+ pLastErrMsg = L"DuplicateToken()";
+ break;
+ }
+ }
+
+ // Create the SID corresponding to the Administrators group.
+ BYTE adminSID[SECURITY_MAX_SID_SIZE];
+ cbSize = sizeof(adminSID);
+ if (!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &adminSID, &cbSize))
+ {
+ Globals.dwLastError = GetLastError();
+ pLastErrMsg = L"CreateWellKnownSid()";
+ break;
+ }
+
+ // Check if the token to be checked contains admin SID.
+ // http://msdn.microsoft.com/en-us/library/aa379596(VS.85).aspx:
+ // To determine whether a SID is enabled in a token, that is, whether it
+ // has the SE_GROUP_ENABLED attribute, call CheckTokenMembership.
+ if (!CheckTokenMembership(hTokenToCheck, &adminSID, &fInAdminGroup))
+ {
+ Globals.dwLastError = GetLastError();
+ pLastErrMsg = L"CheckTokenMembership()";
+ break;
+ }
+
+ } while (false); // Centralized cleanup for all allocated resources.
+
+ if (hToken)
+ {
+ CloseHandle(hToken);
+ hToken = NULL;
+ }
+ if (hTokenToCheck)
+ {
+ CloseHandle(hTokenToCheck);
+ hTokenToCheck = NULL;
+ }
+
+ if (Globals.dwLastError != ERROR_SUCCESS) {
+ MsgBoxLastError(pLastErrMsg, Globals.dwLastError);
+ }
+
+ return fInAdminGroup;
+}
+
+
+//=============================================================================
+//
+// IsRunAsAdmin()
+//
+// PURPOSE: The function checks whether the current process is run as
+// administrator. In other words, it dictates whether the primary access
+// token of the process belongs to user account that is a member of the
+// local Administrators group and it is elevated.
+//
+// RETURN VALUE: Returns TRUE if the primary access token of the process
+// belongs to user account that is a member of the local Administrators
+// group and it is elevated. Returns FALSE if the token does not.
+//
+bool IsRunAsAdmin()
+{
+ BOOL fIsRunAsAdmin = FALSE;
+ PSID pAdministratorsGroup = NULL;
+
+ Globals.dwLastError = ERROR_SUCCESS;
+ const WCHAR* pLastErrMsg = L"";
+
+ do {
+ // Allocate and initialize a SID of the administrators group.
+ SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
+ if (!AllocateAndInitializeSid(
+ &NtAuthority,
+ 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0,
+ &pAdministratorsGroup))
+ {
+ Globals.dwLastError = GetLastError();
+ pLastErrMsg = L"AllocateAndInitializeSid()";
+ break;
+ }
+
+ // Determine whether the SID of administrators group is enabled in
+ // the primary access token of the process.
+ if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin))
+ {
+ Globals.dwLastError = GetLastError();
+ pLastErrMsg = L"CheckTokenMembership()";
+ break;
+ }
+
+ } while (false); // Centralized cleanup for all allocated resources.
+
+ // Centralized cleanup for all allocated resources.
+ if (pAdministratorsGroup)
+ {
+ FreeSid(pAdministratorsGroup);
+ pAdministratorsGroup = NULL;
+ }
+
+ return (bool)fIsRunAsAdmin;
+}
@@ -484,7 +735,7 @@ bool IsUserAdmin()
//{
// FARPROC pfnSetWindowTheme;
//
-// if (IsVista()) {
+// if (IsVistaOrHigher()) {
// if (hLocalModUxTheme) {
// pfnSetWindowTheme = GetProcAddress(hLocalModUxTheme,"SetWindowTheme");
//
diff --git a/src/Helpers.h b/src/Helpers.h
index bd7dc8576..e6a60bb2b 100644
--- a/src/Helpers.h
+++ b/src/Helpers.h
@@ -175,28 +175,28 @@ inline COLORREF GetBackgroundColor(HWND hwnd) { return GetBkColor(GetDC(hwnd));
// ----------------------------------------------------------------------------
//#define Is2k() (g_uWinVer >= 0x0500)
-#define IsXP() IsWindowsXPOrGreater() // Indicates if the current OS version matches,or is greater than,the Windows XP version.
-#define IsXP1() IsWindowsXPSP1OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows XP with Service Pack 1 (SP1)version.
-#define IsXP2() IsWindowsXPSP2OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows XP with Service Pack 2 (SP2)version.
-#define IsXP3() IsWindowsXPSP3OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows XP with Service Pack 3 (SP3)version.
+#define IsXPOrHigher() IsWindowsXPOrGreater() // Indicates if the current OS version matches,or is greater than,the Windows XP version.
+#define IsXP1OrHigher() IsWindowsXPSP1OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows XP with Service Pack 1 (SP1)version.
+#define IsXP2OrHigher() IsWindowsXPSP2OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows XP with Service Pack 2 (SP2)version.
+#define IsXP3OrHigher() IsWindowsXPSP3OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows XP with Service Pack 3 (SP3)version.
-#define IsVista() IsWindowsVistaOrGreater() // Indicates if the current OS version matches,or is greater than,the Windows Vista version.
-#define IsVista1() IsWindowsVistaSP1OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows Vista with Service Pack 1 (SP1)version.
-#define IsVista2() IsWindowsVistaSP2OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows Vista with Service Pack 2 (SP2)version.
+#define IsVistaOrHigher() IsWindowsVistaOrGreater() // Indicates if the current OS version matches,or is greater than,the Windows Vista version.
+#define IsVista1OrHigher() IsWindowsVistaSP1OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows Vista with Service Pack 1 (SP1)version.
+#define IsVista2OrHigher() IsWindowsVistaSP2OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows Vista with Service Pack 2 (SP2)version.
-#define IsWin7() IsWindows7OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows 7 version.
-#define IsWin71() IsWindows7SP1OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows 7 with Service Pack 1 (SP1)version.
-#define IsWin8() IsWindows8OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows 8 version.
-#define IsWin81() IsWindows8Point1OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows 8.1 version.
- // For Windows 10,IsWindows8Point1OrGreater returns false unless the application contains a manifest that includes
- // a compatibility section that contains the GUIDs that designate Windows 8.1 and/or Windows 10.
+#define IsWin7OrHigher() IsWindows7OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows 7 version.
+#define IsWin71OrHigher() IsWindows7SP1OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows 7 with Service Pack 1 (SP1)version.
+#define IsWin8OrHigher() IsWindows8OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows 8 version.
+#define IsWin81OrHigher() IsWindows8Point1OrGreater() // Indicates if the current OS version matches,or is greater than,the Windows 8.1 version.
+ // For Windows 10,IsWindows8Point1OrGreater returns false unless the application contains a manifest that includes
+ // a compatibility section that contains the GUIDs that designate Windows 8.1 and/or Windows 10.
-#define IsWin10() IsWindows10OrGreater() // Indicates if the current OS version matches, or is greater than, the Windows 10 version.
- // For Windows 10,IsWindows10OrGreater returns false unless the application contains a manifest that includes
- // a compatibility section that contains the GUID that designates Windows 10.
+#define IsWin10OrHigher() IsWindows10OrGreater() // Indicates if the current OS version matches, or is greater than, the Windows 10 version.
+ // For Windows 10,IsWindows10OrGreater returns false unless the application contains a manifest that includes
+ // a compatibility section that contains the GUID that designates Windows 10.
-#define IsWinServer() IsWindowsServer() // Indicates if the current OS is a Windows Server release.
- // Applications that need to distinguish between server and client versions of Windows should call this function.
+#define IsWinServer() IsWindowsServer() // Indicates if the current OS is a Windows Server release.
+ // Applications that need to distinguish between server and client versions of Windows should call this function.
void GetWinVersionString(LPWSTR szVersionStr, size_t cchVersionStr);
@@ -209,6 +209,8 @@ void GetWinVersionString(LPWSTR szVersionStr, size_t cchVersionStr);
// ----------------------------------------------------------------------------
bool SetClipboardTextW(HWND hwnd, LPCWSTR pszTextW, size_t cchTextW);
+HBITMAP ConvertIconToBitmap(const HICON hIcon, const int cx, const int cy);
+void SetUACIcon(const HMENU hMenu, const UINT nItem);
// ----------------------------------------------------------------------------
@@ -253,8 +255,9 @@ inline float GetBaseFontSize(HWND hwnd) { return ((IsFullHD(hwnd, -1, -1) < 0) ?
// ----------------------------------------------------------------------------
HRESULT PrivateSetCurrentProcessExplicitAppUserModelID(PCWSTR AppID);
-bool IsElevated();
-bool IsUserAdmin();
+bool IsProcessElevated();
+bool IsUserInAdminGroup();
+bool IsRunAsAdmin();
//bool SetExplorerTheme(HWND);
@@ -277,13 +280,14 @@ inline bool IsButtonUnchecked(HWND hwnd, int iButtonID) { return (IsDlgButtonChe
#define EnableCmd(hmenu,id,b) EnableMenuItem((hmenu),(id),(b)?MF_BYCOMMAND|MF_ENABLED:MF_BYCOMMAND|MF_GRAYED)
#define CheckCmd(hmenu,id,b) CheckMenuItem((hmenu),(id),(b)?MF_BYCOMMAND|MF_CHECKED:MF_BYCOMMAND|MF_UNCHECKED)
-#define EnableTool(htbar,id,b) SendMessage(htbar,TB_ENABLEBUTTON,id, MAKELONG(((b) ? 1 : 0), 0))
-#define CheckTool(htbar,id,b) SendMessage(htbar,TB_CHECKBUTTON,id, MAKELONG((b),0))
+#define EnableTool(htbar,id,b) SendMessage((htbar),TB_ENABLEBUTTON,(id), MAKELONG(((b) ? 1 : 0), 0))
+#define CheckTool(htbar,id,b) SendMessage((htbar),TB_CHECKBUTTON,(id), MAKELONG((b),0))
#define EnableCmdPos(hmenu,pos,b) EnableMenuItem((hmenu),(pos),(b)?MF_BYPOSITION|MF_ENABLED:MF_BYPOSITION|MF_GRAYED)
#define CheckCmdPos(hmenu,pos,b) CheckMenuItem((hmenu),(pos),(b)?MF_BYPOSITION|MF_CHECKED:MF_BYPOSITION|MF_UNCHECKED)
+
bool GetKnownFolderPath(REFKNOWNFOLDERID, LPWSTR lpOutPath, size_t cchCount);
void PathRelativeToApp(LPWSTR lpszSrc,LPWSTR lpszDest,int cchDest,bool,bool,bool);
void PathAbsoluteFromApp(LPWSTR lpszSrc,LPWSTR lpszDest,int cchDest,bool);
diff --git a/src/MuiLanguage.c b/src/MuiLanguage.c
index b41d7e639..f18912393 100644
--- a/src/MuiLanguage.c
+++ b/src/MuiLanguage.c
@@ -241,13 +241,13 @@ LANGID LoadLanguageResources()
WCHAR tchUserLangMultiStrg[LARGE_BUFFER] = { L'\0' };
if (!_LngStrToMultiLngStr(tchAvailLngs, tchUserLangMultiStrg, COUNTOF(tchUserLangMultiStrg)))
{
- GetLastErrorToMsgBox(L"_LngStrToMultiLngStr()", ERROR_MUI_INVALID_LOCALE_NAME);
+ MsgBoxLastError(L"Trying to load Language resource!", ERROR_MUI_INVALID_LOCALE_NAME);
}
DWORD langCount = 0;
// using SetProcessPreferredUILanguages is recommended for new applications (esp. multi-threaded applications)
if (!SetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, tchUserLangMultiStrg, &langCount) || (langCount == 0))
{
- GetLastErrorToMsgBox(L"SetProcessPreferredUILanguages()", 0);
+ MsgBoxLastError(L"Trying to set preferred Language!", ERROR_RESOURCE_LANG_NOT_FOUND);
}
// obtains access to the proper resource container
@@ -266,7 +266,7 @@ LANGID LoadLanguageResources()
}
if (!_hLangResourceContainer) {
// fallback to ENGLISH_US
- //GetLastErrorToMsgBox(L"LoadMUILibrary", 0);
+ //MsgBoxLastError(L"LoadMUILibrary", 0);
Globals.bPrefLngNotAvail = (languageID != MUI_LanguageDLLs[0].LangId);
languageID = MUI_LanguageDLLs[0].LangId;
_hLangResourceContainer = Globals.hInstance;
diff --git a/src/Notepad3.c b/src/Notepad3.c
index 1b24a2723..b5754adc4 100644
--- a/src/Notepad3.c
+++ b/src/Notepad3.c
@@ -606,6 +606,9 @@ static void _SetSaveNeededFlag(const bool setSaveNeeded)
PostWMCommand(Globals.hwndDlgFindReplace, IDC_DOC_MODIFIED);
}
}
+ else {
+ Encoding_HasChanged(Encoding_Current(CPI_GET));
+ }
}
//==============================================================================
@@ -625,10 +628,11 @@ static void _InitGlobals()
Globals.pFileMRU = NULL;
Globals.pMRUfind = NULL;
Globals.pMRUreplace = NULL;
- Globals.CallTipType = CT_NONE;
Globals.uConsoleCodePage = 0;
Globals.iAvailLngCount = 1;
+ Globals.iPrefLANGID = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
Globals.iWrapCol = 0;
+ Globals.CallTipType = CT_NONE;
Globals.flagPosParam = false;
Globals.flagWindowPos = 0;
@@ -660,7 +664,7 @@ static void _InitGlobals()
Flags.RelativeFileMRU = DefaultFlags.RelativeFileMRU = true;
Flags.PortableMyDocs = DefaultFlags.PortableMyDocs = Flags.RelativeFileMRU;
Flags.NoFadeHidden = DefaultFlags.NoFadeHidden = false;
- Flags.ToolbarLook = DefaultFlags.ToolbarLook = IsXP() ? 1 : 2;
+ Flags.ToolbarLook = DefaultFlags.ToolbarLook = IsXPOrHigher() ? 1 : 2;
Flags.SimpleIndentGuides = DefaultFlags.SimpleIndentGuides = false;
Flags.NoHTMLGuess =DefaultFlags.NoHTMLGuess = false;
Flags.NoCGIGuess = DefaultFlags.NoCGIGuess = false;
@@ -812,13 +816,13 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
// check if running at least on Windows 7
- if (!IsWin7()) {
- GetLastErrorToMsgBox(L"WinMain", ERROR_OLD_WIN_VERSION);
+ if (!IsWin7OrHigher()) {
+ MsgBoxLastError(L"Application Initialization", ERROR_OLD_WIN_VERSION);
return 1; // exit
}
// Check if running with elevated privileges
- s_bIsElevated = IsUserAdmin() || IsElevated();
+ s_bIsElevated = IsUserInAdminGroup() || IsProcessElevated() || IsRunAsAdmin();
// Default Encodings (may already be used for command line parsing)
Encoding_InitDefaults();
@@ -905,12 +909,15 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
if (!Globals.hIconMsgQuest) {
LoadIconWithScaleDown(NULL, IDI_QUESTION, cxl, cyl, &(Globals.hIconMsgQuest));
}
+ if (!Globals.hIconMsgShieldSmall) {
+ LoadIconWithScaleDown(NULL, IDI_SHIELD, cxs, cys, &(Globals.hIconMsgShieldSmall));
+ }
if (!Globals.hIconMsgShield) {
LoadIconWithScaleDown(NULL, IDI_SHIELD, cxl, cyl, &(Globals.hIconMsgShield));
}
- if (!Globals.hIconMsgWinLogo) {
- LoadIconWithScaleDown(NULL, IDI_SHIELD, cxl, cyl, &(Globals.hIconMsgWinLogo));
- }
+ //if (!Globals.hIconMsgWinLogo) {
+ // LoadIconWithScaleDown(NULL, IDI_SHIELD, cxl, cyl, &(Globals.hIconMsgWinLogo));
+ //}
// Command Line Help Dialog
if (s_flagDisplayHelp) {
@@ -923,7 +930,7 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
Globals.hMainMenu = LoadMenu(Globals.hLngResContainer, MAKEINTRESOURCE(IDR_MUI_MAINMENU));
if (!Globals.hMainMenu) {
- GetLastErrorToMsgBox(L"LoadMenu()", 0);
+ MsgBoxLastError(L"LoadMenu()", 0);
_CleanUpResources(NULL, false);
return 1;
}
@@ -1796,7 +1803,7 @@ static void _SetWrapVisualFlags(HWND hwndEditCtrl)
//
static void _InitializeSciEditCtrl(HWND hwndEditCtrl)
{
- if (IsVista()) {
+ if (IsVistaOrHigher()) {
// Current platforms perform window buffering so it is almost always better for this option to be turned off.
// There are some older platforms and unusual modes where buffering may still be useful - so keep it ON
//~SciCall_SetBufferedDraw(true); // default is true
@@ -2037,7 +2044,7 @@ LRESULT MsgCreate(HWND hwnd, WPARAM wParam,LPARAM lParam)
SetWindowLongPtr(Globals.hwndEdit,GWL_EXSTYLE,GetWindowLongPtr(Globals.hwndEdit,GWL_EXSTYLE) & ~WS_EX_CLIENTEDGE);
SetWindowPos(Globals.hwndEdit,NULL,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED);
- if (IsVista()) {
+ if (IsVistaOrHigher()) {
s_cxEditFrame = 0;
s_cyEditFrame = 0;
}
@@ -2381,10 +2388,10 @@ void CreateBars(HWND hwnd, HINSTANCE hInstance)
if (Flags.ToolbarLook == 1) {
fProcessed = BitmapAlphaBlend(hbmpCopy, GetSysColor(COLOR_3DFACE), 0x60);
}
- else if (Flags.ToolbarLook == 2 || (!IsXP() && Flags.ToolbarLook == 0)) {
+ else if (Flags.ToolbarLook == 2 || (!IsXPOrHigher() && Flags.ToolbarLook == 0)) {
fProcessed = BitmapGrayScale(hbmpCopy);
}
- if (fProcessed && !IsXP()) {
+ if (fProcessed && !IsXPOrHigher()) {
BitmapMergeAlpha(hbmpCopy, GetSysColor(COLOR_3DFACE));
}
if (fProcessed) {
@@ -2619,7 +2626,7 @@ LRESULT MsgThemeChanged(HWND hwnd, WPARAM wParam ,LPARAM lParam)
SetWindowLongPtr(Globals.hwndEdit,GWL_EXSTYLE,GetWindowLongPtr(Globals.hwndEdit,GWL_EXSTYLE) & ~WS_EX_CLIENTEDGE);
SetWindowPos(Globals.hwndEdit,NULL,0,0,0,0,SWP_NOZORDER|SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE);
- if (IsVista()) {
+ if (IsVistaOrHigher()) {
s_cxEditFrame = 0;
s_cyEditFrame = 0;
}
@@ -3168,7 +3175,10 @@ LRESULT MsgInitMenu(HWND hwnd, WPARAM wParam, LPARAM lParam)
EnableCmd(hmenu, CMD_RECODEGB18030, cf);
EnableCmd(hmenu, IDM_FILE_LAUNCH, cf);
- EnableCmd(hmenu,IDM_FILE_LAUNCH_ELEVATED, !s_bIsElevated);
+ SetUACIcon(hmenu, IDM_FILE_LAUNCH_ELEVATED);
+ CheckCmd(hmenu, IDM_FILE_LAUNCH_ELEVATED, s_bIsElevated);
+ EnableCmd(hmenu, IDM_FILE_LAUNCH_ELEVATED, !s_bIsElevated);
+
EnableCmd(hmenu,IDM_FILE_LAUNCH,cf);
EnableCmd(hmenu,IDM_FILE_PROPERTIES,cf);
EnableCmd(hmenu,IDM_FILE_CREATELINK,cf);
@@ -3542,7 +3552,7 @@ static void _DynamicLanguageMenuCmd(int cmd)
Globals.iPrefLANGID = LoadLanguageResources();
Globals.hMainMenu = LoadMenu(Globals.hLngResContainer, MAKEINTRESOURCE(IDR_MUI_MAINMENU));
if (!Globals.hMainMenu) {
- GetLastErrorToMsgBox(L"LoadMenu()", 0);
+ MsgBoxLastError(L"LoadMenu()", 0);
CloseApplication();
return;
}
@@ -3752,7 +3762,8 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
fioStatus.iEncoding = Encoding_Current(CPI_GET);
fioStatus.iEOLMode = SciCall_GetEOLMode();
- if (DoElevatedRelaunch(&fioStatus, false)) {
+ if (DoElevatedRelaunch(&fioStatus, false))
+ {
CloseApplication();
}
else {
@@ -7787,7 +7798,7 @@ void ParseCommandLine()
lp1 + CSTRLEN(RELAUNCH_ELEVATED_BUF_ARG), len - CSTRLEN(RELAUNCH_ELEVATED_BUF_ARG));
TrimSpcW(s_wchTmpFilePath);
NormalizePathEx(s_wchTmpFilePath, COUNTOF(s_wchTmpFilePath), true, s_flagSearchPathIfRelative);
- s_bIsElevated = s_IsThisAnElevatedRelaunch = true;
+ s_bIsElevated = s_IsThisAnElevatedRelaunch = IsProcessElevated();
}
else {
@@ -9564,7 +9575,7 @@ bool FileLoad(bool bDontSave, bool bNew, bool bReload,
Style_SetDefaultLexer(Globals.hwndEdit);
s_bFileReadOnly = false;
- _SetSaveNeededFlag(false);
+ SciCall_SetSavePoint();
UpdateAllBars(false);
@@ -9960,7 +9971,7 @@ bool DoElevatedRelaunch(EditFileIOStatus* pFioStatus, bool bAutoSaveOnRelaunch)
if (RelaunchElevated(szArguments)) {
// set no change and quit
SciCall_SetSavePoint();
- _SetSaveNeededFlag(false);
+ //_SetSaveNeededFlag(false);
}
else {
Globals.dwLastError = GetLastError();
@@ -10118,7 +10129,7 @@ bool FileSave(bool bSaveAlways, bool bAsk, bool bSaveAs, bool bSaveCopy, bool bP
SHAddToRecentDocs(SHARD_PATHW, Globals.CurrentFile);
}
- _SetSaveNeededFlag(false);
+ SciCall_SetSavePoint();
// Install watching of the current file
if (bSaveAs && Settings.ResetFileWatching) {
@@ -10134,7 +10145,7 @@ bool FileSave(bool bSaveAlways, bool bAsk, bool bSaveAs, bool bSaveCopy, bool bP
{
if (!s_bIsElevated && (Globals.dwLastError == ERROR_ACCESS_DENIED))
{
- INT_PTR const answer = InfoBoxLng(MB_YESNO | MB_ICONWARNING, NULL, IDS_MUI_ERR_ACCESSDENIED, PathFindFileName(Globals.CurrentFile));
+ INT_PTR const answer = InfoBoxLng(MB_YESNO | MB_ICONSHIELD, NULL, IDS_MUI_ERR_ACCESSDENIED, PathFindFileName(Globals.CurrentFile));
if ((IDOK == answer) || (IDYES == answer)) {
if (DoElevatedRelaunch(&fioStatus, true))
{
@@ -10542,12 +10553,13 @@ bool RelaunchMultiInst() {
//
bool RelaunchElevated(LPWSTR lpNewCmdLnArgs)
{
- if (!IsVista() ||
- !s_flagDoRelaunchElevated ||
- s_bIsElevated || s_IsThisAnElevatedRelaunch ||
- s_flagDisplayHelp)
+ if (!IsVistaOrHigher() ||
+ !s_flagDoRelaunchElevated ||
+ s_bIsElevated ||
+ s_IsThisAnElevatedRelaunch ||
+ s_flagDisplayHelp)
{
- return false;
+ return false;
}
STARTUPINFO si;
diff --git a/src/TypeDefs.h b/src/TypeDefs.h
index 7a36fb0c8..032960903 100644
--- a/src/TypeDefs.h
+++ b/src/TypeDefs.h
@@ -155,6 +155,8 @@ typedef enum {
#define STATUSBAR_SECTION_WIDTH_SPECS L"30 20 20 20 20 20 0 0 0 0 0 0 20 20 20"
#define STAUSBAR_RIGHT_MARGIN 20
+#define MB_ICONSHIELD 0x000000B0L
+
// --------------------------------------------------------------------------
typedef enum { CT_NONE = 0, CT_ZOOM, CT_ZEROLEN_MATCH, CT_ENC_INFO, CT_DWELL } CALLTIPTYPE;
@@ -305,7 +307,8 @@ typedef struct _globals_t
HICON hIconMsgError;
HICON hIconMsgQuest;
HICON hIconMsgShield;
- HICON hIconMsgWinLogo;
+ HICON hIconMsgShieldSmall;
+ //HICON hIconMsgWinLogo;
HWND hwndDlgFindReplace;
HWND hwndDlgCustomizeSchemes;
int iDefaultCharSet;
diff --git a/src/VersionEx.h b/src/VersionEx.h
index 13aa563e4..02ac50012 100644
--- a/src/VersionEx.h
+++ b/src/VersionEx.h
@@ -8,8 +8,8 @@
#define SAPPNAME "Notepad3"
#define VERSION_MAJOR 5
#define VERSION_MINOR 19
-#define VERSION_REV 1122
-#define VERSION_BUILD 2685
+#define VERSION_REV 1123
+#define VERSION_BUILD 2686
#define SCINTILLA_VER 421
#define ONIGURUMA_REGEX_VER 6.9.4
#define UCHARDET_VER 2018.09.27