1
0
mirror of https://github.com/valinet/ExplorerPatcher.git synced 2024-11-24 07:30:22 +01:00

Implemented GUI (fixes #29)

This commit is contained in:
Valentin Radu 2021-10-02 04:02:07 +03:00
parent fdfeecb28b
commit 1b1bc67c56
18 changed files with 1488 additions and 45 deletions

View File

@ -2,6 +2,12 @@
This document includes the same release notes as in the [Releases](https://github.com/valinet/ExplorerPatcher/releases) section on GitHub. This document includes the same release notes as in the [Releases](https://github.com/valinet/ExplorerPatcher/releases) section on GitHub.
## 22000.194.0.21
Tested on build: 22000.194.
* Implemented configuration GUI; to access it, right click the Start button (or press `Win`+`X`) and choose "Properties"
## 22000.194.0.20 ## 22000.194.0.20
Tested on build: 22000.194. Tested on build: 22000.194.

View File

@ -51,8 +51,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 22000,194,0,20 FILEVERSION 22000,194,0,21
PRODUCTVERSION 22000,194,0,20 PRODUCTVERSION 22000,194,0,21
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -69,12 +69,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "VALINET Solutions SRL" VALUE "CompanyName", "VALINET Solutions SRL"
VALUE "FileDescription", "ExplorerPatcher" VALUE "FileDescription", "ExplorerPatcher"
VALUE "FileVersion", "22000.194.0.20" VALUE "FileVersion", "22000.194.0.21"
VALUE "InternalName", "ExplorerPatcher.dll" VALUE "InternalName", "ExplorerPatcher.dll"
VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved." VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
VALUE "OriginalFilename", "ExplorerPatcher.dll" VALUE "OriginalFilename", "ExplorerPatcher.dll"
VALUE "ProductName", "ExplorerPatcher" VALUE "ProductName", "ExplorerPatcher"
VALUE "ProductVersion", "22000.194.0.20" VALUE "ProductVersion", "22000.194.0.21"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@ -83,6 +83,31 @@ BEGIN
END END
END END
/////////////////////////////////////////////////////////////////////////////
//
// RCDATA
//
IDR_REGISTRY1 RCDATA "settings.reg"
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_PRODUCTNAME "ExplorerPatcher"
IDS_COPYRIGHT "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
IDS_VERSION "Version %d.%d.%d.%d"
IDS_PRODUCTTAG "This project aims to bring back a productive working environment\r\non Windows 11. Proudly programmed by Valentin-Gabriel Radu."
IDS_VISITGITHUB "Visit project Github"
IDS_VISITWEBSITE "Visit web site"
IDS_LICENSEINFO "E-mail author"
END
#endif // English (United States) resources #endif // English (United States) resources
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View File

@ -195,6 +195,9 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="ArchiveMenu.c" /> <ClCompile Include="ArchiveMenu.c" />
<ClCompile Include="dllmain.c" /> <ClCompile Include="dllmain.c" />
<ClCompile Include="fmemopen.c" />
<ClCompile Include="getline.c" />
<ClCompile Include="GUI.c" />
<ClCompile Include="HideExplorerSearchBar.c" /> <ClCompile Include="HideExplorerSearchBar.c" />
<ClCompile Include="SettingsMonitor.c" /> <ClCompile Include="SettingsMonitor.c" />
<ClCompile Include="StartMenu.c" /> <ClCompile Include="StartMenu.c" />
@ -205,6 +208,9 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="ArchiveMenu.h" /> <ClInclude Include="ArchiveMenu.h" />
<ClInclude Include="dxgi_imp.h" /> <ClInclude Include="dxgi_imp.h" />
<ClInclude Include="fmemopen.h" />
<ClInclude Include="getline.h" />
<ClInclude Include="GUI.h" />
<ClInclude Include="HideExplorerSearchBar.h" /> <ClInclude Include="HideExplorerSearchBar.h" />
<ClInclude Include="hooking.h" /> <ClInclude Include="hooking.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
@ -217,6 +223,9 @@
<ItemGroup> <ItemGroup>
<ResourceCompile Include="ExplorerPatcher.rc" /> <ResourceCompile Include="ExplorerPatcher.rc" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="settings.reg" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>

View File

@ -45,6 +45,15 @@
<ClInclude Include="utility.h"> <ClInclude Include="utility.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="GUI.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="getline.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="fmemopen.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="ExplorerPatcher.rc"> <ResourceCompile Include="ExplorerPatcher.rc">
@ -76,5 +85,17 @@
<ClCompile Include="utility.c"> <ClCompile Include="utility.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="GUI.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="getline.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fmemopen.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="settings.reg" />
</ItemGroup> </ItemGroup>
</Project> </Project>

938
ExplorerPatcher/GUI.c Normal file
View File

@ -0,0 +1,938 @@
#include "GUI.h"
static HRESULT GUI_AboutProc(
HWND hwnd,
UINT uNotification,
WPARAM wParam,
LPARAM lParam,
LONG_PTR lpRefData
)
{
switch (uNotification)
{
case TDN_BUTTON_CLICKED:
{
if (wParam == IDOK || wParam == IDCANCEL)
{
return S_OK;
}
else if (wParam == IDS_VISITGITHUB)
{
ShellExecuteA(
NULL,
"open",
"https://github.com/valinet/ExplorerPatcher",
NULL,
NULL,
SW_SHOWNORMAL
);
}
else if (wParam == IDS_VISITWEBSITE)
{
ShellExecuteA(
NULL,
"open",
"https://www.valinet.ro",
NULL,
NULL,
SW_SHOWNORMAL
);
}
else if (wParam == IDS_LICENSEINFO)
{
ShellExecuteA(
NULL,
"open",
"mailto:valentingabrielradu@gmail.com",
NULL,
NULL,
SW_SHOWNORMAL
);
}
}
}
return S_OK;
}
static BOOL GUI_Build(HDC hDC, HWND hwnd, POINT pt)
{
GUI* _this;
LONG_PTR ptr = GetWindowLongPtr(hwnd, GWLP_USERDATA);
_this = (int*)(ptr);
double dx = _this->dpi.x / 96.0, dy = _this->dpi.y / 96.0;
_this->padding.left = GUI_PADDING_LEFT * dx;
_this->padding.right = GUI_PADDING_RIGHT * dx;
_this->padding.top = GUI_PADDING_TOP * dy;
_this->padding.bottom = GUI_PADDING_BOTTOM * dy;
RECT rc;
GetClientRect(hwnd, &rc);
HRSRC hRscr = FindResourceA(
hModule,
MAKEINTRESOURCEA(IDR_REGISTRY1),
RT_RCDATA
);
if (!hRscr)
{
return FALSE;
}
HGLOBAL hgRscr = LoadResource(
hModule,
hRscr
);
if (!hgRscr)
{
return FALSE;
}
PVOID pRscr = LockResource(hgRscr);
DWORD cbRscr = SizeofResource(
hModule,
hRscr
);
LOGFONT logFont;
memset(&logFont, 0, sizeof(logFont));
logFont.lfHeight = GUI_CAPTION_FONT_SIZE * dy;
logFont.lfWeight = FW_BOLD;
wcscpy_s(logFont.lfFaceName, 32, L"Segoe UI");
HFONT hFontCaption = CreateFontIndirect(&logFont);
logFont.lfHeight = GUI_TITLE_FONT_SIZE * dy;
HFONT hFontTitle = CreateFontIndirect(&logFont);
logFont.lfWeight = FW_REGULAR;
logFont.lfUnderline = 1;
HFONT hFontUnderline = CreateFontIndirect(&logFont);
logFont.lfWeight = FW_REGULAR;
logFont.lfUnderline = 0;
HFONT hFontRegular = CreateFontIndirect(&logFont);
HFONT hOldFont = NULL;
DTTOPTS DttOpts;
DttOpts.dwSize = sizeof(DTTOPTS);
DttOpts.dwFlags = DTT_COMPOSITED | DTT_TEXTCOLOR;
DttOpts.crText = GUI_TEXTCOLOR;
DWORD dwTextFlags = DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS;
RECT rcText;
DWORD dwCL = 0;
HDC hdcPaint = NULL;
BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) };
params.dwFlags = BPPF_ERASE;
HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hDC, &rc, BPBF_TOPDOWNDIB, &params, &hdcPaint);
if (!hDC || (hDC && hdcPaint))
{
FILE* f = fmemopen(pRscr, cbRscr, "r");
char* line = malloc(MAX_LINE_LENGTH * sizeof(char));
wchar_t* text = malloc(MAX_LINE_LENGTH * sizeof(wchar_t));
wchar_t* name = malloc(MAX_LINE_LENGTH * sizeof(wchar_t));
wchar_t* section = malloc(MAX_LINE_LENGTH * sizeof(wchar_t));
size_t bufsiz = 0, numChRd = 0;
while ((numChRd = getline(&line, &bufsiz, f)) != -1)
{
if (strcmp(line, "Windows Registry Editor Version 5.00\r\n") && strcmp(line, "\r\n"))
{
if (!strncmp(line, "[", 1))
{
ZeroMemory(section, MAX_LINE_LENGTH * sizeof(wchar_t));
MultiByteToWideChar(
CP_UTF8,
MB_PRECOMPOSED,
line[1] == '-' ? line + 2 : line + 1,
numChRd - (line[1] == '-' ? 5 : 4),
section,
MAX_LINE_LENGTH
);
//wprintf(L"%s\n", section);
}
DWORD dwLineHeight = GUI_LINE_HEIGHT;
rcText.left = _this->padding.left;
rcText.top = _this->padding.top + dwCL;
rcText.right = (rc.right - rc.left) - _this->padding.right;
rcText.bottom = dwCL + dwLineHeight * dy - _this->padding.bottom;
if (!strncmp(line, ";T ", 3))
{
hOldFont = SelectObject(hDC ? hdcPaint : GetDC(hwnd), hFontTitle);
}
else if (!strncmp(line, ";M ", 3))
{
hOldFont = SelectObject(hDC ? hdcPaint : GetDC(hwnd), hFontCaption);
}
else if (!strncmp(line, ";u ", 3))
{
hOldFont = SelectObject(hDC ? hdcPaint : GetDC(hwnd), hFontUnderline);
}
else
{
hOldFont = SelectObject(hDC ? hdcPaint : GetDC(hwnd), hFontRegular);
}
if (!strncmp(line, ";T ", 3) || !strncmp(line, ";t ", 3) || !strncmp(line, ";u ", 3) || !strncmp(line, ";M ", 3))
{
ZeroMemory(text, MAX_LINE_LENGTH * sizeof(wchar_t));
MultiByteToWideChar(
CP_UTF8,
MB_PRECOMPOSED,
line + 3,
numChRd - 3,
text,
MAX_LINE_LENGTH
);
if (!strncmp(line, ";M ", 3))
{
rcText.bottom += GUI_CAPTION_LINE_HEIGHT - dwLineHeight;
dwLineHeight = GUI_CAPTION_LINE_HEIGHT;
_this->extent.cyTopHeight = rcText.bottom;
}
if (hDC)
{
DrawThemeTextEx(
_this->hTheme,
hdcPaint,
hOldFont ? 0 : 8,
0,
text,
-1,
dwTextFlags,
&rcText,
&DttOpts
);
}
else
{
RECT rcTemp;
rcTemp = rcText;
DrawText(
GetDC(hwnd),
text,
-1,
&rcTemp,
DT_CALCRECT
);
rcTemp.bottom = rcText.bottom;
if (!strncmp(line, ";u ", 3) && PtInRect(&rcTemp, pt))
{
numChRd = getline(&line, &bufsiz, f);
char* p = strchr(line, '\r');
if (p) *p = 0;
p = strchr(line, '\n');
if (p) *p = 0;
if (!strncmp(line + 1, "restart", 7))
{
PROCESSENTRY32 pe32 = { 0 };
pe32.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnapshot = CreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS,
0
);
if (Process32First(hSnapshot, &pe32) == TRUE)
{
do
{
if (!wcscmp(pe32.szExeFile, TEXT("sihost.exe")))
{
HANDLE hSihost = OpenProcess(
PROCESS_TERMINATE,
FALSE,
pe32.th32ProcessID
);
TerminateProcess(hSihost, 0);
CloseHandle(hSihost);
return TRUE;
}
} while (Process32Next(hSnapshot, &pe32) == TRUE);
}
CloseHandle(hSnapshot);
}
else if (!strncmp(line + 1, "reset", 5))
{
wchar_t wszPath[MAX_PATH];
ZeroMemory(
wszPath,
MAX_PATH * sizeof(wchar_t)
);
SHGetFolderPathW(
NULL,
SPECIAL_FOLDER,
NULL,
SHGFP_TYPE_CURRENT,
wszPath
);
wcscat_s(
wszPath,
MAX_PATH,
TEXT(APP_RELATIVE_PATH)
);
CreateDirectoryW(wszPath, NULL);
wcscat_s(
wszPath,
MAX_PATH,
L"\\settings.reg"
);
wprintf(L"%s\n", wszPath);
HANDLE hFile = CreateFileW(
wszPath,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile)
{
DWORD dwNumberOfBytesWritten = 0;
if (WriteFile(
hFile,
pRscr,
cbRscr,
&dwNumberOfBytesWritten,
NULL
))
{
CloseHandle(hFile);
SHELLEXECUTEINFO ShExecInfo = { 0 };
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = wszPath;
ShExecInfo.lpParameters = L"";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
DWORD dwExitCode = 0;
GetExitCodeProcess(ShExecInfo.hProcess, &dwExitCode);
if (!dwExitCode)
{
PostMessage(hwnd, WM_CLOSE, 0, 0);
}
CloseHandle(ShExecInfo.hProcess);
DeleteFileW(wszPath);
}
}
}
else if (!strncmp(line + 1, "about", 5))
{
DWORD dwLeftMost = 0;
DWORD dwSecondLeft = 0;
DWORD dwSecondRight = 0;
DWORD dwRightMost = 0;
QueryVersionInfo(hModule, VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost);
TCHAR wszIDS_VISITGITHUB[100];
LoadString(hModule, IDS_VISITGITHUB, wszIDS_VISITGITHUB, 100);
TCHAR wszIDS_VISITWEBSITE[100];
LoadString(hModule, IDS_VISITWEBSITE, wszIDS_VISITWEBSITE, 100);
TCHAR wszIDS_LICENSEINFO[100];
LoadString(hModule, IDS_LICENSEINFO, wszIDS_LICENSEINFO, 100);
TCHAR wszIDS_PRODUCTNAME[100];
LoadString(hModule, IDS_PRODUCTNAME, wszIDS_PRODUCTNAME, 100);
TCHAR wszIDS_VERSION[100];
LoadString(hModule, IDS_VERSION, wszIDS_VERSION, 100);
TCHAR wszIDS_PRODUCTTAG[406];
wsprintf(wszIDS_PRODUCTTAG, wszIDS_VERSION, dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost);
wcscat_s(
wszIDS_PRODUCTTAG,
406,
L"\r\n"
);
LoadString(hModule, IDS_COPYRIGHT, wszIDS_PRODUCTTAG + wcslen(wszIDS_PRODUCTTAG), 100);
wcscat_s(
wszIDS_PRODUCTTAG,
406,
L"\r\n\r\n"
);
LoadString(hModule, IDS_PRODUCTTAG, wszIDS_PRODUCTTAG + wcslen(wszIDS_PRODUCTTAG), 200);
TASKDIALOG_BUTTON buttons[3];
buttons[0].nButtonID = IDS_VISITGITHUB;
buttons[0].pszButtonText = wszIDS_VISITGITHUB;
buttons[1].nButtonID = IDS_VISITWEBSITE;
buttons[1].pszButtonText = wszIDS_VISITWEBSITE;
buttons[2].nButtonID = IDS_LICENSEINFO;
buttons[2].pszButtonText = wszIDS_LICENSEINFO;
TASKDIALOGCONFIG td;
ZeroMemory(&td, sizeof(TASKDIALOGCONFIG));
td.cbSize = sizeof(TASKDIALOGCONFIG);
td.hwndParent = hwnd;
td.hInstance = hModule;
td.dwFlags = TDF_ALLOW_DIALOG_CANCELLATION | TDF_SIZE_TO_CONTENT | TDF_USE_COMMAND_LINKS;
td.dwCommonButtons = TDCBF_OK_BUTTON;
td.pszWindowTitle = L" ";
td.pszMainIcon = TD_INFORMATION_ICON;
td.pszMainInstruction = wszIDS_PRODUCTNAME;
td.pszContent = wszIDS_PRODUCTTAG;
td.cButtons = sizeof(buttons) / sizeof(buttons[0]);
td.pButtons = buttons;
td.nDefaultButton = IDOK;
td.cRadioButtons = 0;
td.pRadioButtons = NULL;
td.cxWidth = 0;
td.pszFooter = L"";
td.pfCallback = GUI_AboutProc;
td.lpCallbackData = 0;
int ret;
HRESULT hr = TaskDialogIndirect(
&td,
&ret,
NULL,
NULL
);
}
}
}
dwCL += dwLineHeight * dy;
}
else if (!strncmp(line, ";l ", 3) || !strncmp(line, ";c ", 3) || !strncmp(line, ";b ", 3) || !strncmp(line, ";i ", 3) || !strncmp(line, ";d ", 3) || !strncmp(line, ";v ", 3))
{
ZeroMemory(text, MAX_LINE_LENGTH * sizeof(wchar_t));
text[0] = L'\u2795';
text[1] = L' ';
text[2] = L' ';
MultiByteToWideChar(
CP_UTF8,
MB_PRECOMPOSED,
!strncmp(line, ";c ", 3) ? strchr(line + 3, ' ') + 1 : line + 3,
numChRd - 3,
text + 3,
MAX_LINE_LENGTH
);
wchar_t* x = wcschr(text, L'\n');
if (x) *x = 0;
x = wcschr(text, L'\r');
if (x) *x = 0;
if (!strncmp(line, ";c ", 3) || !strncmp(line, ";b ", 3) || !strncmp(line, ";i ", 3) || !strncmp(line, ";d ", 3) || !strncmp(line, ";v ", 3))
{
HMENU hMenu = NULL;
BOOL bChoice = !strncmp(line, ";c ", 3);
BOOL bInvert = !strncmp(line, ";i ", 3);
BOOL bJustCheck = !strncmp(line, ";d ", 3);
BOOL bBool = !strncmp(line, ";b ", 3);
BOOL bValue = !strncmp(line, ";v ", 3);
DWORD numChoices = 0;
if (bChoice)
{
char* p = strchr(line + 3, ' ');
if (p) *p = 0;
numChoices = atoi(line + 3);
hMenu = CreatePopupMenu();
for (unsigned int i = 0; i < numChoices; ++i)
{
char* l = malloc(MAX_LINE_LENGTH * sizeof(char));
numChRd = getline(&l, &bufsiz, f);
if (strncmp(l, ";x ", 3))
{
i--;
continue;
}
char* p = strchr(l + 3, ' ');
if (p) *p = 0;
char* ln = p + 1;
p = strchr(p + 1, '\r');
if (p) *p = 0;
p = strchr(p + 1, '\n');
if (p) *p = 0;
MENUITEMINFOA menuInfo;
ZeroMemory(&menuInfo, sizeof(MENUITEMINFOA));
menuInfo.cbSize = sizeof(MENUITEMINFOA);
menuInfo.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA | MIIM_STATE;
menuInfo.wID = atoi(l + 3) + 1;
menuInfo.dwItemData = l;
menuInfo.fType = MFT_STRING;
menuInfo.dwTypeData = ln;
menuInfo.cch = strlen(ln);
InsertMenuItemA(
hMenu,
i,
TRUE,
&menuInfo
);
}
}
numChRd = getline(&line, &bufsiz, f);
ZeroMemory(name, MAX_LINE_LENGTH * sizeof(wchar_t));
MultiByteToWideChar(
CP_UTF8,
MB_PRECOMPOSED,
line[0] == '"' ? line + 1 : line,
numChRd,
name,
MAX_LINE_LENGTH
);
wchar_t* d = wcschr(name, L'=');
if (d) *d = 0;
wchar_t* p = wcschr(name, L'"');
if (p) *p = 0;
HKEY hKey;
DWORD dwDisposition;
DWORD dwSize = sizeof(DWORD);
DWORD value = FALSE;
//wprintf(L"%s %s %s\n", section, name, d + 1);
if (!wcsncmp(d + 1, L"dword:", 6))
{
wchar_t* x = wcschr(d + 1, L':');
x++;
value = _wtoi(x);
}
if (!bJustCheck)
{
RegCreateKeyExW(
HKEY_CURRENT_USER,
wcschr(section, L'\\') + 1,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | (hDC ? 0 : KEY_WRITE),
NULL,
&hKey,
&dwDisposition
);
RegQueryValueExW(
hKey,
name,
0,
NULL,
&value,
&dwSize
);
if (hDC && bInvert)
{
value = !value;
}
}
else
{
RegOpenKeyExW(
HKEY_CURRENT_USER,
wcschr(section, L'\\') + 1,
REG_OPTION_NON_VOLATILE,
KEY_READ | (hDC ? 0 : KEY_WRITE),
&hKey
);
value = hKey;
}
if (bInvert || bBool || bJustCheck)
{
if (value)
{
text[0] = L'\u2714';
}
else
{
text[0] = L'\u274C';
}
text[1] = L' ';
text[2] = L' ';
}
else if (bValue)
{
wcscat_s(
text,
MAX_LINE_LENGTH,
L" : "
);
wchar_t buf[100];
_itow_s(value, buf, 100, 10);
wcscat_s(
text,
MAX_LINE_LENGTH,
buf
);
}
else if (bChoice)
{
wcscat_s(
text,
MAX_LINE_LENGTH,
L" : "
);
MENUITEMINFOA menuInfo;
ZeroMemory(&menuInfo, sizeof(MENUITEMINFOA));
menuInfo.cbSize = sizeof(MENUITEMINFOA);
menuInfo.fMask = MIIM_STRING;
GetMenuItemInfoA(hMenu, value + 1, FALSE, &menuInfo);
char* buf = malloc(sizeof(char) * (menuInfo.cch + 1));
menuInfo.dwTypeData = buf;
menuInfo.cch += 1;
GetMenuItemInfoA(hMenu, value + 1, FALSE, &menuInfo);
MultiByteToWideChar(
CP_UTF8,
MB_PRECOMPOSED,
buf,
menuInfo.cch,
text + wcslen(text),
MAX_LINE_LENGTH
);
}
RECT rcTemp;
rcTemp = rcText;
DrawText(
GetDC(hwnd),
text,
-1,
&rcTemp,
DT_CALCRECT
);
rcTemp.bottom = rcText.bottom;
if (!hDC && PtInRect(&rcTemp, pt))
{
if (bJustCheck)
{
if (hKey)
{
RegCloseKey(hKey);
RegDeleteKeyExW(
HKEY_CURRENT_USER,
wcschr(section, L'\\') + 1,
REG_OPTION_NON_VOLATILE,
0
);
}
else
{
RegCreateKeyExW(
HKEY_CURRENT_USER,
wcschr(section, L'\\') + 1,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
NULL,
&hKey,
&dwDisposition
);
if (d[1] == '"')
{
wchar_t* p = wcschr(d + 2, L'"');
if (p) *p = 0;
RegSetValueExW(
hKey,
!wcsncmp(name, L"@", 1) ? NULL : name,
0,
REG_SZ,
d + 2,
wcslen(d + 2) * sizeof(wchar_t)
);
}
}
}
else
{
if (bChoice)
{
POINT p;
p.x = rcText.left;
p.y = rcText.bottom;
ClientToScreen(
hwnd,
&p
);
DWORD val = TrackPopupMenu(
hMenu,
TPM_RETURNCMD | TPM_RIGHTBUTTON,
p.x,
p.y,
0,
hwnd,
0
);
if (val > 0) value = val - 1;
}
else if (bValue)
{
}
else
{
value = !value;
}
RegSetValueExW(
hKey,
name,
0,
REG_DWORD,
&value,
sizeof(DWORD)
);
}
InvalidateRect(hwnd, NULL, FALSE);
}
RegCloseKey(hKey);
if (bChoice)
{
for (unsigned int i = 0; i < numChoices; ++i)
{
MENUITEMINFOA menuInfo;
ZeroMemory(&menuInfo, sizeof(MENUITEMINFOA));
menuInfo.cbSize = sizeof(MENUITEMINFOA);
menuInfo.fMask = MIIM_DATA;
GetMenuItemInfoA(hMenu, i, TRUE, &menuInfo);
if (menuInfo.dwItemData)
{
free(menuInfo.dwItemData);
}
}
DestroyMenu(hMenu);
}
}
if (!hDC && !strncmp(line, ";l ", 3))
{
RECT rcTemp;
rcTemp = rcText;
DrawText(
GetDC(hwnd),
text,
-1,
&rcTemp,
DT_CALCRECT
);
rcTemp.bottom = rcText.bottom;
//printf("%d %d %d %d %d %d %d %d\n", rcText.left, rcText.top, rcText.right, rcText.bottom, rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom);
if (PtInRect(&rcTemp, pt))
{
numChRd = getline(&line, &bufsiz, f);
char* p = strchr(line, '\r');
if (p) *p = 0;
p = strchr(line, '\n');
if (p) *p = 0;
ShellExecuteA(
NULL,
"open",
line + 1,
NULL,
NULL,
SW_SHOWNORMAL
);
}
}
if (hDC)
{
DrawThemeTextEx(
_this->hTheme,
hdcPaint,
0,
0,
text,
-1,
dwTextFlags,
&rcText,
&DttOpts
);
}
dwCL += dwLineHeight * dy;
}
}
}
fclose(f);
if (hDC)
{
SelectObject(hdcPaint, hOldFont);
DeleteObject(hFontRegular);
DeleteObject(hFontTitle);
DeleteObject(hFontUnderline);
DeleteObject(hFontCaption);
}
EndBufferedPaint(hBufferedPaint, TRUE);
}
return TRUE;
}
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
GUI* _this;
if (uMsg == WM_CREATE)
{
CREATESTRUCT* pCreate = (CREATESTRUCT*)(lParam);
_this = (int*)(pCreate->lpCreateParams);
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)_this);
UINT dpiX, dpiY, dpiXP, dpiYP;
POINT ptCursor, ptZero;
ptZero.x = 0;
ptZero.y = 0;
GetCursorPos(&ptCursor);
HMONITOR hMonitor = MonitorFromPoint(ptCursor, MONITOR_DEFAULTTOPRIMARY);
HMONITOR hPrimaryMonitor = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY);
HRESULT hr = GetDpiForMonitor(
hMonitor,
MDT_DEFAULT,
&dpiX,
&dpiY
);
hr = GetDpiForMonitor(
hPrimaryMonitor,
MDT_DEFAULT,
&dpiXP,
&dpiYP
);
MONITORINFO mi;
mi.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(hMonitor, &mi);
double dx = dpiX / 96.0, dy = dpiY / 96.0, dxp = dpiXP / 96.0, dyp = dpiYP / 96.0;
_this->dpi.x = dpiX;
_this->dpi.y = dpiY;
SetWindowPos(
hWnd,
hWnd,
mi.rcWork.left + ((mi.rcWork.right - mi.rcWork.left) / 2 - (_this->size.cx * dx) / 2),
mi.rcWork.top + ((mi.rcWork.bottom - mi.rcWork.top) / 2 - (_this->size.cy * dy) / 2),
_this->size.cx * dxp,
_this->size.cy * dyp,
SWP_NOZORDER | SWP_NOACTIVATE
);
}
else
{
LONG_PTR ptr = GetWindowLongPtr(hWnd, GWLP_USERDATA);
_this = (int*)(ptr);
}
if (uMsg == WM_DESTROY)
{
PostQuitMessage(0);
return 0;
}
else if (uMsg == WM_NCHITTEST)
{
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
ScreenToClient(hWnd, &pt);
if (pt.y < _this->extent.cyTopHeight)
{
return HTCAPTION;
}
}
else if (uMsg == WM_LBUTTONDOWN)
{
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
GUI_Build(0, hWnd, pt);
}
else if (uMsg == WM_DPICHANGED)
{
_this->dpi.x = LOWORD(wParam);
_this->dpi.y = HIWORD(wParam);
RECT* rc = lParam;
SetWindowPos(
hWnd,
hWnd,
rc->left,
rc->top,
rc->right - rc->left,
rc->bottom - rc->top,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS
);
return 0;
}
else if (uMsg == WM_PAINT)
{
MARGINS marGlassInset = { -1, -1, -1, -1 }; // -1 means the whole window
DwmExtendFrameIntoClientArea(hWnd, &marGlassInset);
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
RECT rc;
GetClientRect(hWnd, &rc);
POINT pt;
pt.x = 0;
pt.y = 0;
GUI_Build(hDC, hWnd, pt);
EndPaint(hWnd, &ps);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
__declspec(dllexport) int ZZGUI(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow)
{
/*
FILE* conout;
AllocConsole();
freopen_s(
&conout,
"CONOUT$",
"w",
stdout
);
*/
printf("Started \"GUI\" thread.\n");
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
GUI _this;
_this.hBackgroundBrush = (HBRUSH)GetStockObject(BLACK_BRUSH);
_this.location.x = GUI_POSITION_X;
_this.location.y = GUI_POSITION_Y;
_this.size.cx = GUI_POSITION_WIDTH;
_this.size.cy = GUI_POSITION_HEIGHT;
_this.padding.left = GUI_PADDING_LEFT;
_this.padding.right = GUI_PADDING_RIGHT;
_this.padding.top = GUI_PADDING_TOP;
_this.padding.bottom = GUI_PADDING_BOTTOM;
_this.hTheme = OpenThemeData(NULL, TEXT(GUI_WINDOWSWITCHER_THEME_CLASS));
WNDCLASS wc = { 0 };
ZeroMemory(&wc, sizeof(WNDCLASSW));
wc.style = CS_DBLCLKS;
wc.lpfnWndProc = WindowProc;
wc.hbrBackground = _this.hBackgroundBrush;
wc.hInstance = hModule;
wc.lpszClassName = L"ExplorerPatcherGUI";
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
RegisterClassW(&wc);
TCHAR title[260];
LoadStringW(GetModuleHandleW(L"ExplorerFrame.dll"), 726, title, 260);
HWND hwnd = CreateWindowEx(
NULL,
L"ExplorerPatcherGUI",
title,
WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
0,
0,
0,
0,
NULL, NULL, hModule, &_this
);
if (!hwnd)
{
return 1;
}
BOOL value = 1;
DwmSetWindowAttribute(hwnd, 1029, &value, sizeof(BOOL));
WTA_OPTIONS ops;
ops.dwFlags = WTNCA_NODRAWCAPTION | WTNCA_NODRAWICON;
ops.dwMask = WTNCA_NODRAWCAPTION | WTNCA_NODRAWICON;
SetWindowThemeAttribute(
hwnd,
WTA_NONCLIENT,
&ops,
sizeof(WTA_OPTIONS)
);
ShowWindow(hwnd, SW_SHOW);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
printf("Ended \"GUI\" thread.\n");
}

62
ExplorerPatcher/GUI.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef _H_GUI_H_
#define _H_GUI_H_
#include <Windows.h>
#pragma comment(lib, "Version.lib")
#include <windowsx.h>
#include <tlhelp32.h>
#include <shellscalingapi.h>
#pragma comment(lib, "Shcore.lib")
#include <conio.h>
#include <stdio.h>
#include <Uxtheme.h>
#pragma comment(lib, "UxTheme.lib")
#include <dwmapi.h>
#pragma comment(lib, "Dwmapi.lib")
#include "resource.h"
#include "getline.h"
#include "fmemopen.h"
#include "utility.h"
#define MAX_LINE_LENGTH 2000
extern HMODULE hModule;
#define GUI_POSITION_X CW_USEDEFAULT
#define GUI_POSITION_Y CW_USEDEFAULT
#define GUI_POSITION_WIDTH 467
#define GUI_POSITION_HEIGHT 790
#define GUI_WINDOWSWITCHER_THEME_CLASS "ControlPanelStyle"
#define GUI_CAPTION_FONT_SIZE -22
#define GUI_TITLE_FONT_SIZE -12
#define GUI_LINE_HEIGHT 30
#define GUI_CAPTION_LINE_HEIGHT 42
#define GUI_TEXTCOLOR RGB(0, 0, 0)
#define GUI_PADDING 5
#define GUI_PADDING_LEFT GUI_PADDING * 3
#define GUI_PADDING_RIGHT GUI_PADDING * 3
#define GUI_PADDING_TOP GUI_PADDING
#define GUI_PADDING_BOTTOM GUI_PADDING
typedef struct _GUI
{
POINT location;
SIZE size;
RECT padding;
HBRUSH hBackgroundBrush;
HTHEME hTheme;
POINT dpi;
MARGINS extent;
} GUI;
static HRESULT GUI_AboutProc(
HWND hwnd,
UINT uNotification,
WPARAM wParam,
LPARAM lParam,
LONG_PTR lpRefData
);
static BOOL GUI_Build(HDC hDC, HWND hWnd);
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
__declspec(dllexport) int ZZGUI(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow);
#endif

View File

@ -27,6 +27,7 @@
#include "SettingsMonitor.h" #include "SettingsMonitor.h"
#include "HideExplorerSearchBar.h" #include "HideExplorerSearchBar.h"
#include "StartMenu.h" #include "StartMenu.h"
#include "GUI.h"
#define SB_MICA_EFFECT_SUBCLASS_OFFSET 0x5C70 #define SB_MICA_EFFECT_SUBCLASS_OFFSET 0x5C70
#define SB_INIT1 0x26070 #define SB_INIT1 0x26070
@ -245,6 +246,32 @@ DWORD ShowLauncherTipContextMenu(
{ {
goto finalize; goto finalize;
} }
TCHAR buffer[260];
LoadStringW(GetModuleHandleW(L"ExplorerFrame.dll"), 50222, buffer + 1, 260);
buffer[0] = L'&';
wchar_t* p = wcschr(buffer, L'(');
if (p)
{
p--;
*p = 0;
}
MENUITEMINFOW menuInfo;
ZeroMemory(&menuInfo, sizeof(MENUITEMINFOW));
menuInfo.cbSize = sizeof(MENUITEMINFOW);
menuInfo.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA | MIIM_STATE;
menuInfo.wID = 3999;
menuInfo.dwItemData = 0;
menuInfo.fType = MFT_STRING;
menuInfo.dwTypeData = buffer;
menuInfo.cch = wcslen(buffer);
InsertMenuItemW(
*((HMENU*)((char*)params->_this + 0xe8)),
GetMenuItemCount(*((HMENU*)((char*)params->_this + 0xe8))) - 1,
TRUE,
&menuInfo
);
INT64* unknown_array = calloc(4, sizeof(INT64)); INT64* unknown_array = calloc(4, sizeof(INT64));
ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc( ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc(
@ -272,9 +299,19 @@ DWORD ShowLauncherTipContextMenu(
); );
free(unknown_array); free(unknown_array);
RemoveMenu(
*((HMENU*)((char*)params->_this + 0xe8)),
3999,
MF_BYCOMMAND
);
if (res > 0) if (res > 0)
{ {
if (res < 4000) if (res == 3999)
{
CreateThread(0, 0, ZZGUI, 0, 0, 0);
}
else if (res < 4000)
{ {
INT64 info = *(INT64*)((char*)(*(INT64*)((char*)params->_this + 0xa8 - 0x58)) + (INT64)res * 8 - 8); INT64 info = *(INT64*)((char*)(*(INT64*)((char*)params->_this + 0xa8 - 0x58)) + (INT64)res * 8 - 8);
CLauncherTipContextMenu_ExecuteCommandFunc( CLauncherTipContextMenu_ExecuteCommandFunc(
@ -1073,7 +1110,7 @@ __declspec(dllexport) DWORD WINAPI main(
DWORD bAllocConsole = FALSE; DWORD bAllocConsole = FALSE;
RegQueryValueExW( RegQueryValueExW(
hKey, hKey,
TEXT("bAllocConsole"), TEXT("AllocConsole"),
0, 0,
NULL, NULL,
&bAllocConsole, &bAllocConsole,
@ -1119,7 +1156,7 @@ __declspec(dllexport) DWORD WINAPI main(
RegQueryValueExW( RegQueryValueExW(
hKey, hKey,
TEXT("bHideExplorerSearchBar"), TEXT("HideExplorerSearchBar"),
0, 0,
NULL, NULL,
&bHideExplorerSearchBar, &bHideExplorerSearchBar,
@ -1127,7 +1164,7 @@ __declspec(dllexport) DWORD WINAPI main(
); );
RegQueryValueExW( RegQueryValueExW(
hKey, hKey,
TEXT("bMicaEffectOnTitlebar"), TEXT("MicaEffectOnTitlebar"),
0, 0,
NULL, NULL,
&bMicaEffectOnTitlebar, &bMicaEffectOnTitlebar,
@ -1135,7 +1172,7 @@ __declspec(dllexport) DWORD WINAPI main(
); );
RegQueryValueExW( RegQueryValueExW(
hKey, hKey,
TEXT("bHideControlCenterButton"), TEXT("HideControlCenterButton"),
0, 0,
NULL, NULL,
&bHideControlCenterButton, &bHideControlCenterButton,
@ -1143,7 +1180,7 @@ __declspec(dllexport) DWORD WINAPI main(
); );
RegQueryValueExW( RegQueryValueExW(
hKey, hKey,
TEXT("bSkinMenus"), TEXT("SkinMenus"),
0, 0,
NULL, NULL,
&bSkinMenus, &bSkinMenus,
@ -1151,7 +1188,7 @@ __declspec(dllexport) DWORD WINAPI main(
); );
RegQueryValueExW( RegQueryValueExW(
hKey, hKey,
TEXT("bSkinIcons"), TEXT("SkinIcons"),
0, 0,
NULL, NULL,
&bSkinIcons, &bSkinIcons,
@ -1365,7 +1402,7 @@ __declspec(dllexport) DWORD WINAPI main(
DWORD delay = 0; DWORD delay = 0;
RegQueryValueExW( RegQueryValueExW(
hKey, hKey,
TEXT("vExplorerReadyDelay"), TEXT("ExplorerReadyDelay"),
0, 0,
NULL, NULL,
&delay, &delay,
@ -1401,7 +1438,7 @@ __declspec(dllexport) DWORD WINAPI main(
DWORD bEnableArchivePlugin = 0; DWORD bEnableArchivePlugin = 0;
RegQueryValueExW( RegQueryValueExW(
hKey, hKey,
TEXT("bArchiveMenu"), TEXT("ArchiveMenu"),
0, 0,
NULL, NULL,
&bEnableArchivePlugin, &bEnableArchivePlugin,

View File

@ -0,0 +1,67 @@
/*-
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of Novell nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "fmemopen.h"
FILE*
fmemopen(void* buf, size_t size, const char* mode)
{
char temppath[MAX_PATH + 1];
char tempnam[MAX_PATH + 1];
DWORD l;
HANDLE fh;
FILE* fp;
if (strcmp(mode, "r") != 0 && strcmp(mode, "r+") != 0)
return 0;
l = GetTempPathA(MAX_PATH, temppath);
if (!l || l >= MAX_PATH)
return 0;
if (!GetTempFileNameA(temppath, "solvtmp", 0, tempnam))
return 0;
fh = CreateFileA(tempnam, DELETE | GENERIC_READ | GENERIC_WRITE, 0,
NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
NULL);
if (fh == INVALID_HANDLE_VALUE)
return 0;
fp = _fdopen(_open_osfhandle((intptr_t)fh, 0), "w+b");
if (!fp)
{
CloseHandle(fh);
return 0;
}
if (buf && size && fwrite(buf, size, 1, fp) != 1)
{
fclose(fp);
return 0;
}
rewind(fp);
return fp;
}

View File

@ -0,0 +1,8 @@
#ifndef _H_FMEMOPEN_H_
#define _H_FMEMOPEN_H_
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <windows.h>
FILE* fmemopen(void* buf, size_t size, const char* mode);
#endif

78
ExplorerPatcher/getline.c Normal file
View File

@ -0,0 +1,78 @@
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "getline.h"
ssize_t
getdelim(char** buf, size_t* bufsiz, int delimiter, FILE* fp)
{
char* ptr, * eptr;
if (*buf == NULL || *bufsiz == 0) {
*bufsiz = BUFSIZ;
if ((*buf = (char*)malloc(*bufsiz)) == NULL)
return -1;
}
for (ptr = *buf, eptr = *buf + *bufsiz;;) {
int c = fgetc(fp);
if (c == -1) {
if (feof(fp)) {
ssize_t diff = (ssize_t)(ptr - *buf);
if (diff != 0) {
*ptr = '\0';
return diff;
}
}
return -1;
}
*ptr++ = c;
if (c == delimiter) {
*ptr = '\0';
return ptr - *buf;
}
if (ptr + 2 >= eptr) {
char* nbuf;
size_t nbufsiz = *bufsiz * 2;
ssize_t d = ptr - *buf;
if ((nbuf = (char*)realloc(*buf, nbufsiz)) == NULL)
return -1;
*buf = nbuf;
*bufsiz = nbufsiz;
eptr = nbuf + nbufsiz;
ptr = nbuf + d;
}
}
}
ssize_t
getline(char** buf, size_t* bufsiz, FILE* fp)
{
return getdelim(buf, bufsiz, '\n', fp);
}

12
ExplorerPatcher/getline.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef _H_GETLINE_H_
#define _H_GETLINE_H_
#include <stdio.h>
#include <stdlib.h>
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
ssize_t getdelim(char** buf, size_t* bufsiz, int delimiter, FILE* fp);
ssize_t getline(char** buf, size_t* bufsiz, FILE* fp);
#endif

View File

@ -2,12 +2,20 @@
// Microsoft Visual C++ generated include file. // Microsoft Visual C++ generated include file.
// Used by ExplorerPatcher.rc // Used by ExplorerPatcher.rc
// //
#define IDR_REGISTRY1 101
#define IDS_PRODUCTNAME 102
#define IDS_COPYRIGHT 103
#define IDS_VERSION 104
#define IDS_PRODUCTTAG 105
#define IDS_VISITGITHUB 106
#define IDS_VISITWEBSITE 107
#define IDS_LICENSEINFO 108
// Next default values for new objects // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101 #define _APS_NEXT_SYMED_VALUE 101

View File

@ -0,0 +1,93 @@
Windows Registry Editor Version 5.00
;M Properties
;T Shell
;l Enable missing system tray icons
;shell:::{05d7b0f4-2121-4eff-bf6b-ed3f69b894d9}\SystemIcons
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced]
;c 3 Combine taskbar icons on main taskbar *
;x 0 Always combine
;x 1 Combine when taskbar is full
;x 2 Never combine
"TaskbarGlomLevel"=dword:00000002
;c 3 Combine taskbar icons on other taskbars *
;x 0 Always combine
;x 1 Combine when taskbar is full
;x 2 Never combine
"MMTaskbarGlomLevel"=dword:00000002
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher]
;b Disable Control Center button *
"HideControlCenterButton"=dword:00000000
;b Apply immersive style to system tray icon menus *
"SkinMenus"=dword:00000001
;b Apply Windows 11 style to system tray icons (requires StartIsBack64.dll) *
"SkinIcons"=dword:00000001
;T File Explorer
[-HKEY_CURRENT_USER\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32]
;d Disable immersive context menu *
@=""
[-HKEY_CURRENT_USER\Software\Classes\CLSID\{d93ed569-3b3e-4bff-8355-3c44f6a52bb5}\InprocServer32]
;d Disable command bar *
@=""
[-HKEY_CURRENT_USER\Software\Classes\CLSID\{1d64637d-31e9-4b06-9124-e83fb178ac6e}\TreatAs]
;d Disable modern search bar
@="{64bc32b5-4eec-4de7-972d-bd8bd0324537}"
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher]
;b Hide search bar completely *
"HideExplorerSearchBar"=dword:00000000
;b Mica effect on title bar (requires StartIsBack64.dll) *
"MicaEffectOnTitlebar"=dword:00000000
;T Start menu
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StartPage]
;b Open Start to All apps by default
"MakeAllAppsDefault"=dword:00000000
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced]
;c 22 Maximum number of frequent apps to show in Start
;x 0 None
;x 1 1
;x 2 2
;x 3 3
;x 4 4
;x 5 5
;x 6 6 (default)
;x 7 7
;x 8 8
;x 9 9
;x 10 10
;x 11 11
;x 12 12
;x 13 13
;x 14 14
;x 15 15
;x 16 16
;x 17 17
;x 18 18
;x 19 19
;x 20 20
;x 99999 Unlimited
"Start_MaximumFrequentApps"=dword:00000006
;T Advanced
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher]
;b Enable console *
"AllocConsole"=dword:00000000
;c 7 Supplimentary delay at logon *
;x 0 None (default)
;x 300 300 ms
;x 600 600 ms
;x 1000 1 second
;x 1500 1.5 seconds
;x 2000 2 seconds
;x 3000 3 seconds
"ExplorerReadyDelay"=dword:00000000
;t Settings marked with an (*) require restarting the File Explorer process.
;u Restart File Explorer
;restart
;u Restore default settings
;reset
;u About ExplorerPatcher
;about

View File

@ -125,7 +125,7 @@ DWORD DownloadSymbols(DownloadSymbolsParams* params)
); );
SHGetFolderPathA( SHGetFolderPathA(
NULL, NULL,
CSIDL_APPDATA, SPECIAL_FOLDER,
NULL, NULL,
SHGFP_TYPE_CURRENT, SHGFP_TYPE_CURRENT,
szSettingsPath szSettingsPath
@ -133,7 +133,7 @@ DWORD DownloadSymbols(DownloadSymbolsParams* params)
strcat_s( strcat_s(
szSettingsPath, szSettingsPath,
MAX_PATH, MAX_PATH,
SYMBOLS_RELATIVE_PATH APP_RELATIVE_PATH
); );
CreateDirectoryA(szSettingsPath, NULL); CreateDirectoryA(szSettingsPath, NULL);
strcat_s( strcat_s(
@ -440,7 +440,7 @@ DWORD DownloadSymbols(DownloadSymbolsParams* params)
} }
RegSetValueExW( RegSetValueExW(
hKey, hKey,
TEXT("szOSBuild"), TEXT("OSBuild"),
0, 0,
REG_SZ, REG_SZ,
szReportedVersion, szReportedVersion,
@ -683,7 +683,7 @@ BOOL LoadSymbols(symbols_addr* symbols_PTRS)
dwSize = MAX_PATH; dwSize = MAX_PATH;
RegQueryValueExW( RegQueryValueExW(
hKey, hKey,
TEXT("szOSBuild"), TEXT("OSBuild"),
0, 0,
NULL, NULL,
szStoredVersion, szStoredVersion,

View File

@ -9,7 +9,6 @@
#define EXIT_CODE_EXPLORER 1 #define EXIT_CODE_EXPLORER 1
#define SYMBOLS_RELATIVE_PATH "\\ExplorerPatcher"
#define TWINUI_PCSHELL_SB_NAME "twinui.pcshell" #define TWINUI_PCSHELL_SB_NAME "twinui.pcshell"
#define TWINUI_PCSHELL_SB_0 "CImmersiveContextMenuOwnerDrawHelper::s_ContextMenuWndProc" #define TWINUI_PCSHELL_SB_0 "CImmersiveContextMenuOwnerDrawHelper::s_ContextMenuWndProc"
#define TWINUI_PCSHELL_SB_1 "CLauncherTipContextMenu::GetMenuItemsAsync" #define TWINUI_PCSHELL_SB_1 "CLauncherTipContextMenu::GetMenuItemsAsync"

View File

@ -355,4 +355,34 @@ POINT GetDefaultWinXPosition(BOOL bUseRcWork, BOOL* lpBottom, BOOL* lpRight)
} }
} }
return point; return point;
}
void QueryVersionInfo(HMODULE hModule, WORD Resource, DWORD* dwLeftMost, DWORD* dwSecondLeft, DWORD* dwSecondRight, DWORD* dwRightMost)
{
HRSRC hResInfo;
DWORD dwSize;
HGLOBAL hResData;
LPVOID pRes, pResCopy;
UINT uLen;
VS_FIXEDFILEINFO* lpFfi;
hResInfo = FindResource(hModule, MAKEINTRESOURCE(Resource), RT_VERSION);
dwSize = SizeofResource(hModule, hResInfo);
hResData = LoadResource(hModule, hResInfo);
pRes = LockResource(hResData);
pResCopy = LocalAlloc(LMEM_FIXED, dwSize);
CopyMemory(pResCopy, pRes, dwSize);
FreeResource(hResData);
VerQueryValue(pResCopy, TEXT("\\"), (LPVOID*)&lpFfi, &uLen);
DWORD dwFileVersionMS = lpFfi->dwFileVersionMS;
DWORD dwFileVersionLS = lpFfi->dwFileVersionLS;
*dwLeftMost = HIWORD(dwFileVersionMS);
*dwSecondLeft = LOWORD(dwFileVersionMS);
*dwSecondRight = HIWORD(dwFileVersionLS);
*dwRightMost = LOWORD(dwFileVersionLS);
LocalFree(pResCopy);
} }

View File

@ -9,6 +9,8 @@
#define APPID L"Microsoft.Windows.Explorer" #define APPID L"Microsoft.Windows.Explorer"
#define REGPATH "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ExplorerPatcher" #define REGPATH "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ExplorerPatcher"
#define SPECIAL_FOLDER CSIDL_APPDATA
#define APP_RELATIVE_PATH "\\ExplorerPatcher"
#pragma region "Weird stuff" #pragma region "Weird stuff"
INT64 nimpl4_1(INT64 a1, DWORD* a2); INT64 nimpl4_1(INT64 a1, DWORD* a2);
@ -43,4 +45,6 @@ __declspec(dllexport) CALLBACK ZZLaunchExplorer(HWND hWnd, HINSTANCE hInstance,
__declspec(dllexport) CALLBACK ZZLaunchExplorerDelayed(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow); __declspec(dllexport) CALLBACK ZZLaunchExplorerDelayed(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow);
POINT GetDefaultWinXPosition(BOOL bUseRcWork, BOOL* lpBottom, BOOL* lpRight); POINT GetDefaultWinXPosition(BOOL bUseRcWork, BOOL* lpBottom, BOOL* lpRight);
void QueryVersionInfo(HMODULE hModule, WORD Resource, DWORD*, DWORD*, DWORD*, DWORD*);
#endif #endif

View File

@ -4,10 +4,11 @@ This project aims to bring back a productive working environment on Windows 11.
<details> <details>
<summary>About ExplorerPatcher and StartIsBack</summary> <summary>About ExplorerPatcher and StartIsBack</summary>
The well-known [StartIsBack](https://www.startisback.com/) application recently introduced support for Windows 11. Currently, regarding Windows 11 functionality, it offers the same features as this patcher, plus all the functionalities from the older releases of the software; thus the differences between the two at the moment, besides their internal implementation (probably) resort in the cost, licensing, support and development model: StartIsBack is a paid app, proprietary, closed source and comes with support, while ExplorerPatcher is free ([gratis and libre - as in free beer and free speech](https://en.wikipedia.org/wiki/Gratis_versus_libre)), open source and is provided as-is, with support offered in a best-effort attempt. The well-known [StartIsBack](https://www.startisback.com/) application recently introduced support for Windows 11. Currently, regarding Windows 11 functionality, it offers the same features as this patcher, plus all the functionalities from the older releases of the software; thus the differences between the two at the moment, besides their internal implementation (probably) resort in the cost, licensing, support and development model: StartIsBack is a paid app, proprietary, closed source and comes with support, while ExplorerPatcher is free ([gratis and libre - as in free beer and free speech](https://en.wikipedia.org/wiki/Gratis_versus_libre)), open source and is provided as-is, with support offered in a best-effort attempt.
ExplorerPatcher is offered more like a tool for people to study the source code and the techniques used, to learn and adapt it in order and to enable people to build each on top of the work of the others. The aim is to benefit both the community and its users. You are encouraged to take a look at the source and adapt it to your needs. While the source and the application in its current form will always be available here, I cannot make any guarantes over how long it will work in newer Windows 11 builds. Thus, these things being considered, if you would like, you can check out the beta test for StartIsBack [here](http://startisback.com/tbd/) and report any issues and make suggestions to its developer. It will probably mature in a release that will be better supported from a consumer point of view than ExplorerPatcher. ExplorerPatcher is offered more like a tool for people to study the source code and the techniques used, to learn and adapt it in order and to enable people to build each on top of the work of the others. The aim is to benefit both the community and its users. You are encouraged to take a look at the source and adapt it to your needs. While the source and the application in its current form will always be available here, I cannot make any guarantes over how long it will work in newer Windows 11 builds. Thus, these things being considered, if you would like, you can check out the beta test for StartIsBack [here](http://startisback.com/tbd/) and report any issues and make suggestions to its developer. It will probably mature in a release that will be better supported from a consumer point of view than ExplorerPatcher.
</details> </details>
<img src="https://gist.githubusercontent.com/valinet/d0f72ff09773702584e77c46065b95e0/raw/94036ed3e38218b87744a29ae5c40b06be637daf/ep_img0.png" width=100% height=100%>
Screenshots: [<1>](https://gist.githubusercontent.com/valinet/d0f72ff09773702584e77c46065b95e0/raw/94036ed3e38218b87744a29ae5c40b06be637daf/ep_img0.png) [<2>](https://user-images.githubusercontent.com/6503598/131937638-d513ca72-ead7-459b-a8ce-619fb302b7da.png) Screenshots: [<1>](https://gist.githubusercontent.com/valinet/d0f72ff09773702584e77c46065b95e0/raw/94036ed3e38218b87744a29ae5c40b06be637daf/ep_img0.png) [<2>](https://user-images.githubusercontent.com/6503598/131937638-d513ca72-ead7-459b-a8ce-619fb302b7da.png)
## dxgi.dll - the patcher ## dxgi.dll - the patcher
@ -34,7 +35,25 @@ Also, if you place the `StartIsBack64.dll` file from StartIsBack(TBD) Preview 2
After you have completed the above setup, make sure you have an active Internet connection and restart the Explorer process using Task Manager or by issuing the following command: `taskkill /f /im explorer.exe`. Once File Explorer restarts, some necessary files (symbol files) will be downloaded from Microsoft (around 50MB). This should be relatively quick, depending on your Internet connection speed. When this is done, File Explorer will restart again and will be ready for use. Notifications should show up informing you about the progress, and you can also use Task Manager to watch for network activity. This process only happens when a new Windows 11 build is installed on the machine. After you have completed the above setup, make sure you have an active Internet connection and restart the Explorer process using Task Manager or by issuing the following command: `taskkill /f /im explorer.exe`. Once File Explorer restarts, some necessary files (symbol files) will be downloaded from Microsoft (around 50MB). This should be relatively quick, depending on your Internet connection speed. When this is done, File Explorer will restart again and will be ready for use. Notifications should show up informing you about the progress, and you can also use Task Manager to watch for network activity. This process only happens when a new Windows 11 build is installed on the machine.
Now, the classic taskbar should be enabled. Still, there is some more setup to do, depending on your preferences. Now, the classic taskbar should be enabled. Still, there is some more setup to do, depending on your preferences.
## Configuration interface
To configure the most common options, the application now comes with a configuration user interface. To open it, right click the Start button (or press `Win`+`X`) and choose "Properties".
<img src="https://user-images.githubusercontent.com/6503598/135698816-b97b7305-f425-4320-b5e6-69843677e510.png" width=70% height=70%>
The icon near an option signifies its current state:
* ✔️ enabled
* ❌ disabled
* performs an action that allows you to change that option (usually, the current value is located after the colon in its description)
The links at the bottom allow you to perform the most frequent actions.
## Manual configuration
To learn how to configure all the options manually, read on:
### Enable system tray icons ### Enable system tray icons
As you have noticed, some system tray icons are missing (for example, the clock, notification center button, network, battery, sound etc). To enable these icons, open the following using Run: As you have noticed, some system tray icons are missing (for example, the clock, notification center button, network, battery, sound etc). To enable these icons, open the following using Run:
@ -121,37 +140,64 @@ To disable the blue highlight in the context menu and return to the classic gray
### Disable window rounded corners ### Disable window rounded corners
You can try one of my other utilities available [here](https://github.com/valinet/Win11DisableRoundedCorners). You can try one of my other utilities available [here](https://github.com/valinet/Win11DisableRoundedCorners).
## Configuration ### Patcher settings
Now that you have set up the basic stuff, you can choose to enable additional settings to enhance the experience even more. For this, edit the file `%appdata%\ExplorerPatcher\settings.ini` and add the following section to it (change to `0` the setting that you do not want to enable): Now that you have set up the basic stuff, you can choose to enable additional settings to enhance the experience even more. For this, customize the following commands by changing the number acording to your needs:
``` * `HideExplorerSearchBar` completely removes the search box in File Explorer (default = 0)
[General]
HideExplorerSearchBar=1
HideControlCenterButton=1
MicaEffectOnTitlebar=1
SkinMenus=1
SkinIcons=1
AllocConsole=1
```
* `HideExplorerSearchBar` completely removes the search box in File Explorer ```
* `HideControlCenterButton` disables the Control Center button and its associated shortcut key (`Win`+`A`) reg.exe add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher" /f /v "bHideExplorerSearchBar" /t REG_DWORD /d 1
* `MicaEffectOnTitlebar` enables Mica effect on File Explorer windows (requires `StartIsBack64.dll`) ```
* `SkinMenus` applies the immersive skin to "Safe to Remove Hardware" and "Bluetooth" pop-up menus
* `SkinIcons` applies Windows 11 icon skins to taskbar buttons (requires `StartIsBack64.dll`) * `HideControlCenterButton` disables the Control Center button and its associated shortcut key (`Win`+`A`) (default = 0)
* `AllocConsole` will display a console window (for debugging purposes)
```
reg.exe add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher" /f /v "bHideControlCenterButton" /t REG_DWORD /d 1
```
* `MicaEffectOnTitlebar` enables Mica effect on File Explorer windows (requires `StartIsBack64.dll`) (default = 0)
```
reg.exe add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher" /f /v "bMicaEffectOnTitlebar" /t REG_DWORD /d 1
```
* `SkinMenus` applies the immersive skin to "Safe to Remove Hardware" and "Bluetooth" pop-up menus (default = 1)
```
reg.exe add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher" /f /v "bSkinMenus" /t REG_DWORD /d 1
```
* `SkinIcons` applies Windows 11 icon skins to taskbar buttons (requires `StartIsBack64.dll`) (default = 1)
```
reg.exe add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher" /f /v "bSkinIcons" /t REG_DWORD /d 1
```
* `AllocConsole` will display a console window (for debugging purposes) (default = 0, for advanced users only)
```
reg.exe add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher" /f /v "bAllocConsole" /t REG_DWORD /d 1
```
* `ExplorerReadyDelay` adds even more delay before the shell is announced that Explorer is ready loading (helps if you experience a delay at logon) - the unit is ms (milliseconds), 1000ms = 1 second (default = 0, for advanced users only)
```
reg.exe add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher" /f /v "vExplorerReadyDelay" /t REG_DWORD /d 1000
```
Also, if you chose to place the patcher in `C:\Windows\SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy` as well, use the following commands to configure Start menu options: Also, if you chose to place the patcher in `C:\Windows\SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy` as well, use the following commands to configure Start menu options:
* Open Start menu to "All apps" directly (replace with 0 to disable) * Open Start menu to "All apps" directly (replace with 0 to disable)
```
reg.exe add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\StartPage /f /v "MakeAllAppsDefault" /t REG_DWORD /d 1
```
* Show only 4 most recent apps (change the number to customize)
```
reg.exe add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /f /v "Start_MaximumFrequentApps" /t REG_DWORD /d 4
```
```
reg.exe add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\StartPage /f /v "MakeAllAppsDefault" /t REG_DWORD /d 1
```
* Show only 4 most recent apps (change the number to customize)
```
reg.exe add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /f /v "Start_MaximumFrequentApps" /t REG_DWORD /d 4
```
## More configuration ## More configuration
Even more registry configuration settings are described in the following document, make sure to take a look on it [here](https://github.com/valinet/ExplorerPatcher/issues/9). Even more registry configuration settings are described in the following document, make sure to take a look on it [here](https://github.com/valinet/ExplorerPatcher/issues/9).