11#include " ./hooks.h"
22#include " ../config.h"
3+ #include " ../entry.h"
4+ #include " ../script/quickjspp.hpp"
5+ #include " blook/memo.h"
36#include " contextmenu.h"
47#include " menu_render.h"
5- #include " ../script/quickjspp.hpp"
6- #include " ../entry.h"
78
89#include " blook/blook.h"
910#include < atlcomcli.h>
11+ #include < atomic>
1012#include < shobjidl_core.h>
1113#include < thread>
1214
1517#include " Windows.h"
1618#include " shlobj_core.h"
1719
18-
1920std::atomic_bool mb_shell::context_menu_hooks::has_active_menu = false ;
2021
2122void mb_shell::context_menu_hooks::install_common_hook () {
@@ -43,21 +44,18 @@ void mb_shell::context_menu_hooks::install_common_hook() {
4344 menu menu = menu::construct_with_hmenu (hMenu, hWnd);
4445 perf.end (" construct_with_hmenu" );
4546
46- auto selected_menu_future = renderer
47- .add_task ([&]() {
48- auto menu_render = menu_render::create (x, y, menu);
49- menu_render.rt ->last_time = menu_render.rt ->clock .now ();
50-
51- perf.end (" menu_render::create" );
52- menu_render.rt ->start_loop ();
47+ auto selected_menu_future = renderer.add_task ([&]() {
48+ auto menu_render = menu_render::create (x, y, menu);
49+ menu_render.rt ->last_time = menu_render.rt ->clock .now ();
5350
54- return menu_render. selected_menu ;
55- } );
51+ perf. end ( " menu_render::create " ) ;
52+ menu_render. rt -> start_loop ( );
5653
57- qjs::wait_with_msgloop ([&]() {
58- selected_menu_future.wait ();
54+ return menu_render.selected_menu ;
5955 });
6056
57+ qjs::wait_with_msgloop ([&]() { selected_menu_future.wait (); });
58+
6159 auto selected_menu = selected_menu_future.get ();
6260
6361 has_active_menu = false ;
@@ -110,6 +108,55 @@ void mb_shell::context_menu_hooks::install_SHCreateDefaultContextMenu_hook() {
110108 auto SHELL32_SHCreateDefaultContextMenu =
111109 shell32.value ()->exports (" SHELL32_SHCreateDefaultContextMenu" );
112110
111+ static std::atomic_bool close_next_create_window_exw_window = false ;
112+
113+ auto user32 = proc->module (" user32.dll" );
114+ auto CreateWindowExWFunc = user32.value ()->exports (" CreateWindowExW" );
115+ if (!CreateWindowExWFunc) {
116+ std::cerr << " Failed to find CreateWindowExW in user32.dll" << std::endl;
117+ }
118+ static auto CreateWindowExWHook = CreateWindowExWFunc->inline_hook ();
119+ CreateWindowExWHook->install (+[](DWORD dwExStyle, LPCWSTR lpClassName,
120+ LPCWSTR lpWindowName, DWORD dwStyle, int X,
121+ int Y, int nWidth, int nHeight,
122+ HWND hWndParent, HMENU hMenu,
123+ HINSTANCE hInstance,
124+ LPVOID lpParam) -> HWND {
125+ std::wstring class_name = [&]{
126+ if (!lpClassName) {
127+ return std::wstring (L" " );
128+ }
129+ if (blook::Pointer ((void *)lpClassName).try_read <int >()) {
130+ return std::wstring (lpClassName);
131+ } else {
132+ // read as registered class
133+ wchar_t class_name_buffer[256 ];
134+ if (GetClassNameW ((HWND)lpClassName, class_name_buffer, 256 ) > 0 ) {
135+ return std::wstring (class_name_buffer);
136+ } else {
137+ return std::wstring (L" " );
138+ }
139+ }
140+ }();
141+
142+ bool should_close =
143+ close_next_create_window_exw_window &&
144+ class_name.starts_with (L" HwndWrapper[OneCommander.exe" );
145+
146+ if (should_close) {
147+ dwStyle &= ~WS_VISIBLE;
148+ }
149+
150+ auto res = CreateWindowExWHook->call_trampoline <HWND>(
151+ dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight,
152+ hWndParent, hMenu, hInstance, lpParam);
153+ if (res && should_close) {
154+ close_next_create_window_exw_window = false ;
155+ PostMessageW (res, WM_CLOSE, 0 , 0 );
156+ }
157+ return res;
158+ });
159+
113160 /* *
114161 prototype: SHSTDAPI SHCreateDefaultContextMenu(
115162 [in] const DEFCONTEXTMENU *pdcm,
@@ -123,12 +170,11 @@ void mb_shell::context_menu_hooks::install_SHCreateDefaultContextMenu_hook() {
123170 SHELL32_SHCreateDefaultContextMenu->inline_hook ();
124171 SHCreateDefaultContextMenuHook->install (+[](DEFCONTEXTMENU *def, REFIID riid,
125172 void **ppv) -> HRESULT {
126- IContextMenu *pdcm = NULL ;
127173 SHCreateDefaultContextMenuHook->uninstall ();
128- auto res =
129- SHCreateDefaultContextMenu (def, riid, reinterpret_cast <void **>(&pdcm));
174+ auto res = SHCreateDefaultContextMenu (def, riid, ppv);
130175 SHCreateDefaultContextMenuHook->install ();
131176
177+ IContextMenu *pdcm = (IContextMenu *)*ppv;
132178 if (SUCCEEDED (res) && pdcm) {
133179 IContextMenu2 *pcm2 = NULL ;
134180
@@ -158,8 +204,10 @@ void mb_shell::context_menu_hooks::install_SHCreateDefaultContextMenu_hook() {
158204
159205 pCM->InvokeCommand ((LPCMINVOKECOMMANDINFO)&ici);
160206 }
207+
208+ close_next_create_window_exw_window = true ;
161209 }
162210
163- return S_FALSE ;
211+ return res ;
164212 });
165213}
0 commit comments