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

#31:  Author: MVVLocation: Ростов-Дон PostPosted: Tue Apr 20, 2010 16:02
    —
HankHank wrote:
MVV wrote:
Видимо, ты плохо разобрался с форматом буфера для WM_COPYDATA, который ожидает ТК. Вот он:
Code:
<first_path>\r<second_path>\0<flags>

Флаги: 'T' - в новой вкладке, 'S' - менять пути активной и неактивной панелей вместо левой и правой.

Так ясно. По началу строчка wsprintf показалась заумной. И я решил, что хватит с меня и первого параметра с путём, куда надо переключить активную панель. А откуда эта инфо ?

Ну, официально Гислер вроде это не документировал, в history.txt упоминается только про само сообщение без описания формата. Но вообще на TotalcmdWiki есть пример функции, отправляющей WM_COPYDATA.

HankHank wrote:
MVV wrote:
Таким образом, правильный буфер:
Code:
static char cdnet[]="\\\\\\net\r\0S";


Да, так работает. Буду ковать дальше.

Это главное. Значит, я не ошибся, когда составлял эту строчку. Very Happy

HankHank wrote:
Ещё заметил такую деталь. Может, интересно кому.
Вот здесь http://www.firststeps.ru/mfc/winapi/win/r.php?126 прочитал про WM_COPYDATA:
Quote:
Если принимающая программа обрабатывает это сообщение, она должна возвратить значение ИСТИНА (TRUE); в противном случае она должна возвратить - ЛОЖЬ (FALSE).

У меня же передача параметров срабатывает, происходит переход куда требуется, но SendMessage возвращает при этом 0.

Я обычно читаю MSDN. Но суть не в том. Не обращай внимание на то, что должно быть. Тем более, имея дело с VCL, на которой построены окошки в дельфийских программах - там черт ногу сломит. Кроме того, ничто не мешает ТК обработать сообщение, но вернуть 0. И в нашем случае цель отправки сообщения - не возвращаемое значение, а действие. Smile

#32:  Author: HankHank PostPosted: Tue Apr 20, 2010 21:43
    —
Хочется задействовать командную строку в плагине. Минимальными трудозатратами. Можно попытаться отдать строку Коммандеру, после чего умыть руки. А он уж её пускай обрабатывает.
На уровне идеи, без реализации, на примере клавиатурного хука выглядит как-то так:

Code:


DWORD __stdcall ExecEmulate(void)
{
   // focus to command line
   SendMessage(hMainWnd, WM_USER + 51, 4003, 0);
   // ENTER-pressing
   keybd_event(VK_RETURN, 0, KEYEVENTF_EXTENDEDKEY, 0);
   return 0;
}

bool ExecCommandLine()
{
   HANDLE thread=CreateThread(0, 0, ExecEmulate, 0, 0, 0);
   if (!thread) return 0;
   CloseHandle(thread);
   return 1;
}

LRESULT CALLBACK CallMouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
   if (wParam==WM_LBUTTONDBLCLK)
   {
      HWND mylb=GetActivePanel();
      POINT pt;
      GetCursorPos(&pt);
      ScreenToClient(mylb, &pt);
      int index=SendMessage(mylb, LB_ITEMFROMPOINT, 0, MAKELPARAM(pt.x, pt.y)); // get item index under cursor
      if (!index&&IsForbiddenLevelUp())
      { // it is ".." item and we should refuse 'level up'
         HWND cmdpanel, edit;
         if ((cmdpanel=FindWindowEx(hMainWnd, cmdpanel, "TMyPanel", "")))
            if ((edit=FindWindowEx(cmdpanel, edit, "TMyComboBox", "")))
               if ((FindWindowEx(edit, 0, "TMyComboBox", "")))
               {
                  char buf[1024];
                  int k=GetWindowText(edit, buf, TSIZE(buf));
                  
pseudo code: if buf not emty then
                     ExecCommandLine();

                  
                  return 1; // kill doubleclick event
               }


         DoMyAction();
         return 1; // kill doubleclick event
      }
   }
   return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}

Принял обтекаемую форму. Very Happy Вижу, что топорно.

#33:  Author: MVVLocation: Ростов-Дон PostPosted: Tue Apr 20, 2010 22:23
    —
Я ваще не пойму, какое отношение имеет мышиный хук к командной строке - вход в папку с помощью мыши в ТК никогда не затрагивал содержимого командной строки.
И потом, не пойму, зачем тебе командная строка в пределах твоего плагина - какие там могут быть команды? Пускай юзер перейдет в нормальную папку - благо, команду cd ты ему обеспечишь - а там уже выполняет любые команды.
Наконец, панель состояния - далеко не единственная панель в окне ТК, поэтому просто поиском окна с заданным классом искать ее не советую. В моем примере панель пути искалась до тех пор, пока найденная панель не содержала знак больше в конце строки - иначе это могла быть, скажем, панель с информацией о свободном месте на диске (в ТК 7.04a и ТК 7.50a некоторые классы окон называются по-разному).

#34:  Author: HankHank PostPosted: Wed Apr 21, 2010 09:09
    —
MVV wrote:
Я ваще не пойму, какое отношение имеет мышиный хук к командной строке - вход в папку с помощью мыши в ТК никогда не затрагивал содержимого командной строки.

Речь всего лишь о подходящем месте. Идея состоит в том, чтобы именно из хука отправить содержимое командной строки, если оно, конечно, там есть. А хуки должны быть использованы оба, и клавиатурный в том числе.

MVV wrote:
зачем тебе командная строка в пределах твоего плагина - какие там могут быть команды?

Да мне лично по барабану командная строка в плагине. А пользователю всё едино, если он зашёл в Коммандер – что плагин, что “штатные панели”. Т.е. для того, чтобы не нарушать его “целостности представления” об интерфейсе. Юзеру же в голову может прийти сделать что-нибудь и другое, например: “copy a.txt b.txt” в любом месте TC.

MVV wrote:
панель состояния - далеко не единственная панель в окне ТК, поэтому просто поиском окна с заданным классом искать ее не советую.

Здесь мои представления слабы.
Каким разумным способом можно поискать командную строку и извлечь её содержимое ?

ЗЫ
Что касается версий, то меня вполне устраивают TC не ниже 7.50.

#35:  Author: HankHank PostPosted: Wed Apr 21, 2010 11:12
    —
Всех деталей не упомнишь. Поэтому некоторые уточнения.
Посмотрел попристальнее на командную строку в обычных режимах Коммандера и в плагине.
В обычном режиме (файловые панели) строка выполняется Коммандером только при переводе в неё фокуса ввода после двойного щелчка мышью или нажатия Enter. (Этот момент, кстати, некоторые используют для кратковременного хранения коротких информационных строчек и совсем по разному поводу. Работают в др. приложении или TC, а строчки временно хранят в ком. строке. Изврат, но реально используется).
Пока у меня в плагине осуществляется вылет в сетевое окружение коммандера (где все плагины) после двойного клика или нажатия Enter.

#36:  Author: MVVLocation: Ростов-Дон PostPosted: Wed Apr 21, 2010 12:07
    —
Quote:
А пользователю всё едино, если он зашёл в Коммандер – что плагин, что “штатные панели”.

Между прочим, какую папку ты будешь делать текущей при выполнении команды из папки твоего плагина? У тебя она там попросту неопределена. Да и команда copy - это внутренняя команда командного интерпретатора Windows, она без него вообще не работает, а ему тоже нужна рабочая папка.

Quote:
Каким разумным способом можно поискать командную строку и извлечь её содержимое ?

Юзай мой способ поиска панели с текущим путем (путь тебе все равно пригодится) - рядом (с тем же предком) будет окно командной строки. Wink

Quote:
Посмотрел попристальнее на командную строку в обычных режимах Коммандера и в плагине.

Да, я об этом и говорил. Я сам иногда перехожу между папками мышью, чтобы не стирать набранную командную строку - и я не ожидаю, что она будет выполнена в этот момент.

Quote:
Пока у меня в плагине осуществляется вылет в сетевое окружение коммандера (где все плагины) после двойного клика или нажатия Enter.

То есть, ничего не работает? А как же хуки, которые блокируют команду и устанавливают нужный путь?

#37:  Author: HankHank PostPosted: Wed Apr 21, 2010 22:56
    —
Извини, мысли с утра формулировались с трудом - текучка. На программирование время по остаточному принципу.
Поясняю подробнее.
MVV wrote:
Quote:
А пользователю всё едино, если он зашёл в Коммандер - что плагин, что "штатные панели".

Между прочим, какую папку ты будешь делать текущей при выполнении команды из папки твоего плагина? У тебя она там попросту неопределена. Да и команда copy - это внутренняя команда командного интерпретатора Windows, она без него вообще не работает, а ему тоже нужна рабочая папка.

Команда copy - только для примера. И пример, канеш, неполный. Если к файлам добавить пути и написать так:
Code:

copy c:\temp\a.txt d:\temp2\b.txt
, то должно стать понятным, что я имел в виду - какую-то команду для командного процессора. Или ту же команду перехода на хост типа
Code:

cd \\192.168.1.2
и т.п.
В общем, что в голову взбредёт. Т.е. пользователю удобно в принципе использовать командную строку, как он привык. Он её непременно вобъёт и в моей самописной мульке. У нас юзеры привыкли к Коммандеру. И особенно не заморачиваются раздумьями "что да почему". TC - как-бы часть ОС. Very Happy

MVV wrote:
Юзай мой способ поиска панели с текущим путем (путь тебе все равно пригодится) - рядом (с тем же предком) будет окно командной строки. Wink

Пасиб.

MVV wrote:
Quote:
Посмотрел попристальнее на командную строку в обычных режимах Коммандера и в плагине.

Да, я об этом и говорил. Я сам иногда перехожу между папками мышью, чтобы не стирать набранную командную строку - и я не ожидаю, что она будет выполнена в этот момент.

Вот и ты тоже используешь как временный "карман".

MVV wrote:
Quote:
Пока у меня в плагине осуществляется вылет в сетевое окружение коммандера (где все плагины) после двойного клика или нажатия Enter.

То есть, ничего не работает? А как же хуки, которые блокируют команду и устанавливают нужный путь?

Всё работает на ура. Ходьба вверх-вниз через итем [..] происходит лучше не придумаешь. На порядок лучше, чем в AHK. А вот вариант, когда дополнительно что-то введено в командную строку TC + в одной из панелей сетевое окружение моего плагина "на верхнем уровне" + в командной строке делаю двойной клик мышью или нажимаю Enter, - вот тогда происходит вылет на уровень выше, т.е в сетевое окружение коммандера (где список плагинов и прочее). А должна по идее выполниться командная строка.

Захотелось из хорошего сделать ещё лучше - задействовать командную строку и в этом случае. Так сказать, поставить логическую точку. Так понятней ?

#38:  Author: MVVLocation: Ростов-Дон PostPosted: Thu Apr 22, 2010 00:17
    —
Quote:
Всё работает на ура. Ходьба вверх-вниз через итем [..] происходит лучше не придумаешь. На порядок лучше, чем в AHK.

Ну дык) чистый ассемблер куда лучше всяких байт-кодов.

Quote:
А вот вариант, когда дополнительно что-то введено в командную строку TC + в одной из панелей сетевое окружение моего плагина "на верхнем уровне" + в командной строке делаю двойной клик мышью или нажимаю Enter, - вот тогда происходит вылет на уровень выше, т.е в сетевое окружение коммандера (где список плагинов и прочее). А должна по идее выполниться командная строка.

Чего-то я не понимаю. Если в командной строке делать даблклик или жать Enter, ТК чисто выполняет командную строку, при этом папка не меняется (если, конечно, команда не cd). И этот клик по идее игнорируется хуками, так как при этом активное окно - не файловая панель. И поведение это изменению не поддается, да и нет в том необходимости. Или ты хочешь выполнять эту командную строку?

Под сетевым окружением твоего плагина "на верхнем уровне" ты понимаешь папку своего плагина?

#39:  Author: HankHank PostPosted: Thu Apr 22, 2010 10:32
    —
MVV wrote:
Под сетевым окружением твоего плагина "на верхнем уровне" ты
понимаешь папку своего плагина?

Согласен, коряво и длинно выазился. Недостаток общения по обсуждаемой проблематике. Very Happy Но ты понял верно: да, именно папка моего плагина и есть место преткновения.

MVV wrote:
Если в командной строке делать даблклик или жать Enter, ТК чисто выполняет командную строку, при этом папка не меняется (если, конечно, команда не cd).

Совершенно справедливо для типовых файловых панелей.

MVV wrote:
И этот клик по идее игнорируется хуками, так как при этом активное окно - не файловая панель.

Активна не файловая панель, в которой в этот момент папка моего плагина. Активной оказывается командная строка. На ней фокус ввода.

MVV wrote:
И поведение это изменению не поддается, да и нет в том необходимости.

Получается нелогичное с точки зрения неискушённого юзера поведение TC.
Это поведение одинаково для любого элемента списка папки моего плагина, необязательно для начального элемента списка [..]. При даблклике или нажатии Enter (в активном окне) командной строки происходит “вылет” на уровень вверх с установкой курсора на начало списка плагинов. При этом командная строка ”проглатывается” Коммандером, но команду он при этом не выполняет...

------------------------------
Блииин... Полезно бывает копаться в деталях. Только сейчас допёрло, что у меня в этот момент слева от командной строки изображено-то: \\\net> Exclamation
Ну, лопухнулся. Я этот момент не отслеживаю как надо. А как надо Question

MVV wrote:
Или ты хочешь выполнять эту командную строку?

Именно так. Мне представляется логичным выполнить командную строку в папке моего плагина, если у юзера есть в том необходимость.

#40:  Author: HankHank PostPosted: Thu Apr 22, 2010 11:03
    —
Решение напрашивается такое.
В функции InitializeHooks(), помимо окна класса TMyPanel, содержащего магический значок “>” в конце пути, надо найти хэндл на класс Edit - editpanel. Интересно, он один с таким именем в оконном списке ?
А в хуках уже смотреть, не пустая ли командная строка с помощью GetWindowText(editpanel, buf, TSIZE(buf)) ?
Если не пустая, выполнить функцию ExecCommandLine() из моей пурги в начале странички.

#41:  Author: MVVLocation: Ростов-Дон PostPosted: Thu Apr 22, 2010 13:03
    —
Уточню еще раз.

Если при нажатии клавиши Enter командная строка не пуста, то нажатие клавиши приводит к выполнению команды без смены текущей папки.

Если при нажатии клавиши Enter командная строка пуста, или же выполняется даблклик мышью по элементу файловой панели, то происходит изменение текущей папки без выполнения какой-либо команды и очистки командной строки.

Эти аспекты должны иметь место быть при работе с любыми файловыми панелями, будь то панели содержимого папки на диске, сетевой папки или папки плагина файловой системы. И их искажение я не считаю допустимым и в какой бы то ни было мере разумным.

Все что от тебя требуется - это при особом желании выполнить командную строку, которую ТК передаст тебе, вызывав функцию FsExecuteFile в момент нажатия юзером клавиши Enter или даблклике мышью по непустой командной строке. Извлекать текст командной строки при этом тебе абсолютно не нужно. Замечу, что в этом месте может играть роль то, что плагин не поддерживает Юникод, так как командная строка может содержать юникод-символы не из системной кодовой страницы. Также при выполнении команды не забывай, что текущая рабочая папка не определена.

Если тебе все-таки неймется, дескриптор командной строки ты можешь получить, если возьмешь GetParent() от дескриптора панели с текстом текущего пути, и в найденном окне найдешь TMyComboBox, в котором потом найдешь Edit (гарантированно тот самый, который нужен). Или же сразу встроишься в цикл поиска панели пути, где дескриптор родительского окна есть:
Code:
   while (1) {
      if (!(cmdpanel=FindWindowEx(hMainWnd, cmdpanel, "TMyPanel", L""))) break;
      if ((cmdlbox=FindWindowEx(cmdpanel, 0, "TMyComboBox", L"")) || (cmdlbox=FindWindowEx(cmdpanel, 0, "TComboBox", L""))) {
         HWND pathpanel=FindWindowEx(cmdpanel, 0, "TMyPanel", 0);
         int k=GetWindowText(pathpanel, buf, TSIZE(buf));
         if (k&&buf[k-1]=='>') {
            stpath=pathpanel;
            cmdline=FindWindowEx(cmdlbox, 0, "Edit", 0);
            break;
         }
      }
   }

(переменная cmdlbox - локальная, будет содержать дескриптор комбобокса с командной строкой, который в ТК 7.04a и 7.50a имеет разные классы - здесь ищутся оба; переменная cmdline - глобальная, получит дескриптор окна командной строки)

#42:  Author: HankHank PostPosted: Thu Apr 22, 2010 14:05
    —
MVV wrote:
...при особом желании выполнить командную строку, которую ТК передаст тебе, вызывав функцию FsExecuteFile в момент нажатия юзером клавиши Enter или даблклике мышью по непустой командной строке. Извлекать текст командной строки при этом тебе абсолютно не нужно.

Вот этот момент я совершенно упустил из виду. Плохо изучал API. Собственно, это и есть исчерпывающее решение.

И за это также респект:
MVV wrote:
Замечу, что в этом месте может играть роль то, что плагин не поддерживает Юникод, так как командная строка может содержать юникод-символы не из системной кодовой страницы. Также при выполнении команды не забывай, что текущая рабочая папка не определена.


Пазл собрался. Very Happy
Всем, кто помогал найти решение, - сердечная благодарность.



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


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

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

Powered by phpBB © 2001, 2005 phpBB Group