Подмена "штатного" сетевого окружения при возврате с хоста

Только для тех, кто пишет плагины под Total Commander. Обмен опытом, решение проблем.

Модераторы: d-view, Моторокер, Avada, CaptainFlint, Nik

HankHank
Сообщения: 39
Зарегистрирован: Чт апр 15, 2010 16:35

Подмена "штатного" сетевого окружения при возврате с хоста

Сообщение HankHank »

Привет присутствующим.

Есть непростой вопросец для работы с удалённым компьютером.
Предположим, что переходим к удалённому хосту командой типа:
cd \\<IP-адрес или NetBIOS -имя> ,
задавая её в командной строке Коммандера.
Поработав на удалённом хосте, “возвращаемся назад”, многократно щёлкая кнопкой мыши или нажимая Enter на [..] (возврат на уровень вверх). Когда достигаем самого “верхнего уровня” хоста, по умолчанию (?) возвращаемся в “штатное” сетевое окружение Коммандера.

Есть ли способ вызвать подменой (либо как-то иначе) другой плагин (или кнопку, или команду) вместо “штатного” сетевого окружения ?

Есть решение с помощью AHK. Но оно не устраивает.
HankHank
Сообщения: 39
Зарегистрирован: Чт апр 15, 2010 16:35

Сообщение HankHank »

Буду благодарен за любые мысли вслух, пусть даже фантастические, чтобы выявить направления поиска...
Аватара пользователя
Rodny
Сообщения: 949
Зарегистрирован: Ср янв 24, 2007 00:59
Откуда: Могилёв, Беларусь

Сообщение Rodny »

HankHank
Есть ли способ вызвать подменой (либо как-то иначе) другой плагин (или кнопку, или команду) вместо “штатного” сетевого окружения ?
Не совсем понятно, что ты хочешь.
Чтобы кнопка "Сеть / FS-плагины" имела другую функцию? Нет, нельзя.
Кнопку/команду для перехода в определённый плагин? Пожалуйста, "cd \\\Плагин"
HankHank
Сообщения: 39
Зарегистрирован: Чт апр 15, 2010 16:35

Сообщение HankHank »

Rodny писал(а):Не совсем понятно, что ты хочешь.
Чтобы кнопка "Сеть / FS-плагины" имела другую функцию? Нет, нельзя.
Объясняю ещё раз.
После выхода из хоста, на который зашли по команде cd \\<имя хоста или его IP>, Коммандер выбрасывает пользователя не в окно, как ты пишешь "Сеть / FS-плагины" , а в сетевое окружение Коммандера. Я его условно называю "штатным". По сути, - это рабочая группа, полученная через механизм броузера Windows. Как это окно формируется Гислером, это тоже возможный путь для моей "подмены". Но я реализации пока не понимаю.

Вот ЕСТЬ НУЖДА МИНОВАТЬ ЭТО "ШТАТНОЕ", а перейти в другое АВТОМАТИЧЕСКИ - по команде, подменой кода или каким-то иным способом. Под "другим" окружением я разумею плагин, который можно вызвать перечисленными способами. Поэтому я и призываю спецов и любителей хотя бы пофантазировать на заданную тему, если отсутствует готовое решение.

Есть способ перехвата момента появления штатного окружения с помощью скрипта, о чём я написал ранее. Но получается некрасиво, долго, в целом - непрофессионально.

Так понятнее задача ?
Коротко она звучит так: "Отловить момент возврата из хоста и автоматичи передть управление не на штатное сетевое окружение, а на другой исполняемый код".
Последний раз редактировалось HankHank Пт апр 16, 2010 11:26, всего редактировалось 1 раз.
Аватара пользователя
alexey65536
Сообщения: 1056
Зарегистрирован: Пт янв 20, 2006 10:58
Откуда: Taganrog

Сообщение alexey65536 »

Т.е., допустим, нажав [..] в корне хоста \\COMP, я должен попадать не в WORKGROUP/MSHOME/что-то еще, а в произвольное место (плагин и т.п.)?
#199018
HankHank
Сообщения: 39
Зарегистрирован: Чт апр 15, 2010 16:35

Сообщение HankHank »

Так точно !
Аватара пользователя
MVV
Сообщения: 4815
Зарегистрирован: Чт окт 15, 2009 10:58
Откуда: Ростов-Дон

Сообщение MVV »

Объясню то, что написал на оф. форуме, но по-русски. Если ты обрабатываешь в хуке сообщения клавы и мыши, ты можешь удалять невыгодные тебе сообщения (обычно в конце хук-обработчика нужно вызывать CallNextHookEx, но в этих обработчиках можно просто вернуть ненулевое значение - и сообщение дальше твоего хука не пойдет). Т.е. ты ловишь попытку юзера нажать Enter или сделать двойной щелчок на элементе ".." до того как ТК получит это сообщение и, если видишь, что при таком раскладе юзер попадет в Сетевое окружение, просто удаляешь сообщение, а ТК говоришь перейти в нужный тебе каталог. В итоге ТК вообще не узнает о том, что юзер хотел зайти в Сетевое окружение.

Ловить двойной щелчок или нажатие Enter несложно, далее просто получаешь индекс текущего элемента - если ноль, значит, это элемент "..". Далее, если ноль (если не ноль, надо вызывать следующий обработчик и не тормозить систему лишний раз), начинаешь проверять текущий путь - например, как я писал, получаешь его из поля строки состояния (при инициализации плагина один раз получаешь его дескриптор и запоминаешь - он не изменится до закрытия ТК) и определяешь, верхний ли это уровень. Если да - действуешь.
HankHank
Сообщения: 39
Зарегистрирован: Чт апр 15, 2010 16:35

Сообщение HankHank »

Чёрт побери, приятная неожиданность, MVV ! Где только не встретишь наших людей ! :D
Да ещё и сподобиться получить ответ от Гислера в тот же день. Хотя, по сути - пустой ответ. Но мы не ищем лёгких путей.
MVV писал(а):Если ты обрабатываешь в хуке сообщения клавы и мыши, ты можешь удалять невыгодные тебе сообщения ...
Да, я понял мысль - написать собственный обработчик, о чём не имею понятия. Но тогда встаёт в полный рост вопрос:
Can you recommend samples of ready templates with a code of a similar trap for M$ Visual C++ ?
Аватара пользователя
MVV
Сообщения: 4815
Зарегистрирован: Чт окт 15, 2009 10:58
Откуда: Ростов-Дон

Сообщение MVV »

HankHank писал(а):Где только не встретишь наших людей ! :D
Наши везде пролезут:) Я тут видел твое сообщение до того, как увидел там - поэтому понял, что то - твой пост, и отписался тут.
HankHank писал(а):Да ещё и сподобиться получить ответ от Гислера в тот же день. Хотя, по сути - пустой ответ.
Согласись, его можно понять - ты предлагаешь хардкодить грабли:)

В общем, я набросал тебе пример, выложил в теме на оф. сайте.
Для экспериментов сделал копию папки проекта своей VP и извращался с ней. :D
Вроде все работает. Хук-функции получились маленькие, работать будут быстро, тем более, быстрые отсекающие проверки делаются в первую очередь. Вопросы, комментарии - вэлкам.

Как я уже советовал там, лучше при переходе из плагина по сетевому пути запоминать его корневую папку (имя сервера) - и при 'подъеме' проверять, на этом ли серваке юзер (а то может он уже ушел гулять по другим, а ты ему будешь малину портить).
Кстати, в настройках своего плагина сделай опцию отключать эти извращения - хуки можно не вырубать, а при входе в них сразу проверяй флаг и выходи из хук-функции (не забудь вызывать CallNextHookEx) - проще всего добавить условный блок верхнего уровня, внутри которого проверяются и обрабатываются сообщения. То есть, юзер отключил фишку - сразу вызываешь следующий хук.
HankHank
Сообщения: 39
Зарегистрирован: Чт апр 15, 2010 16:35

Сообщение HankHank »

Сердечная благодарность за помощь. На неделе попытаюсь разобраться и прикрутить. Вопросы наверняка появятся.
Хороших выходных !
VadiMGP
Сообщения: 1625
Зарегистрирован: Ср мар 21, 2007 20:58

Сообщение VadiMGP »

MVV
Я детально не штудировал твой пример, но две проблемы сразу заметны. Они касаются листбоксов (mylb1 и mylb2).
1. Ты исходишь из предположения, что в ТС всегда 2 листбокса. Но это не так. Окна с деревьями тоже листбоксы, значит в разное время может быть от 2 до 4 листбоксов.
2. Ты берешь HWND от них только один раз при инициализации. Но ТС часто уничтожает и создает листбоксы динамически. Например при переключении между режимами (подробный, эскизы, пользовательские колонки).
Аватара пользователя
MVV
Сообщения: 4815
Зарегистрирован: Чт окт 15, 2009 10:58
Откуда: Ростов-Дон

Сообщение MVV »

VadiMGP писал(а):Я детально не штудировал твой пример, но две проблемы сразу заметны. Они касаются листбоксов (mylb1 и mylb2).
Что ж, я не давал клятву, что он идеален. :)
VadiMGP писал(а):1. Ты исходишь из предположения, что в ТС всегда 2 листбокса. Но это не так. Окна с деревьями тоже листбоксы, значит в разное время может быть от 2 до 4 листбоксов.
Да, действительно. Но я заметил, что у листбоксов деревьев имя текст окна не пуст, значит, можно искать окна файловых панелей по пустому тексту. Тогда в моем примере надо чуть изменить (указать не любой, а пустой текст окна при поиске):

Код: Выделить всё

   mylb1=FindWindowEx(hMainWnd, 0, L"TMyListBox", L""); 
   mylb2=FindWindowEx(hMainWnd, mylb1, L"TMyListBox", L"");
Так мы гарантированно найдем окна панелей. Кстати, по идее можно просто брать активное окно, а не искать их - оно будет листбоксом при щелчке мышью и нажатии клавиш в интересующий нас момент.
VadiMGP писал(а):2. Ты берешь HWND от них только один раз при инициализации. Но ТС часто уничтожает и создает листбоксы динамически. Например при переключении между режимами (подробный, эскизы, пользовательские колонки).
Подтверждаю. Тоже не учел. В таком случае нужно либо искать окна панелей каждый раз (два окна найти - не проблема), а можно просто использовать указанный выше фокус. То есть, вызываем GetFocus(), и если окно с фокусом - TMyListBox, значит, берем из него индекс и т.д. Панель состояния в любом случае не изменяется.

Итак, убираем дескрипторы mylb1, mylb2 и их поиск, а функцию GetActivePanel модифицируем следующим образом:

Код: Выделить всё

HWND GetActivePanel() {
   HWND hwnd=GetFocus();
   wchar_t buf[256];
   if (!GetClassName(hwnd, buf, TSIZE(buf)) || lstrcmp(buf, L"TMyListBox")) return 0;
   if (GetWindowText(hwnd, buf, TSIZE(buf)) || GetLastError()) return 0;
   return hwnd; 
}
Ну а в хук-функциях проверять, не ноль ли дескриптор окна - если ноль, ниче не делать.
VadiMGP
Сообщения: 1625
Зарегистрирован: Ср мар 21, 2007 20:58

Сообщение VadiMGP »

Еще одна проблема - будет ложное срабатывание в режиме эскизов.
Если в строке, скажем, 3 эскиза, то LB_ITEMFROMPOINT вернет 0 для любого из этих трех эскизов, а не только для "..".

Добавлено. Пригляделся еще раз. Нет, похоже, не будет вообще срабатывания. В функции IsForbiddenLevelUp GetWindowText не даст текста. В режиме эскизов невозможно получить текст элемента.
Аватара пользователя
MVV
Сообщения: 4815
Зарегистрирован: Чт окт 15, 2009 10:58
Откуда: Ростов-Дон

Сообщение MVV »

В функции IsForbiddenLevelUp я беру текст из панели в строке состояния, текст в которой есть независимо от режима панели. Текст элементов я вообще нигде не пытаюсь получить - он мне не нужен, расчет на то, что элемент ".." всегда имеет индекс 0.

А сообщение LB_ITEMFROMPOINT по идее должно возвращать индекс с учетом того, что листбокс может иметь несколько колонок или строк. Ты проверял, как работает LB_ITEMFROMPOINT, или это предположение?

Да, похоже, в режиме эскизов LB_ITEMFROMPOINT работает неправильно - действительно возвращает номер строки. Как, кстати, и LB_GETCARETINDEX - видимо, этот режим Гислер реализовывал сам, и об этих сообщениях не позаботился. Так что оба хука - и клавы, и мыши - будут срабатывать в режиме эскизов на всех элементах первой строки содержимого панели. Нужно что-то придумывать дополнительно.
Последний раз редактировалось MVV Вс апр 18, 2010 12:49, всего редактировалось 4 раза.
VadiMGP
Сообщения: 1625
Зарегистрирован: Ср мар 21, 2007 20:58

Сообщение VadiMGP »

MVV писал(а):В функции IsForbiddenLevelUp я беру текст из панели в строке состояния,
А, значит я ошибся насчет этого.
MVV писал(а):А сообщение LB_ITEMFROMPOINT по идее должно возвращать индекс с учетом того, что листбокс может иметь несколько колонок или строк.
По идее, конечно. Я тоже в свое время на это рассчитывал.
MVV писал(а):Ты проверял, как работает LB_ITEMFROMPOINT, или это предположение?
Еще как проверял. Я знаешь, как в TWinKey нажрался проблем с эскизами... Мама не горюй.
Ответить