Подмена "штатного" сетевого окружения при возврате с хоста
Select messages from
# through # FAQ
[/[Print]\]
Goto page 1, 2, 3  Next  :| |:
Total Commander -> Написание плагинов для Total Commander

#1: Подмена "штатного" сетевого окружения при возврате с хоста Author: HankHank PostPosted: Thu Apr 15, 2010 16:48
    —
Привет присутствующим.

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

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

Есть решение с помощью AHK. Но оно не устраивает.

#2:  Author: HankHank PostPosted: Fri Apr 16, 2010 10:03
    —
Буду благодарен за любые мысли вслух, пусть даже фантастические, чтобы выявить направления поиска...

#3:  Author: RodnyLocation: Могилёв, Беларусь PostPosted: Fri Apr 16, 2010 10:58
    —
HankHank
Quote:
Есть ли способ вызвать подменой (либо как-то иначе) другой плагин (или кнопку, или команду) вместо “штатного” сетевого окружения ?

Не совсем понятно, что ты хочешь.
Чтобы кнопка "Сеть / FS-плагины" имела другую функцию? Нет, нельзя.
Кнопку/команду для перехода в определённый плагин? Пожалуйста, "cd \\\Плагин"

#4:  Author: HankHank PostPosted: Fri Apr 16, 2010 11:16
    —
Rodny wrote:
Не совсем понятно, что ты хочешь.
Чтобы кнопка "Сеть / FS-плагины" имела другую функцию? Нет, нельзя.

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

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

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

Так понятнее задача ?
Коротко она звучит так: "Отловить момент возврата из хоста и автоматичи передть управление не на штатное сетевое окружение, а на другой исполняемый код".


Last edited by HankHank on Fri Apr 16, 2010 11:26; edited 1 time in total

#5:  Author: alexey65536Location: Taganrog PostPosted: Fri Apr 16, 2010 11:26
    —
Т.е., допустим, нажав [..] в корне хоста \\COMP, я должен попадать не в WORKGROUP/MSHOME/что-то еще, а в произвольное место (плагин и т.п.)?

#6:  Author: HankHank PostPosted: Fri Apr 16, 2010 11:27
    —
Так точно !

#7:  Author: MVVLocation: Ростов-Дон PostPosted: Fri Apr 16, 2010 17:04
    —
Объясню то, что написал на оф. форуме, но по-русски. Если ты обрабатываешь в хуке сообщения клавы и мыши, ты можешь удалять невыгодные тебе сообщения (обычно в конце хук-обработчика нужно вызывать CallNextHookEx, но в этих обработчиках можно просто вернуть ненулевое значение - и сообщение дальше твоего хука не пойдет). Т.е. ты ловишь попытку юзера нажать Enter или сделать двойной щелчок на элементе ".." до того как ТК получит это сообщение и, если видишь, что при таком раскладе юзер попадет в Сетевое окружение, просто удаляешь сообщение, а ТК говоришь перейти в нужный тебе каталог. В итоге ТК вообще не узнает о том, что юзер хотел зайти в Сетевое окружение.

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

#8:  Author: HankHank PostPosted: Fri Apr 16, 2010 22:00
    —
Чёрт побери, приятная неожиданность, MVV ! Где только не встретишь наших людей ! Very Happy
Да ещё и сподобиться получить ответ от Гислера в тот же день. Хотя, по сути - пустой ответ. Но мы не ищем лёгких путей.

MVV wrote:
Если ты обрабатываешь в хуке сообщения клавы и мыши, ты можешь удалять невыгодные тебе сообщения ...

Да, я понял мысль - написать собственный обработчик, о чём не имею понятия. Но тогда встаёт в полный рост вопрос:
Can you recommend samples of ready templates with a code of a similar trap for M$ Visual C++ ?

#9:  Author: MVVLocation: Ростов-Дон PostPosted: Fri Apr 16, 2010 22:16
    —
HankHank wrote:
Где только не встретишь наших людей ! Very Happy

Наши везде пролезутSmile Я тут видел твое сообщение до того, как увидел там - поэтому понял, что то - твой пост, и отписался тут.

HankHank wrote:
Да ещё и сподобиться получить ответ от Гислера в тот же день. Хотя, по сути - пустой ответ.

Согласись, его можно понять - ты предлагаешь хардкодить граблиSmile

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

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

#10:  Author: HankHank PostPosted: Fri Apr 16, 2010 23:16
    —
Сердечная благодарность за помощь. На неделе попытаюсь разобраться и прикрутить. Вопросы наверняка появятся.
Хороших выходных !

#11:  Author: VadiMGP PostPosted: Sun Apr 18, 2010 01:41
    —
MVV
Я детально не штудировал твой пример, но две проблемы сразу заметны. Они касаются листбоксов (mylb1 и mylb2).
1. Ты исходишь из предположения, что в ТС всегда 2 листбокса. Но это не так. Окна с деревьями тоже листбоксы, значит в разное время может быть от 2 до 4 листбоксов.
2. Ты берешь HWND от них только один раз при инициализации. Но ТС часто уничтожает и создает листбоксы динамически. Например при переключении между режимами (подробный, эскизы, пользовательские колонки).

#12:  Author: MVVLocation: Ростов-Дон PostPosted: Sun Apr 18, 2010 10:24
    —
VadiMGP wrote:
Я детально не штудировал твой пример, но две проблемы сразу заметны. Они касаются листбоксов (mylb1 и mylb2).

Что ж, я не давал клятву, что он идеален. Smile

VadiMGP wrote:
1. Ты исходишь из предположения, что в ТС всегда 2 листбокса. Но это не так. Окна с деревьями тоже листбоксы, значит в разное время может быть от 2 до 4 листбоксов.

Да, действительно. Но я заметил, что у листбоксов деревьев имя текст окна не пуст, значит, можно искать окна файловых панелей по пустому тексту. Тогда в моем примере надо чуть изменить (указать не любой, а пустой текст окна при поиске):
Code:
   mylb1=FindWindowEx(hMainWnd, 0, L"TMyListBox", L"");
   mylb2=FindWindowEx(hMainWnd, mylb1, L"TMyListBox", L"");

Так мы гарантированно найдем окна панелей. Кстати, по идее можно просто брать активное окно, а не искать их - оно будет листбоксом при щелчке мышью и нажатии клавиш в интересующий нас момент.

VadiMGP wrote:
2. Ты берешь HWND от них только один раз при инициализации. Но ТС часто уничтожает и создает листбоксы динамически. Например при переключении между режимами (подробный, эскизы, пользовательские колонки).

Подтверждаю. Тоже не учел. В таком случае нужно либо искать окна панелей каждый раз (два окна найти - не проблема), а можно просто использовать указанный выше фокус. То есть, вызываем GetFocus(), и если окно с фокусом - TMyListBox, значит, берем из него индекс и т.д. Панель состояния в любом случае не изменяется.

Итак, убираем дескрипторы mylb1, mylb2 и их поиск, а функцию GetActivePanel модифицируем следующим образом:
Code:
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;
}

Ну а в хук-функциях проверять, не ноль ли дескриптор окна - если ноль, ниче не делать.

#13:  Author: VadiMGP PostPosted: Sun Apr 18, 2010 11:01
    —
Еще одна проблема - будет ложное срабатывание в режиме эскизов.
Если в строке, скажем, 3 эскиза, то LB_ITEMFROMPOINT вернет 0 для любого из этих трех эскизов, а не только для "..".

Добавлено. Пригляделся еще раз. Нет, похоже, не будет вообще срабатывания. В функции IsForbiddenLevelUp GetWindowText не даст текста. В режиме эскизов невозможно получить текст элемента.

#14:  Author: MVVLocation: Ростов-Дон PostPosted: Sun Apr 18, 2010 12:29
    —
В функции IsForbiddenLevelUp я беру текст из панели в строке состояния, текст в которой есть независимо от режима панели. Текст элементов я вообще нигде не пытаюсь получить - он мне не нужен, расчет на то, что элемент ".." всегда имеет индекс 0.

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

Да, похоже, в режиме эскизов LB_ITEMFROMPOINT работает неправильно - действительно возвращает номер строки. Как, кстати, и LB_GETCARETINDEX - видимо, этот режим Гислер реализовывал сам, и об этих сообщениях не позаботился. Так что оба хука - и клавы, и мыши - будут срабатывать в режиме эскизов на всех элементах первой строки содержимого панели. Нужно что-то придумывать дополнительно.


Last edited by MVV on Sun Apr 18, 2010 12:49; edited 4 times in total

#15:  Author: VadiMGP PostPosted: Sun Apr 18, 2010 12:37
    —
MVV wrote:
В функции IsForbiddenLevelUp я беру текст из панели в строке состояния,
А, значит я ошибся насчет этого.
MVV wrote:
А сообщение LB_ITEMFROMPOINT по идее должно возвращать индекс с учетом того, что листбокс может иметь несколько колонок или строк.
По идее, конечно. Я тоже в свое время на это рассчитывал.
MVV wrote:
Ты проверял, как работает LB_ITEMFROMPOINT, или это предположение?
Еще как проверял. Я знаешь, как в TWinKey нажрался проблем с эскизами... Мама не горюй.



Total Commander -> Написание плагинов для Total Commander


output generated using printer-friendly topic mod. All times are GMT + 4 Hours

Goto page 1, 2, 3  Next  :| |:
Page 1 of 3

Powered by phpBB © 2001, 2005 phpBB Group