diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 000000000..f6b1819bc
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,94 @@
+name: Build
+
+permissions:
+ contents: read # Default to secure
+
+on:
+ pull_request:
+ branches:
+ - master
+ paths:
+ - 'Src/**'
+ - 'Localization/**'
+ - '.github/workflows/build.yml'
+
+ workflow_dispatch: # allows manual trigger for main/master
+
+jobs:
+ build:
+ runs-on: windows-2022
+ outputs:
+ new_version: ${{ steps.versioning.outputs.NEW_VERSION }}
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 0 # Essential to see all tags
+
+ - name: Prepare version
+ id: versioning
+ shell: pwsh
+ run: |
+ # Fetch latest tag
+ $latestTag = git describe --tags --abbrev=0 2>$null
+
+ if ($latestTag -notmatch '^v\d+\.\d+\.\d+$') {
+ Write-Error "Error: Could not find a valid vX.Y.Z tag in history. Found: '$latestTag'"
+ exit 1
+ }
+
+ # Parse and Increment
+ $version = [version]$latestTag.Substring(1)
+ $baseVersion = "$($version.Major).$($version.Minor).$($version.Build + 1)"
+
+ # Handle PR Suffix
+ if ("${{ github.event_name }}" -eq "pull_request") {
+ $shortSha = "${{ github.event.pull_request.head.sha }}".Substring(0, 7)
+ $finalVersion = "$baseVersion-pr-$shortSha"
+ } else {
+ $finalVersion = $baseVersion
+ }
+
+ # Export
+ "NEW_VERSION=$finalVersion" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
+ Write-Host "Building version: $finalVersion"
+
+ - name: Build
+ shell: cmd
+ env:
+ APPVEYOR_BUILD_VERSION: ${{ steps.versioning.outputs.NEW_VERSION }}
+ run: Src\Setup\__MakeFinal.bat
+
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: OpenShell
+ path: |
+ Src/Setup/Final/
+ !Src/Setup/Final/OpenShellLoc.zip
+
+ release:
+ if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/master' # Only manual master builds
+ needs: build
+ runs-on: ubuntu-latest # Cheaper/faster than windows for just uploading
+ permissions:
+ contents: write # Elevate permissions ONLY for this job
+ steps:
+ - name: Download artifacts
+ uses: actions/download-artifact@v8
+ with:
+ name: OpenShell
+
+ - name: Create GitHub Release
+ uses: softprops/action-gh-release@v3
+ with:
+ tag_name: v${{ needs.build.outputs.new_version }}
+ name: ${{ needs.build.outputs.new_version }}
+ generate_release_notes: true
+ prerelease: true
+ files: |
+ OpenShellSetup*.exe
+ OpenShellSymbols_*.7z
+ Utility.exe
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 283a3da2e..75591d3db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,12 +20,15 @@
# Build results
[Dd]ebug/
[Dd]ebug64/
+[Dd]ebugARM64/
[Dd]ebugPublic/
[Rr]elease/
[Rr]elease64/
+[Rr]eleaseARM64/
[Rr]eleases/
x64/
x86/
+ARM64/
bld/
[Bb]in/
[Oo]bj/
diff --git a/README.md b/README.md
index 76e3aa704..f05fed121 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ A collection of utilities bringing back classic features to Windows.
*Originally* **[Classic Shell](http://www.classicshell.net)** *by [Ivo Beltchev](https://sourceforge.net/u/ibeltchev/profile/)*
-[](https://github.com/Open-Shell/Open-Shell-Menu/releases/latest) [](https://github.com/Open-Shell/Open-Shell-Menu/releases) [](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master) [](https://gitq.com/passionate-coder/Classic-Start) [](https://gitter.im/open-shell/Lobby) [](https://discord.gg/7H6arr5)
+[](https://github.com/Open-Shell/Open-Shell-Menu/releases/latest) [](https://github.com/Open-Shell/Open-Shell-Menu/releases) [](https://github.com/Open-Shell/Open-Shell-Menu/actions/workflows/build.yml) [](https://ci.appveyor.com/project/passionate-coder/open-shell-menu/branch/master) [](https://gitq.com/passionate-coder/Classic-Start) [](https://gitter.im/open-shell/Lobby) [](https://discord.gg/7H6arr5)
[Open-Shell Homepage](https://open-shell.github.io/Open-Shell-Menu)
@@ -23,8 +23,11 @@ You can find the latest stable version here:
[](https://github.com/Open-Shell/Open-Shell-Menu/releases/latest)
-### ⚠️ Windows for ARM compatibility ⚠️
-Open-Shell is not compatible with Windows for ARM. If you install it on a Windows for ARM installation (ex. using Parallels Desktop on an Apple Silicon Mac), you will no longer be able to log into your account the next time you reboot. Please refrain from installing Open-Shell on Windows for ARM.
+> [!IMPORTANT]
+> #### Windows for ARM compatibility
+> Open-Shell is compatible with Windows for ARM since version [4.4.196](https://github.com/Open-Shell/Open-Shell-Menu/releases/tag/v4.4.196).
+>
+> If you install older one on a Windows for ARM installation (ex. using Parallels Desktop on an Apple Silicon Mac), you will no longer be able to log into your account the next time you reboot. Please refrain from installing Open-Shell on Windows for ARM.
### Temporary Translation/Language Solution
1. Download [language DLL](https://coddec.github.io/Classic-Shell/www.classicshell.net/translations/index.html)
diff --git a/Src/ClassicExplorer/ClassicExplorer.vcxproj b/Src/ClassicExplorer/ClassicExplorer.vcxproj
index 4280d8376..2ec90585b 100644
--- a/Src/ClassicExplorer/ClassicExplorer.vcxproj
+++ b/Src/ClassicExplorer/ClassicExplorer.vcxproj
@@ -1,6 +1,14 @@
+
+ Debug
+ ARM64
+
+
+ Debug
+ ARM64EC
+
Debug
Win32
@@ -9,6 +17,14 @@
Debug
x64
+
+ Release
+ ARM64
+
+
+ Release
+ ARM64EC
+
Release
Win32
@@ -17,6 +33,14 @@
Release
x64
+
+ Setup
+ ARM64
+
+
+ Setup
+ ARM64EC
+
Setup
Win32
@@ -53,6 +77,13 @@
$(ProjectName)64
+
+ $(ProjectName)64
+
+
+ $(ProjectName)64
+ true
+
true
diff --git a/Src/ClassicExplorer/ClassicExplorer.vcxproj.filters b/Src/ClassicExplorer/ClassicExplorer.vcxproj.filters
index 3b72d121a..419ebce35 100644
--- a/Src/ClassicExplorer/ClassicExplorer.vcxproj.filters
+++ b/Src/ClassicExplorer/ClassicExplorer.vcxproj.filters
@@ -146,4 +146,4 @@
Resource Files
-
+
\ No newline at end of file
diff --git a/Src/ClassicIE/ClassicIE.vcxproj b/Src/ClassicIE/ClassicIE.vcxproj
index 4a5b9a4b4..83f8308ba 100644
--- a/Src/ClassicIE/ClassicIE.vcxproj
+++ b/Src/ClassicIE/ClassicIE.vcxproj
@@ -1,6 +1,10 @@
+
+ Debug
+ ARM64
+
Debug
Win32
@@ -9,6 +13,10 @@
Debug
x64
+
+ Release
+ ARM64
+
Release
Win32
@@ -17,6 +25,10 @@
Release
x64
+
+ Setup
+ ARM64
+
Setup
Win32
@@ -53,6 +65,9 @@
$(ProjectName)_64
+
+ $(ProjectName)_64
+
NotUsing
diff --git a/Src/ClassicIE/ClassicIEDLL/ClassicIEDLL.vcxproj b/Src/ClassicIE/ClassicIEDLL/ClassicIEDLL.vcxproj
index 57068dd0c..10ea42734 100644
--- a/Src/ClassicIE/ClassicIEDLL/ClassicIEDLL.vcxproj
+++ b/Src/ClassicIE/ClassicIEDLL/ClassicIEDLL.vcxproj
@@ -1,6 +1,14 @@
+
+ Debug
+ ARM64
+
+
+ Debug
+ ARM64EC
+
Debug
Win32
@@ -9,6 +17,14 @@
Debug
x64
+
+ Release
+ ARM64
+
+
+ Release
+ ARM64EC
+
Release
Win32
@@ -17,6 +33,14 @@
Release
x64
+
+ Setup
+ ARM64
+
+
+ Setup
+ ARM64EC
+
Setup
Win32
@@ -53,6 +77,13 @@
$(ProjectName)_64
+
+ $(ProjectName)_64
+
+
+ $(ProjectName)_64
+ true
+
_USRDLL;CLASSICIEDLL_EXPORTS;%(PreprocessorDefinitions)
diff --git a/Src/ClassicIE/ClassicIEDLL/ClassicIEDLL.vcxproj.filters b/Src/ClassicIE/ClassicIEDLL/ClassicIEDLL.vcxproj.filters
index 8af204741..8f49852ad 100644
--- a/Src/ClassicIE/ClassicIEDLL/ClassicIEDLL.vcxproj.filters
+++ b/Src/ClassicIE/ClassicIEDLL/ClassicIEDLL.vcxproj.filters
@@ -98,4 +98,4 @@
Resource Files
-
+
\ No newline at end of file
diff --git a/Src/Common.props b/Src/Common.props
index 62a42c9fe..2a0a2ceee 100644
--- a/Src/Common.props
+++ b/Src/Common.props
@@ -16,6 +16,14 @@
$(MSBuildThisFileDirectory)..\build\bin\$(Configuration)64\
$(MSBuildThisFileDirectory)..\build\obj\$(ProjectName)\$(Configuration)64\
+
+ $(MSBuildThisFileDirectory)..\build\bin\$(Configuration)ARM64\
+ $(MSBuildThisFileDirectory)..\build\obj\$(ProjectName)\$(Configuration)ARM64\
+
+
+ $(MSBuildThisFileDirectory)..\build\bin\$(Configuration)ARM64EC\
+ $(MSBuildThisFileDirectory)..\build\obj\$(ProjectName)\$(Configuration)ARM64EC\
+
diff --git a/Src/Lib/IatHookHelper.cpp b/Src/Lib/IatHookHelper.cpp
index 4a34d315b..5305811ed 100644
--- a/Src/Lib/IatHookHelper.cpp
+++ b/Src/Lib/IatHookHelper.cpp
@@ -70,12 +70,17 @@ IatHookData *SetIatHook( IMAGE_DOS_HEADER *dosHeader, DWORD iatOffset, DWORD int
{
IatHookData *hook=g_IatHooks+g_IatHookCount;
g_IatHookCount++;
+#if defined(_M_AMD64) || defined(_M_IX86)
hook->jump[0]=hook->jump[1]=0x90; // NOP
hook->jump[2]=0xFF; hook->jump[3]=0x25; // JUMP
-#ifdef _WIN64
+#if defined(_M_AMD64)
hook->jumpOffs=0;
#else
hook->jumpOffs=(DWORD)(hook)+8;
+#endif
+#elif defined(_M_ARM64)
+ hook->jump[0]=0x48; hook->jump[1]=0x00; hook->jump[2]=0x00; hook->jump[3]=0x58; // LDR X8, newProc
+ hook->jump[4]=0x00; hook->jump[5]=0x01; hook->jump[6]=0x1F; hook->jump[7]=0xD6; // BR X8
#endif
hook->newProc=newProc;
hook->oldProc=(void*)thunk->u1.Function;
diff --git a/Src/Lib/IatHookHelper.h b/Src/Lib/IatHookHelper.h
index 2a4603f0d..d522bfbd7 100644
--- a/Src/Lib/IatHookHelper.h
+++ b/Src/Lib/IatHookHelper.h
@@ -6,8 +6,12 @@
struct IatHookData
{
+#if defined(_M_AMD64) || defined(_M_IX86)
unsigned char jump[4]; // jump instruction 0x90, 0x90, 0xFF, 0x25
DWORD jumpOffs; // jump instruction offset
+#elif defined(_M_ARM64)
+ unsigned char jump[8]; // LDR , BR
+#endif
void *newProc; // the address of the new proc
void *oldProc; // the address of the old proc
IMAGE_THUNK_DATA *thunk; // the IAT thunk
diff --git a/Src/Lib/Lib.vcxproj b/Src/Lib/Lib.vcxproj
index 7d7c023ba..8c29ee77c 100644
--- a/Src/Lib/Lib.vcxproj
+++ b/Src/Lib/Lib.vcxproj
@@ -1,6 +1,14 @@
+
+ Debug
+ ARM64
+
+
+ Debug
+ ARM64EC
+
Debug
Win32
@@ -9,6 +17,14 @@
Debug
x64
+
+ Release
+ ARM64
+
+
+ Release
+ ARM64EC
+
Release
Win32
@@ -42,6 +58,9 @@
$(IntDir)
+
+ true
+
_LIB;%(PreprocessorDefinitions)
diff --git a/Src/Lib/ResourceHelper.cpp b/Src/Lib/ResourceHelper.cpp
index 62a32fb8b..b7388a554 100644
--- a/Src/Lib/ResourceHelper.cpp
+++ b/Src/Lib/ResourceHelper.cpp
@@ -384,14 +384,14 @@ HICON CreateDisabledIcon( HICON hIcon, int iconSize )
}
// Loads an image file into a bitmap and optionally resizes it
-HBITMAP LoadImageFile( const wchar_t *path, const SIZE *pSize, bool bUseAlpha, bool bPremultiply, std::vector *pButtonAnim )
+HBITMAP LoadImageFile( const wchar_t *path, const SIZE *pSize, bool bUseAlpha, bool bPremultiply, std::vector *pButtonAnim, UINT dpi )
{
HBITMAP srcBmp=NULL;
if (_wcsicmp(PathFindExtension(path),L".bmp")==0)
{
srcBmp=(HBITMAP)LoadImage(NULL,path,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE);
}
- if (srcBmp && !pSize)
+ if (srcBmp && !pSize && !dpi)
return srcBmp;
CComPtr pFactory;
if (FAILED(pFactory.CoCreateInstance(CLSID_WICImagingFactory)))
@@ -482,6 +482,12 @@ HBITMAP LoadImageFile( const wchar_t *path, const SIZE *pSize, bool bUseAlpha, b
else
frameHeightD=frameWidthD*frameHeightS/frameWidthS;
}
+
+ if (dpi)
+ {
+ frameWidthD=ScaleForDpi(dpi,frameWidthD);
+ frameHeightD=ScaleForDpi(dpi,frameHeightD);
+ }
}
BITMAPINFO bi={0};
@@ -946,7 +952,12 @@ UINT GetDpi(HWND hwnd)
return dpi;
}
+int ScaleForDpi(UINT dpi, int value)
+{
+ return MulDiv(value, dpi, USER_DEFAULT_SCREEN_DPI);
+}
+
int ScaleForDpi(HWND hwnd, int value)
{
- return MulDiv(value, GetDpi(hwnd), USER_DEFAULT_SCREEN_DPI);
+ return ScaleForDpi(GetDpi(hwnd), value);
}
diff --git a/Src/Lib/ResourceHelper.h b/Src/Lib/ResourceHelper.h
index d44eb6b59..5afc1d1dc 100644
--- a/Src/Lib/ResourceHelper.h
+++ b/Src/Lib/ResourceHelper.h
@@ -35,7 +35,7 @@ HICON ShExtractIcon( const char *path, int index, int iconSize );
HBITMAP BitmapFromIcon( HICON hIcon, int iconSize, unsigned int **pBits, bool bDestroyIcon );
// Loads an image file into a bitmap and optionally resizes it
-HBITMAP LoadImageFile( const wchar_t *path, const SIZE *pSize, bool bUseAlpha, bool bPremultiply, std::vector *pButtonAnim );
+HBITMAP LoadImageFile( const wchar_t *path, const SIZE *pSize, bool bUseAlpha, bool bPremultiply, std::vector *pButtonAnim, UINT dpi=0 );
// Loads a bitmap from a IMAGE resource
HBITMAP LoadImageResource( HMODULE hModule, const wchar_t *name, bool bTopDown, bool bPremultiply );
@@ -88,6 +88,8 @@ HFONT CreateFontSetting( const wchar_t *fontStr, int dpi );
// Return DPI of given window (or system DPI on older systems)
UINT GetDpi(HWND hwnd = nullptr);
+// Scale given value according to given DPI
+int ScaleForDpi(UINT dpi, int value);
// Scale given value according to DPI of window
int ScaleForDpi(HWND hwnd, int value);
diff --git a/Src/Lib/Settings.cpp b/Src/Lib/Settings.cpp
index 8937d4c39..599cb9fed 100644
--- a/Src/Lib/Settings.cpp
+++ b/Src/Lib/Settings.cpp
@@ -1670,7 +1670,7 @@ LRESULT CSettingsDlg::OnBackup( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL&
ofn.lpstrTitle=title;
ofn.lpstrDefExt=L".xml";
ofn.Flags=OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_EXPLORER|OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY|OFN_NOCHANGEDIR;
- if (GetSaveFileName(&ofn))
+ if (GetSaveFileNameSafe(&ofn))
{
CString err=g_SettingsManager.SaveSettingsXml(path);
if (!err.IsEmpty())
@@ -1699,7 +1699,7 @@ LRESULT CSettingsDlg::OnBackup( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL&
CString title=LoadStringEx(IDS_XML_TITLE_LOAD);
ofn.lpstrTitle=title;
ofn.Flags=OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_NOCHANGEDIR;
- if (GetOpenFileName(&ofn))
+ if (GetOpenFileNameSafe(&ofn))
{
SetCurTab(m_Index,true); // reload tab once to force-close any active edit boxes
CString error=g_SettingsManager.LoadSettingsXml(path);
diff --git a/Src/Lib/SettingsUIHelper.cpp b/Src/Lib/SettingsUIHelper.cpp
index 9372677c5..9b988e282 100644
--- a/Src/Lib/SettingsUIHelper.cpp
+++ b/Src/Lib/SettingsUIHelper.cpp
@@ -15,6 +15,7 @@
#include
#include
diff --git a/Src/Setup/Setup.vcxproj.filters b/Src/Setup/Setup.vcxproj.filters
index 613885939..00a2d7a1a 100644
--- a/Src/Setup/Setup.vcxproj.filters
+++ b/Src/Setup/Setup.vcxproj.filters
@@ -61,5 +61,6 @@
+
\ No newline at end of file
diff --git a/Src/Setup/Setup.wxs b/Src/Setup/Setup.wxs
index 58b5cddc4..b1a2f993f 100644
--- a/Src/Setup/Setup.wxs
+++ b/Src/Setup/Setup.wxs
@@ -3,7 +3,7 @@
# This comment is generated by WixEdit, the specific commandline
# arguments for the WiX Toolset are stored here.
- candleArgs: "" -out ".wixobj" -ext WixUIExtension -ext WixUtilExtension -dx64=0
+ candleArgs: "" -out ".wixobj" -ext WixUIExtension -ext WixUtilExtension -dx64=0 -dARM64=0
lightArgs: ".wixobj" -out ".msi" -ext WixUIExtension -ext WixUtilExtension -loc OpenShellText-en-US.wxl
-->
@@ -11,6 +11,11 @@
+
+
+
+
+
@@ -22,9 +27,13 @@
-
+
+
not Msix64
+
+ NOT (WIX_NATIVE_MACHINE AND WIX_NATIVE_MACHINE="43620")
+
VersionNT>=601
NOT NEWERPRODUCTFOUND OR Installed
@@ -59,7 +68,7 @@
-
+
@@ -71,7 +80,7 @@
-
+
@@ -98,7 +107,7 @@
-
+
@@ -443,6 +452,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Src/Setup/Utility/Utility.cpp b/Src/Setup/Utility/Utility.cpp
index f4cbe7c65..3cc524f4a 100644
--- a/Src/Setup/Utility/Utility.cpp
+++ b/Src/Setup/Utility/Utility.cpp
@@ -86,7 +86,7 @@ int CalcMsiChecksum( wchar_t *const *params, int count )
// load files
wchar_t path1[_MAX_PATH];
- std::vector buf1, buf2;
+ std::vector buf1, buf2, buf3;
Sprintf(path1,_countof(path1),L"%s\\Setup32.msi",params[1]);
LoadFile(path1,buf1);
if (buf1.empty())
@@ -102,20 +102,30 @@ int CalcMsiChecksum( wchar_t *const *params, int count )
Printf("Failed to open file %s\n",path2);
return 1;
}
+ wchar_t path3[_MAX_PATH];
+ Sprintf(path3,_countof(path3),L"%s\\SetupARM64.msi",params[1]);
+ LoadFile(path3,buf3);
+ if (buf3.empty())
+ {
+ Printf("Failed to open file %s\n",path3);
+ return 1;
+ }
int len1=(int)buf1.size();
int len2=(int)buf2.size();
+ int len3=(int)buf3.size();
for (std::vector::iterator it=buf1.begin();it!=buf1.end();++it)
*it^=0xFF;
for (std::vector::iterator it=buf2.begin();it!=buf2.end();++it)
*it^=0xFF;
+ for (std::vector::iterator it=buf3.begin();it!=buf3.end();++it)
+ *it^=0xFF;
- // detect common blocks (assuming at least 256K in size and in the same order in both files)
- const int BLOCK_SIZE=256*1024;
+ const int BLOCK_SIZE = 256 * 1024;
+ // detect x86/x64 common blocks (assuming at least 256K in size and in the same order in both files)
std::vector chunks;
- int start2=0;
- for (int i=0;i chunks2;
+ for (int i=0,start2=0;i0 && chunk.start2>0 && buf1[chunk.start1-1]==buf3[chunk.start2-1])
+ {
+ chunk.start1--;
+ chunk.start2--;
+ chunk.len++;
+ }
+ while (chunk.start1+chunk.len::const_iterator it=chunks2.begin();it!=chunks2.end();++it)
+ {
+ if (it->start2-start>0)
+ fwrite(&buf3[start],1,it->start2-start,f);
+ start=it->start2+it->len;
+ }
+ if (len3-start>0)
+ fwrite(&buf3[start],1,len3-start,f);
+ fclose(f);
+ }
+
+ unsigned int fnvs[3];
fnvs[0]=CalcFNVHash(&buf1[0],len1,FNV_HASH0);
fnvs[1]=CalcFNVHash(&buf2[0],len2,FNV_HASH0);
+ fnvs[2]=CalcFNVHash(&buf3[0],len3,FNV_HASH0);
// save fnvs and chunks
{
@@ -193,6 +254,9 @@ int CalcMsiChecksum( wchar_t *const *params, int count )
int count=(int)chunks.size();
fwrite(&count,1,4,f);
fwrite(&chunks[0],sizeof(Chunk),count,f);
+ count=(int)chunks2.size();
+ fwrite(&count,1,4,f);
+ fwrite(&chunks2[0],sizeof(Chunk),count,f);
fclose(f);
}
return 0;
@@ -841,7 +905,7 @@ static HRESULT CALLBACK TaskDialogCallback( HWND hwnd, UINT uNotification, WPARA
// Open-Shell utility - multiple utilities for building and maintaining Open-Shell
// Usage:
// no parameters - saves a troubleshooting log
-// crcmsi // creates a file with checksum of both msi files
+// crcmsi // creates a file with checksum of all msi files
// makeEN // extracts the localization resources and creates a sample en-US.DLL
// extract // extracts the string table, the dialog text, and the L10N text from a DLL and stores it in a CSV
// extract en-us.dll // extracts the string table, the dialog text, and the L10N text from two DLL and stores it in a CSV
diff --git a/Src/Setup/Utility/Utility.vcxproj b/Src/Setup/Utility/Utility.vcxproj
index b98da855c..744de02c8 100644
--- a/Src/Setup/Utility/Utility.vcxproj
+++ b/Src/Setup/Utility/Utility.vcxproj
@@ -1,6 +1,10 @@
+
+ Debug
+ ARM64
+
Debug
Win32
@@ -9,6 +13,10 @@
Debug
x64
+
+ Release
+ ARM64
+
Release
Win32
@@ -63,6 +71,7 @@
true
+ true
diff --git a/Src/Setup/resource.h b/Src/Setup/resource.h
index 85076b8d8..e77b7a46d 100644
--- a/Src/Setup/resource.h
+++ b/Src/Setup/resource.h
@@ -8,6 +8,7 @@
#define IDS_ERR_CORRUPTED 102
#define IDR_MSI_FILE32 132
#define IDR_MSI_FILE64 164
+#define IDR_MSI_FILEARM64 165
#define IDS_ERR_INTERNAL 166
#define IDS_ERR_EXTRACT 167
#define IDR_MSI_CHECKSUM 167
diff --git a/Src/StartMenu/StartMenu.vcxproj b/Src/StartMenu/StartMenu.vcxproj
index c535f82b5..96d346e4c 100644
--- a/Src/StartMenu/StartMenu.vcxproj
+++ b/Src/StartMenu/StartMenu.vcxproj
@@ -1,6 +1,10 @@
+
+ Debug
+ ARM64
+
Debug
Win32
@@ -9,6 +13,10 @@
Debug
x64
+
+ Release
+ ARM64
+
Release
Win32
@@ -17,6 +25,10 @@
Release
x64
+
+ Setup
+ ARM64
+
Setup
Win32
diff --git a/Src/StartMenu/StartMenuDLL/ItemManager.h b/Src/StartMenu/StartMenuDLL/ItemManager.h
index 0c273b6ca..e10775bdf 100644
--- a/Src/StartMenu/StartMenuDLL/ItemManager.h
+++ b/Src/StartMenu/StartMenuDLL/ItemManager.h
@@ -383,7 +383,7 @@ class CItemManager
static DWORD CALLBACK StaticRefreshInfoThread( void *param );
static DWORD CALLBACK SaveCacheFileThread( void *param );
- // all paths are in caps and end with \
+ // all paths are in caps and end with backslash
CString m_RootStartMenu1;
CString m_RootStartMenu2;
CString m_RootStartMenu3;
diff --git a/Src/StartMenu/StartMenuDLL/MenuContainer.cpp b/Src/StartMenu/StartMenuDLL/MenuContainer.cpp
index 52ed2c738..856ead1e4 100644
--- a/Src/StartMenu/StartMenuDLL/MenuContainer.cpp
+++ b/Src/StartMenu/StartMenuDLL/MenuContainer.cpp
@@ -6366,7 +6366,10 @@ LRESULT CMenuContainer::OnRefresh( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
}
}
else if (m_Items[m_OriginalCount].id==MENU_SEARCH_CATEGORY)
- hotItem=m_OriginalCount+1;
+ {
+ if (!bSearching || !s_SearchResults.programs.empty())
+ hotItem=m_OriginalCount+1;
+ }
}
else
hotItem=-1;
diff --git a/Src/StartMenu/StartMenuDLL/StartButton.cpp b/Src/StartMenu/StartMenuDLL/StartButton.cpp
index 39d07d419..f279fa10f 100644
--- a/Src/StartMenu/StartMenuDLL/StartButton.cpp
+++ b/Src/StartMenu/StartMenuDLL/StartButton.cpp
@@ -526,16 +526,16 @@ void CStartButton::LoadBitmap( void )
}
else
{
+ int dpi=GetDpi(GetParent());
bool bResource=false;
std::vector buttonAnim;
if (*path)
{
- m_Bitmap=LoadImageFile(path,&size,true,true,&buttonAnim);
+ m_Bitmap=LoadImageFile(path,&size,true,true,&buttonAnim,dpi);
}
if (!m_Bitmap)
{
int id;
- int dpi=GetDpi(GetParent());
if (dpi<120)
id=IDB_BUTTON96;
else if (dpi<144)
diff --git a/Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp b/Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp
index 7cf742a2c..9111cb40c 100644
--- a/Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp
+++ b/Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp
@@ -67,6 +67,8 @@ static SIZE g_TaskbarTextureSize;
static TTaskbarTile g_TaskbarTileH, g_TaskbarTileV;
static RECT g_TaskbarMargins;
int g_CurrentCSMTaskbar=-1, g_CurrentWSMTaskbar=-1;
+// ExplorerPatcher taskbar
+static bool g_epTaskbar = false;
static void FindWindowsMenu( void );
static void RecreateStartButton( size_t taskbarId );
@@ -1342,7 +1344,7 @@ static void UpdateStartButtonPosition(const TaskbarInfo* taskBar, const WINDOWPO
// Start button on Win11 is a bit shifted to the right
// We will shift our Aero button to cover original button
- if (IsWin11() && (x == info.rcMonitor.left) && (GetStartButtonType() == START_BUTTON_AERO))
+ if (IsWin11() && (x == info.rcMonitor.left) && (GetStartButtonType() == START_BUTTON_AERO) && !g_epTaskbar)
x += ScaleForDpi(taskBar->taskBar, 6);
}
@@ -1622,7 +1624,7 @@ static void ComputeTaskbarColors( int *data )
{
bool bDefLook;
int look=GetSettingInt(L"TaskbarLook",bDefLook);
- if (GetWinVersion()bCustomLook && SetWindowCompositionAttribute && GetWinVersion()WIN_VER_WIN7)
{
- color=GetSystemGlassColor8();
- color=((color&0xFF)<<16)|(color&0xFF00)|((color>>16)&0xFF);
+ if (IsAppThemed())
+ {
+ color=GetSystemGlassColor8();
+ color=((color&0xFF)<<16)|(color&0xFF00)|((color>>16)&0xFF);
+ }
+ else
+ {
+ color=GetSysColor(COLOR_BTNFACE);
+ }
}
BITMAPINFO bi={0};
bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
@@ -2772,6 +2782,17 @@ static void WINAPI SHFillRectClr2( HDC hdc, const RECT *pRect, COLORREF color )
g_SHFillRectClr(hdc,pRect,color);
}
+static IatHookData* g_ExtTextOutWHook = nullptr;
+
+// used by ExplorerPatcher's custom implementation of `SHFillRectClr`
+static BOOL WINAPI ExtTextOutW2(HDC hdc, int X, int Y, UINT fuOptions, const RECT* lprc, LPCWSTR lpString, UINT cbCount, const INT* lpDx)
+{
+ if (fuOptions != ETO_OPAQUE || lpString || cbCount || lpDx || !g_CurrentTaskList || !g_TaskbarTexture || GetCurrentThreadId() != g_TaskbarThreadId)
+ return ExtTextOutW(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx);
+
+ return FALSE;
+}
+
static HRESULT STDAPICALLTYPE DrawThemeBackground2( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCRECT pRect, LPCRECT pClipRect )
{
if (g_CurrentTaskList && g_TaskbarTexture && iPartId==1 && iStateId==0 && GetCurrentThreadId()==g_TaskbarThreadId)
@@ -2956,6 +2977,15 @@ static void InitStartMenuDLL( void )
if (GetSettingBool(L"CustomTaskbar"))
{
auto module=GetModuleHandle(L"taskbar.dll");
+ if (!module)
+ {
+ module = GetModuleHandle(L"ep_taskbar.5.dll");
+ if (!module)
+ module = GetModuleHandle(L"ep_taskbar.2.dll");
+
+ if (module)
+ g_epTaskbar = true;
+ }
if (!module)
module=GetModuleHandle(NULL);
@@ -2975,6 +3005,10 @@ static void InitStartMenuDLL( void )
g_StretchDIBitsHook=SetIatHook(module,"gdi32.dll","StretchDIBits",StretchDIBits2);
if (!g_StretchDIBitsHook)
g_StretchDIBitsHook=SetIatHook(module,"ext-ms-win-gdi-draw-l1-1-0.dll","StretchDIBits",StretchDIBits2);
+
+ // ExplorerPatcher compatibility
+ if (g_epTaskbar)
+ g_ExtTextOutWHook = SetIatHook(module, "gdi32.dll", "ExtTextOutW", ExtTextOutW2);
}
{
@@ -2986,7 +3020,10 @@ static void InitStartMenuDLL( void )
if (GetWinVersion()<=WIN_VER_WIN81)
g_DrawThemeBackgroundHook=SetIatHook(module,"uxtheme.dll","DrawThemeBackground",DrawThemeBackground2);
g_DrawThemeTextHook=SetIatHook(module,"uxtheme.dll","DrawThemeText",DrawThemeText2);
- g_DrawThemeTextExHook=SetIatHook(module,"uxtheme.dll","DrawThemeTextEx",DrawThemeTextEx2);
+ if (IsAppThemed())
+ {
+ g_DrawThemeTextExHook=SetIatHook(module,"uxtheme.dll","DrawThemeTextEx",DrawThemeTextEx2);
+ }
g_DrawThemeTextCtlHook=SetIatHook(GetModuleHandle(L"comctl32.dll"),"uxtheme.dll","DrawThemeText",DrawThemeText2);
if (GetWinVersion()>=WIN_VER_WIN10)
g_SetWindowCompositionAttributeHook=SetIatHook(module,"user32.dll","SetWindowCompositionAttribute",SetWindowCompositionAttribute2);
@@ -3204,6 +3241,7 @@ static void RecreateStartButton( size_t taskbarId )
{
RECT rc;
GetWindowRect(btn,&rc);
+ MapWindowPoints(NULL,taskBar.taskBar,(POINT*)&rc,2); // convert to taskbar coordinates
SetWindowPos(btn,HWND_TOP,rc.left,rc.top,0,0,SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER);
}
}
@@ -3230,6 +3268,8 @@ static void CleanStartMenuDLL( void )
g_SHFillRectClrHook=NULL;
ClearIatHook(g_StretchDIBitsHook);
g_StretchDIBitsHook=NULL;
+ ClearIatHook(g_ExtTextOutWHook);
+ g_ExtTextOutWHook = NULL;
ClearIatHook(g_DrawThemeBackgroundHook);
g_DrawThemeBackgroundHook=NULL;
diff --git a/Src/StartMenu/StartMenuDLL/StartMenuDLL.rc b/Src/StartMenu/StartMenuDLL/StartMenuDLL.rc
index b7007ee1e..fbaf3e9a2 100644
--- a/Src/StartMenu/StartMenuDLL/StartMenuDLL.rc
+++ b/Src/StartMenu/StartMenuDLL/StartMenuDLL.rc
@@ -1081,9 +1081,9 @@ BEGIN
IDS_RIGHT_SHIFT_TIP "When this is checked, right-click on the start button will open the standard Windows context menu instead of the Open-Shell menu. Otherwise Shift+right-click will open it"
IDS_RIGHT_SHIFTX "Right click opens Win+X menu"
IDS_RIGHT_SHIFTX_TIP "When this is checked, right-click on the start button will open the Win+X power menu instead of the Open-Shell menu. Otherwise Shift+right-click will open it"
- IDS_STARTSCREEN_ITEM "Show Start screen shortcut"
+ IDS_STARTSCREEN_ITEM "Show Start Menu/Screen shortcut"
IDS_STARTSCREEN_ITEM_TIP
- "When this is checked, the main menu will contain a shortcut to open the Start screen"
+ "When this is checked, the main menu will contain a shortcut to open original Start menu/screen"
IDS_MIN_HEIGHT "Minimum menu height"
IDS_MIN_HEIGHT_TIP "The main menu will be at least as tall as this many search results"
IDS_GLASS_OVERRIDE "Override glass color"
diff --git a/Src/StartMenu/StartMenuDLL/StartMenuDLL.vcxproj b/Src/StartMenu/StartMenuDLL/StartMenuDLL.vcxproj
index 1da1c24a0..b60797b41 100644
--- a/Src/StartMenu/StartMenuDLL/StartMenuDLL.vcxproj
+++ b/Src/StartMenu/StartMenuDLL/StartMenuDLL.vcxproj
@@ -1,6 +1,10 @@
+
+ Debug
+ ARM64
+
Debug
Win32
@@ -9,6 +13,10 @@
Debug
x64
+
+ Release
+ ARM64
+
Release
Win32
@@ -17,6 +25,10 @@
Release
x64
+
+ Setup
+ ARM64
+
Setup
Win32
diff --git a/Src/StartMenu/StartMenuHelper/StartMenuExt.h b/Src/StartMenu/StartMenuHelper/StartMenuExt.h
index f7f11aa75..8ad501941 100644
--- a/Src/StartMenu/StartMenuHelper/StartMenuExt.h
+++ b/Src/StartMenu/StartMenuHelper/StartMenuExt.h
@@ -55,8 +55,8 @@ END_COM_MAP()
STDMETHODIMP InvokeCommand( CMINVOKECOMMANDINFO *pInfo );
STDMETHODIMP GetCommandString( UINT_PTR idCmd, UINT uFlags, UINT* pwReserved, LPSTR pszName, UINT cchMax );
- wchar_t m_PinFolder1[_MAX_PATH]; // ending with \
- wchar_t m_PinFolder2[_MAX_PATH]; // ending with \
+ wchar_t m_PinFolder1[_MAX_PATH]; // ending with backslash
+ wchar_t m_PinFolder2[_MAX_PATH]; // ending with backslash
wchar_t m_FileName[_MAX_PATH];
LPITEMIDLIST m_FilePidl;
bool m_bInPinFolder1, m_bInPinFolder2;
diff --git a/Src/StartMenu/StartMenuHelper/StartMenuHelper.vcxproj b/Src/StartMenu/StartMenuHelper/StartMenuHelper.vcxproj
index c293faf8c..363990fba 100644
--- a/Src/StartMenu/StartMenuHelper/StartMenuHelper.vcxproj
+++ b/Src/StartMenu/StartMenuHelper/StartMenuHelper.vcxproj
@@ -1,6 +1,14 @@
+
+ Debug
+ ARM64
+
+
+ Debug
+ ARM64EC
+
Debug
Win32
@@ -9,6 +17,14 @@
Debug
x64
+
+ Release
+ ARM64
+
+
+ Release
+ ARM64EC
+
Release
Win32
@@ -17,6 +33,14 @@
Release
x64
+
+ Setup
+ ARM64
+
+
+ Setup
+ ARM64EC
+
Setup
Win32
@@ -53,6 +77,13 @@
$(ProjectName)64
+
+ $(ProjectName)64
+
+
+ $(ProjectName)64
+ true
+
_USRDLL;%(PreprocessorDefinitions)
diff --git a/appveyor.yml b/appveyor.yml
index a7d00344c..a9390d421 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -21,5 +21,5 @@ deploy:
on:
APPVEYOR_ACCOUNT_NAME: passionate-coder
auth_token:
- secure: SOu6Y71k0oIxXJR35x+7ZTrqDa3HqUM4kLNJc+DbohPz9zhVHh9O8QYwmI7LI0qslug5L11fo9pZVfVgZttw4eBgooHaX9TNBTTA6sJItkXqMX+M6mKAG7tbI/O3Eg0v
+ secure: SOu6Y71k0oIxXJR35x+7ZeU/+WRW8kaGnCWcbR3OVOd8HeCJwB1Tw3hUJa5EveLGKaGoMKGqAh01Pwc8tWX4xmphZsYYUr09IVjA0+rqgN5VT87CXD6OQxUxBJ7g+9IN
prerelease: true