|
Post by The Jackal on Mar 22, 2023 10:01:15 GMT -8
Just noticed that under LibreOffice it uses a different set of icons. I wonder, why? View AttachmentThere's two versions of this dialog. It seems it's program dependent which version it calls up (the one introduced in XP, and other, the Windows 2000 one).
|
|
|
Post by anixx on Mar 22, 2023 10:01:49 GMT -8
If one wants to fix Edge appearance, one has to apply the Travis mode for edge only:
// ==WindhawkMod== // @id classic-theme-windows // @name Classic Theme Windows // @description Forces Classic Theme on all Windows // @version 0.1 // @author Travis // @include msedge.exe // @compilerOptions -luxtheme // ==/WindhawkMod==
// ==WindhawkModReadme== /* # Classic Theme Windows Forces Classic Theme on all Windows */ // ==/WindhawkModReadme==
#include <uxtheme.h>
BOOL Wh_ModInit() { Wh_Log(L"Init");
SetThemeAppProperties(0); return TRUE; } This way one can fix problems with any program which has glitches and problems with tranparency of the window border, this assigns them Aero Lite border.
|
|
|
Post by anixx on Mar 22, 2023 10:19:42 GMT -8
It works perfectly! Really nice.
Now all that's left is to work on ClientEdge. Is it possible to do by modifying the resource? Or AHK or code improvements required?
I think, this should be possible using WindHawk as well. In general, all options from ExplorerPatcher and 7+TT can be moved to WindHawk. For instance, there is no point now to use Explorer Patcher's "install as shell extension" mode any more, especially given it is not recommended. All the things (such as navbar and context menus in open-save dialogs) can be done with WindHawk now.
|
|
|
Post by The Jackal on Mar 22, 2023 10:56:50 GMT -8
I actually went back to check if these dialog had client edge on them on W2k/XP...they do. Is there a reason why MS would removed it from them? I mean, it seems a bit silly considering they up and replaced the dialogs themselves starting in Vista?
|
|
|
Post by OrthodoxWin32 on Mar 22, 2023 15:14:20 GMT -8
Superb discovery anixx, well done! I will try all of this as soon as I have time. Indeed, WindHawk can do everything that ExplorerPatcher or 7+TaskbarTweaker does. For my use, the ideal would be a mode that allows using the taskbar with the classic theme but without the labels (as in Windows 7).
|
|
|
Post by anixx on Mar 22, 2023 17:12:13 GMT -8
Just noticed that under LibreOffice it uses a different set of icons. I wonder, why? View AttachmentThere's two versions of this dialog. It seems it's program dependent which version it calls up (the one introduced in XP, and other, the Windows 2000 one). How to call the old one?
|
|
|
Post by The Jackal on Mar 23, 2023 1:38:52 GMT -8
There's two versions of this dialog. It seems it's program dependent which version it calls up (the one introduced in XP, and other, the Windows 2000 one). How to call the old one? I dont know how, just each program is different and calls up a different one. There's got to be a way to distinguish each one by internal name show-how and if we can work that out, maybe then we can isolate the type you want to show.
|
|
Cynosphere
Freshman Member
Posts: 46
OS: Windows 10 Home 22H2
Theme: Classic (Scheme: Amora Focus)
CPU: AMD Ryzen 7 3700X
RAM: 32 GB
GPU: AMD Radeon RX 7900 XT
|
Post by Cynosphere on Apr 3, 2023 17:31:15 GMT -8
Using anixx 's snippet from here, I was able to add client edge to the ListView. BOOL CALLBACK SetClientEdge(HWND hWnd, LPARAM lParam) { DWORD dwProcessId = 0; DWORD dwThreadId = GetWindowThreadProcessId(hWnd, &dwProcessId); if (!dwThreadId || dwProcessId != GetCurrentProcessId()) { return TRUE; }
if (g_uiThreadId && g_uiThreadId != dwThreadId) { return TRUE; }
HWND cn = NULL; HWND p = hWnd; wchar_t bufr[256]; GetClassName(hWnd, bufr, 256);
// File picker if (lstrcmpW(bufr, L"#32770") == 0) { p = FindWindowEx(p, NULL, L"SHELLDLL_DefView", NULL); if(p != NULL) { p = FindWindowEx(p, NULL, L"SysListView32", NULL); if(p != NULL) { cn = p; } } }
if(cn != NULL) { SetWindowLongPtrW(cn, GWL_EXSTYLE, GetWindowLongPtrW(cn, GWL_EXSTYLE) | WS_EX_CLIENTEDGE); RECT rect; GetWindowRect(cn, &rect); SetWindowPos(cn, NULL, NULL, NULL, rect.right - rect.left + 1, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE); SetWindowPos(cn, NULL, NULL, NULL, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE); }
return TRUE; }
using CreateWindowExW_t = decltype(&CreateWindowExW); CreateWindowExW_t CreateWindowExW_Orig; HWND WINAPI CreateWindowExW_Hook(DWORD dwExStyle,LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) { HWND hWnd = CreateWindowExW_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam);
if (!hWnd) { return hWnd; }
if (g_uiThreadId && g_uiThreadId != GetCurrentThreadId()) { return hWnd; }
if (IsWindow(hWnd)) { if (!g_uiThreadId) { g_uiThreadId = GetCurrentThreadId(); }
EnumWindows(SetClientEdge, 0); }
return hWnd; }
// and then add this to Wh_ModInit Wh_SetFunctionHook((void*)CreateWindowExW, (void*)CreateWindowExW_Hook, (void**)&CreateWindowExW_Orig);
I've only had issues with this not applying to dialogs spawned from Electron programs (e.g. Discord, VSCode)
|
|
|
Post by anixx on Apr 3, 2023 19:16:51 GMT -8
I tried to add this to your Classic File Picker mod, it returns a lot of errors:
c:\ProgramData\Windhawk\EditorWorkspace\mod.wh.cpp:53:9: error: use of undeclared identifier 'g_uiThreadId' if (g_uiThreadId && g_uiThreadId != dwThreadId) { ^ c:\ProgramData\Windhawk\EditorWorkspace\mod.wh.cpp:53:25: error: use of undeclared identifier 'g_uiThreadId' if (g_uiThreadId && g_uiThreadId != dwThreadId) { ^ c:\ProgramData\Windhawk\EditorWorkspace\mod.wh.cpp:97:9: error: use of undeclared identifier 'g_uiThreadId'; did you mean 'GetThreadId'? if (g_uiThreadId && g_uiThreadId != GetCurrentThreadId()) { ^~~~~~~~~~~~ GetThreadId c:/Program Files/Windhawk/Compiler/include/processthreadsapi.h:40:27: note: 'GetThreadId' declared here WINBASEAPI DWORD WINAPI GetThreadId (HANDLE Thread); ^ c:\ProgramData\Windhawk\EditorWorkspace\mod.wh.cpp:97:25: error: use of undeclared identifier 'g_uiThreadId' if (g_uiThreadId && g_uiThreadId != GetCurrentThreadId()) { ^ c:\ProgramData\Windhawk\EditorWorkspace\mod.wh.cpp:102:14: error: use of undeclared identifier 'g_uiThreadId'; did you mean 'GetThreadId'? if (!g_uiThreadId) { ^~~~~~~~~~~~ GetThreadId c:/Program Files/Windhawk/Compiler/include/processthreadsapi.h:40:27: note: 'GetThreadId' declared here WINBASEAPI DWORD WINAPI GetThreadId (HANDLE Thread); ^ c:\ProgramData\Windhawk\EditorWorkspace\mod.wh.cpp:102:14: warning: address of function 'GetThreadId' will always evaluate to 'true' [-Wpointer-bool-conversion] if (!g_uiThreadId) { ~^~~~~~~~~~~~ c:\ProgramData\Windhawk\EditorWorkspace\mod.wh.cpp:102:14: note: prefix with the address-of operator to silence this warning if (!g_uiThreadId) { ^ & c:\ProgramData\Windhawk\EditorWorkspace\mod.wh.cpp:103:13: error: use of undeclared identifier 'g_uiThreadId' g_uiThreadId = GetCurrentThreadId(); ^ 1 warning and 6 errors generated.
|
|
|
Post by anixx on Apr 3, 2023 19:26:50 GMT -8
Well, added DWORD g_uiThreadId; to the top, now works.
I think, this is great!
P.S. Confirming: does not work in Electron apps.
|
|
|
Post by anixx on Apr 3, 2023 20:14:35 GMT -8
When changing the displayed folder in the dialog, for insctance, entering a folder, the ClientEdge disappears.
|
|
|
Post by anixx on Apr 4, 2023 0:42:18 GMT -8
By the way, the file picker dialog has a ListBox which by default has ClientEdge, but invisible, it occupies the same area as SysListView32. It retains clientedge when changing the folder. The problem is, it is empty.
|
|
|
Post by The Jackal on Apr 4, 2023 10:23:42 GMT -8
Well, added DWORD g_uiThreadId; to the top, now works.
I think, this is great!
P.S. Confirming: does not work in Electron apps.
Can you please post a complete version of this script because I'm struggling to understand what goes where tbh? Cheers.
|
|
|
Post by anixx on Apr 4, 2023 13:57:48 GMT -8
// ==WindhawkMod== // @id classic-file-picker // @name Classic File Picker // @description Redirect the Windows Vista+ file picker to the Windows XP one // @version 0.1 // @author Cynosphere // @include * // @exclude ApplicationFrameHost.exe // @compilerOptions -lole32 -lcomdlg32 -luxtheme // ==/WindhawkMod==
// ==WindhawkModReadme== /* # Classic File Picker */ // ==/WindhawkModReadme==
#include <uxtheme.h>
template<class S> CLSID CreateGUID(const S& hexString) { CLSID clsid; CLSIDFromString(hexString, &clsid);
return clsid; }
DWORD g_uiThreadId;
// File Picker dialogs
const CLSID CLSID_FileOpenDialog = CreateGUID(L"{DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7}"); const CLSID CLSID_FileOpenDialogLegacy = CreateGUID(L"{725F645B-EAED-4fc5-B1C5-D9AD0ACCBA5E}"); const CLSID CLSID_FileSaveDialog = CreateGUID(L"{c0b4e2f3-ba21-4773-8dba-335ec946eb8b}"); const CLSID CLSID_FileSaveDialogLegacy = CreateGUID(L"{AF02484C-A0A9-4669-9051-058AB12B9195}");
using CoCreateInstance_t = decltype(&CoCreateInstance); CoCreateInstance_t CoCreateInstance_Original; HRESULT WINAPI CoCreateInstance_Hook(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv) { if (rclsid == CLSID_FileOpenDialog) { return CoCreateInstance_Original(CLSID_FileOpenDialogLegacy, pUnkOuter, dwClsContext, riid, ppv); } else if (rclsid == CLSID_FileSaveDialog) { return CoCreateInstance_Original(CLSID_FileSaveDialogLegacy, pUnkOuter, dwClsContext, riid, ppv); }
return CoCreateInstance_Original(rclsid, pUnkOuter, dwClsContext, riid, ppv); }
// ClientEdge
BOOL CALLBACK SetClientEdge(HWND hWnd, LPARAM lParam) { DWORD dwProcessId = 0; DWORD dwThreadId = GetWindowThreadProcessId(hWnd, &dwProcessId); if (!dwThreadId || dwProcessId != GetCurrentProcessId()) { return TRUE; }
if (g_uiThreadId && g_uiThreadId != dwThreadId) { return TRUE; }
HWND cn = NULL; HWND p = hWnd; wchar_t bufr[256]; GetClassName(hWnd, bufr, sizeof(bufr));
// File picker if (lstrcmpW(bufr, L"#32770") == 0) { p = FindWindowEx(p, NULL, L"SHELLDLL_DefView", NULL); if(p != NULL) { p = FindWindowEx(p, NULL, L"SysListView32", NULL); if(p != NULL) { cn = p; } } }
//Mathematica if (lstrcmpW(bufr, L"NotebookFrame") == 0) { p = FindWindowEx(p, NULL, L"NotebookContent", NULL); if(p != NULL) { cn = p; }
}
// Notepad
if (lstrcmpW(bufr, L"Notepad") == 0) { p = FindWindowEx(p, NULL, L"Edit", NULL); if(p != NULL) { cn = p; }
}
if(cn != NULL) { SetWindowLongPtrW(cn, GWL_EXSTYLE, GetWindowLongPtrW(cn, GWL_EXSTYLE) | WS_EX_CLIENTEDGE); RECT rect; GetWindowRect(cn, &rect); SetWindowPos(cn, NULL, NULL, NULL, rect.right - rect.left + 1, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE); SetWindowPos(cn, NULL, NULL, NULL, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE); }
return TRUE; }
using CreateWindowExW_t = decltype(&CreateWindowExW); CreateWindowExW_t CreateWindowExW_Orig; HWND WINAPI CreateWindowExW_Hook(DWORD dwExStyle,LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) { HWND hWnd = CreateWindowExW_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam);
if (!hWnd) { return hWnd; }
if (g_uiThreadId && g_uiThreadId != GetCurrentThreadId()) { return hWnd; }
if (IsWindow(hWnd)) { if (!g_uiThreadId) { g_uiThreadId = GetCurrentThreadId(); }
EnumWindows(SetClientEdge, 0); }
return hWnd; }
BOOL Wh_ModInit() { // SetThemeAppProperties(STAP_ALLOW_NONCLIENT); Wh_SetFunctionHook((void*)CoCreateInstance, (void*)CoCreateInstance_Hook, (void**)&CoCreateInstance_Original); Wh_SetFunctionHook((void*)CreateWindowExW, (void*)CreateWindowExW_Hook, (void**)&CreateWindowExW_Orig); return TRUE; }
|
|
|
Post by The Jackal on Apr 4, 2023 14:08:44 GMT -8
Thank you Anixx (and ofc Cynosphere)
|
|
|
Post by classics on Apr 5, 2023 7:25:37 GMT -8
I had problems too, now seems to be working, thanks. Cynosphere, why not add it like the other mods in Windhawk so that ppl could just click install? And also update easier?
|
|
|
Post by R.O.B. on Apr 7, 2023 23:09:29 GMT -8
Wanted to post on this sooner - I just wanted to say that this is wonderful. Another subtle little tweak that goes a long way in restoring that classic Windows feel. Great work, everyone!
|
|
|
Post by anixx on Apr 10, 2023 23:48:27 GMT -8
Here are a set of WindHawk mods that replace the Vista-style file picker with classic (Windows 2000/XP) file picker dialogs in all programs. You should already have enabled classic theme by other means (otherwise the window frames will remain themed).
This is the main mod by Cynosphere that replaces the file picker in windows which have declared classic theme.
// ==WindhawkMod== // @id classic-file-picker // @name Classic File Picker // @description Redirect the Windows Vista+ file picker to the Windows XP one // @version 0.1 // @author Cynosphere // @include * // @exclude dwm.exe // @exclude ApplicationFrameHost.exe // @compilerOptions -lole32 -lcomdlg32 // ==/WindhawkMod==
// ==WindhawkModReadme== /* # Classic File Picker */ // ==/WindhawkModReadme==
template<class S> CLSID CreateGUID(const S& hexString) { CLSID clsid; CLSIDFromString(hexString, &clsid);
return clsid; }
DWORD g_uiThreadId;
// File Picker dialogs
const CLSID CLSID_FileOpenDialog = CreateGUID(L"{DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7}"); const CLSID CLSID_FileOpenDialogLegacy = CreateGUID(L"{725F645B-EAED-4fc5-B1C5-D9AD0ACCBA5E}"); const CLSID CLSID_FileSaveDialog = CreateGUID(L"{c0b4e2f3-ba21-4773-8dba-335ec946eb8b}"); const CLSID CLSID_FileSaveDialogLegacy = CreateGUID(L"{AF02484C-A0A9-4669-9051-058AB12B9195}");
using CoCreateInstance_t = decltype(&CoCreateInstance); CoCreateInstance_t CoCreateInstance_Original; HRESULT WINAPI CoCreateInstance_Hook(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv) { if (rclsid == CLSID_FileOpenDialog) { return CoCreateInstance_Original(CLSID_FileOpenDialogLegacy, pUnkOuter, dwClsContext, riid, ppv); } else if (rclsid == CLSID_FileSaveDialog) { return CoCreateInstance_Original(CLSID_FileSaveDialogLegacy, pUnkOuter, dwClsContext, riid, ppv); }
return CoCreateInstance_Original(rclsid, pUnkOuter, dwClsContext, riid, ppv); }
BOOL Wh_ModInit() { Wh_SetFunctionHook((void*)CoCreateInstance, (void*)CoCreateInstance_Hook, (void**)&CoCreateInstance_Original); return TRUE; } This is the mod that affects the majority of applications, except Edge and Chrome browsers: it declares the app to be unthemed while keeps the window frame untouched. It is based on the mod by Travis.
// ==WindhawkMod== // @id untheme // @name Unthemed+NativeFrame // @description Removes composition from windows // @version 0.1 // @include * // @exclude dwm.exe // @exclude ApplicationFrameHost.exe // @exclude msedge.exe // @exclude chrome.exe // @exclude steam.exe // @compilerOptions -luxtheme // ==/WindhawkMod==
#include <uxtheme.h>
BOOL Wh_ModInit() { Wh_Log(L"Init"); SetThemeAppProperties(STAP_ALLOW_NONCLIENT); return TRUE; } This is the mod that declares the app unthemed and also sets the window frame to Aero Light. This is needed for apps like Edge and Chrome, whose window frames are glitchy when unthemed.
// ==WindhawkMod== // @id classic-browser-fix // @name Unthemed+Nocomposition // @description Removes composition from windows and sets Light window frame // @version 0.1 // @include msedge.exe // @include chrome.exe // @include steam.exe // @compilerOptions -luxtheme // ==/WindhawkMod==
#include <uxtheme.h>
BOOL Wh_ModInit() { Wh_Log(L"Init"); SetThemeAppProperties(0); return TRUE; }
For 3D border in the open/save dialogs, you also have to apply this mod:
|
|
|
Post by OrthodoxWin32 on Apr 11, 2023 9:00:49 GMT -8
Thanks you, It works perfectly with ClassicThemeTray enabled.
In general, I noticed a few subtleties: If the visual style is not disabled (when I say disabled, I mean disabled in memory, like with ClassicThemeTray), the explorer windows as well as the ExplorerPatcher configuration window crashes. Excluding explorer.exe from the first mod, and including it in the second makes the explorer work again, unless the window comes from a new process (as a result, the control panel remains blocked). The main visual difference between the 1st mod and the 2nd mod is that in the first the scrollbar is displayed with visual style, unlike the 2nd. The other difference is that in the 1st, the "Basic" title bar appears if BasicThemer is used, while in the 2nd, BasicThemer makes the classic title bar appear. For some reason the ExplorerPatcher configuration window works even with the 1st mod if high contrast is enabled. Finally, I don't quite understand what you mean by "Aero Light Title Bar" on the 2nd mod.
|
|
|
Post by OrthodoxWin32 on May 4, 2023 14:04:05 GMT -8
it doesnt seem to work on win10 v1511 with the non dwm method, is there a way to do it for this setup? Sorry, not sure, but I imagine it has to do with DWM being disabled.
|
|